Defining more than three mwArray gives error

3 views (last 30 days)
Bir
Bir on 4 Feb 2011
Dear Matlab users,
Can you declare and define more than three mwArray in a standalone cpp file that calls the Matlab function in a c++ shared lib (generated by Matlab compiler mcc)? Just try four mwArray:
int N; N=1000;
mwArray in1(N,1,mxDOUBLE_CLASS, mxREAL);
mwArray in2(N,1,mxDOUBLE_CLASS, mxREAL);
mwArray in3(N,1,mxDOUBLE_CLASS, mxREAL);
mwArray in4(3,1,mxINT32_CLASS, mxREAL);
No need to even call the Matlab function after this. I get Matlab runtime crash errors, which goes away if I restrict to only 3 mwArray (any three above).
But this does not happen for following:
mwArray out1,out2,out3,out4;
where notice I didn't allocate lengths of the array because they are output arrays returned by the matlab function I call subsequently.
It is interesting how all examples of using Matlab compiler generated c++ shared library in a c++ code have three or less mwArray defined, two for inputs and one for output.
I am running Matlab R2010b on Ubuntu. Compiler version 4.14.
Another important question: How to transfer in and out a matlab "structure" (with numerical array fields), from a c++ code? I can think of writing it to the disk as mat file and then reading it, but any other elegant idea?
Thanks a lot,
Bir
  3 Comments
