Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Pass by reference in MexFunction

Subject: Pass by reference in MexFunction

From: Marc Moreau

Date: 13 Nov, 2010 21:27:03

Message: 1 of 14

Hello all,

I'm doing some work with EEGLAB where I would like implement a Wavelet transform on CUDA. One of the concerns we have with memory allocation. The input and output to the function is large, so large in fact, that we would like to not have to create new output matrixes for each call. We would like to preallocate the output array and then repeatedly use it on subsequent calls. I have been looking around and have been unable to locate any documentation on how this is possible or why it isn't.

Any suggestions?

Marc Moreau

Subject: Pass by reference in MexFunction

From: James Tursa

Date: 14 Nov, 2010 01:36:03

Message: 2 of 14

"Marc Moreau" <jebnor@gmail.com> wrote in message <ibmvr7$9no$1@fred.mathworks.com>...
> Hello all,
>
> I'm doing some work with EEGLAB where I would like implement a Wavelet transform on CUDA. One of the concerns we have with memory allocation. The input and output to the function is large, so large in fact, that we would like to not have to create new output matrixes for each call. We would like to preallocate the output array and then repeatedly use it on subsequent calls. I have been looking around and have been unable to locate any documentation on how this is possible or why it isn't.
>
> Any suggestions?
>
> Marc Moreau

Arguments to mex routines are pass by reference and can (if you are careful) be modified in-place. Is that what you mean?

James Tursa

Subject: Pass by reference in MexFunction

From: Marc Moreau

Date: 14 Nov, 2010 02:37:04

Message: 3 of 14

"James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <ibnee3$mer$1@fred.mathworks.com>...

> Arguments to mex routines are pass by reference and can (if you are careful) be modified in-place. Is that what you mean?

Yes, that is exactly what I mean. Thank you.

As a follow up, in the interest of keeping the interface to the function I am replicating as close as possible to the existing, I'd like to call myfunc() like this:

bigdata = myfunc( bigdata );

Is it well defined within MATLAB for my myfunc() to get the data pointer from the rhs[0], manipulate it and then set the lhs[0] data pointer to the same underlying data?

Subject: Pass by reference in MexFunction

From: James Tursa

Date: 14 Nov, 2010 07:32:07

Message: 4 of 14

"Marc Moreau" <jebnor@gmail.com> wrote in message <ibni0g$cud$1@fred.mathworks.com>...
> "James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <ibnee3$mer$1@fred.mathworks.com>...
>
> > Arguments to mex routines are pass by reference and can (if you are careful) be modified in-place. Is that what you mean?
>
> Yes, that is exactly what I mean. Thank you.
>
> As a follow up, in the interest of keeping the interface to the function I am replicating as close as possible to the existing, I'd like to call myfunc() like this:
>
> bigdata = myfunc( bigdata );
>
> Is it well defined within MATLAB for my myfunc() to get the data pointer from the rhs[0], manipulate it and then set the lhs[0] data pointer to the same underlying data?

Usually if you set an output variable, e.g. plhs[0], in a mex function MATLAB makes a shared data copy to return. The above *may* work, but that is not how I would do it. My advice is to simply call it like this:

myfunc( bigdata );

Then modify bigdata in-place and don't set plhs[0] to anything ... just leave it alone.

James Tursa

Subject: Pass by reference in MexFunction

From: Amit

Date: 9 Jul, 2011 16:17:11

Message: 5 of 14

"James Tursa" wrote in message <ibo39m$pgo$1@fred.mathworks.com>...
> "Marc Moreau" <jebnor@gmail.com> wrote in message <ibni0g$cud$1@fred.mathworks.com>...
> > "James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <ibnee3$mer$1@fred.mathworks.com>...
> >
> > > Arguments to mex routines are pass by reference and can (if you are careful) be modified in-place. Is that what you mean?
> >
> > Yes, that is exactly what I mean. Thank you.
> >
> > As a follow up, in the interest of keeping the interface to the function I am replicating as close as possible to the existing, I'd like to call myfunc() like this:
> >
> > bigdata = myfunc( bigdata );
> >
> > Is it well defined within MATLAB for my myfunc() to get the data pointer from the rhs[0], manipulate it and then set the lhs[0] data pointer to the same underlying data?
>
> Usually if you set an output variable, e.g. plhs[0], in a mex function MATLAB makes a shared data copy to return. The above *may* work, but that is not how I would do it. My advice is to simply call it like this:
>
> myfunc( bigdata );
>
> Then modify bigdata in-place and don't set plhs[0] to anything ... just leave it alone.
>
> James Tursa

Hi,
I want to do exactly same as you have suggested for my problem. But I dont know how to modify input data prhs[0] in place and leave plhs[0] alone. please explain by any simple example.
Thanks in advance,
Amit

