Problem with mex file!

Hello there, I'm writing some codes in matlab that calls some mex subroutines. I don't know why, I have a problem with one of these mex subroutines: MATLAB is working well when I call it with 7 inputs, but it is crashing, as I add an eighth variable as imput.
This is the main code:
#include<stdio.h>
#include<stdlib.h>
#include <math.h>
#include<time.h>
#include <unistd.h>
#include <mex.h>
#include <matrix.h>
void rejectsam(double *y, double *p, double *r, double *w, double *ww, double *mx, double *cv, double *c2v, double *u, double *xx) {
int j,t,h, flag, count, m, m2;
double meanz[2][1]={},sigmz[2][2]={}, meanz2[6][1]={},sigmz2[6][6]={}, Ycat[76672]={}, Ycat2[76672]={}, aux2[2][1]={}, aux[6][1]={}, aux3[3][1]={},aux3b[3][1]={}, L2[2][2]={}, L6[6][6]={},Z[8][76672]={}, omegai[9][9]={},
beta[9]={}, Ycont[76672]={},meanb[2][1]={}, sigmab[2][2]={}, meany12, vary12, mis[76672]={}, invaux[3][3]={}, invomega[3][3]={}, omega0238[6][3]={}, omega0238t[3][6]={}, interm[6][3]={}, interm2[6][6]={}, cov[76672], cov2[76672];
memcpy(&omegai, y, sizeof(omegai));
memcpy(&beta, p, sizeof(beta));
memcpy(&Ycont, r, sizeof(Ycont));
memcpy(&Ycat, w, sizeof(Ycat));
memcpy(&Ycat2, ww, sizeof(Ycat2));
memcpy(&mis, mx, sizeof(mis));
memcpy(&cov, cv, sizeof(cov));
memcpy(&cov2, c2v, sizeof(cov2));
for (j=0;j<3;j++) {
for (t=0;t<3;t++) invaux[t][j]=omegai[t][j];
}
for (j=0;j<2;j++) {
sigmab[j][j]=1;
meanb[j][0]=beta[j+1];
}
/*here I don't copy some stuff that doesn't matter because it still crash if I put them as comment*/
memcpy(u, &Z, sizeof(Z));
memcpy(xx, &Ycont, sizeof(Ycont));
printf("%f %f %f %f\n",omegai[0][0], cov[0], beta[2], cov2[20000]);
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
double *y,*u, *p, *w, *r, *mx, *xx, *ww, *cv, *c2v;
/* check for proper number of arguments */
/* NOTE: You do not need an else statement when using mexErrMsgIdAndTxt
within an if statement, because it will never get to the else
statement if mexErrMsgIdAndTxt is executed. (mexErrMsgIdAndTxt breaks you out of
the MEX-file) */
if(nrhs!=8)
mexErrMsgIdAndTxt( "MATLAB:xtimesy:invalidNumInputs",
"Eight inputs required.");
if(nlhs!=2)
mexErrMsgIdAndTxt( "MATLAB:xtimesy:invalidNumOutputs",
"Two output required.");
/* create a pointer to the input matrix y */
y = mxGetPr(prhs[0]);
/* create a pointer to the input matrix p*/
p = mxGetPr(prhs[1]);
/* create a pointer to the input matrix r */
r = mxGetPr(prhs[2]);
/* create a pointer to the input matrix w */
w = mxGetPr(prhs[3]);
/* create a pointer to the input matrix ww */
ww = mxGetPr(prhs[4]);
/* create a pointer to the input matrix mx */
mx = mxGetPr(prhs[5]);
/* create a pointer to the input matrix cv */
cv = mxGetPr(prhs[6]);
/* create a pointer to the input matrix c2v */
c2v = mxGetPr(prhs[7]);
/* set the output pointer to the output matrix */
plhs[0] = mxCreateDoubleMatrix( 8, 76672, mxREAL);
/* create a C pointer to a copy of the output matrix */
u = mxGetPr(plhs[0]);
/* set the output pointer to the output matrix */
plhs[1] = mxCreateDoubleMatrix( 1, 76672, mxREAL);
/* create a C pointer to a copy of the output matrix */
xx = mxGetPr(plhs[1]);
/* call the C subroutine */
rejectsam(y,p,r,w,ww,mx,cv,c2v,u,xx);
}
It all works perfectly until I add the variable c2v, which I'm sure is a 76672 doubles vector. It is 3 days that I'm trying to sort it out, the only thing I can imagine is that maybe there is some limit in the number of inputs I can pass to a mex function... In the last line of the main program, if I didn't put between the variables to print cov2, then the program works, so it seems that it crashes only when I consider this variable... Do you have any idea? Thanks in advance! Ps: when I say "crashes" I mean that Matlab window just closes without any message or so, I just have to re-launch Matlab...

