问题
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