Subject: Pass by reference in MexFunction

From: James Tursa

Date: 9 Jul, 2011 21:28:09

Message: 6 of 14

"Amit " <amitsingh.singh@gmail.com> wrote in message <iv9uu7$rqk$1@newscl01ah.mathworks.com>...
> "James Tursa" wrote in message <ibo39m$pgo$1@fred.mathworks.com>...
> > "Marc Moreau" <jebnor@gmail.com> wrote in message <ibni0g$cud$1@fred.mathworks.com>...
> > > "James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <ibnee3$mer$1@fred.mathworks.com>...
> > >
> > > > Arguments to mex routines are pass by reference and can (if you are careful) be modified in-place. Is that what you mean?
> > >
> > > Yes, that is exactly what I mean. Thank you.
> > >
> > > As a follow up, in the interest of keeping the interface to the function I am replicating as close as possible to the existing, I'd like to call myfunc() like this:
> > >
> > > bigdata = myfunc( bigdata );
> > >
> > > Is it well defined within MATLAB for my myfunc() to get the data pointer from the rhs[0], manipulate it and then set the lhs[0] data pointer to the same underlying data?
> >
> > Usually if you set an output variable, e.g. plhs[0], in a mex function MATLAB makes a shared data copy to return. The above *may* work, but that is not how I would do it. My advice is to simply call it like this:
> >
> > myfunc( bigdata );
> >
> > Then modify bigdata in-place and don't set plhs[0] to anything ... just leave it alone.
> >
> > James Tursa
>
> Hi,
> I want to do exactly same as you have suggested for my problem. But I dont know how to modify input data prhs[0] in place and leave plhs[0] alone. please explain by any simple example.
> Thanks in advance,
> Amit

Call it like this:

myfunc( bigdata );

And then the mex function myfunc.c would look like this:

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    double *pr;
    pr = mxGetPr(prhs[0]);
    pr[0] = 99.0;
}

So the short example above changes the first element of bigdata to 99 in-place.

James Tursa

Subject: Pass by reference in MexFunction

From: Amit

Date: 10 Jul, 2011 04:25:09

Message: 7 of 14

"James Tursa" wrote in message <ivah59$au6$1@newscl01ah.mathworks.com>...
> "Amit " <amitsingh.singh@gmail.com> wrote in message <iv9uu7$rqk$1@newscl01ah.mathworks.com>...
> > "James Tursa" wrote in message <ibo39m$pgo$1@fred.mathworks.com>...
> > > "Marc Moreau" <jebnor@gmail.com> wrote in message <ibni0g$cud$1@fred.mathworks.com>...
> > > > "James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <ibnee3$mer$1@fred.mathworks.com>...
> > > >
> > > > > Arguments to mex routines are pass by reference and can (if you are careful) be modified in-place. Is that what you mean?
> > > >
> > > > Yes, that is exactly what I mean. Thank you.
> > > >
> > > > As a follow up, in the interest of keeping the interface to the function I am replicating as close as possible to the existing, I'd like to call myfunc() like this:
> > > >
> > > > bigdata = myfunc( bigdata );
> > > >
> > > > Is it well defined within MATLAB for my myfunc() to get the data pointer from the rhs[0], manipulate it and then set the lhs[0] data pointer to the same underlying data?
> > >
> > > Usually if you set an output variable, e.g. plhs[0], in a mex function MATLAB makes a shared data copy to return. The above *may* work, but that is not how I would do it. My advice is to simply call it like this:
> > >
> > > myfunc( bigdata );
> > >
> > > Then modify bigdata in-place and don't set plhs[0] to anything ... just leave it alone.
> > >
> > > James Tursa
> >
> > Hi,
> > I want to do exactly same as you have suggested for my problem. But I dont know how to modify input data prhs[0] in place and leave plhs[0] alone. please explain by any simple example.
> > Thanks in advance,
> > Amit
>
> Call it like this:
>
> myfunc( bigdata );
>
> And then the mex function myfunc.c would look like this:
>
> #include "mex.h"
>
> void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
> {
> double *pr;
> pr = mxGetPr(prhs[0]);
> pr[0] = 99.0;
> }
>
> So the short example above changes the first element of bigdata to 99 in-place.
>
> James Tursa

Thanks a lot. It worked for me.

Amit

Subject: Pass by reference in MexFunction

From: Satheesh

Date: 17 Apr, 2013 18:40:08

Message: 8 of 14


> void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
> {
> double *pr;
> pr = mxGetPr(prhs[0]);
> pr[0] = 99.0;
> }

Hi James Tursa

