Updates from January, 2010 Toggle Comment Threads | Keyboard Shortcuts

  • Robert 00:02 on January 26, 2010 Permalink | Reply
    Tags: peer   

    Peer-to-peer distributed Matlab computing 

    In a recent meeting with the SPM developers, we discussed parallel computing using the Matlab distributed computing toolbox, Star-P, Sun Grid Engine, and other batch systems that can be linked to Matlab. These are all limited in their usefulness for the typical neuroimaging research setting in that they are based on a centralized job distribution system. That may work fine on a large cluster with a centralized configuration and system administration, but even then the usefullness is limited because all input and output data (which are typically large) have to be send over the network twice: first to the job manager, then to the compute node (and vice versa for the results).

    To resolve some of these problems, I came up with the idea of peer-to-peer distributed computing in Matlab. The full description can be found on http://fieldtrip.fcdonders.nl/development/peer

     
  • Robert 09:31 on July 13, 2009 Permalink | Reply  

    Automatically compile a missing mex file on the fly 

    I am maintaining a few open source Matlab toolboxes. Although most functions are plain Matlab, some functions are implemented as mex file. The mex files have to be compiled on each platform, i.e. 32 and 64 Linux, 32 and 64 bit Windows, ppc and intel Mac OS X, etc. Since I don’t have access to all those platforms, I have devised a trick to automatically compile the mex files on the end-user’s platform.

    Let’s say that you have a function mymexfile, then the file mymexfile.c would contain the c-code implementation of the Matlab mex file. You should save the following code as mymexfile.m. If the compiled mex file (e.g. mymexfile.mexw32) does not exist upon the first call to the function, the m-file will be executed. The m-file will automatically compile the c-file and will subsequently call the compiled mex file. On all subsequent calls, the compiled mex file will be executed directly.

    function [varargout] = autocompile(varargin)

    % AUTOCOMPILE compile the missing mex file on the fly

    % remember the original working directory
    pwdir = pwd;

    % determine the name and full path of this function
    funname = mfilename('fullpath');
    mexsrc = [funname '.c'];
    [mexdir, mexname] = fileparts(funname);

    try
    % try to compile the mex file on the fly
    warning('trying to compile MEX file from %s', mexsrc);
    cd(mexdir);
    mex(mexsrc);
    cd(pwdir);
    success = true;

    catch
    % compilation failed
    disp(lasterr);
    error('could not locate MEX file for %s', mexname);
    cd(pwdir);
    success = false;
    end

    if success
    % execute the mex file that was juist created
    funname = mfilename;
    funhandle = str2func(funname);
    [varargout{1:nargout}] = funhandle(varargin{:});
    end

     
  • Robert 22:32 on March 5, 2008 Permalink | Reply  

    Multithreading in a MATLAB mex file 

    Together with colleagues from the F.C. Donders Centre and the NICI, I am currently working on a project on real-time analysis of EEG and MEG data for Brain-Computer Interfacing (BCI). Since we already have a lot of relevant code in MATLAB and since a lot of the target end-users are familiar with it, we would like to do the real-time processing in MATLAB.

    The idea is to read the data that is streaming from the EEG amplifier, do the computation on the data (e.g. spatial filtering, spectral decomposition and classification) and then continue with the next section of the data. The challenge is not to lose any of the streaming EEG data while MATLAB is busy with the computation. A potential solution would be to implement the reading/acquisition of the data into matlab in a mex file which is multi-threaded.

    For this purpose I wrote some code for testing the multithreading in MATLAB. The test code below demonstrates that it works, and shows how easy it actually is.

    I am working on an Apple PowerBook G4 with OS X 10.4.11 and with MATLAB Version 7.4 (R2007a). The example code uses the POSIX Pthread libraries and I would expect the same code to work on most Unix and Linux systems. It will not work on a windows system, but might work with pthreads-win32.

    Put the following code in a file with the name threads.c

    #include < pthread.h > /* for threading */
    #include < unistd.h > /* for sleep */
    #include "mex.h"
    #include "matrix.h"

    void *do_thread(void *threadid)
    {
    int tid;
    tid = (int)threadid;
    mexPrintf("In thread: just started thread #%d\n", tid);
    sleep(4); /* pretend that the code is busy for a few seconds */
    mexPrintf("In thread: about to exit from thread #%d\n", tid);
    pthread_exit(NULL);
    }

    void mexFunction (int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[])
    {
    int num;

    if (nrhs<1)
    mexErrMsgTxt("not enough input arguments");
    else
    num = mxGetScalar(prhs[0]);

    pthread_t threads[num];
    int rc, t;
    for(t=0; t < num ; t++){
    mexPrintf("In main: creating thread %d\n", t);
    rc = pthread_create(&threads[t], NULL, do_thread, (void *)t);
    if (rc){
    mexErrMsgTxt("problem with return code from pthread_create()");
    }
    sleep(1); /* wait some time before making the next thread */
    }
    return;
    }

    Subsequently, in MATLAB you should compile the mex file using the following command:

    >> mex threads.c -lpthread

    After that, you can run the mex function. It takes a single argument, corresponding to the number of threads to create. Each thread will live for three seconds (pretending that it is busy for some time), and the time between threads being created is one second. Some example output is below.

    >> threads(6)
    In main: creating thread 0
    In thread: just started thread #0
    In main: creating thread 1
    In thread: just started thread #1
    In main: creating thread 2
    In thread: just started thread #2
    In main: creating thread 3
    In thread: just started thread #3
    In thread: about to exit from thread #0
    In main: creating thread 4
    In thread: just started thread #4
    In thread: about to exit from thread #1
    In main: creating thread 5
    In thread: just started thread #5
    In thread: about to exit from thread #2
    >> In thread: about to exit from thread #3
    In thread: about to exit from thread #4
    In thread: about to exit from thread #5
    >>

    You can see each thread starting and stopping. The last threads stop after the control has been returned to the MATLAB prompt.

    Here you can find some comments from Mathworks, including some windows specific example code. Important to note is that MATLAB itself is single-threaded, and not thread safe. Hence you should take care in interfacing your threaded c-code in the mex file with the MATLAB core.

    I would appreciate it to get some feedback on this. Please leave a comment below if you tested it successfully or if it does not work for you, with some details on your configuration (like operating system and MATLAB version).

     
    • Shay 00:54 on March 6, 2008 Permalink

      Hey Robert,

      Would you mind performing a small variation in your test? When I was trying to figure this out, I found the mexPrintf was usually fine in threads, but that more elaborate mex calls eg mexEvalString(“eval(zeros(1,10));”); would cause matlab to crash.

      In your threads, instead of just sleeping for 4 seconds, would you try to say evaluate a matlab expression as well?

      Cheers,
      Shay

    • Robert 10:38 on March 6, 2008 Permalink

      Hi Shay,

      I have inserted mexEvalString(“eval(zeros(1,10));”); into the thread function as you suggested, and it indeed crashes. This is actually also what I would expect, since matlab is not thread-safe. The technical solution 1-V3B5T from Mathworks (see link in my post) states

      “… it is possible to create new threads from a C MEX-file in a supported fashion; as long as those threads do not access MATLAB in any way. Since the MEX API is not thread safe, no MEX API functions can be used in the spawned threads including printf because printf is defined to be mexPrintf in the mex.h header file…”

      See also http://en.wikipedia.org/wiki/Thread-safety

      Although my example runs through, it appears from the Mathworks comment that even mexPrintf and printf are forbidden. For me not being allowed to use mexXXX functions in the c-code is not a problem, because I don’t want the threads to access the matlab engine directly. In my application the thread should be listening to the external EEG data as it comes in, and I would rather use another (thread-safe) mex file to copy the data from buffer thread (c.f. shared memory between the threads in the different mex files) into matlab workspace.

      A work-around for the limitation in using mexXXX functions in the thread might be to use a mutex around each mexXXX call to ensure that they do not execute something simultaneously in the matlab engine. I tried that with

      pthread_mutex_lock(&mexMutex);
      mexEvalString(“eval(zeros(1,10));”);
      pthread_mutex_unlock(&mexMutex);

      But that does not seem to work, i.e. matlab again crashes.

      Robert

    • Shay 18:50 on March 6, 2008 Permalink

      Hey Robert,
      Thanks for doing that test. The results are as expected and consistent with my understanding as well. In fact I was surprised that your MexPrintf worked for you, when I tried that I managed to crash Matlab with that too.

      What I was trying to achieve was to create a MexFunction that would execute and return control back to Matlab, yet still have a thread running in the background that could communicated (2-ways) back to Matlab. The only way I have found to do this is with JAVA and associating callbacks to ActionListeners.

      Cheers,
      shay

    • geri 16:24 on March 29, 2008 Permalink

      I’m using threads in a mex file as described by mathworks, with no contact to matlab. thats’s fine. but I’d like to send some messages to matlab to run some code. I tried to implement the old way described in here: http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=349
      But Im doing something wrong (2007b). It somehow losts ‘connection’ and messages are not received any more.
      Do somebody has experiences with it?

    • Flavio 01:57 on January 22, 2009 Permalink

      Thank you very much !

      Clear and simple code… the best way to learn :)

    • Frank 23:50 on May 11, 2009 Permalink

      Thanks for the post. I am trying to implement the example you described on Matlab 2007b on OS X 10.5.4. I have the appropriate libraries and have added them to the path, but when I execute the mex threads.c -lpthread I get the following errors, any ideas what I am doing wrong?

      threads.c:1:43: error: pthread.h : No such file or directory
      threads.c:2:38: error: unistd.h : No such file or directory
      threads.c:3:10: error: #include expects “FILENAME” or
      threads.c:4:10: error: #include expects “FILENAME” or
      threads.c: In function ‘do_thread’:
      threads.c:10: error: syntax error before ‘?’ token
      threads.c:10: error: stray ‘#’ in program
      threads.c:10: error: stray ‘\’ in program
      threads.c:12: error: syntax error before ‘?’ token
      threads.c:12: error: stray ‘#’ in program
      threads.c:12: error: stray ‘\’ in program
      threads.c:13: error: ‘NULL’ undeclared (first use in this function)
      threads.c:13: error: (Each undeclared identifier is reported only once
      threads.c:13: error: for each function it appears in.)
      threads.c: At top level:
      threads.c:16: error: syntax error before ‘mxArray’
      threads.c: In function ‘mexFunction’:
      threads.c:20: error: ‘nrhs’ undeclared (first use in this function)
      threads.c:21: error: syntax error before ‘?’ token
      threads.c:25: error: ‘pthread_t’ undeclared (first use in this function)
      threads.c:29: error: ‘threads’ undeclared (first use in this function)
      threads.c:29: error: ‘NULL’ undeclared (first use in this function)

      mex: compile of ‘threads.c’ failed.

    • Robert 09:11 on May 12, 2009 Permalink

      the first two error lines indicate a general problem with the location of the include files (pthread.h and unistd.h). Normally the gcc compiler (which is called by the mex command) should find these include files automatically. You should check that gcc/SDK/Xcode are installed correctly on your system. If I do the following, I can see that the include files are present:

      manzana> locate pthread.h
      /Developer/SDKs/MacOSX10.4u.sdk/usr/include/pthread.h
      /Developer/SDKs/MacOSX10.5.sdk/usr/include/pthread.h

      manzana> locate unistd.h
      /Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/libsa/unistd.h
      /Developer/SDKs/MacOSX10.4u.sdk/usr/include/sys/unistd.h
      /Developer/SDKs/MacOSX10.4u.sdk/usr/include/unistd.h
      /Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/Kernel.framework/Versions/A/Headers/libsa/unistd.h
      /Developer/SDKs/MacOSX10.5.sdk/usr/include/unistd.h

      have you ever tried compiling a “hello world”-like command line application? Or a simple command line threading example? If you cannot compile a simple command line application, then it is a problem with your gcc/SDK/Xcode installation. If it works on the command line and only fails in Matlab, then you can try “mex -setup” in matlab and try compiling another mex file.

    • Cesare 12:51 on June 17, 2009 Permalink

      To Frank,
      try removing the spaces before and after the symbols in and in the following include. It worked for me.

      To Robert,
      thanks for the nice example.

      Cesare

    • BELKACEM 06:08 on December 7, 2011 Permalink

      I need know at what time i run my matlab software ( or exactly I need this for each M-file)

      J’ai besoin de savoir à quelle heure je lance mon logiciel Matlab (ou exactement j’ai besoin de cela pour chaque M-file)

    • Robert 08:34 on December 7, 2011 Permalink

      For this you would not need a mex file or multithreading, but a plain function with a persistent variable. Something like this should do:

      function output = report_calltime(input)
      persistent storage

      if isempty(input)
      if isempty(storage)
      % create a new structure
      storage.parentname = evalin(‘caller’, ‘mfilename’); % get the mfilename of the calling function
      storage.time = clock; % get the current time
      else
      % append to the existing structure
      storage(end+1).parentname = evalin(‘caller’, ‘mfilename’); % get the mfilename of the calling function
      storage(end).time = clock; % get the current time
      end
      output = storage;
      clear storage
      end

      You would call “report_calltime” at the beginning of each of your functions. After they are done, you can do “storage = report_calltime(1)” to get the recorded structure.

      Note that I did not test the function that I just made up, so it might have some small errors.

    • Thomas 19:35 on January 16, 2012 Permalink

      Dear Robert,

      thank you very much for your post. What about using mxXXX functions like mxGetField? Those should be threadsafe, right?

      Greetings, Thomas

    • Robert 18:25 on February 4, 2012 Permalink

      I don’t know whether these are threadsafe. I suggest to just give it a try.

c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
esc
cancel