Skip to content

Commit 45a119f

Browse files
authored
Add support for freeform SHM'ed output (#33)
1 parent 60592cf commit 45a119f

File tree

8 files changed

+55
-26
lines changed

8 files changed

+55
-26
lines changed

edge_impulse_linux/runner.py

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ def now():
1313
return round(time.time() * 1000)
1414

1515
class ImpulseRunner:
16-
def __init__(self, model_path: str, timeout: int = 5):
16+
def __init__(self, model_path: str, timeout: int = 30, allow_shm = True):
1717
self._model_path = model_path
1818
self._tempdir = None
1919
self._runner = None
2020
self._client = None
2121
self._ix = 0
2222
self._debug = False
2323
self._hello_resp = None
24-
self._shm = None
24+
self._allow_shm = allow_shm
25+
self._input_shm = None
26+
self._freeform_output_shm = []
2527
self._timeout = timeout
2628

2729
def init(self, debug=False):
@@ -57,17 +59,32 @@ def init(self, debug=False):
5759

5860
hello_resp = self._hello_resp = self.hello()
5961

60-
if ('features_shm' in hello_resp.keys()):
61-
shm_name = hello_resp['features_shm']['name']
62-
# python does not want the leading slash
63-
shm_name = shm_name.lstrip('/')
64-
shm = shared_memory.SharedMemory(name=shm_name)
65-
self._shm = {
66-
'shm': shm,
67-
'type': hello_resp['features_shm']['type'],
68-
'elements': hello_resp['features_shm']['elements'],
69-
'array': np.ndarray((hello_resp['features_shm']['elements'],), dtype=np.float32, buffer=shm.buf)
70-
}
62+
if self._allow_shm:
63+
if ('features_shm' in hello_resp.keys()):
64+
shm_name = hello_resp['features_shm']['name']
65+
# python does not want the leading slash
66+
shm_name = shm_name.lstrip('/')
67+
shm = shared_memory.SharedMemory(name=shm_name)
68+
self._input_shm = {
69+
'shm': shm,
70+
'type': hello_resp['features_shm']['type'],
71+
'elements': hello_resp['features_shm']['elements'],
72+
'array': np.ndarray((hello_resp['features_shm']['elements'],), dtype=np.float32, buffer=shm.buf)
73+
}
74+
75+
if ('freeform_output_shm' in hello_resp.keys()):
76+
for output_shm in hello_resp['freeform_output_shm']:
77+
shm_name = output_shm['name']
78+
# python does not want the leading slash
79+
shm_name = shm_name.lstrip('/')
80+
shm = shared_memory.SharedMemory(name=shm_name)
81+
self._freeform_output_shm.append({
82+
'index': output_shm['index'],
83+
'shm': shm,
84+
'type': output_shm['type'],
85+
'elements': output_shm['elements'],
86+
'array': np.ndarray((output_shm['elements'],), dtype=np.float32, buffer=shm.buf)
87+
})
7188

7289
return self._hello_resp
7390

@@ -88,18 +105,23 @@ def stop(self):
88105
# todo: in Node we send a SIGHUP after 0.5sec if process has not died, can we do this somehow here too?
89106
self._runner = None
90107

91-
if self._shm is not None:
92-
self._shm['shm'].close()
93-
resource_tracker.unregister(self._shm['shm']._name, "shared_memory")
94-
self._shm = None
108+
if self._input_shm is not None:
109+
self._input_shm['shm'].close()
110+
resource_tracker.unregister(self._input_shm['shm']._name, "shared_memory")
111+
self._input_shm = None
112+
113+
for shm in self._freeform_output_shm:
114+
shm['shm'].close()
115+
resource_tracker.unregister(shm['shm']._name, "shared_memory")
116+
self._freeform_output_shm = []
95117

96118
def hello(self):
97119
msg = {"hello": 1}
98120
return self.send_msg(msg)
99121

100122
def classify(self, data):
101-
if self._shm:
102-
self._shm['array'][:] = data
123+
if self._input_shm:
124+
self._input_shm['array'][:] = data
103125

