# Having the error , " the parfor loop cannot run due to the way variable is used".

51 views (last 30 days)
Amit Chakraborty on 20 Jun 2021
Answered: Edric Ellis on 21 Jun 2021
The following is my code. I am having the error message " the parfor loop cannot run due to the way variable, 'a' is used".
Nvoxels=64
N_angle= 61
zd=17;
zp=10;
xv=3;
yv=3;
zv=3;
parfor i = 1:Nvoxels
kai = 20;
shai = 15;
g = 11;
for k=1:N_angle
a(k) = xv+(-1).*zp.*sin(k)+zd.*((-1).*zp+(g+(-1).*zv).*cos(k)+((-1).*kai+xv).*sin(k)).^(-1).*(kai+(-1).*xv+zp.*sin(k));
b(k) = yv+((-1).*shai+yv).*zd.*(zp+((-1).*g+zv).*cos(k)+(kai+(-1).*xv).*sin(k)).^(-1);
end
end
Comment: I did not give the real value here as data are big. But I have actually focused my abovementioned probelm.

Edric Ellis on 21 Jun 2021
The parfor implementation thinks you're doing something order-dependent involving a (and b). Here's an example with a similar error:
parfor i = 1:3
for j = 1:3
a(j) = 7;
end
end
Error: Unable to classify the variable 'a' in the body of the parfor-loop. For more information, see Parallel for Loops in MATLAB, "Solve Variable Classification Issues in parfor-Loops".
Basically, because you aren't completely initialising a before the inner for-loop, parfor thinks the values from the previous parfor loop iteration might still influence the computation (even though you and I can see that this is not the case). You can fix this by fully assigning a before the inner for loop.
parfor i = 1:3
a = zeros(1,3); % pre-allocate 'a'
for j = 1:3
a(j) = 7;
end
end

Walter Roberson on 20 Jun 2021
MATLAB's analysis is not smart enough to recognize that you are not using i at all inside the parfor and not using any random values, and that therefore the result of every iteration is the same and so the loop over i can be removed in favour of just calculating the body once.
Instead, MATLAB notices that a and b appear to be output variables, and that they are not being indexed by the parfor index, and it thinks their value is probably dependent on the parfor index, so it is asking the question, "Huh? So which i value should be the one that is used to create the final a and b?" since you overwrite all of a and b each time .
Remember that parfor loops are rarely completed in sequence of the loop variable.
In non-parallel loops, it is valid to say
for i = randi(9, 1, 5)
for k = 1 : 7
a(k) = i.^2 + k;
end
end
This is valid non-parallel code, and has the same net effect as if you had done
temp = randi(9, 1, 5);
i = temp(:,end);
for k = 1 : 7
a(k) = i.^2 + k;
end
because each iteration of i is completely overwriting all of a .
But in parallel code, what does it mean for the "last" to overwrite all previous versions? Does it mean that the last to complete should overwrite all the previous ones? Does it mean that parfor should keep track of the highest loop index that writes to each part of each variable, and at the end reconstruct the answer "as if" the loops had been done in serial order?