Two-loops error using parfor in the external for

三世轮回 提交于 2019-12-22 18:29:09

问题


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?


回答1:


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



回答2:


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



来源:https://stackoverflow.com/questions/37674333/two-loops-error-using-parfor-in-the-external-for

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!