2011-03-23 261 views
4

我正在處理一個非常大的矩陣,因此想要在MATLAB中使用並行計算來運行羣集。在這裏,我已經創建使用稀疏矩陣:嘗試在MATLAB中使用parfor(並行for循環)時出錯

Ad = sparse(length(con)*length(uni_core), length(con)*length(uni_core)); 

我有一個書面的功能adj使用,我可以填滿基Ad。 每次循環運行時,從函數adj中我得到一個方形對稱矩陣,將在第一個索引中指定從3682*(i-1)+13682 *(i-1)+3682,同樣在第二個索引中指定。這是顯示在這裏:

parfor i = 1:length(con) 
    Ad((3682*(i-1))+1:((3682*(i-1))+3682), ... 
    (3682*(i-1))+1:((3682*(i-1))+3682)) = adj(a, b, uni_core); 
end 

在一個正常的循環它運行沒有任何問題。但在parfor並行計算中,我收到一個錯誤,說明在使用帶有parfor的分片陣列時存在問題。

回答

5

來自PARFOR循環的輸出必須是減少變量(例如,計算求和)或「切片」。有關更多信息,請參閱文檔中的this page

就你而言,你試圖形成一個「切片」輸出,但是你的索引表達式對於PARFOR來說太複雜了。在PARFOR中,分片輸出必須通過以下方式進行索引:一個下標的循環變量,以及其他下標的某個常量表達式。常量表達式必須是:,end或文字標量。下面的例子顯示了幾個分割輸出:

x3 = zeros(4, 10, 3); 
parfor ii = 1:10 
    x1(ii) = rand; 
    x2(ii,:) = rand(1,10); 
    x3(:,ii,end) = rand(4,1); 
    x4{ii} = rand(ii); 
end 

在你的情況,你的索引表達式轉換成廣告太複雜了PARFOR處理。也許你可以做最簡單的事情就是返回的計算,一個單元陣列,然後使用常規FOR循環其注入Ad在主機端,就像這樣:

parfor i = 1:length(con) 
    tmpout{i} = ....; 
end 
for i = 1:length(con) 
    Ad(...) = tmpout{i}; 
end 
+0

這似乎是非常有用的...非常感謝你。我會立即嘗試,並會發布,如果任何進一步的問題。 – sushma 2011-03-25 06:16:46

4

Edric has already explained爲什麼你得到一個錯誤,但我想提出一個解決方案的另一個建議。您正在創建的矩陣Ad由沿着主對角線的一系列3682-by-3682塊組成,其他地方都爲零。一種解決方案是首先在PARFOR循環中創建塊,並將它們存儲在單元陣列中。然後可以用一個呼叫它們全部合併成一個矩陣的函數BLKDIAG

cellArray = cell(1,length(con)); %# Preallocate the cell array 
parfor i = 1:length(con) 
    cellArray{i} = sparse(adj(a,b,uni_core)); %# Compute matrices in parallel 
end 
Ad = blkdiag(cellArray{:}); 

所得矩陣Ad將疏,因爲每個塊被放置在所述單元陣列中之前被轉換爲一sparse matrix

+0

函數我從來不知道它的存在,非常感謝你的回覆我會試試這個。 – sushma 2011-03-25 06:18:29