# parfor gives different result to for

9 views (last 30 days)
Adam Craig on 8 Mar 2022
Commented: Walter Roberson on 20 Dec 2022
Hello all
Any idea why the following loop would give a different answer using "parfor" and "for" .. ??
pobj and obj are the parameter functions.
At the end of the loop the obj variable is intact, seemingly ruling out a "pointer" problem.
I've also tried initializing the pobj in the loop by manually copying the elements of the struct, like you would in a constructor.
As you can see, all the input variables are initialized to zero in each iteration for each value of Vpoint.
I've tried putting the contents of the parfor in a function.
When run as a parfor, you get the error
"The temporary variable 'qfe' will be cleared at the beginning of each iteration of the parfor-loop. If 'qfe' is used before
it is set, a runtime error will occur."
Indeed, when I specify qfe(:,Vpoint) to keep the data apart for the different loops, I get a different answer again.
But Matlab forces me to initalize to zero, so it doesn't help.
Using Matlab r2021a.
Thanks guys.
--------------------------------
%%% follows Stodtmann 2018
iterations = 20000;
parfor Vpoint=1:1%size(Vpoints,1)
pobj=0;
pobj=obj;
Vapplied = Vpoints(Vpoint,1);
% % must add Vb/2 to M(1,9)
pobj(1,1).V = pobj(1,1).V + Vapplied/0.026/2;
pobj(size(pobj,1),1).V = pobj(size(pobj,1),1).V - Vapplied/0.026/2;
for iter = 1:iterations
if (rem(iter,1000)==0) disp(iter); end
dielec = 0;
dielec = [pobj.epsi]';
dielec = dielec(2:size(dielec,1));
d2V = 0;
d2V = diff(dielec(:,1).*diff([pobj.V]'))/prec/prec; % find d2V/dx2 of trial solution
d2V = vertcat(0,d2V,0); % V^2cm-2
qfe = zeros(size(pobj,1)-1,1);
qfh = zeros(size(pobj,1)-1,1);
qfe = findQFLe(pobj, Vapplied/0.026, prec);
qfh = findQFLh(pobj, Vapplied/0.026, prec);
RHS=zeros(size(pobj,1),1);
for i=2:size(pobj,1)-1
RHS(i,1)=-prec*prec*(-rhoV(i,pobj,qfe,qfh)+d2V(i,1)); % sign of rho corresponds to sign of e-
end
%define ODE matrix
A = eye(size(pobj,1))*-2;
for i=2:size(pobj,1)-1
A(i,i-1)=1;
A(i,i+1)=1;
end
A(size(pobj,1),size(pobj,1)-1) =0;
A(size(pobj,1),size(pobj,1) ) =1;
A(1 ,2) = 0;
A(1 ,1) = 1;
psi_delta=0;
psi_delta=A\RHS;
f = 0;
f = 0.002*norm([pobj.V]')/norm(psi_delta);
psi_delta = psi_delta*f;
newV = 0;
newV = [pobj.V]'+psi_delta;
newVcell = num2cell(newV);
[pobj.V]=newVcell{:};
end
sum=0;
for i=2:size(qfe,1)
sum = sum + qfe(i,1) - qfh(i,1);
sum = sum + pobj(i,1).Na - pobj(i,1).Nd;
end
dx = 0;
dX = pobj(2,1).pos - pobj(1,1).pos;
sum = sum*1.602e-19 * dX;
chargeSum(Vpoint,2)=sum;
end
chargeSum(:,1)=Vpoints;
------------------

Alvaro on 19 Dec 2022
When using parfor, variables that are initialized within the loop are temporary and not passed onto other iterations. MATLAB is detecting that you have temporary variables and is issuing a warning.
"In contrast to the behavior of a for-loop, MATLAB® clears any temporary variables before each iteration of a parfor-loop. To help ensure the independence of iterations, the values of temporary variables cannot be passed from one iteration of the loop to another. Therefore, temporary variables must be set inside the body of a parfor-loop, so that their values are defined separately for each iteration."
Walter Roberson on 20 Dec 2022
Right. When you use parfor, the calculation of the iterations must be independent of each other, except for reduction variables; https://www.mathworks.com/help/parallel-computing/reduction-variable.html