Continue in parfor loop

牧云@^-^@ 提交于 2019-12-12 03:59:14

问题


I have a kind of weird error in Matlab.

metr = cell(1,length(paths));
parfor i = 1:length(paths)
    try
        a = read(path{i});
    catch err
        continue;
    end
    metr{i} = dosomething(a);
end

The above code works fine as a normal loop and catches two errors and continues. If I make it a parfor loop, the moment it catches an error it goes totally crazy running the for loop again from the beginning and at the end crashing with an error of not finding the variable metr.

However, if I rewrite it as follows I don't get any error and the parfor loop works, whether or not I leave the continue statement:

metr = cell(1,length(paths));
parfor i = 1:length(paths)
    try
        a = read(path{i});
        errB = 0;
    catch err
        errB = 1;
        continue;
    end
    if ~errB
        metr{i} = dosomething(a);
    end
end

Does anyone understand what is going on? It seems like it keeps executing after the continue statement. I thought only break; was not supported in parfor loops and that continue worked. I'm very confused...

p.s. the error:

An UndefinedFunction error was thrown on the workers for 'metr'.
This may be because the file containing 'metr' is not accessible on the workers.

Edit: Okay I found who's at fault. It seems that if I remove the err variable from the catch err line it suddenly works correctly! I still have no clue why assigning the error to a variable makes the loop go crazy.


回答1:


I took a closer look at your code. I was not able to reproduce exactly your error, but there is a problem with the parallel computing toolbox and continue. In Matlab 2013a the following lines crash with a probability of 50%

metr = cell(1,100);
parfor ix = 1:100
    disp(ix);
    try
        if rand<0.5
            error('dummy');
        end
    catch err
        disp('catch')
        continue;
    end
    metr{ix} = 1;
end

The problem occurs when the 100th iteration is not writing the result (metr{ix} = 1). I can only give the recommendation not to use continue in a parfor loop. It should be replaceable with if in any case.




回答2:


Rather old question but just in case, I don't think the logic in the original code is correct. I would avoid using the continue statement since the body of the parfor is executed in every worker node independently. For the worker there is no concept of a loop in this case and therefore as it stands there is nothing to continue to. parfor will continue to the next element in the iteration assuming the code hasn't crashed. My take on the original code would be

% Initialise empty cell array
metr = cell(1,length(paths));

% Iterate over the elements in parallel
parfor i = 1:length(paths)
    try
        % Try to execute the below
        a = read(path{i});
        errB = 0;
    catch ME
        % Suppress the exception - parfor loop now continues
        errB = 1;            
    end

    % Execute dosomething() 
    if ~errB
        metr{i} = dosomething(a);
    end
end

An even better take could be

% Initialise empty cell array
metr = cell(1,length(paths));

% Iterate over the elements in parallel
parfor i = 1:length(paths)
    try
        % Try to execute the below
        metr{i} = dosomething(read(path{i}));
    catch ME
        % Suppress the exception - parfor loop now continues
        % NOTE: metr{i} is empty for this i.
    end     
end

Not sure if there is a reason for having metr as columns but since Matlab operates in column-major order it feels a bit more natural to do metr = cell(length(paths),1) instead.



来源:https://stackoverflow.com/questions/28901392/continue-in-parfor-loop

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