2011-03-23 777 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