Even I'm in a similar situation as described by Marc. I tested the solution provided by you and it works. But the Matlab documentation says that prhs values should not be modified in MEX functions.

"Array of pointers to the input mxArrays. Do not modify any prhs values in your MEX-file. Changing the data in these read-only mxArrays can produce undesired side effects."

Reference - http://www.mathworks.com/help/matlab/apiref/mexfunction.html

So I'm not sure if I should go ahead and use the solution as it works for me. Please advise.

Satheesh

Subject: Pass by reference in MexFunction

From: James Tursa

Date: 17 Apr, 2013 19:46:07

Message: 9 of 14

"Satheesh" wrote in message <kkmqa8$kv8$1@newscl01ah.mathworks.com>...
>
> > void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
> > {
> > double *pr;
> > pr = mxGetPr(prhs[0]);
> > pr[0] = 99.0;
> > }
>
> Hi James Tursa
>
> Even I'm in a similar situation as described by Marc. I tested the solution provided by you and it works. But the Matlab documentation says that prhs values should not be modified in MEX functions.
>
> "Array of pointers to the input mxArrays. Do not modify any prhs values in your MEX-file. Changing the data in these read-only mxArrays can produce undesired side effects."
>
> Reference - http://www.mathworks.com/help/matlab/apiref/mexfunction.html
>
> So I'm not sure if I should go ahead and use the solution as it works for me. Please advise.
>
> Satheesh

The reason for the caution is that MATLAB variables can be "shared", meaning that two different variables can be pointed to the exact same data location. So changing one of them in-place in a mex routine will change the other as well. Example (pr is the data pointer),

format debug
A = 1:5;
B = A; % B is actually sharing the same data area as A, see the pr value
my_inplace_mex_function(A); % This call will change B also !!!

So the official advice is never to do it, since you can't always tell in a mex routine if a variable is shared or not (MATLAB provides no such functions in the API).

That being said, if you are working with very large variables you might be forced to do it anyway because of memory or time constraints. So the *unofficial* advice on doing in-place calculations in a mex routine is to only do it if you *know* in advance that the variable is not shared (or that you can tolerate the potential side-effects). I.e., take care to never do anything with the variable (assignment, reshape, etc) that would create a shared data copy of it. There are unofficial ways to hack into the mxArray in a mex routine to detect sharing, but it can get complicated for cell and struct arrays so I will not get into those details here.

James Tursa

Subject: Pass by reference in MexFunction

From: Eric Sampson

Date: 17 Apr, 2013 20:40:08

Message: 10 of 14

"James Tursa" wrote in message <kkmu5v$44o$1@newscl01ah.mathworks.com>...
> "Satheesh" wrote in message <kkmqa8$kv8$1@newscl01ah.mathworks.com>...
> >
> > > void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
> > > {
> > > double *pr;
> > > pr = mxGetPr(prhs[0]);
> > > pr[0] = 99.0;
> > > }
> >
> > Hi James Tursa
> >
> > Even I'm in a similar situation as described by Marc. I tested the solution provided by you and it works. But the Matlab documentation says that prhs values should not be modified in MEX functions.
> >
> > "Array of pointers to the input mxArrays. Do not modify any prhs values in your MEX-file. Changing the data in these read-only mxArrays can produce undesired side effects."
> >
> > Reference - http://www.mathworks.com/help/matlab/apiref/mexfunction.html
> >
> > So I'm not sure if I should go ahead and use the solution as it works for me. Please advise.
> >
> > Satheesh
>
> The reason for the caution is that MATLAB variables can be "shared", meaning that two different variables can be pointed to the exact same data location. So changing one of them in-place in a mex routine will change the other as well. Example (pr is the data pointer),
>
> format debug
> A = 1:5;
> B = A; % B is actually sharing the same data area as A, see the pr value
> my_inplace_mex_function(A); % This call will change B also !!!
>
> So the official advice is never to do it, since you can't always tell in a mex routine if a variable is shared or not (MATLAB provides no such functions in the API).
>
> That being said, if you are working with very large variables you might be forced to do it anyway because of memory or time constraints. So the *unofficial* advice on doing in-place calculations in a mex routine is to only do it if you *know* in advance that the variable is not shared (or that you can tolerate the potential side-effects). I.e., take care to never do anything with the variable (assignment, reshape, etc) that would create a shared data copy of it. There are unofficial ways to hack into the mxArray in a mex routine to detect sharing, but it can get complicated for cell and struct arrays so I will not get into those details here.
>
> James Tursa

James, did you end up releasing your MEX in-place guide document on the FEX, as you had mentioned a while back?

Subject: Pass by reference in MexFunction

From: James Tursa

Date: 17 Apr, 2013 21:26:11

