I am trying to execute the RunInference method of a BasicEngine object on a separate process using the multiprocessing module. It looks like it enters in a deadlock, but I don't know why. My final objective is to get the CPU usage profile of the RunInference method.
I am trying to run it on a RaspberryPi3B+ with a Coral Accelerator and Python 3.5. The RunInference method is correctly executed when the BasicEngine is instanciated in the same process.
from edgetpu.classification.engine import BasicEngine
import random
import numpy as np
import psutil
import time
import multiprocessing as mp
#Code inspired from https://stackoverflow.com/questions/49197916/how-to-profile-cpu-usage-of-a-python-script
def run_on_another_process(target, args=(), kwargs={}):
worker_process = mp.Process(target=target, args=args, kwargs=kwargs)
worker_process.start()
p = psutil.Process(worker_process.pid)
while worker_process.is_alive():
#Do something in the parent, e.g., measure the CPU percentage
print("[Parent] CPU PERCENT: " + str(p.cpu_percent()))
time.sleep(0.1)
worker_process.join()
#Loading model
model_path = "<path_to_model>/inception_v1_224_quant_edgetpu.tflite"
engine = BasicEngine(model_path)
print("Engine and model ready!")
#Prepare data
input_size = engine.required_input_array_size()
data = np.array([random.randint(0, 255) for _ in range(input_size)], dtype=np.uint8)
#Infernce on another process
run_on_another_process(engine.RunInference, args=(data,))
The method looks like it is in a deadlock. If I fire a KeybordInterrupt I get these errors:
Traceback (most recent call last):
File "/<path_to_script>/script.py", line 31, in <module>
run_on_another_process(lambda data: engine.RunInference(data), args=(data,))
File "/<path_to_script>/script.py", line 17, in run_on_another_process
time.sleep(0.1)
KeyboardInterrupt
Then, I get
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/usr/lib/python3.5/multiprocessing/popen_fork.py", line 29, in poll
pid, sts = os.waitpid(self.pid, flag)
KeyboardInterrupt
Any help would be really helpful!
Edit #1:
Here in the following a working example when both the BasicEngine and the RunInference methods are called on the same process. The parent process prints a limited number of messages.
from edgetpu.classification.engine import BasicEngine
import random
import numpy as np
import psutil
import time
import multiprocessing as mp
def child_func():
#Loading model
model_path = "<path_to_model>/inception_v1_224_quant_edgetpu.tflite"
engine = BasicEngine(model_path)
print("[Child] Engine and model ready!")
#Prepare data
input_size = engine.required_input_array_size()
data = np.array([random.randint(0, 255) for _ in range(input_size)], dtype=np.uint8)
engine.RunInference(data)
def run_on_another_process(target, args=(), kwargs={}):
worker_process = mp.Process(target=target, args=args, kwargs=kwargs)
worker_process.start()
p = psutil.Process(worker_process.pid)
while worker_process.is_alive():
#Do something in the parent, e.g., measure the CPU percentage
print("[Parent] CPU PERCENT: " + str(p.cpu_percent()))
time.sleep(0.1)
worker_process.join()
#Run on another process
run_on_another_process(child_func)