Working around segmentation faults that occur in parallel due to a non-thread-safe API function - matlab

I am currently coding a MEX file in MATLAB to run experiments in parallel using the parfor function in MATLAB 2012a. The MEX file does some very straightforward numerical tasks but relies on the CPLEX 12.4 API from IBM.
Although my MEX file works sequentially, I will inevitably receive "random" segmentation fault when I run in in parallel. After sending a stack trace of the segmentation fault to MATLAB, they have suggested that the error originates from the "putenv()" function from the C library, which is apparently not thread-safe.
I do not use the putenv() function in my MEX code, but it turns out that one of functions that I absolutely have to call from the CPLEX 12.4 does use it. I'm wondering if there is anything I could do to avoid the segmentation faults that come as a result of this function. Someone previously suggested "locking my bits" and "using semaphores" but I'm really little over my head when it comes to these concepts.
Any advice or direction would be very much appreciated.

It turns out that the violation occurs since I use the CPLEX MATLAB API in my MATLAB code and the CPLEX C API in my MEX code at the same time. Both APIs use the putenv() function, which is not thread-safe. In particular, the crash occurs whenever two threads try to use the putenv() function at the same time (either in the MEX file or the MATLAB code).
The fix is to use the package and add a mutex_lock / mutex_unlock around the functions that use putenv() in C and MATLAB (i.e. CPXopenCPLEX in C / Cplex() in MATLAB). More information and exact code to create the mutex_lock / mutex_unlock can be found in the following post on the CPLEX forums

Related

Basic networking with Matlab Coder

I'm trying to get very basic network functionality with Matlab Coder (I need to turn it into C code). However, all the network classes and objects I try arn't supported by Coder. It seems unreasonable that Matlab would completely neglect networking entirely with this tool. Is there some method of sending data over a network that DOES work with coder?
I'd prefer TCP, but UDP or anything else that will actually send/receive data will work, as long as it is compatible with Coder.
This answer assumes that the DSP System Toolbox is not available. If it is, the System Objects dsp.UDPSender and dsp.UDPReceiver may be considered.
Since the final goal is to generate C code, and because network I/O is usually done via a library, a good approach would be to integrate external C code that does the network I/O into your MATLAB Code. The basic way to call an external C function is using coder.ceval and the process is explained here.
Recommended Steps
Write C(++) functions implementing the behaviour you need or find a C library providing the necessary functionality. Assume we implement the function externalUDPSend in the files externalUDPSend.h/.c.
Write one or more MATLAB functions that call your C(++) functions using coder.ceval as shown in the linked documentation. These will serve as a wrapper around your external code, and will expose the C(++) code to MATLAB. Something like callfoo in the linked example will work:
function y = useExternalUDP(x)
%#codegen
if coder.target('MATLAB')
% Running in MATLAB. Use standard MATLAB
% network I/O code here
...
else
% Generating code. Call external code/library
% Include header for external code
coder.cinclude('externalUDPSend.h');
% Set the type of the output. Assume double scalar
% Change the RHS to match the return type
y = 0;
y = coder.ceval('externalUDPSend',x,numel(x));
end
Develop your project. Call the wrapper function(s), which will work in MATLAB and in the generated code because of the use of coder.target.
Generate a MEX function using something like:
codegen useExternalUDP -config:mex externalUDPSend.c -args ...
The generated MEX function serves as the MATLAB interface to your custom code so there is no need to hand write a MEX interface. MATLAB Coder will generate all of MEX interfacing logic for you. Then test that MEX function in MATLAB. Testing the MEX function is important because runtime errors like out of bounds indexing, using features not supported for code generation, etc. can be detected and reported in MEX. These checks are removed from generated standalone code.
Generate standalone code and either let MATLAB Coder compile it to a library or deploy the code to an external IDE and compile it there.
Integrating External Libraries/Encapsulating Dependencies
Note that you may also need to link in libraries if you choose to use an existing network I/O library, or you may need to modify the build of the generated code. You can either use coder.updateBuildInfo or coder.ExternalDependency to achieve this in your MATLAB Code.
Further Reading
The file reading example shows some more advanced custom code integration tools such as coder.ref, coder.opaque, and dealing with C strings from MATLAB code when calling external code. Note that the MATLAB functions fprintf and fread are supported for code generation so this example is meant to be instructive rather than a necessity for doing file I/O.
If you have the DSP System Toolbox, the System Objects dsp.UDPSender and dsp.UDPReceiver are supported for code generation since they are listed in the comprehensive list of supported functions.
The code generated from them relies on prebuilt libraries shipped with MATLAB and will run on desktop platforms compatible with those libraries. See the documentation for the UDP Receive block for more details.

