我写了一个简单的化学模拟,它可以并行计算大量网格盒的属性。因此,我使用并行循环索引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
答案 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);
)。
for
循环。