MATLAB Answers

0

mex usage efficiency question

Asked by Itzik Ben Shabat on 14 May 2015
Latest activity Edited by James Tursa
on 14 May 2015
Hi, I am new to mex. im using mex with PCL (Point Cloud Library). what i want to do is calculate different features of the point cloud. for each feature calculation i have a different mex file.
my question is which of the following two options is more efficient:
  1. Give the mex as input a file name and have it open that file and create the PCL cloud class (the basic structure to do anything) in each of the mexs.
  2. Open the file in MATLAB (or a different mex), store the point data in a MATLAB matrix and pass this matrix to each of the other mex files (and create the cloud class in each mex using this data).
so i guess my question is what would probably be more efficient - reading a file to create a class or manually creating a class every time ?

  0 Comments

Sign in to comment.

Tags

1 Answer

Answer by James Tursa
on 14 May 2015
 Accepted Answer

You don't say definitely whether or not you will need the PCL cloud class data in a MATLAB variable for some reason (maybe some calculations based on m-code). My comments below assume you don't really need the PCL cloud class data on the MATLAB side.
(1) Give the mex as input a file name and have it open that file and create the PCL cloud class (the basic structure to do anything) in each of the mexs.
This approach allows you to build the PCL cloud class in native C++ using presumably already available code. The downside of doing it exactly as you propose, using multiple mex files, is that you need to duplicate the reading and creating of the PCL cloud class for each separate mex routine. I prefer this approach over (2) below, but would change the approach to only one mex routine (see last comment).
(2) Open the file in MATLAB (or a different mex), store the point data in a MATLAB matrix and pass this matrix to each of the other mex files (and create the cloud class in each mex using this data).
The approach requires you to write new code to create a semblance of the PCL cloud class in a MATLAB variable. And each time you want to calculate something with this variable in a mex routine, you will need to copy all of it into its native C++ format first. This is not going to be efficient, and requires new code.
"... for each feature calculation i have a different mex file ..."
If you are looking for efficiency, then I would not do this. Rather, I would have one mex routine with all of the code in it for all of the calculations I wanted to do. When calling the mex routine, pass in an argument that specifies which function you want to do. E.g., this argument could be a string. If you passed in 'create' then it would read a file to create the PCL class variable and store it in a persistent memory block. Other strings would cause calculations to be performed on that PCL class variable. Passing in 'delete' would delete the PCL class variable. Etc. The advantage of this approach is that you only need to read in and create the PCL class variable once, only one copy of it exists in memory, and you can calculate different functions on it without re-reading it into memory. You would need to register a mexAtExit function to automatically do the 'delete' function if the mex file itself was cleared from memory.

  2 Comments

Yes,I would need the class data to perform further calculations within MATLAB. Is there a way to output the class from the mex to matlab ?
Your "secret option c" is a good one (instead of having multiple mex files, have only one to do everything... i think i will do that. thanks
James Tursa
on 14 May 2015
You will probably need to write custom C++ code to copy the PCL class variable data into a MATLAB variable of some type (e.g., struct). Maybe that could be one of the string argument inputs allowed ... e.g., 'get' would take the existing C++ variable and copy the data into a MATLAB variable and return it to the caller.
If you go with option "c", I would put some variables at the top level, outside of mexFunction, so they will persist between calls. E.g., a simple outline:
// Syntax: myMex % prints status of dymanic var
// myMex('create') % creates dynamic var
// myMex('set',value) % sets value of dynamic var
// y = myMex('get') % returns copy of dynamic var
// myMex('delete') % deletes dynamic var
#include "mex.h"
#include <stdlib.h>
#include <string.h>
int first_call = 1; // This will persist between calls
double *dp = NULL; // This will persist between calls
void myExit(void)
{
if( dp ) {
mexPrintf("Free'ing dynamic variable\n");
free(dp);
dp = NULL;
}
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
char *directive;
if( first_call ) {
mexAtExit(myExit);
first_call = 0;
}
if( nrhs == 0 ) {
if( dp ) {
mexPrintf("A dynamic variable is currently created\n");
} else {
mexPrintf("A dynamic variable is not currently created\n");
}
} else {
if( !mxIsChar(prhs[0]) ) {
mexErrMsgTxt("1st argument must be a string directive");
}
directive = mxArrayToString(prhs[0]);
if( strcmp(directive,"create") == 0 ) {
mxFree(directive);
if( dp ) {
mexErrMsgTxt("Dynamic variable is already created");
} else {
mexPrintf("Creating uninitialized dynamic variable\n");
dp = (double *) malloc(8);
if( dp == NULL ) {
mexErrMsgTxt("Unable to allocate dynamic variable");
}
}
} else if( strcmp(directive,"set") == 0 ) {
mxFree(directive);
if( dp ) {
if( nrhs >= 2 ) {
mexPrintf("Setting dynamic variable value\n");
*dp = mxGetScalar(prhs[1]);
} else {
*dp = 0.0;
}
} else {
mexErrMsgTxt("Dynamic variable is not created");
}
} else if( strcmp(directive,"get") == 0 ) {
mxFree(directive);
if( dp ) {
mexPrintf("Returning dynamic variable value\n");
plhs[0] = mxCreateDoubleScalar(*dp);
} else {
mexErrMsgTxt("Dynamic variable is not created");
}
} else if( strcmp(directive,"delete") == 0 ) {
mxFree(directive);
myExit();
} else {
mxFree(directive);
mexErrMsgTxt("Unknown directive");
}
}
}

Sign in to comment.