I need to parallelize a code in order to save time. I have a loop internal to another loop, and I would like to parallelize the external one (because I think it this way the code is faster). My code looks like this:
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
parfor i = 1:size(A,1)
for j= 1:1:size(B,1)
if B(i,1) > A(j,1)
Biggers(i,j) = A(j,1);
end
end
end
but if I run it this way I get the error:
Error: The variable Biggers in a parfor cannot be classified.
See Parallel for Loops in MATLAB, "Overview".
this condition does not occur if I instead parallelize the internal loop, i.e. if design the code as:
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
for i = 1:size(A,1)
parfor j= 1:1:size(B,1)
if B(i,1) > A(j,1)
Biggers(i,j) = A(j,1);
end
end
end
I don't understand why in the first case Biggers
is not considered a sliced variable, since every worker should focus only on a line of my variable.
How can I solve the problem?
As to exactly why it does not work with the outer loop I am not sure. MATLAB has very strict regulations on what can and what can't go into the parfor
loop which are not always crystal clear.
The "simple" solution would be to wrap everything you have inside your parfor
loop into a function, then parfor
suddenly eats everything. i.e.
function Biggers = parforfunc(A,B,ii)
for jj= 1:size(B,1)
if B(ii,1) > A(jj,1)
Biggers(ii,jj) = A(jj,1);
end
end
end
Save that as parforfunc.m
and run your script with
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(size(B,1),size(A,1));
parfor ii = 1:size(A,1)
Biggers = parforfunc(A,B,ii);
end
@Adriaan's answer solves the problem neatly - but if you're curious, the problem here is the "non-constant" bounds of the inner for
loop. You and I can clearly see that the bounds of the inner for
loop are constant in practice, but MATLAB's rules for parfor
require that the bounds of any inner for
loop are "broadcast" variables. So, the fix is trivial - hoist the inner loop bounds computation out of the parfor
loop, like so:
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
n = size(B,1);
parfor i = 1:size(A,1)
for j= 1:n
if B(i,1) > A(j,1)
Biggers(i,j) = A(j,1);
end
end
end
This case is described in the doc.