我正在处理一个非常庞大的矩阵,因此希望在MATLAB中使用并行计算来运行集群。在这里,我使用:
创建了一个稀疏矩阵Ad = sparse(length(con)*length(uni_core), length(con)*length(uni_core));
我有一个书面函数adj
,我可以用它来填充矩阵Ad
。
每次循环运行时,从函数adj
我得到一个方形对称矩阵,该矩阵将被分配给第一个索引中Ad
到3682*(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
的切片数组时出现问题。
答案 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。