2013-02-20 56 views
1

我写了一个简单的化学模拟,它可以并行计算大量网格的属性。因此,我用一个并行循环索引Y维:PARFOR with if/else clause based on external boolean

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

controlArg是假的,optionalArg是不确定的。我想MATLAB不会相信你,controlArg将永远是错误的(因此,我的意思是它没有任何机制来推断它,尽管对于上面的代码,人类可能认为它是显而易见的)。因此,它不能保证没有parfor迭代需要知道optionalArg在这一点上你的代码:

 if controlArg 
      tempNum = tempNum * optionalArg; 
     end 

快速修复,定义optionalArg周围无if语句 - 你再次检查controlArg反正你使用它之前。或者,尝试用10*controlArg(或全部三条线,将0(false)映射到1和1(true)到您期望的optionalArg的值,例如tempNum = tempNum * (controlArg*9+1);)来替换optionalArg

btw:也许你可以更多地讲述实际问题(不一定在这个问题中)。上面的输出数组可以通过一行或两行代码生成,我猜想MATLAB的优点之一,可以同时向多个类似操作进行矢量化计算(无需显式并行化)也可以应用于您的问题(即,您可能不需要for循环的三个级别

+0

不幸的是,这个问题比我在这里给出的更复杂 - 如果controlArg为true,那么定义了一大堆其他变量(由optionalArg表示)并定义了一组额外的计算(特别是气溶胶化学,因为它是值得的)我猜我很困惑,因为如果我使用'for',只有'parfor'没有错误,我可以按照你所建议的方式解决它,但是这很令人沮丧,因为它意味着我有额外的变量声明不必要 - 将很好地知道为什么会发生这种情况! – Skipsh 2013-02-20 21:53:06

+0

正如我暗示上面,我猜它发生是因为matlab分析了parfor块中的代码,检查所有使用的变量在循环内部没有改变(这会使得循环迭代相互依赖并且不容易并行)并且遇到不必要定义的变量。你的额外变量是几百万个元素矩阵吗?如果不是,那究竟是什么问题?无论如何,如果存在复杂的计算差异,则应该为内部部分编写两个独立的函数'complexCalculationWithoutControl'和'complexCalculationWithControl'。 – 2013-02-20 22:02:57

+0

够公平的。我没有真正考虑过它可能会使环路相互依赖。我会按照建议重写代码 - 谢谢! – Skipsh 2013-02-21 00:20:05