我在代码开发中达到了这样一个阶段,一个名为
arr
、长度为 (N_r * N_theta * N_phi)
的向量“表示”一个名为 ten
、形状为 (N_rs, N_thetas, N_phis)
的 3D 张量,它被跨进程分割,如下所示:每个进程都有一个给定一组 i
索引,以及所有第二维和第三维。如下:
进程 0 有
ten[i, :, :]
,i = 0, i = 1, i = 2, ... i = i_f0
进程 1 有
ten[i, :, :]
,i = i_f0 + 1 , i = i_f0 + 2, ... , i = i_f1
等等...
第二维和第三维以 C 顺序连续存储在内存中(最后一个索引变化最快)。正如人们所期望的那样。
我现在需要执行一些 MPI 魔法才能达到以下目的:
进程 0 有
ten[:, L, M]
(L, M) = (0, 0), (L, M) = (0, 1), ..., (L, M) = (L_f0, M_f0)
进程 1 具有
ten[:, L, M]
,对于 (L, M) = (L_f0, M_f0 + 1), (L, M) = (L_f0, M_f0 + 2), ..., (L, M) = (L_f1, M_f1)
等等...
我觉得我需要使用 MPI 派生数据类型。正确吗?
我因此读到了
MPI_Type_vector
。
我觉得我需要使用
MPI_Alltoall
。正确吗?
问题:如何在 Alltoall 通信中使用定制的派生数据类型?
谢谢!
你的张量的维度是 3,它足够小,可以在空间中表示。所以如果你画一张图,我给出的解释会更容易理解。像 5x4x3 张量一样绘制,沿 3 个空间轴使用点而不是数据。
由此,您将看到,对于第一维中的固定索引 i,存储的数据是二维张量或矩阵,它是第一维中索引为 i 的每个 coef。
因此,第一个 i_f0 矩阵存储在 proc 0 上,然后下一个 i_f1 矩阵存储在 proc 1 上,依此类推...
现在,从一组对 (L,M) 中,您要检索的是沿第一个轴的向量,其所有 coef 都有第二个和第三个索引 (L,M)。
因此,如果您循环 L 和 M,您想要的是沿第一个轴的数据,并且 i_f0 首先存储在 proc 0 上,接下来的 i_f1 存储在 proc 1 上等等...
从那里开始,您应该能够得到一个有效的代码。