Message: 11 of 14

"Eric Sampson" wrote in message <kkn1b8$ekv$1@newscl01ah.mathworks.com>...
>
> James, did you end up releasing your MEX in-place guide document on the FEX, as you had mentioned a while back?

... sigh ... no, unfortunately. I keep adding to it. I need to stop that and at some point release what I have, I suppose.

James Tursa

Subject: Pass by reference in MexFunction

From: Eric Sampson

Date: 17 Apr, 2013 21:53:09

Message: 12 of 14

"James Tursa" wrote in message <kkn41j$mc6$1@newscl01ah.mathworks.com>...
> "Eric Sampson" wrote in message <kkn1b8$ekv$1@newscl01ah.mathworks.com>...
> >
> > James, did you end up releasing your MEX in-place guide document on the FEX, as you had mentioned a while back?
>
> ... sigh ... no, unfortunately. I keep adding to it. I need to stop that and at some point release what I have, I suppose.
>
> James Tursa

Thankfully the FEX has the ability to handle revisions! Release early and often :) Push the button now, we don't want to risk a 'bus incident' :)

Subject: Pass by reference in MexFunction

From: Pierre

Date: 22 Apr, 2013 12:30:11

Message: 13 of 14

"James Tursa" wrote in message <kkmu5v$44o$1@newscl01ah.mathworks.com>...
> [...] That being said, if you are working with very large variables you might be forced to do it anyway because of memory or time constraints. So the *unofficial* advice on doing in-place calculations in a mex routine is to only do it if you *know* in advance that the variable is not shared (or that you can tolerate the potential side-effects). I.e., take care to never do anything with the variable (assignment, reshape, etc) that would create a shared data copy of it. There are unofficial ways to hack into the mxArray in a mex routine to detect sharing, but it can get complicated for cell and struct arrays so I will not get into those details here.
>
> James Tursa

I'd like to point out, that when I used in-place modification of an array some time ago, it did produce erronous results, although, based solely on the MATLAB script, there was no obvious reason for shared memory issues. The situation was like this:
  function cost = costFunction(...)
  M = initialize_memory_space_for_huge_matrix();
  for i=1:n
      computeValueForMInPlace(M, inputData{i});
      cost(i) = computeScoreBasedOnM(M);
  end

costFunction was subject to optimization by lsqnonlin. I did that because memory allocation represented a serious problem and caused tremendous execution times, if memory for M was allocated inside the mex at each iteration. Now, for some reason, executing this code in debug mode worked just fine, but running it normally, caused the results to get messed up all over the place.

I suppose, although it's pure speculation, that either MATLAB somehow interlaced execution of the iterations (even though we don't have the parallel processing toolbox), based on the assumption, that M would remain constant during the entire loop as it's never being used on lhs inside the loop. Or that perhaps lsqnonlin has some parallel evaluation mechanism of costFunction which caused things to get messed up... but I cannot imagine how latter would create hidden shared-memory issues in this case?!

That being said: even if you are very convinced, that there can't be any memory shared, double- and triple-check, if your code still runs in non-debug mode.

Subject: Pass by reference in MexFunction

From: James Tursa

Date: 22 Apr, 2013 15:08:09

Message: 14 of 14

"Pierre " <ppsscchhrrooeeddeerr@vitechnology.com> wrote in message <kl3agj$7pu$1@newscl01ah.mathworks.com>...
>
> I'd like to point out, that when I used in-place modification of an array some time ago, it did produce erronous results, although, based solely on the MATLAB script, there was no obvious reason for shared memory issues. The situation was like this:
> function cost = costFunction(...)
> M = initialize_memory_space_for_huge_matrix();
> for i=1:n
> computeValueForMInPlace(M, inputData{i});
> cost(i) = computeScoreBasedOnM(M);
> end
>
> costFunction was subject to optimization by lsqnonlin. I did that because memory allocation represented a serious problem and caused tremendous execution times, if memory for M was allocated inside the mex at each iteration. Now, for some reason, executing this code in debug mode worked just fine, but running it normally, caused the results to get messed up all over the place.
>
> I suppose, although it's pure speculation, that either MATLAB somehow interlaced execution of the iterations (even though we don't have the parallel processing toolbox), based on the assumption, that M would remain constant during the entire loop as it's never being used on lhs inside the loop. Or that perhaps lsqnonlin has some parallel evaluation mechanism of costFunction which caused things to get messed up... but I cannot imagine how latter would create hidden shared-memory issues in this case?!

I would be interested in seeing a minimal version of the code that produces this problem. From your scant description it is hard to guess what the underlying problem was. (e.g., maybe a temporary variable that was cleared and you didn't realize it).

james Tursa

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us