alle_meije
alle_meije

Reputation: 2480

mex code crash on new matlab version / architecture

I have a routine that computes the shift-invariant discrete wavelet transform, as specified in the Rice Wavelet Toolbox, in the frequency domain. The code is in MEX (c-syntax) and uses some extra routines to do imaginary polynomials etc. in a separate file.

The source files fsidwt.c, fisidwt.c and the helper routines polyphase.[chm] are zipped together in a file here: http://ubuntuone.com/6zXIIuA3J4OTTlSquycMlz

This code worked without problems in older matlab versions, and other matlab functions depend on it.

Now however, when I compile it now, there is first a warning message

>> mex fisidwt.c polyphase.c % message about different gcc version
>> mex fsidwt.c polyphase.c % message about different gcc version
    fsidwt.c: In function ‘multiMRFWD1D’:
    fsidwt.c:187: warning: cast to pointer from integer of different size
    fsidwt.c:188: warning: cast to pointer from integer of different size
    fsidwt.c:189: warning: cast to pointer from integer of different size
    fsidwt.c:190: warning: cast to pointer from integer of different size

which is odd because no integers are cast to pointers. But it's only a warning, so let's carry on.

Now the mex files fsidwt and fisidwt compute the forward and inverse frequency-domain shift-ivariant wavelet transform.

My test program is very simple:

>> clear all; len_sig=256; wlevels=3; numsig=1; numtest=1; 
    % 256 points, 3 wavelet decomposition levels
>> st=4; ts=(1:(len_sig/st))'*(1:st); ts=ts(:); ts=ts*ones(1,numsig); Ts=fft(ts); 
    % sawtooth with 4 'teeth' of increasing height and its FFT
>> h=[1;1]/sqrt(2); g=qmf(h); h=[h(:) g(:)]; H=fft(h,len_sig); 
    % Haar wavelet filters and 256-point FFTs
>> [ffs ffd] = fsidwt(Ts, H, wlevels); 
    % forward wavelet transform
>> ffr=fisidwt(ffs,ffd,cH,levels); 
    % recontruction

Unfortunately it exits with a segmentation violation whose cause I cannot trace from the core dump output...

The lines in the code [in the zipfile at http://ubuntuone.com/6zXIIuA3J4OTTlSquycMlz], line numbers 187-190 of fsidwt.c, read:

Hfilter2d = (dComplexMat) dComplexMake2D ( hcomp[0],  NQ, Q);
Gfilter2d = (dComplexMat) dComplexMake2D ( hcomp[1],  NQ, Q);
Detail2d  = (dComplexMat) dComplexMake2D ( workspaced, Q, NQ);
Approx2d  = (dComplexMat) dComplexMake2D ( workspacec, Q, NQ);

All the LHS are of type

dComplexMat

which is

typedef struct {double r,i;} dComplex;
typedef dComplex *dComplexVec;
typedef dComplexVec *dComplexMat;

All the RHS are of type

(dComplexVec, long, long)

and the code of dComplexMake2D() is:

dComplexMat dComplexMake2D(
            dComplexVec array1D,
            int width, int height) {
    register int i;
    dComplexMat theMatrix = (dComplexMat) mxCalloc ( width, sizeof(dComplexVec) );
    theMatrix[0]=(dComplexVec)array1D;
    for(i=1;i<width;i++)
        theMatrix[i] = theMatrix[i-1] + height;
    return theMatrix;
}

How would I start finding the cause of this segmentation violation? Does it have to do with the warning? Is it the new Matlab version? Or the 64-bit architecture?

Upvotes: 3

Views: 458

Answers (1)

alle_meije
alle_meije

Reputation: 2480

Oh dear. The MathWorks helpdesk found, as they were investigating this, that the function header for dComplexMake2D had an extra d that I must have overlooked at least 42 times.

So embarrassing. But anyway, the code works like a dream (will put it online soon) and a lesson learned:

MEX warned about the return type of dComplexMake2D as it could not find a matching header, carried on (as it appears to do) but assumed return type int, linked to the compiled file where dComplexMake2D returns a pointer (a long int sized type) and that's where things went wrong...

Thanks to the tech support at MathWorks. They did point out that debugging MEX files is not in any way their business.

Upvotes: 1

Related Questions