2013-02-20 98 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