首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在parfor循环中继续

在parfor循环中继续
EN

Stack Overflow用户
提问于 2015-03-06 14:54:43
回答 2查看 2.4K关注 0票数 0

我在Matlab中有一个奇怪的错误。

代码语言:javascript
复制
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语句:

代码语言:javascript
复制
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变量,它就会突然正确工作!我仍然不知道为什么将错误分配给变量会使循环变得疯狂。

EN

回答 2

Stack Overflow用户

发布于 2016-02-04 12:56:34

我仔细看了你的代码。我无法准确地再现您的错误,但是并行计算工具箱和继续存在一个问题。在Matlab2013a中,下列线路崩溃的概率为50%

代码语言:javascript
复制
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替换。

票数 0
EN

Stack Overflow用户

发布于 2017-01-25 14:36:57

这是一个老问题,但以防万一,我认为原始代码中的逻辑是不正确的。我将避免使用continue语句,因为parfor的主体是在每个worker节点中独立执行的。对于工作人员来说,在这种情况下没有循环的概念,因此,就目前情况而言,没有什么可继续的。如果代码没有崩溃,parfor将继续到迭代中的下一个元素。我对原始代码的看法是

代码语言:javascript
复制
% 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

更好的选择可能是

代码语言:javascript
复制
% 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)更自然一些。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28901392

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档