1

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)
  • I tried to reproduce this issue. For me it is continuously printing ""[Parent] CPU PERCENT: 0.0 ". Is this what you are referring to a deadlock ? Did you also try to run another demo in loop which performs inferences on an image ? – Manoj Jul 03 '19 at 09:59
  • 1
    That message is printed by the Parent process and it is expected, but it should print only a few messages since the RunInference call should be quite fast. The problem is with the Child process that looks it is blocked and the parent waits. I added an example (Edit #1) that works when the child process is executes both the BasicEngine instantiation and the RunInference method. – Mattia Antonini Jul 03 '19 at 10:22

0 Answers0