我在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上面的代码作为一个普通循环很好地工作,并捕获两个错误并继续。如果我把它变成一个parfor循环,当它捕捉到一个错误的时候,它就会疯狂地从一开始和最后再次运行for循环,从而导致找不到变量metr的错误。
但是,如果我按如下方式重写它,则不会得到任何错误,而且parfor循环可以工作,无论我是否保留了continue语句:
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有人明白这是怎么回事吗?它似乎在continue语句之后继续执行。我认为只有break;在parfor循环中不受支持,而且continue可以工作。我很困惑..。
附注:错误:
为“metr”向工作人员抛出一个UndefinedFunction错误。 这可能是因为工作人员无法访问包含“metr”的文件。
编辑:好的,我找到了谁的错。看起来,如果我从err行中删除catch err变量,它就会突然正确工作!我仍然不知道为什么将错误分配给变量会使循环变得疯狂。
发布于 2016-02-04 12:56:34
我仔细看了你的代码。我无法准确地再现您的错误,但是并行计算工具箱和继续存在一个问题。在Matlab2013a中,下列线路崩溃的概率为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当第100次迭代没有写入结果(metr{ix} = 1)时,就会出现问题。我只能建议不要在parfor循环中使用continue。在任何情况下,它都应该可以用if替换。
发布于 2017-01-25 14:36:57
这是一个老问题,但以防万一,我认为原始代码中的逻辑是不正确的。我将避免使用continue语句,因为parfor的主体是在每个worker节点中独立执行的。对于工作人员来说,在这种情况下没有循环的概念,因此,就目前情况而言,没有什么可继续的。如果代码没有崩溃,parfor将继续到迭代中的下一个元素。我对原始代码的看法是
% 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更好的选择可能是
% 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不确定是否有理由将metr作为列,但是由于Matlab按列的主要顺序操作,所以使用metr = cell(length(paths),1)更自然一些。
https://stackoverflow.com/questions/28901392
复制相似问题