MATLAB: Contiguous memory for complex arrays in mex

complexlapackmemorymex

Is it possible to allocate a complex array in a mex file and have the real and imaginary parts be contiguous with each other? I'm working with very large matrices and need to conserve memory and would like to not have to make a copy of the input matrices to get them into FORTRAN format. If the memory were contiguous, I could just rearrange the data into interleaved real and imaginary. I've already been able to pass in a real valued array from matlab and have LAPACK treat it as a complex (it just assumes the real and imaginary are interleaved), but this isn't exactly an elegant solution since I still have to write the data to a file and read it back into complex form. At that point it becomes useless to use MATLAB at all and I might as well just write a standalone program in C or FORTRAN. Any ideas if this can be done or am I out of luck?

Best Answer

Yes and No. It is easily possible to physically do this, but the clearing of such a variable will likely crash MATLAB if you are not very careful. The outline is as follows.
In the mex routine create a double array that is sized to hold all of your intended complex data. E.g., if you want a 1x5 complex array then create a double array that is 1x10. Then manually use mxSetN to change the column size to 5. Then pick the midpoint of the real data area and use mxSetPi to set the imaginary data pointer to that address. That will create a complex mxArray variable with the real and imaginary parts contiguous.
This will work fine up until the point that MATLAB tries to clear this variable from memory. Then it will try to free the address you just set with the mxSetPi function. Since this is not a valid address to free, the results are unpredictable and MATLAB will likely crash.
The only robust solution I can think of is to manually create a shared data copy of this variable, make it persistent, and keep this shared data copy inside the mex routine so MATLAB cannot try to clear it. Then use a mexAtExit function to manually reverse the process, use mxSetPi with a NULL, and then clear the variable. But I will tell you right now that this is very tricky to accomplish and requires that you dig under the hood of the mxArray structure to do some unofficial manipulation. You need to be able to detect when the mxArray is shared with other variables inside your mex routine, etc etc. Not recommended for the faint of heart and not easy to accomplish even for a seasoned programmer IMO.
You might be able to get away with it if you can keep all the operations inside the mex routine so that you can carefully manage all of the operations on the variable to ensure there is no shared data copy of it floating around in memory elsewhere, and then manually fix & clear it yourself inside the mex routine.
What operations will you be doing with this variable?