Thread Subject: Starting matlab engine from one thread, using it in another

Subject: Starting matlab engine from one thread, using it in another

From: Akshay Ambekar

Date: 23 Feb, 2011 04:30:20

Message: 1 of 7

Hello,

I am writing a C mex-function to be called from Matlab, which in turn starts multiple matlab engines to evaluate multiple instances of a function parallely (from seperate threads in the C mex-function).

Here is some code excerpt:

typedef struct {
    mxArray *matrix_pointer;
    Engine *ep;
    unsigned int threadno;
} arglist;

mxArray *plhs_global;

// The multi-threaded function
unsigned int __stdcall RunRuncommand(void *CallingArg)
{
    unsigned int status;
    arglist CallingArguments, *CallingArgs;
    mxArray *out_matrix_pointer;
    CallingArgs = (arglist *)CallingArg;
    CallingArguments = *CallingArgs;

     status = engPutVariable(CallingArguments.ep, "input_matrix", CallingArguments.matrix_pointer);
     status = engEvalString(CallingArguments.ep, "inv_matrix = inv(input_matrix);");
     out_matrix_pointer = engGetVariable(CallingArguments.ep, "inv_matrix");
     mxSetCell(plhs_global, CallingArguments.threadno, out_matrix_pointer);
     _endthreadex(0);
    return status;
}