Bir
Bir on 11 Feb 2011
Hi Shaf,
Here I post some parts of the code. Sorry for this delay because I took few steps back in an attempt to fix the bug.
I'd like to first describe my case.
If I have two classes (their cpp and header files) and I want to call two matlab compiled functions from functions in these two different classes, how should I do it? Right now, I call mclmcrInitialize() in the constructor of the class that will call a matlab function first (and only one time). I don't use mclRunMain((mclMainFcnType)run_main,0,NULL) command from the matrixdriverp demo on mathworks website because I don't know how to use it for a multi-class app. Is it important?
Here are important functions in my first class:
PresField::PresField(void)
{ // constructor
mclmcrInitialize();
int i;
char filename[] = "/home/me/src/examples/3d/mytests/tet4_500m/tet4_500m_ascii.gmv";
i=run_matlab(1,filename);
} // constructor
PresField::~PresField(void)
{ // destructor
libTPFATerminate();
mclTerminateApplication();
} // destructor
The run_matlab function in this class is:
int PresField::run_matlab(int argc,char* filename)
{
if (!mclInitializeApplication(NULL,0))
{
std::cerr << "could not initialize the application properly"
<< std::endl;
return -1;
}
//mclInhibitShutdown(); //its presence or absence does not seem to make any difference
if( !libTPFAInitialize() )
{
std::cerr << "could not initialize the TPFA library properly"
<< std::endl;
return -1;
}
else
{
try
{
mwArray out1,out2,out3;
// Call the library function
readGMV(3, out1, out2, out3, filename);
nCell = out1.NumberOfElements()/4.0;
nNode = out2.NumberOfElements()/3.0;
T = new int[nCell*4];
P = new double[nNode*3];
nCellPerNode = new int[nNode];
out1.GetData(T,nCell*4);
out2.GetData(P,nNode*3);
out3.GetData(nCellPerNode,nNode);
}
catch (const mwException& e)
{
std::cerr << e.what() << std::endl;
return -2;
}
catch (...)
{
std::cerr << "Unexpected error thrown" << std::endl;
return -3;
}
}
return 0;
}
Note that this code runs ok, I get the desired output.
Now, in the 2nd class which calls a matlab function many times during a run, I have:
void class2::solve(PresField* pField,const double t,const double dt)
{
int i1;
i1=run_matlab(pField,t);
}
int class2::run_matlab(PresField* pField,const double t)
{
int nNode, nCell;
nNode = pField->getNNodes();
nCell = pField->getNCells();
int* T; T = pField->getTetNodes();
double* P; P = pField->getTetCoords();
try
{
mwArray in1(nCell*4, 1, mxINT32_CLASS, mxREAL);
mwArray in2(nNode*3, 1, mxDOUBLE_CLASS, mxREAL);
in1.SetData(T, nCell*4); in2.SetData(P, nNode*3);
mwArray out;
// Call the library function
TPFA(1, out, in1, in2);
double p[nCell];
out.GetData(p,nCell);
pField->updatePres(p,t);
}
catch (const mwException& e)
{
std::cerr << e.what() << std::endl;
return -2;
}
catch (...)
{
std::cerr << "Unexpected error thrown" << std::endl;
return -3;
}
return 0;
}
This code also runs ok. Note I don't call lib or matlab initialization as they are open from the first call to them in PresField class.
After this function (Class2::run_matlab) is called n times, the application ends, goes to the destructor of 1st class, successfully goes through libTPFATerminate(),
mclTerminateApplication() and but then the application code tries to free up all memory and class pointers and I get a SIGSEGV down the road. Good thing is that by now
the application has run and saved whatever it was supposed to do. But I thought leaving this harmless SIGSEGV here may create trouble for me later.
Where should I put mclTerminateApplication()? If there is separate code that deletes the class pointers, should mclTerminateApplication() be called after the class
(that initialized mcr and used matlab) is deleted or before.
However, the first time I get SIGSEGV is at if( !libTPFAInitialize() ) line which goes into my library file libmatrixp.cpp's following line:
if (ctfStream) {
bResult = mclInitializeComponentInstanceEmbedded( &_mcr_inst,
error_handler,
print_handler,
ctfStream,
148509);
Here is the debugger (gdb) window:
68 if (ctfStream) {
(gdb) s
73 148509);
(gdb) s
[New Thread 0x4584b70 (LWP 18753)]
[New Thread 0x4d85b70 (LWP 18754)]
[New Thread 0x5586b70 (LWP 18755)]
[Thread 0x4d85b70 (LWP 18754) exited]
[New Thread 0x4d85b70 (LWP 18756)]
[New Thread 0x5d87b70 (LWP 18757)]
[Thread 0x4d85b70 (LWP 18756) exited]
[Thread 0x5586b70 (LWP 18755) exited]
[Thread 0x4584b70 (LWP 18753) exited]
[New Thread 0x4584b70 (LWP 18758)]
[New Thread 0x5586b70 (LWP 18759)]
[New Thread 0x6b4eb70 (LWP 18760)]
[New Thread 0x6bcfb70 (LWP 18761)]
[New Thread 0x6c50b70 (LWP 18762)]
[New Thread 0x6ca1b70 (LWP 18763)]
[New Thread 0x6cf2b70 (LWP 18764)]
[New Thread 0x6d43b70 (LWP 18765)]
[New Thread 0x6dc4b70 (LWP 18766)]
[New Thread 0x6e45b70 (LWP 18767)]
[New Thread 0x6e96b70 (LWP 18768)]
[New Thread 0x6f17b70 (LWP 18769)]
[New Thread 0x712fb70 (LWP 18770)]
[New Thread 0x7180b70 (LWP 18771)]
[New Thread 0x71d1b70 (LWP 18772)]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x4584b70 (LWP 18758)]
0xb3fa9c30 in ?? ()
If I say 'continue' with the execution it goes ahead ok at this point. So I ignore this error. It doesn't even show up on my terminal window. Note that
I get this error even with mathworks's matrixdriver demo where I have no classes, just follow the demo instructions and I get SIGSEGV during library
initialization. For that demo, when I say 'run' on gdb after the SIGSEGV, program restars and runs and there is no SIGSEGV now. So this error only comes first
time for the demo, every time for my multi-class application. But this SIGSEGV during lib initialization appears completely harmless so far, so I ignored it.
Thanks a lot for your time,
Bir
Shaf
Shaf on 16 Feb 2011
Hi Bir,
The jvm uses SIGSEGV for flow control. The MCR starts up the jvm during mclInitializeComponentInstanceEmbedded() and that's where the SIGSEGV is coming from and it's safe to ignore. I will look at the code you posted and see if I spot anything. There really aren't any limitations on the number of mwArrays you can create other than running out of memory which doesn't seem to be the case.

Sign in to comment.

Answers (1)

Shaf
Shaf on 8 Feb 2011
I will answer the structure question first. You can use mwArrays to create and return MATLAB structures. To assign elements to the struct mwArray you can use mwArray::get() followed by an mwArray::set(const mwArray&). Here are the relevant documentation pages:
http://www.mathworks.com/help/toolbox/compiler/mwarraymwsizenum_rowsmwsizenum_colsintnum_fieldsconstcharfieldnames.html
http://www.mathworks.com/help/toolbox/compiler/mwarraymwsizenum_dimsconstmwsizedimsintnum_fieldsconstcharfieldnames.html
http://www.mathworks.com/help/toolbox/compiler/mwarraygetconstcharnamemwsizenum_indices....html
http://www.mathworks.com/help/toolbox/compiler/voidsetconstmwarrayarr.html
http://www.mathworks.com/help/toolbox/compiler/mwarraygetconstcharnamemwsizenum_indicesconstmwindexindex.html

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!