使用基于外部布尔值的if / else子句进行PARFOR

时间:2013-02-20 18:25:57

标签: matlab if-statement parfor

我写了一个简单的化学模拟,它可以并行计算大量网格盒的属性。因此,我使用并行循环索引Y维度:

function[outputArray] = stackTest()

numX = 10;
numY = 10;
numZ = 10;
outputArray = zeros(numX,numY,numZ);
for iX = 1:numX
    parfor iY = 1:numY
        coreArray = outputArray(iX,iY,:);
        for iZ = 1:numZ
            tempNum = iX*iY*iZ;
            coreArray(1,1,iZ) = tempNum;
        end
        outputArray(iX,iY,:) = coreArray;
    end
end
end

这很好用。但是,我使用布尔值来控制是否执行某些操作,如下面的代码所示。这在Y上使用简单的for循环时效果很好,但在使用parfor时,代码失败并声明optionalArg未定义:

function[outputArray] = stackTest(controlArg)

numX = 10;
numY = 10;
numZ = 10;
outputArray = zeros(numX,numY,numZ);
if (controlArg)
    optionalArg = 10;
end
for iX = 1:numX
    parfor iY = 1:numY
        coreArray = outputArray(iX,iY,:);
        for iZ = 1:numZ
            tempNum = iX*iY*iZ;
            if controlArg
                tempNum = tempNum * optionalArg;
            end
            coreArray(1,1,iZ) = tempNum;
        end
        outputArray(iX,iY,:) = coreArray;
    end
end
end

stackTest现在可以正常使用controlArg = true,但如果controlArg = false则不行;我找到的唯一方法是定义optionalArg独立于controlArg。毋庸置疑,这是问题的简化版本,但我会感激任何可以向我解释的人;我怀疑它是parfor循环与全局变量有关的问题的一个子集,但由于我没有定义全局变量,所以我有点困惑。

此致

Skipsh

1 个答案:

答案 0 :(得分:0)

controlArg为false时,optionalArg未定义。我猜MATLAB不相信你controlArg将永远是假的(并且由此,我的意思是它没有推断它的机制,尽管对于上面的代码,人类可能认为它是显而易见的)。因此,在代码的这一点上,不能保证parfor迭代不需要知道optionalArg

        if controlArg
            tempNum = tempNum * optionalArg;
        end

要快速修复,请定义optionalArg,不要使用周围的if子句 - 无论如何都要在使用之前再次检查controlArg。或者,尝试将optionalArg替换为10*controlArg(或将所有三行替换为将0(false)映射为1和1(true)的数学表达式,使其达到所需的值optionalArg,例如tempNum = tempNum * (controlArg*9+1);)。

顺便说一句:也许你可以多说一点实际问题(不一定是这个问题)。上面的输出数组可以通过一行代码或两行代码生成,我猜想MATLAB的一个优点是,同时对许多类似操作进行矢量化计算(没有显式并行化)也可以应用于你的问题(即你可能不需要三级for循环。