我正在做一个非常大的计算(大气吸收),其中有很多单独的窄峰,最后都会加起来。对于每个峰,我已经预先计算了峰形函数值高于我选择的阈值的范围,然后我逐行将峰添加到我的光谱中。下面给出了一个最小示例:
X = 1:1e7;
K = numel(a); % count the number of peaks I have.
spectrum = zeros(size(X));
for k = 1:K
grid = X >= rng(1,k) & X <= rng(2,k);
spectrum(grid) = spectrum(grid) + peakfn(X(grid),a(k),b(k),c(k)]);
end
在这里,每个峰都有一些参数来定义位置和形状(a
、b
、c
),以及进行计算的范围(rng
)。这很好用,在我的机器上,它以大约 220 秒的时间进行基准测试,以完成一个完整的数据集。但是,我有一台 4 核机器,我最终想在集群上运行它,所以我想并行化它并使其可扩展。
因为每个循环都依赖于上一次迭代的结果,所以我不能使用parfor
,所以我迈出了学习如何使用spmd
块的第一步。我的第一次尝试是这样的:
X = 1:1e7;
cores = matlabpool('size');
K = numel(a);
spectrum = zeros(size(X),cores);
spmd
n = labindex:cores:K
N = numel(n);
for k = 1:N
grid = X >= rng(1,n(k)) & X <= rng(2,n(k));
spectrum(grid,labindex) = spectrum(grid,labindex) + peakfn(X(grid),a(n(k)),b(n(k)),c(n(k))]);
end
end
finalSpectrum = sum(spectrum,2);
这几乎可以工作。该程序在最后一行崩溃,因为spectrum
它是 type Composite
,并且2013a
关于如何将Composite
数据转换为矩阵的文档参差不齐(cell2mat
不起作用)。这也不能很好地扩展,因为我拥有的核心越多,矩阵就越大,并且必须将大矩阵复制到每个工作人员,然后忽略大部分数据。问题 1:如何将 Composite 数据类型转换为可用数组?
我尝试的第二件事是使用codistributed
数组。
spmd
spectrum = codistributed.zeros(K,cores);
disp(size(getLocalPart(spectrum)))
end
这告诉我每个工人都有一个大小为 [K 1] 的向量,我相信这是我想要的,但是当我尝试融合上述方法时
spmd
spectrum = codistributed.zeros(K,cores);
n = labindex:cores:K
N = numel(n);
for k = 1:N
grid = X >= rng(1,n(k)) & X <= rng(2,n(k));
spectrum(grid) = spectrum(grid) + peakfn(X(grid),a(n(k)),b(n(k)),c(n(k))]); end
finalSpectrum = gather(spectrum);
end
finalSpectrum = sum(finalSpectrum,2);
我得到Matrix dimensions must agree
错误。因为它在一个并行块中,所以我不能使用我的正常调试拐杖来单步执行循环并查看每个块在每个点的大小以查看发生了什么。问题 2:在块中索引进出共分布数组的正确方法是什么spmd
?