insert new mexPrintf to stop Matlab crash

2 visualizaciones (últimos 30 días)
Jane Jean
Jane Jean el 28 de Mzo. de 2012
Hello,
I'm encountering a very weird situation. My Matlab program crashed when I tried to run the mexw64 file and after modifier the c code by adding a mexPrintf("ok") line at the beginning and at the end, the program works. What could happen to my code?

Respuesta aceptada

Jane Jean
Jane Jean el 29 de Mzo. de 2012
#if !defined(_WIN32)
#define dgemm dgemm_
#endif
#include "mex.h"
#include "geometryMatrix64.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *arrayLat, *arrayLong, *arraySeax, *arrayGm, *arrayTime, *arrayIncl, *arrayPeri;
double *A, *B, *C, *D, *E, *R1, *R3, *R_L, *v, *r; /* pointers to input & output matrices*/
double t_S, raan, anom;
int ind_s, ind_s_vis;
int i, j, outputRowLen, outputColLen;
size_t m,n,p,q; /* matrix dimensions */
/* form of op(A) & op(B) to use in matrix multiplication */
char *chn = "N";
/* scalar values to use in dgemm */
double one = 1.0, zero = 0.0;
arrayLat = mxGetPr(prhs[0]);
arrayLong = mxGetPr(prhs[1]);
arraySeax = mxGetPr(prhs[2]);
arrayGm = mxGetPr(prhs[3]);
arrayTime = mxGetPr(prhs[4]);
arrayIncl = mxGetPr(prhs[5]);
arrayPeri = mxGetPr(prhs[6]);
plhs[0] = mxCreateDoubleMatrix(m, n, mxREAL);
C = mxGetPr(plhs[0]);
for (i=0;i<outputRowLen;i++){
for(j=0; j<outputColLen; j++){
C[i*outputRowLen+j] = 0;
}
}
This is a very simple code with many entrees and Matlab returned me this
Error using geometryMatrix64
Out of memory. Type HELP MEMORY for your options.
Isn't that weird while all entrees are either scalar or 3by3 matrix? What could have happened ?
  3 comentarios
Jane Jean
Jane Jean el 29 de Mzo. de 2012
Thanks. OMG. I keep making silly mistakes lately due to long working hours... Thank you very much!! ;p
Jan
Jan el 29 de Mzo. de 2012
It's time for a coffee break.

Iniciar sesión para comentar.

Más respuestas (4)

James Tursa
James Tursa el 28 de Mzo. de 2012
Inserting mexPrintf calls changes the state of some internal register(s) and can have an effect on buggy code. E.g., I once saw a case where a function had an incorrect prototype. It really returned a 1-byte value but the prototype said it returned an int, so it was picking up 3 bytes of garbage on the return value. This garbage value was then used downstream for a size and it turned out to be huge and crashed MATLAB. However, by inserting a mexPrintf call just before this mis-prototyped function call things worked. It was because mexPrintf returned a 4-byte int, 3 bytes of which happened to be 0, effectively clearing out the garbage bytes in the return register before the mis-prototyped function call returned its 1 byte value.
Bottom line: Inserting seemingly unrelated printing code can have an effect on the output if your code has errors.
To see what is really going on in your code you will have to post it.
  2 comentarios
Jane Jean
Jane Jean el 28 de Mzo. de 2012
I have experienced a couple of times that the compiled mexw64 is very unstable. The same code can be compiled and run without crash then somehow it doesn't work anymore. Why is Matlab behaving this way? Why isn't it as stable as normal c programming?
Jan
Jan el 28 de Mzo. de 2012
Dear Jane, mexw64 functions are unstable, if the programs contain bugs. Because C-mex functions are standard C-files compiled by standard C-compilers, their level of stability are exactly like all other C-files. This does not concern Matlab.
In opposite to Matlab, it is very easy to create invalid commands with a valid syntax.

Iniciar sesión para comentar.


