尝试在MATLAB中使用parfor(并行for循环)时出错

时间:2011-03-23 06:07:55

标签: matlab loops parallel-processing

我正在处理一个非常庞大的矩阵,因此希望在MATLAB中使用并行计算来运行集群。在这里,我使用:

创建了一个稀疏矩阵
Ad = sparse(length(con)*length(uni_core), length(con)*length(uni_core));

我有一个书面函数adj,我可以用它来填充矩阵Ad。 每次循环运行时,从函数adj我得到一个方形对称矩阵,该矩阵将被分配给第一个索引中Ad3682*(i-1)+1的{​​{1}}在第二个索引中。这显示在这里:

3682 *(i-1)+3682

在正常的for循环中,它运行没有任何问题。但是在并行计算的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的切片数组时出现问题。

2 个答案:

答案 0 :(得分: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

在您的情况下,您在Ad中的索引表达式太复杂,无法处理PARFOR。您可以做的最简单的事情是将计算作为单元格数组返回,然后使用常规FOR循环将它们注入主机端的Ad,如下所示:

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

答案 1 :(得分:4)

Edric has already explained 为什么你收到错误,但我想提出另一个解决方案的建议。您正在创建的矩阵Ad由沿主对角线的一系列3682乘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