在parfor循环中继续

时间:2015-03-06 14:54:44

标签: matlab parfor

我在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而崩溃。 / p>

但是,如果我按如下方式重写它,我不会收到任何错误,并且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语句之后继续执行。我认为parfor循环中不支持break;continue有效。 我很困惑......

P.S。错误:

  

对于'metr',工人抛出了UndefinedFunction错误   这可能是因为包含'metr'的文件   工人无法进入。

编辑:好的,我发现谁有错。似乎如果我从err行删除catch err变量,它突然正常工作!我仍然不知道为什么将错误分配给变量会使循环变得疯狂。

2 个答案:

答案 0 :(得分:0)

我仔细研究了你的代码。我无法准确再现您的错误,但并行计算工具箱存在问题并继续。在Matlab 2013a中,以下几行崩溃概率为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替换。

答案 1 :(得分:0)

相当古老的问题,但为了以防万一,我不认为原始代码中的逻辑是正确的。我会避免使用continue语句,因为parfor的主体是在每个工作节点中独立执行的。对于工人来说,在这种情况下没有循环的概念,因此,现在没有任何东西可以继续。假设代码没有崩溃,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)