gpt4 book ai didi

C++将整数数组分成 block

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:23:39 25 4
gpt4 key购买 nike

我想我的问题有两部分:

(1) 这是将数组的不同 block 发送到不同处理器的正确方法吗?假设我有 n 个处理器,其等级范围从 0n-1。我有一个大小为 d 的数组。我想将此数组拆分为 k 个大小相等的 block 。假设 d 可以被 k 整除。我想将这些 block 中的每一个发送到等级小于 k 的处理器。如果我可以使用像 MPI_Scatter 这样的东西,那会很容易,但是这个函数发送到所有其他处理器,我只想发送到一定数量的 proc。所以我所做的是,我有一个 k 迭代循环并执行 k MPI_Isend。这样有效率吗?

(2) 如果是,我如何将数组拆分成 block ?总有简单的方法,那就是

int size = d/k;
int buffs[k][size];

for (int rank = 0; rank < k; ++rank)
{
for (int i = 0; i < size ++i)
buffs[rank][i] = input[rank*size + i];
MPI_Isend(&buffs[rank], size, MPI_INT, rank, 1, comm, &request);
}

最佳答案

您正在寻找的是 MPI_Scatterv,它允许您明确指定每个 block 的长度及其相对于缓冲区开头的位置。如果您不想将数据发送到某些行列,只需将其 block 的长度设置为 0:

int blen[n];
MPI_Aint displ[n];

for (int rank = 0; rank < n; rank++)
{
blen[rank] = (rank < k) ? size : 0;
displ[rank] = rank * size;
}

int myrank;
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

MPI_Scatterv(input, blen, displ, MPI_INT,
mybuf, myrank < k ? size : 0, MPI_INT,
0, MPI_COMM_WORLD);

请注意,对于 rank >= k,位移将超过缓冲区的末尾。没关系,因为 rank >= k 的 block 长度设置为零,并且不会访问任何数据。

至于您原来的方法,它不可移植,可能并不总是有效。原因是您正在覆盖相同的 request 句柄并且您从不等待发送完成。正确的实现是:

MPI_Request request[k];

for (int rank = 0; rank < k; ++rank)
{
MPI_Isend(&input[rank*size], size, MPI_INT, rank, 1, comm, &request[rank]);
}
MPI_Waitall(k, request, MPI_STATUSES_IGNORE);

最佳实现是在子通信器中使用 MPI_Scatter:

MPI_Comm subcomm;
MPI_Comm_split(MPI_COMM_WORLD, myrank < k ? 0 : MPI_UNDEFINED, myrank,
&subcomm);
// Now there are k ranks in subcomm
// Perform the scatter in the subcommunicator
if (subcomm != MPI_COMM_NULL)
MPI_Scatter(input, size, MPI_INT, mybuf, size, MPI_INT, 0, subcomm);

MPI_Comm_split 调用拆分 MPI_COMM_WORLD 并从小于 k 的所有原始等级创建一个新的通信器。它使用原始等级作为对新通信器中的等级进行排序的关键字,因此 MPI_COMM_WORLD 中的等级 0 变为 subcomm 中的等级 0。由于 MPI_Scatter 的性能通常优于 MPI_Scatterv,因此这是最佳解决方案。

关于C++将整数数组分成 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29225001/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com