5.0

5.0 | 1 rating Rate this file 11 Downloads (last 30 days) File Size: 9.64 KB File ID: #31257
image thumbnail

mexme - write MEX files in no time

by Patrick Mineault

 

30 Apr 2011 (Updated 09 May 2011)

writes fully valid MEX .c files including mexFunction boilerplate based on numeric C snippet

| Watch this File

File Information
Description

mexme automates the process of writing MEX files. You give mexme a snippet of C which just does numeric computations, as well a list of arguments, and it generates a valid MEX .c file. New in version 1.1, it writes tedious input and output validation code for you. This way you can write a MEX file without manually coding calls to mx* API functions. It's inspired by SciPy's weave function.

Example: translate this piece of (non-vectorizable) .m code that applies a recursive filter into C:

function [y] = myrecursivefilter(x,alpha)
    y = zeros(size(x));
    y(1) = x(1)*alpha;
    for ii = 2:length(x)
        y(ii) = y(ii-1)*(1-alpha) + x(ii)*alpha;
    end
end

Step 1: Write myrecursivefilter.csnip which does the same thing as the m file:

y[0] = x[0]*alpha;
for(mwSize i = 1; i < x_length; i++) {
    y[i] = x[i]*alpha + y[i-1]*(1-alpha);
}

Step 2: Define arguments to your function (in Matlab):

inputargs = [InputNum('x'),...
             InputNum('alpha',true,true,'double','alpha > 0 && alpha < 1)]; %scalar
             %The last condition
outputarg = OutputNum('y','x_length,1');

Step 3: Generate a fully fledged .c file that can be compiled with mex:

cfile = mexme('myrecursivefilter.csnip',inputargs,outputarg)
writefile('myfilt.c',cfile);
mex myfilt.c
x = randn(1e6,1);
y = myfilt(x,.1);
plot([x,y])

cfile =

/*#include and #define not shown*/
#include "mexmetypecheck.c"

void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{

/*Input output boilerplate*/
    if(nlhs != 1 || nrhs != 2)
        mexErrMsgTxt("Function must be called with 2 arguments and has 1 return values");

    const mxArray *x_ptr = prhs[0];
    const mwSize x_m = mxGetM(x_ptr);
    const mwSize x_n = mxGetN(x_ptr);
    const mwSize x_length = x_m == 1 ? x_n : x_m;
    const mwSize x_numel = mxGetNumberOfElements(x_ptr);
    const int x_ndims = mxGetNumberOfDimensions(x_ptr);
    const mwSize *x_size = mxGetDimensions(x_ptr);
    const double *x = (double *) mxGetData(x_ptr);
    const mxArray *alpha_ptr = prhs[1];
    if(mxGetNumberOfElements(alpha_ptr) != 1)
        mexErrMsgTxt("Argument alpha (#2) must be scalar");
    const double alpha = (double) mxGetScalar(alpha_ptr);
    if(!(alpha > 0 && alpha < 1))
        mexErrMsgTxt("Argument alpha (#2) did not pass test \"alpha > 0 && alpha < 1\"");
    

    mwSize y_dims[] = {x_length,1};
    plhs[0] = mxCreateNumericArray(2,y_dims,mxDOUBLE_CLASS,mxREAL);
    mxArray **y_ptr = &plhs[0];
    double *y = (double *) mxGetData(*y_ptr);
    

/*Actual function*/
#include "myfilt.csnip"

}

For every argument that you define, mexme generates extra "magic" variables. For example, if the variable is x, then in C:

x is the data
x_m is the size of the first dimension
x_n is the size of the second dimension
x_length is the length of a vector
x_numel is the number of elements in an array
x_ndims is the numer of dimensions
x_size is equivalent to the Matlab code size(x)
x_ptr is a reference to the mxArray that contains the x data

And if x is complex, x_r and x_i are the real and imaginary components of the data.

mexme currently does not support sparse data or non-numeric types but it does support full numeric arrays of any type (int8, single, double, etc.).

Acknowledgements

The author wishes to acknowledge the following in the creation of this submission:
verbatim: Get the text of a block comment.
This submission has inspired the following:
Fast B-spline class

MATLAB release MATLAB 7.7 (R2008b)
Tags for This File  
Everyone's Tags
Tags I've Applied
Add New Tags Please login to tag files.
Comments and Ratings (4)
02 May 2011 Patrick Mineault

Sorry, I forgot to include TestMexMe.m in the zip, just uploaded the file, should be there in a day or so.

03 May 2011 Patrick Mineault

It's updated now.

20 May 2011 Eric Patterson

Awesome! Worked as expected for me in my usual Linux environment. Tried to share with a coworker on Windows who couldn't get the c file mexed. I am not as familiar with the Visual Studio compiler, so I haven't been able to figure it out (we have both successfully mexed files in the past). What compiler was it tested with?

20 May 2011 Patrick Mineault

It was tested with gcc on Linux only. Hard to say what the problem is without the error message.

Please login to add a comment or rating.
Updates
02 May 2011

Added reference to verbatim

03 May 2011

Added TestMexMe.m in zip file

09 May 2011

Added input/output validation code generation

Tag Activity for this File
Tag Applied By Date/Time
mex Patrick Mineault 02 May 2011 11:52:41
c Patrick Mineault 02 May 2011 11:52:41
compiled code Patrick Mineault 02 May 2011 11:52:41
mex tools Patrick Mineault 02 May 2011 11:52:41
compile mex Patrick Mineault 03 May 2011 18:35:35
mex code Patrick Mineault 03 May 2011 18:36:12
code generator Patrick Mineault 03 May 2011 18:36:17
weave Patrick Mineault 03 May 2011 18:36:30
write mex code Patrick Mineault 03 May 2011 18:37:48
generate mex code Patrick Mineault 03 May 2011 18:37:53
mex validation code Patrick Mineault 09 May 2011 14:33:35
argument validation Patrick Mineault 09 May 2011 14:33:44
fast code Patrick Mineault 10 May 2011 15:52:03

Contact us at files@mathworks.com