Alternatives to extrinsic functions such as imread and other functions during code generation in MATLAB

As you may know, extrinsic functions are not outputted during the code generation process. Are there alternatives to these functions and/or solutions to this problem? My code generation error report is shown below :
Code Generation Error Report
I am surprised that I can't output size and rgb2gray either. Since these are essential to my program, I cannot avoid them.
Help will be much appreciated!
This is a good question, and I see similar questions fairly frequently. As I started using MATLAB Coder, one of the biggest pitfalls was the constant search for supported functions. I sympathize with your frustration, and I have a few tips, having been through this.
First, to your direct question, while imread isn't supported by Coder, size and rgb2gray are. Probably Coder is complaining about these because they have been passed mxArrays from the call to imread, which is fine when it is extrinsic, but not ok for separate generation. That's just a guess. A very useful tool in writing code is the list of Coder supported functions: List of Functions supported in MATLAB Coder
But even with those two, to replace imread is not a tiny task. You'll have to find another library that supports the particular file you're working with, and then stitch that in using coder.ceval. Alternatively, if you can find a pure MATLAB implementation of it, that might help.
Are you targeting a pure C library or a MEX file? If you intend to use this code within the MATLAB environment, you can always use imread separately and then pass the data.
And now to some more general observations: MATLAB Coder isn't a perfect MATLAB to C translation system. It's extremely powerful, and I've been able to write some very large projects with it, but if what you want is the ability to run any MATLAB code without MATLAB around, you should look at MATLAB Compiler, a different add-on. There's a very good Q and A about this here: MATLAB Compiler vs MATLAB Coder
When writing projects in MATLAB Coder, it's really best to start from scratch, knowing you're targeting C code ultimately. There are so many gotchas in the conversion from MATLAB to C that you have to be always vigilant while writing the MATLAB code.
One tool that helps is to right-click on a file in the "Current Folder" list that usually resides on the left-side of the main window, and select "Check Code Generation Readiness." You'll get a great report of potential problems in the file. I recommend using this often.
Another useful tool is to always put the %#codegen tag into your code. This alerts the MATLAB editor that the .m file is intended for code generation, so it provides extra context-sensitive information while you're writing the file. This helps enormously.
The most commonly missing functions for code generation are file IO functions. There are some good reasons for this, but it's frustrating nonetheless.
When you stitch in external C code, you use the coder.ceval function, which can provide excellent access to external libraries. Using this well is a whole other topic, outside the scope of this question.
If you can indicate exactly what kind of files you're interested in reading (PNG, BMP, TIFF, etc.) perhaps someone may be able to identify a good external library for you to use.

Will Matlab standalone be faster than Matlab from UI for long execution code?

I have built an standalone Matlab application. I was expecting it to be faster than running the application from the Matlab environent but it is indeed a bit slower (1.3 seg per iteration vs 1.5 seg per iteration)
I am not counting the init time required by MCR but the execution of my code.
Is that the expected performance or should I be obtaining a performance improvement?
I haven't found any settings on the deployment tool that could help to reduce execution time.
Thanks in advance
Applications built with MATLAB Compiler should execute at pretty much exactly the same speed as within MATLAB.
MATLAB Compiler does not convert your MATLAB code into machine code in the same way as a C compiler does for C. What it does is to archive and encrypt your MATLAB code (note, it properly encrypts it, not just pcodes it as a comment suggests), create a thin executable wrapper and package them together, possibly also with MATLAB Compiler Runtime (MCR). MCR is very similar to MATLAB itself, without a graphical user interface, and is freely redistibutable.
When you run the executable, it dearchives and decrypts your MATLAB code and runs it against the MCR. It should run exactly the same, both in terms of results and speed.
Very old versions of MATLAB Compiler (pre-version 4.0) worked in a different way, converting a subset of the MATLAB language into C code, and compiling this. This provided a potentially significant speed-up, but only a subset of the language was supported and results, unless you were careful, could sometimes be different. Similar functionality is now available in the separate MATLAB Coder product.
There are a few small things you can do to improve performance: for example, within deploytool you can specify which toolboxes your application uses. deploytool uses a dependency checker to package up all MATLAB functionality that it thinks your code might possibly depend on, but it can't always tell exactly, as the functions your code needs might change at runtime. It therefore errs on the side of caution and includes more than necessary. By specifying only the toolboxes you know to be necessary, you can speed things up a little (it also speeds up the build process quite a bit).

