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

Jan
Jan 2013년 6월 6일
편집: Jan 2013년 6월 6일
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 2013년 6월 6일
편집: Matteo 2013년 6월 6일
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.

댓글을 달려면 로그인하십시오.

 채택된 답변

Friedrich
Friedrich 2013년 6월 6일

1 개 추천

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

Matteo
Matteo 2013년 6월 6일
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 2013년 6월 6일
편집: Friedrich 2013년 6월 6일
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 2013년 6월 6일
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 2013년 6월 6일
편집: Friedrich 2013년 6월 6일
Can you try: mexPrintf instead of printf? and post your updated code with memcpy?
Matteo
Matteo 2013년 6월 6일
Sure! Done! :) It seems that thee is no difference when using mexPrintf instead of printf.
Friedrich
Friedrich 2013년 6월 7일
편집: Friedrich 2013년 6월 7일
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 2013년 6월 7일
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 2013년 6월 7일
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 2013년 6월 7일
Unfortunately, there is no difference. :(
Friedrich
Friedrich 2013년 6월 10일
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 2013년 6월 10일
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 2013년 6월 11일
편집: Friedrich 2013년 6월 11일
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 2013년 6월 11일
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 2013년 6월 11일
Yay. great. I guess I will have a few beer to celebrate that tough one^^

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Write C Functions Callable from MATLAB (MEX Files)에 대해 자세히 알아보기

태그

질문:

2013년 6월 6일

Community Treasure Hunt

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

Start Hunting!

Translated by