//The matlab mex function, standard interface
void mexFunction(int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{
    ...
    HANDLE *ThreadList; // Handles to the worker threads
    arglist CallingArg;
    mxArray *matrix_pointer;
    Engine *ep[nprocess]; //use malloc later!!

    stackidx = 0;
    for (i = 0; i < nprocess; i++) {
        matrix_pointer = mxGetCell(prhs[0], stackidx);
        CallingArg.matrix_pointer = matrix_pointer;
        ep[stackidx] = engOpenSingleUse(NULL, NULL, NULL);
        CallingArg.ep = ep[stackidx];
        CallingArg.threadno = i;
        ThreadList[i] = (HANDLE)_beginthreadex(NULL, 0, &RunRuncommand, (void *)&CallingArg, 0, NULL);
        Sleep(100L);
        stackidx++;
}


    for (i = 0; i < nprocess; i++) {
CloseHandle(ThreadList[i]);
engClose(ep[i]);
}
    plhs[0] = plhs_global;
} // Of mexFunction


However, this does not seem to work for some reason. If I use the engPutVariable() / engEvalString in the same thread as engOpen(), I get desired result. But if I use it like I outlined, the engPutVariable() / engEvalString() return 1, and I get no output.

I also tried putting the engOpen() in the multi-threaded function (which gives required output), but it seems to open and close engines sequentially, rather than parallelly and does not solve my purpose.

I am quite new to Matlab API programing and C multi-threaded application development, so I might be overlooking something basic. Any suggestions?

- Akshay

Subject: Starting matlab engine from one thread, using it in another

From: Rune Allnor

Date: 23 Feb, 2011 08:29:13

Message: 2 of 7

On Feb 23, 5:30 am, "Akshay Ambekar" <akshay.ambe...@ge.com> wrote:
> Hello,
>
> I am writing a C mex-function to be called from Matlab, which in turn starts multiple matlab engines to evaluate multiple instances of a function parallely (from seperate threads in the C mex-function).
...
> I am quite new to Matlab API programing and C multi-threaded application development, so I might be overlooking something basic. Any suggestions?

C was never designed for multi-thread work in the first place.
Doing multi-thread work in C at all, is hard. There are
any number of details that might go wrong.

Recent versions of matlab does already use multi-thread
algorithms, that take advantage of whatever resources
you have available. There needs not be any net gain by
running several matlab engines in parallel. If each engine
uses all available cores, then the overall result will be
indistinguishable from the engines running sequentially.
Your efforts will only be successful if the algorithms
are completely sequential, with no potential for parallelism
whatsoever.

Rune

Subject: Starting matlab engine from one thread, using it in another

From: Akshay Ambekar

Date: 23 Feb, 2011 10:55:09

Message: 3 of 7

Hi Rune,

I am using this as an alternative to the parallel computing toolbox, for parallelizing independent function calls (each function call is quite sequential).
I am pretty certain that I can get computational benefits from this after looking at the CPU load during single execution of the function.

Thanks and Regards,
Akshay

Rune Allnor <allnor@tele.ntnu.no> wrote in message <83d00694-3f01-4829-84c0-45fdf9421aee@u3g2000vbe.googlegroups.com>...
> On Feb 23, 5:30 am, "Akshay Ambekar" <akshay.ambe...@ge.com> wrote:
> > Hello,
> >
> > I am writing a C mex-function to be called from Matlab, which in turn starts multiple matlab engines to evaluate multiple instances of a function parallely (from seperate threads in the C mex-function).
> ...
> > I am quite new to Matlab API programing and C multi-threaded application development, so I might be overlooking something basic. Any suggestions?
>
> C was never designed for multi-thread work in the first place.
> Doing multi-thread work in C at all, is hard. There are
> any number of details that might go wrong.
>
> Recent versions of matlab does already use multi-thread
> algorithms, that take advantage of whatever resources
> you have available. There needs not be any net gain by
> running several matlab engines in parallel. If each engine
> uses all available cores, then the overall result will be
> indistinguishable from the engines running sequentially.
> Your efforts will only be successful if the algorithms
> are completely sequential, with no potential for parallelism
> whatsoever.
>
> Rune

Subject: Starting matlab engine from one thread, using it in another

From: Lucas

Date: 8 Mar, 2011 13:40:15

Message: 4 of 7

Akshay,
    I recently started toying around with the Matlab engine myself, so if you have discovered anything new since your last post I would like to hear about it. A few suggestions:
    (i) You may want to break down your project into smaller pieces. I would try creating the C code to spawn the threads and start the engines stand-alone (no mex function). You can add the mex wrapper later and it may make debugging easier.
    (ii) Opening a Matlab engine takes a considerable amount of time, so you should probably open all the engines you will need in some initialization code and store the pointers in a static or global variable (you will need to provide some cleanup code to shut them down).
    (iii) I would start the threads in the initialization code too. Each thread would communicate with the main thread through message queues. I used this technique once to write a mex function that would read data from a file in a separate thread, and it worked quite well. You just need to be careful to call mexlock when you start the threads and do not call mexunlock until the threads have exited (I sent the thread a command to exit and then called join on it before calling mexunlock).
    (iv) If you know any C++, it may make your life easier to use a singleton class to store the information about the threads and the engines. You can also use the boost thread API (www.boost.org) to make your code more portable.
    (v) You can use engSetVisible() to show the actual instance of Matlab that your code is using. Then you can enter the commands directly, at the same time that you are debugging your code, to see whether the problem is with the command or with the communication with the engine.

You probably knew most of this already, but I hope it has given you some ideas. Please post back if you make any progress.

Regards,
Lucas




"Akshay Ambekar" <akshay.ambekar@ge.com> wrote in message <ik2p2d$i8q$1@fred.mathworks.com>...
> Hi Rune,
>
> I am using this as an alternative to the parallel computing toolbox, for parallelizing independent function calls (each function call is quite sequential).
> I am pretty certain that I can get computational benefits from this after looking at the CPU load during single execution of the function.
>
> Thanks and Regards,
> Akshay
>

Subject: Starting matlab engine from one thread, using it in another

From: Akshay Ambekar

Date: 10 Mar, 2011 04:52:04

Message: 5 of 7

Hey Lucas,

Thanks for the tips. I will try them out over the next few days and write back here.

This is the first time I am trying both - multi-threading in C and using the matlab engine, so I have a steep learning curve. I am using the simple __beginthreadex() / __endthreadex() from process.h for thread control, which might not be the best approach.

When I call engOpen(NULL) from the master thread, it takes some time and returns an Engine pointer only after the engine is open. I can then use engPutVariable() / engEvalString() / engGetVariable() from the master thread to work on this engine. However, when I pass the same Engine pointer to a worker thread, engPutVariable(), etc do not work in the worket thread. Have you had similar experience?

I also tried putting engOpen and engPutVariable(), etc in the worker threads, but then the engines open and execute sequentially, as though engine commands interrupt execution of the master thread itself.

Of course, this might also be because I am calling the master thread from a mexFunction interface, so I will try your first suggestion.

Thanks,
Akshay


"Lucas" wrote in message <il5bjv$16i$1@fred.mathworks.com>...
> Akshay,
> I recently started toying around with the Matlab engine myself, so if you have discovered anything new since your last post I would like to hear about it. A few suggestions:
> (i) You may want to break down your project into smaller pieces. I would try creating the C code to spawn the threads and start the engines stand-alone (no mex function). You can add the mex wrapper later and it may make debugging easier.
> (ii) Opening a Matlab engine takes a considerable amount of time, so you should probably open all the engines you will need in some initialization code and store the pointers in a static or global variable (you will need to provide some cleanup code to shut them down).
> (iii) I would start the threads in the initialization code too. Each thread would communicate with the main thread through message queues. I used this technique once to write a mex function that would read data from a file in a separate thread, and it worked quite well. You just need to be careful to call mexlock when you start the threads and do not call mexunlock until the threads have exited (I sent the thread a command to exit and then called join on it before calling mexunlock).
> (iv) If you know any C++, it may make your life easier to use a singleton class to store the information about the threads and the engines. You can also use the boost thread API (www.boost.org) to make your code more portable.
> (v) You can use engSetVisible() to show the actual instance of Matlab that your code is using. Then you can enter the commands directly, at the same time that you are debugging your code, to see whether the problem is with the command or with the communication with the engine.
>
> You probably knew most of this already, but I hope it has given you some ideas. Please post back if you make any progress.
>
> Regards,
> Lucas
>
>
>
>
> "Akshay Ambekar" <akshay.ambekar@ge.com> wrote in message <ik2p2d$i8q$1@fred.mathworks.com>...
> > Hi Rune,
> >
> > I am using this as an alternative to the parallel computing toolbox, for parallelizing independent function calls (each function call is quite sequential).
> > I am pretty certain that I can get computational benefits from this after looking at the CPU load during single execution of the function.
> >
> > Thanks and Regards,
> > Akshay
> >

Subject: Starting matlab engine from one thread, using it in another

From: tristram.scott@ntlworld.com (Tristram Scott)

Date: 10 Mar, 2011 09:01:03

Message: 6 of 7

Akshay Ambekar <akshay.ambekar@ge.com> wrote:
> Hey Lucas,
>
> Thanks for the tips. I will try them out over the next few days and write
> back here.
>
> This is the first time I am trying both - multi-threading in C and using
> the matlab engine, so I have a steep learning curve. I am using the simple
> __beginthreadex() / __endthreadex() from process.h for thread control,
> which might not be the best approach.
>

What Lucas has suggested seems good advice to me, especially since you are
attempting two different things for the first time. I don't know I am
adding much to what he already said, but:

Do start with stand alone C, and wrap it as a mex function later.
Debugging is much simpler when you only need to deal with a single
environment, so park MATLAB and start with getting the C correct.

Verify that you are correctly creating the threads, and that they can do
some independent work. Start with just some simple hello world stuff,
reporting the thread id, for example.

Next, verify that you have done the right thing so that you can pass data
to and from the threads. What is the scope of the variables you are trying
to use in the threads?

Assuming you are happy up to this point, I would suggest the next step
should be wrapping this as a mex function. Try something simple, such as
passing in an array, and having each thread double one element of the
array.

After that, get back to creating the engines and having them do some work
for you. As Lucas suggested, create all of the engines up front, and then
fire off tasks to them in a loop. Think about having an initialisation
call which creates the threads, followed by subsequent calls asking the
threads to do some work. Use static variables as appropriate to maintain
data across calls to the mex function. Remember to use mexAtExit to clean
up.

Another thing to consider, if you haven't already, is that it is possible
to use engOpen to start MATLAB on a remote machine. If you can do that,
there is certainly scope for quite hefty speedup, even if your code is
already taxing all the processors on your machine. Why not have some other
computer do the work for you?

--
Dr Tristram J. Scott
Energy Consultant

Subject: Starting matlab engine from one thread, using it in another

From: Lucas

Date: 14 Mar, 2011 13:22:06

Message: 7 of 7

Another thing that I just noticed in looking back over your code: You are calling the Sleep function with an input of 100. Depending on your OS, this will produce different results. If you are using Windows, I believe this will suspend the thread for only 100 milliseconds. If this is the case, then most likely what is happening is your 'main' thread is exiting--and consequentially shutting down the Matlab engines--before your worker threads have a chance to finish.

Lucas


tristram.scott@ntlworld.com (Tristram Scott) wrote in message <ila40f$p8n$1@news.eternal-september.org>...
> Akshay Ambekar <akshay.ambekar@ge.com> wrote:
> > Hey Lucas,
> >
> > Thanks for the tips. I will try them out over the next few days and write
> > back here.
> >
> > This is the first time I am trying both - multi-threading in C and using
> > the matlab engine, so I have a steep learning curve. I am using the simple
> > __beginthreadex() / __endthreadex() from process.h for thread control,
> > which might not be the best approach.
> >
>
> What Lucas has suggested seems good advice to me, especially since you are
> attempting two different things for the first time. I don't know I am
> adding much to what he already said, but:
>
> Do start with stand alone C, and wrap it as a mex function later.
> Debugging is much simpler when you only need to deal with a single
> environment, so park MATLAB and start with getting the C correct.
>
> Verify that you are correctly creating the threads, and that they can do
> some independent work. Start with just some simple hello world stuff,
> reporting the thread id, for example.
>
> Next, verify that you have done the right thing so that you can pass data
> to and from the threads. What is the scope of the variables you are trying
> to use in the threads?
>
> Assuming you are happy up to this point, I would suggest the next step
> should be wrapping this as a mex function. Try something simple, such as
> passing in an array, and having each thread double one element of the
> array.
>
> After that, get back to creating the engines and having them do some work
> for you. As Lucas suggested, create all of the engines up front, and then
> fire off tasks to them in a loop. Think about having an initialisation
> call which creates the threads, followed by subsequent calls asking the
> threads to do some work. Use static variables as appropriate to maintain
> data across calls to the mex function. Remember to use mexAtExit to clean
> up.
>
> Another thing to consider, if you haven't already, is that it is possible
> to use engOpen to start MATLAB on a remote machine. If you can do that,
> there is certainly scope for quite hefty speedup, even if your code is
> already taxing all the processors on your machine. Why not have some other
> computer do the work for you?
>
> --
> Dr Tristram J. Scott
> Energy Consultant

Tags for this Thread

Everyone's Tags:

Add a New Tag:

Separated by commas
Ex.: root locus, bode

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Tag Activity for This Thread
Tag Applied By Date/Time
engine Jay Catelli 29 Aug, 2011 17:37:36
engputvariable Akshay Ambekar 22 Feb, 2011 23:34:06
engopen Akshay Ambekar 22 Feb, 2011 23:34:06
multithreaded m... Akshay Ambekar 22 Feb, 2011 23:34:06
matlab api Akshay Ambekar 22 Feb, 2011 23:34:06
matlab engine Akshay Ambekar 22 Feb, 2011 23:34:06
rssFeed for this Thread

Contact us at files@mathworks.com