# Keep a temporary variable after parfor

34 views (last 30 days)
Oisin Kelly on 7 Apr 2021
Commented: Rik on 8 Apr 2021
I am just wondering how do I keep my value z after the parfor has run?
% x (real(c))
tic;
ticBytes(gcp);
dx=0.01; % step
x1=-2;
x2=2;
% y (imag(c))
dy=0.01; % step
y1=-1.5;
y2=1.5;
x=x1:dx:x2;
y=y1:dy:y2;
[X,Y] = meshgrid(x,y); % for vectorized calculation
c=X+1i*Y;
R=1000; % if abs(z)>R then z is considered as infinity
n=1000; % maximal number of iterations, 100 is close to infinity
parfor nc=1:n
z=zeros(size(c)); % starts from zeros
z=z.^2+c; % vectorized
end
I=abs(z)<R; % logical image
imagesc(x,y,I);
colormap((jet));
set(gca,'XColor', 'none','YColor','none');
toc;
tocBytes(gcp);
Rik on 8 Apr 2021
Why do you want to remove your question?
(Just in case you decide to be rude and edit away your question: I have made a capture so I can trivially restore that.)

Paul Hoffrichter on 7 Apr 2021
Edited: Paul Hoffrichter on 7 Apr 2021
>> Parfor loop works when i comment out the plotting parts of the code.
I tried what you said and only experienced what you wrote when I forgot to clear the z-matrix after the previous run. Otherwise, it did not work. Were you leaving around your prevoius z?
Your loop appears to be trying to accumulate a value across an iteration of the loop, regardless of the iteration order. Using Matlab terminology, you wanted your z-matrix to be a reduction variable, rather than a temporary variable.
"Reduction Variables: Variables that accumulates a value across iterations of the loop, regardless of iteration order"
Ref: https://www.mathworks.com/help/parallel-computing/troubleshoot-variables-in-parfor-loops.html
"Another common cause of uninitialized temporaries can arise when you have a variable that you intended to be a reduction variable. However, if you use it elsewhere in the loop, then it is classified as a temporary variable."
Ref: https://www.mathworks.com/help/parallel-computing/temporary-variable.html
Consider these two loops:
s = 0;
constant = 1;
for ii = 1:100
s = s + constant; % i.e., s(n) = s(n-1) + constant;
end
>> s
s =
100
s = 0;
constant = 1;
parfor ii = 1:100
s = s + constant; % i.e., s(n) = s(n-1) + constant;
end
>> s
s =
100
No Matlab errors. Despite the current value of s in the loop being dependent upon the previous value, the Matlab parfor analyzer could see that each parfor worker could initialize its value of s to 0, and then add together the results after all the workers have accumulated their sums. The variable s in this case is called a "reduction" variable.
But in your case, you have:
s = s.^2 + constant;
Because of the squaring, only one worker would know how to initialize the value of s. To initialize the other workers' s-values, a worker would have to compute it knowing its ii-chunk. But that defeats the purpose of parfor.
To see the issue:
s1 = s0.^2 + c;
s2 = s1.^2 + c = (s0.^2 + c).^2 + c = s0.^4 + 2*c*s0.^2 + c.^2 + c; % looking hard to compute for another worker
s3 = s2.^2 + c = (s0.^4 + 2*c*s0.^2 + c.^2 + c).^2 + c; % a parfor worker would give up on initial conditions for s.
Raymond Norris on 8 Apr 2021
Reduction variables are broken into two parts. Let's take the following example
z = 10;
constant = 5;
parpool(4);
parfor idx = 1:400
z = z + constant;
end
parfor will send n chunks to each of the 4 workers. Let's assume that first chunk is n=50. Each worker is going to add constant to the addition identity matrix (i.e. 0) n times.
worker 1
local_z = 0; % Because 0 is the addition identity matrix
for ii=1:50
local_z = local_z+constant
end
worker 2
local_z = 0;
for ii=1:50
local_z = local_z+constant
end
ditto for worker 3 and worker 4.
Once a worker is done, it'll get its next chunk, let's say n=25
local_z = 0;
for ii=1:25
local_z = local_z+constant
end
Eventually, all 400 iterations are complete and each worker has a local summation. Let's assume each worker has done the same, then each local sum is 500. Then parfor does a final summation of the initial value (10) and each of the workers: 10 + 500 + 500 + 500 + 500 = 2010.
This is similar for
z = z * constant;
where we use the multiplication identity matrix (1).