Jane Jean
Jane Jean el 28 de Mzo. de 2012
void matrixMultiplication(int rowA, int colA, int rowB, int colB, double *A, double *B, double *C){
/* C = A*B */
int m = rowA, n = colA, p = rowB, q = colB;
char *chn = "N";
double one = 1.0, zero = 0.0;
int i, lenC;
if (p!=m){
mexPrintf("Inner dimensions of matrix multiply do not match");
}
else {
dgemm(chn, chn, &m, &q, &n, &one, A, &m, B, &n, &zero, C, &m);
}
return;
}
And in the mexFunction:
/* Transformation into ECEF coordinate system */
A = mxMalloc(3*3*sizeof(double));
B = mxMalloc(3*3*sizeof(double));
C = mxMalloc(3*3*sizeof(double));
D = mxMalloc(3*3*sizeof(double));
E = mxMalloc(3*3*sizeof(double));
r = mxMalloc(3*1*sizeof(double));
if(A){
generateRotation3(-raan, A);
}
else{
mexPrintf("Memory allocation error 4.");
}
if(B){
generateRotation1(-arrayIncl[0], B);
}
else{
mexPrintf("Memory allocation error 5.");
}
if(C){
generateRotation3(-arrayPeri[0], C);
}
else{
mexPrintf("Memory allocation error 6.");
}
if(D){
//mexPrintf("entering matrix multiplication.............");
matrixMultiplication(3,3,3,3,A,B,D);
}
else{
mexPrintf("Memory allocation error 7.");
}
for(j=0; j<9; j++){
mexPrintf("A*B[%d] = %f\n",j,D[j] );
}
mxFree(A);
mxFree(B);
mxFree(C);
mxFree(D);
With mexPrintf, the execution works perfectly; without mexPrintf, Matlab crashes...
Thanks again James!! ;)
  3 comentarios
Jane Jean
Jane Jean el 29 de Mzo. de 2012
Thank you very much. At least I have an idea now of what I can do/try. I'll change this right away.
Jane Jean
Jane Jean el 29 de Mzo. de 2012
The program crashed again. Posted some code below.

Iniciar sesión para comentar.


Jane Jean
Jane Jean el 29 de Mzo. de 2012
void matrixMultiplication(mwSignedIndex rowA, mwSignedIndex colA, mwSignedIndex rowB, mwSignedIndex colB, double *A, double *B, double *C){
/* C = A*B */
mwSignedIndex m = rowA, n = colA, p = rowB, q = colB;
char *chn = "N";
double one = 1.0, zero = 0.0;
int i, lenC;
mexPrintf("Entering matrix multiplication...............\n");
if (p!=m){
mexPrintf("Inner dimensions of matrix multiply do not match");
}
else {
mexPrintf("Before dgemm...............\n");
dgemm(chn, chn, &m, &q, &n, &one, A, &m, B, &n, &zero, C, &m);
mexPrintf("After dgemm...............\n");
}
return;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxArray *inputLat, *inputLong, *inputIncl, *inputPeri, *inputSeax, *inputGm, *inputR_E, *inputEle_Mask, *inputTime, *inputTheta;
double *arrayLat, *arrayLong, *arrayIncl, *arrayPeri, *arraySeax, *arrayGm, *arrayR_E, *arrayEle_Mask, *arrayTime, *arrayTheta;
double *outputGeo,*outputGeo1,*outputGeo2;
double t_S = 0, *R_L, raan, anom, *r, *r_s, *r_x, *r_xs_ENU, ele, *Ang, *Dir, norm, *Geo;
double *A, *B , *C, *D, *E, *F, *v, a, b,c,d, sum = 0.0, *Id, *Geo_exp;
double *R1, *R3;
// intermediate matrix created for storing intermediate results of a single operation and freed once the entire operation is done
mwSignedIndex i, ind_s_vis =1, ind_s=0, ind, N_vis, k,j, outputRowLen, outputColLen, outputRowLen1, outputColLen1, outputRowLen2, outputColLen2;
VALUE_INDEX maxi_Ang;
The program still crashed... when I tried to call matrixMultiplication function within the mexFunction. I'm again left with no idea...

Jan
Jan el 29 de Mzo. de 2012
Does it still crash, if you comment out the dgemm call? You can allocate C much larger than required using mxCalloc and check if any non-zeros appear after the multiplication. Perhaps you confused the leading and trailing dimensions of one of the matrices. The Matlab->C->Fortran convetion conversion is not trivial, although it actually is.
  1 comentario
Jane Jean
Jane Jean el 29 de Mzo. de 2012
By commenting out the dgemm call, the program worked well at first then crashed after some time. I have then decided to keep to the matrixMultiply.c example. However, I've discover again a weird thing in mexFunction.
I shall paste the code below.

Iniciar sesión para comentar.

Categorías

Más información sobre Write C Functions Callable from MATLAB (MEX Files) en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by