Segmentation Faults when Running MEX Files in Parallel

I am currently running repetitions of an experiment that uses MEX files in MATLAB 2012a and occasionally running into segmentation faults that I cannot understand.
Some information about the faults
They occur randomly
They only occur when I run multiple repetitions of my experiment in parallel on a Linux machine using a parfor loop.
They do not occur when I run multiple repetitions of my experiment in parallel on Mac OSX 10.7 using a parfor loop.
They do not occur when I run or do they occur when I run the repetitions sequentially.
They seem to occur far less frequently when I run 2 experiments in parallel - as opposed to 12 experiments in parallel.
Some information about my MEX file:
It is written in C
It uses the IBM CPLEX 12.4 API (this is thread-safe)
It was compiled using GCC 4.6.3
My thoughts are that there may be some issue in accessing the MEX file in multiple cores. Can anyone shed any light on what might be going on or suggest a fix? I'd be happy to provide more information as necessary.
I've recently sent a stack trace to the people at MATLAB and it turns out that the culprit is not my code but one of the functions from the CPLEX 12.4 API. It turns out that this function uses the putenv() function in C which is not necessarily thread-safe.
Unfortunately, I have to keep using this function and the API so I've posted a follow-up thread that focuses on finding ways to avoid this fault.
Any advice would be appreciated.
My thoughts are that there may be some issue in accessing the MEX file in multiple cores.
It's much more likely that your MEX file has a bug. Various bugs (which are very easy to make in C), such as accessing dangling memory, double-free()ing, or writing past the end of allocated array, will cause intermittent SIGSEGV.
Your best bet is to run Matlab under a debugger, and see where it crashes.

running old mex file on new matlab releases

I'm trying to run a program originally tested on Matlab 6.5 on a new release (R2009a)
The program uses some mex files, and I get the following error when trying to run it:
??? Invalid MEX-file '/normalizedCut/common_files/sparsifyc.mexglx':
normalizedCut/common_files/sparsifyc.mexglx: symbol mxGetIr, version
libmx.INTERNAL not defined in file libmx.so with link time reference.
(the code I'm trying to tun is Normalized cut by Shi & Malic, and can be found here:
http://www.cis.upenn.edu/~jshi/software/files/NcutClustering_7.zip)
If I try to run the code on the same system but Matlab 2007a it runs ok.
Is there some problem with backwards compatibility for 2009a?
Are there any flags somewhere in the system I can change to help it work?
When I googled it I saw some references to the LD_LIBRARY_PATH env variable, but what exactly should be added to it I could not find out.
Thanks,
Yair
The source code for those mex functions appears to be available in the "Image segmentation with normalized cuts" source on this page: http://www.cis.upenn.edu/~jshi/software/ (in the specific_NcutImage_files subdirectory in the unpacked .zip)
It's pretty common for there to be problems running mex functions with different versions of Matlab. The errors you're getting look like they're due to API changes in Matlab (though that surprises me a little). I've had the most trouble because of binary incompatibilities induced by changes in gcc. I'd suggest contacting Jiambo and asking him if he can build a new version or release the source.
Worst case, you could try re-implementing those mex functions. The normalized cut algorithm is pretty straightforward in Matlab (see the Shi and Malik paper). By the names of the mex functions, they look like they're mostly duplicating existing matlab functionality (matrix multiplication, matrix sparsification). There's a non-zero chance that if you re-implemented them as regular m-code functions they'd be faster anyway due to the multicore support that's been added to Matlab.