3

I am trying to work with matlab through python to prototype a system that I have developed. Is mlabwrap capable of handeling multiprocessing? This may come across as very stupid, but I was thinking I could do the following:

from multiprocessing import Process,Lock
from mlabwrap import mlab
from mlabwrap import mlab as mlab1

def some_Function(mlab,Astring)
    #do some stuff....

p1=Process(target=some_Function,args=(mlab,"Example string 1"))
p2=Process(target=some_Function,args=(mlab1,"Example string 2"))
p1.start()
p2.start()

but I keep getting this error:

Traceback (most recent call last):
  File "/usr/lib64/python2.6/multiprocessing/process.py", line 232, in _bootstrap
    self.run()
  File "/usr/lib64/python2.6/multiprocessing/process.py", line 88, in run
    self._target(*self._args, **self._kwargs)
  File "test.py", line 15, in process_Camera
    res=mlab.RetrieveAndProcess(cameraDirectory)
  File "/home/mar608/data/cameraSystem/mlabwrap-1.1/build/lib.linux-x86_64-2.6/mlabwrap.py", line 607, in mlab_command
    return self._do(name, *args, **update({'nout':nout}, kwargs))
  File "/home/mar608/data/cameraSystem/mlabwrap-1.1/build/lib.linux-x86_64-2.6/mlabwrap.py", line 515, in _do
    mlabraw.eval(self._session,  "cd('%s');" % os.getcwd().replace("'", "''"))
error: Unable to evaluate string in MATLAB(TM) workspace

Note, I do not get this error when I run just the function regularly, even if I run the function once with mlab and again with mlab1. It only happens when I run it as a process, and it happens regardless of whether or not I run another process with it.

Any hints would be greatly appreciated!

Note that this happens for all matlab functions. For instance, calling mlab.sum([2,3]) also gives the same error

NOTE: I know I should not be doing this sort of thing for a final product of my code. I won't be doing this in the final version, I just want to get a demo working.

Mark
  • 409
  • 2
  • 6
  • 17

1 Answers1

1

Matlab itself is single-threaded at the M-code level - that is, the M-code interpreter can only handle a single concurrent M-code execution - so you won't be able to do concurrent processing inside a single Matlab process.

from mlabwrap import mlab
from mlabwrap import mlab as mlab1

This import just aliases both mlab and mlab1 to the same mlabwrap.mlab variable, which is a class variable holding a single mlabwrap instance, so they're probably both pointing at the same mlabwrap object and thus the same Matlab session even once you pass them to your different Process objects. (If you run the function once with mlab and again with mlab1 without Process objects, you're making blocking calls and doing them in sequence, so within that shared Matlab session, only one piece of M-code is running at a time, instead of concurrent execution.)

To get this to work, you'll need to fire up a separate Matlab session for each of your parallel processes. You may be able to do this by creating a new mlabwrap object for each process, instead of just reusing mlab. Mlabwrap uses the Matlab Engine behind the scenes; I don't know if it supports running multiple engine instances from a single program or not; the engOpen documentation doesn't specify. But if it does, using multiple mlabwrap objects might expose it for your Python code, because the mlabwrap.__init__ code attempts to open a new engine when it's constructed.

Andrew Janke
  • 23,508
  • 5
  • 56
  • 85
  • I tried this, it may be the case that this works but I would still need the underlying error of mlabwrap not being able to run in a process (that's where the error above comes from, and I get it regardless of whether or not I invoke another process. So long as I use mlabwrap in a process once, I get that error and no computation is run) – Mark Apr 22 '13 at 18:46
  • You may be able to get around that by constructing the `mlabwrap` object inside the worker Process, instead of constructing it in the main (calling) process and handing it off as an object. That way the Matlab Engine library will be loaded and initialized in the same process that the later Matlab calls happen in. Maybe you could spin up a `multiprocessing.Pool` of workers, each with the Matlab engine loaded in, and then send them Matlab requests. Have each one run a function that initializes an mlabwrap and then reads a queue or something for functions to apply to it. – Andrew Janke Apr 22 '13 at 20:02