104126
msg = {
105127
"classify_shm": {
@@ -113,6 +135,13 @@ def classify(self, data):
113135
msg["debug"] = True
114136

115137
send_resp = self.send_msg(msg)
138+
139+
if 'result' in send_resp and 'freeform' in send_resp['result'] and send_resp['result']['freeform'] == 'shm':
140+
freeform = []
141+
for shm in self._freeform_output_shm:
142+
freeform.append(shm['array'].tolist())
143+
send_resp['result']['freeform'] = freeform
144+
116145
return send_resp
117146

118147
def set_threshold(self, obj):

examples/audio/classify.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def main(argv):
4141
with AudioImpulseRunner(modelfile) as runner:
4242
try:
4343
model_info = runner.init()
44-
# model_info = runner.init(debug=True, timeout=10) # to get debug print out and set longer timeout
44+
# model_info = runner.init(debug=True, timeout=60) # to get debug print out and set longer timeout
4545
labels = model_info['model_parameters']['labels']
4646
print('Loaded runner for "' + model_info['project']['owner'] + ' / ' + model_info['project']['name'] + '"')
4747

examples/custom/classify.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def main(argv):
5454
runner = ImpulseRunner(modelfile)
5555
try:
5656
model_info = runner.init()
57-
# model_info = runner.init(debug=True, timeout=10) # to get debug print out and set longer timeout
57+
# model_info = runner.init(debug=True, timeout=60) # to get debug print out and set longer timeout
5858

5959
print('Loaded runner for "' + model_info['project']['owner'] + ' / ' + model_info['project']['name'] + '"')
6060

examples/image/classify-full-frame.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def main(argv):
7171
with ImageImpulseRunner(modelfile) as runner:
7272
try:
7373
model_info = runner.init()
74-
# model_info = runner.init(debug=True, timeout=10) # to get debug print out and set longer timeout
74+
# model_info = runner.init(debug=True, timeout=60) # to get debug print out and set longer timeout
7575

7676
print('Loaded runner for "' + model_info['project']['owner'] + ' / ' + model_info['project']['name'] + '"')
7777
labels = model_info['model_parameters']['labels']

examples/image/classify-image.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def main(argv):
4343
with ImageImpulseRunner(modelfile) as runner:
4444
try:
4545
model_info = runner.init()
46-
# model_info = runner.init(debug=True, timeout=10) # to get debug print out and set longer timeout
46+
# model_info = runner.init(debug=True, timeout=60) # to get debug print out and set longer timeout
4747

4848
print('Loaded runner for "' + model_info['project']['owner'] + ' / ' + model_info['project']['name'] + '"')
4949
labels = model_info['model_parameters']['labels']

examples/image/classify-video.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def main(argv):
4848
with ImageImpulseRunner(modelfile) as runner:
4949
try:
5050
model_info = runner.init()
51-
# model_info = runner.init(debug=True, timeout=10) # to get debug print out and set longer timeout
51+
# model_info = runner.init(debug=True, timeout=60) # to get debug print out and set longer timeout
5252
print('Loaded runner for "' + model_info['project']['owner'] + ' / ' + model_info['project']['name'] + '"')
5353
labels = model_info['model_parameters']['labels']
5454

examples/image/classify.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def main(argv):
7575
with ImageImpulseRunner(modelfile) as runner:
7676
try:
7777
model_info = runner.init()
78-
# model_info = runner.init(debug=True, timeout=10) # to get debug print out and set longer timeout
78+
# model_info = runner.init(debug=True, timeout=60) # to get debug print out and set longer timeout
7979
print('Loaded runner for "' + model_info['project']['owner'] + ' / ' + model_info['project']['name'] + '"')
8080
labels = model_info['model_parameters']['labels']
8181
if len(args)>= 2:

examples/image/set-thresholds.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def main(argv):
4444
with ImageImpulseRunner(modelfile) as runner:
4545
try:
4646
model_info = runner.init()
47-
# model_info = runner.init(debug=True, timeout=10) # to get debug print out and set longer timeout
47+
# model_info = runner.init(debug=True, timeout=60) # to get debug print out and set longer timeout
4848

4949
print('Loaded runner for "' + model_info['project']['owner'] + ' / ' + model_info['project']['name'] + '"')
5050
if not 'thresholds' in model_info['model_parameters']:

0 commit comments

Comments
 (0)