Can I check that is the output variable same as input variable in mex?

I have two condition:
  1. new = myfunc(origin)
  2. origin = myfunc(origin)
Can I get the name of variable such as "new" and "origin" in mex file?

 Risposta accettata

You don't have enough information available (officially) to do what you are trying to do reliably and safely in a mex routine. The reason is that many MATLAB operations (such as assignments) are, by default, shared data copies of each other. That is, the data pointers point to the same memory. Data copies are only made when the data of one copy changes. E.g., consider this
>> format debug
>> X = 1:3
X =
Structure address = 7711b40
m = 1
n = 3
pr = 32bd2680
pi = 0
1 2 3
>> Y = X
Y =
Structure address = 7712780
m = 1
n = 3
pr = 32bd2680
pi = 0
1 2 3
>> Y(1) = -1
Y =
Structure address = 7712780
m = 1
n = 3
pr = 32bd2900
pi = 0
-1 2 3
When X is first created, the real data pointer pr points to memory location 32bd2680. At this point you could safely modify this variable in-place in a mex routine with no ill side effects since it isn't sharing data with any other variable. But after the assignment Y = X is made, notice that the real data pointer pr for Y is the same as the real data pointer for X, namely that 32bd2680 address again. Now you have a problem if you try to modify X in-place in a mex routine since any changes will happen to the Y variable as well. Then when you change the first element of Y notice that its real data pointer pr has changed to a new address 32bd2900. Now X and Y are not sharing data pointers anymore and you could safely modify X in-place in a mex routine with no ill side effects.
The problem with all of this is that there are NO OFFICIAL API FUNCTIONS to tell you, in a mex routine, when a variable is sharing data with another variable. And in fact, this is not the only way that variables can be sharing. There could be reference copies around (i.e., field or cell elements), and there could be parent copies around (the struct or cell that the variable is part of could be shared with another variable). NONE of this is visible to you in mex routines with any of the official API functions. So even if you could detect how your mex routine was called (new = myfunc(origin) vs origin = myfunc(origin)), you could never be sure that in the origin = myfunc(origin) case it would be safe to modify origin in-place inside the mex routine.
The only way to detect this sharing condition in a mex routine is to hack into the mxArray structure itself and look at the CrossLink and Reference Count fields to see if they are not NULL or 0. And if the variable happens to be a SUB-ELEMENT (cell element or field of a struct) then it can get VERY complicated and messy to try and figure out if there is any parent sharing involved.
The only practical solution I can offer you is to manage, at your m-file calling level, your variable such that data-sharing NEVER takes place. I.e., never do anything (such as a simple assignment to another variable) that could cause data sharing to take place. Then call your mex function in one of two ways:
1) new = myfunc(origin)
2) myfunc(origin)
In method 1, you simply check nlhs to see that it is 1 ... and that is your clue to the mex routine to NOT modify the variable in-place, but rather create a new output variable.
In method 2, you simply check nlhs to see that it is 0 ... and that is your clue to the mex routine that it is directed to modify the variable in-place. The burden to make sure there are no ill side effects is entirely on you at the m-file level to make sure you didn't do anything that would cause data sharing.
Note that I am not advising you to take this approach ... I am simply pointing out what I think to be the only practical way of accomplishing your objective should you really need to modify variables in-place in a mex routine. Bottom line is you need to understand what operations at the m-file level cause data sharing, and avoid those operations with the variable you want to modify in-place.

Più risposte (1)

You call back into MATLAB to call dbstack and you parse that result to find the line number of the file you are executing and you parse the file at that line to figure out what the output variable name is.
But is that really what you care about? Or are you trying to find out whether your situation is going to be a "copy on write" or a "modify in place" situation? Because if you have reason to test for "modify in place", there are other ways than to check the variable names.

3 Commenti

I want to "copy on write" when "new = myfunc(origin)" and "modify in place" when "origin = myfunc(origin)".
That happens automatically, provided that origin is not sharing its data with other variables.
Does that happen in mex function? How does the mechanism?

Accedi per commentare.

Categorie

Community Treasure Hunt

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

Start Hunting!

Translated by