43 views (last 30 days)

Show older comments

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);

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).

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

Start Hunting!