Unfortunately, one of my functions called by the parfor loop absolutely requires persistently-scoped variables.
So my ridiculous question... does anyone know a workaround that will allow me to use persistent variables within a parfor loop?? I've tried using genvarname() to make a list of random variable names, but then got stuck doing eval statements every time I wanted to use the randomly-named variable.
Here's the outline of my code...
-------------
function parallel_test()
...
parfor i = 1:10
inside_function();
end
...
end
-------------
function inside_function()
...
ode_function(0,[],[]); % empty call to set persistent variables
[time values] = ode15s('ode_function',[0 100], initialvalues);
...
end
-------------
function delta = ode_function(t,initvalues)
persistent X;
persistent X_index;
if isempty(t)
X = zeros(1000,1);
X_index = 1;
end
X(X_index) = some_value_calculated_in_this_ode_timestep;
X_index = X_index+1;
% calculate ODE fluxes, pass to next timestep
delta = array_of_updated_values;
end
> I've run into a problem with using persistent variables in functions that are
> called within a parfor loop (Parallel Computing Toolbox). Because the name of
> the variable is the same, every parallel worker is conflicting with each other
> by using the same variable in the workspace. This is exactly why the parfor
> documentation warns against using global or persistent variables.
There are two things going on here. Firstly, the PERSISTENT statement is illegal
when mentioned directly within the body of a PARFOR loop. That's to protect you
from the real underlying problem, which is that different MATLAB instances
execute the different loop body iterations. Therefore, the instances of
persistent variables are not shared between the loop iterations as one might
expect, and any (deliberate or accidental) attempt to transmit information from
one loop iteration to the next via PERSISTENT/GLOBAL variables will result in
unreliable results.
It's fine for functions called within the body of a PARFOR loop to use
persistent variables, providing that each loop iteration will not depend upon
the value of a persistent variable from a previous PARFOR iteration. (This is a
form of non-order-independence). So, the following is perfectly fine:
parfor ii = 1:10
myfcn(); % initialise persistent
for jj = 1:10
myfcn( jj );
end
result(ii) = myfcn();
end
function x = myfcn( in )
persistent store
if isempty( store )
store = 0;
end
x = store;
if nargin == 1
store = store + in;
else
store = 0;
end
But following is all wrong, as it attempts to use persistent information from
the previous loop iteration:
parfor ii = 1:10
result(ii) = myfcn( ii );
end
In conclusion, your example code looks reasonable because you're initializing
and using the persistent data within the scope of a single loop iteration. Are
you having problems with your code? Is it not working as you expect? Do you get
different results with MATLABPOOL closed vs. open?
Cheers,
Edric.