2 comentarios

Jan
Jan el 6 de Jun. de 2013
Editada: Jan el 6 de Jun. de 2013
There is no magic limit for the number of inputs.
Could you please specify where the function crashes?
Your methods to copy the values could be simplified, when you use the count j for bother sides, or even better, call memcpy instead of the loops.
Matteo
Matteo el 6 de Jun. de 2013
Editada: Matteo el 6 de Jun. de 2013
The function crash as soon as I do something with the new variable "cov2". In the case of the code posted above, it happens when I call
printf("%f %f %f %f\n",omegai[0][0], cov[0], beta[20000], cov2[20000]);
Thank you for the memcpy suggestion, I didn't know that.

Iniciar sesión para comentar.

 Respuesta aceptada

Friedrich
Friedrich el 6 de Jun. de 2013

1 voto

Hi,
have you tried debugging your MEX?
This way you can figure out the line which makes it crash and then most likely the reason of the crash.

14 comentarios

Matteo
Matteo el 6 de Jun. de 2013
Thank you for your suggesion, anyway I already figured out which one is the line that makes it crash (see my answer to jan), but still I cannot understand the reason!
Friedrich
Friedrich el 6 de Jun. de 2013
Editada: Friedrich el 6 de Jun. de 2013
It doesnt crash because of COV2 its because of beta. In the call to print you do this with beta:
beta[20000]
However it was declared to be:
double beta[9]={}
The index is out of bounds. And like suggested by Jan use memcopy to speed things up.
Matteo
Matteo el 6 de Jun. de 2013
Thank you very much for your help, I really appreciate it! Anyway, I just noticed that mistake, it was beta[2], but it still doesn't work. I also skip from the previous loops to using memcpy, but nothing has changed.
Friedrich
Friedrich el 6 de Jun. de 2013
Editada: Friedrich el 6 de Jun. de 2013
Can you try: mexPrintf instead of printf? and post your updated code with memcpy?
Matteo
Matteo el 6 de Jun. de 2013
Sure! Done! :) It seems that thee is no difference when using mexPrintf instead of printf.
Friedrich
Friedrich el 7 de Jun. de 2013
Editada: Friedrich el 7 de Jun. de 2013
I cant see anything wrong. So I took your code called it test.c compiled it with SDK 7.1 in 13a and run it liket his:
>> [a,b] = test(1:76672,1:76672,1:76672,1:76672,1:76672,1:76672,1:76672,1:76672);
1.000000 1.000000 3.000000 20001.000000
Which was working. (I remmoved the ={} declarations to it's valid C syntax). Since I don't know the input you use to test your code i simply took the same value for all.
Matteo
Matteo el 7 de Jun. de 2013
That's really strange! If I run the code with your inputs, it still crashes on my machine! I use gcc with Matlab 2011b.
Friedrich
Friedrich el 7 de Jun. de 2013
I also hat to uncomment the include of the unistd header because this doesnt exist for me on windows. what happens when you uncomment that one?
Matteo
Matteo el 7 de Jun. de 2013
Unfortunately, there is no difference. :(
Friedrich
Friedrich el 10 de Jun. de 2013
I guess I figured it out. You're using too much stack.
All those sized variables are allocated on the stack. You're at least using 8587264 bytes whereas standard stack size is limited to about 8192 kb (at least on 64-bit Ubuntu 12.04).
After setting:
ulimit -s unlimited
it works for me on Linux as well.
Matteo
Matteo el 10 de Jun. de 2013
Thank you very much for your help, Friedrich, you're really kind and helpful! I think we are close to finding a solution to the problem, actually it's still not working but I'm quite convinced that it might be a problem of stack memory. If I change the order in which I memorize the variables, the problem is always skipped to the last variable I'm allocating on the stack. But I'm working with 64bit SUSE Linux 11, unfortunately. :D I tried with ulimit -s unlimited, and after typing it in the terminal, if I type ulimit -a I actually see that now the stack memory should be unlimited. But then if I run the program on the MATLAB windows, it still crashes.
Friedrich
Friedrich el 11 de Jun. de 2013
Editada: Friedrich el 11 de Jun. de 2013
I think you always need to start MATLAB from the terminal in which you run ulimit -s unlimited. So open a Shell, run ulimit ..., start MATLAB from that shell, recompile the mex, run the mex. At least this way it works for me.
I also changed the rectsam routine a bit in order to be sure to get the correct adress for the memcpy (i dont trust compilers that much ;))
void rejectsam(double *y, double *p, double *r, double *w, double *ww, double *mx, double *cv, double *c2v, double *u, double *xx) {
int j,t,h, flag, count, m, m2,test;
double meanz[2][1],sigmz[2][2],
meanz2[6][1],sigmz2[6][6],
Ycat[76672], Ycat2[76672],
aux2[2][1], aux[6][1],
aux3[3][1],aux3b[3][1],
L2[2][2], L6[6][6],
Z[8][76672], omegai[9][9],
beta[9], Ycont[76672],
meanb[2][1], sigmab[2][2],
meany12, vary12, mis[76672],
invaux[3][3], invomega[3][3],
omega0238[6][3], omega0238t[3][6],
interm[6][3], interm2[6][6],
cov[76672], cov2[76672];
mexPrintf("start \n");
memcpy(&(omegai[0][0]), y, sizeof(omegai));
mexPrintf("1 \n");
memcpy(&(beta[0]), p, sizeof(beta));
mexPrintf("2 \n");
memcpy(&(Ycont[0]), r, sizeof(Ycont));
mexPrintf("3 \n");
memcpy(&(Ycat[0]), w, sizeof(Ycat));
mexPrintf("4 \n");
memcpy(&(Ycat2[0]), ww, sizeof(Ycat2));
mexPrintf("5 \n");
memcpy(&(mis[0]), mx, sizeof(mis));
mexPrintf("6 \n");
memcpy(&(cov[0]), cv, sizeof(cov));
mexPrintf("7 \n");
memcpy(&(cov2[0]), &(c2v[0]), sizeof(cov2));*/
mexPrintf("loops %i\n",cov2[76671]);
for (j=0;j<3;j++)
{
for (t=0;t<3;t++)
invaux[t][j]=omegai[t][j];
}
for (j=0;j<2;j++)
{
sigmab[j][j]=1;
meanb[j][0]=beta[j+1];
}
mexPrintf("copy \n");
memcpy(&(u[0]), &(Z[0][0]), sizeof(Z));
memcpy(&(xx[0]), &(Ycont[0]), sizeof(Ycont));
mexPrintf("done \n");
}
Matteo
Matteo el 11 de Jun. de 2013
Yeah!!!! It works fine!!! Thank you sooo much Friedrich! I cannot really tell you how am I grateful! When you go to sleep this evening you can think that you did your good deed for today! :D
Friedrich
Friedrich el 11 de Jun. de 2013
Yay. great. I guess I will have a few beer to celebrate that tough one^^

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

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

Etiquetas

Preguntada:

el 6 de Jun. de 2013

Community Treasure Hunt

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

Start Hunting!

Translated by