parallel-processing - MPI_Gather并行编程中的问题

标签 parallel-processing mpi

我是一个插入并行编程的新手。根据我的理解,我尝试自己编写代码。然后我发现,我在 MPI_Gather 中不明白。先看代码再解释。

#include "mpi.h"
#include <stdio.h>
int main (int argc, char *argv[]) {
int size;
int rank;
int a[12];
int i;
int start,end;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if(rank==0)
{
    for(i=0;i<12;i++)
    {
        a[i] = 100;
    }
}

start = 12/size*rank;
end = 12/size*(rank+1);
for(i=start;i<end;i++)
{
    a[i] = rank;
    printf("rank %d set a[%d] equal to %d\n",rank,i,rank);
}
MPI_Gather(&a[start],12/size*rank,MPI_INT,a,12/size*rank,MPI_INT,0,MPI_COMM_WORLD);
if(rank==0)
{
    for(i=0;i<12;i++)
    {
        printf("%d    %d\n",i,a[i]);
    }
}
MPI_Finalize();
return 0;
}

对于此代码,我的目标是收集每个进程中生成的子数组中的值,并将其保存在数组 a 中。然后让进程0打印出来。

首先,我将数组中的所有值初始化为 100

然后,我计算每个进程的开始索引和结束索引(在这种情况下,进程数大部分是 12 的倍数)

接下来,我将值分配给等于它排名的数组

接下来,我收集它

最后,我把它打印在屏幕上

这是 3 个 size = 3 进程的输出

rank 2 设置 a[8] 等于 2

rank 2 设置 a[9] 等于 2

等级 2 设置 a[10] 等于 2

rank 2 设置 a[11] 等于 2

rank 1 设置 a[4] 等于 1

rank 1 设置 a[5] 等于 1

rank 1 设置 a[6] 等于 1

rank 1 设置 a[7] 等于 1

排名 0 设置 a[0] 等于 0

排名 0 设置 a[1] 等于 0

排名 0 设置 a[2] 等于 0

排名 0 设置 a[3] 等于 0

0 0

1 0

2 0

3 0

4 100

5 100

6 100

7 100

8 100

9 100

10 100

11100

如您所见,Gather 只收集了第一个长度的数据,我该如何解决。

提前谢谢你。

最佳答案

恭喜,您几乎在第一次尝试时就成功了。

您需要将 MPI_Gather 行更改为

MPI_Gather(&a[start],12/size,MPI_INT,a,12/size,MPI_INT,0,MPI_COMM_WORLD);

MPI_Gather 的签名是

#include "mpi.h"
int MPI_Gather ( void *sendbuf, int sendcnt, MPI_Datatype sendtype, 
                void *recvbuf, int recvcount, MPI_Datatype recvtype, 
                int root, MPI_Comm comm )

所以你有sendbuf, sendtype, recvbuf, recvtype, rootcomm 正确;问题是计数。你要发送的不是12/size*rank,也就是start,整数;您想要发送 12/size 或只是 end-start 整数,并从每个进程接收同样多的整数。

MPI_Gather 要求每个进程都发送相同数量的信息(否则,您需要使用 MPI_Gatherv())。在你的例子中,第一个进程被告知发送 0,第二个发送 4,第三个发送 8;该标准没有指定在这种情况下该怎么做,而且看起来最后什么也没有发送。 (或者肯定没有收到;您的根进程 0 被告知要发送 0 个整数,因此它大概期望从其他所有任务中发送 0 个整数)。所以你剩下的就是聚集前0级的东西;除了它自己的值为 0 之外,其他地方都是 100。

通过纠正聚集,你应该得到正确的结果:

rank 0 set a[0] equal to 0
rank 0 set a[1] equal to 0
rank 0 set a[2] equal to 0
rank 0 set a[3] equal to 0
rank 1 set a[4] equal to 1
rank 1 set a[5] equal to 1
rank 1 set a[6] equal to 1
rank 1 set a[7] equal to 1
rank 2 set a[8] equal to 2
rank 2 set a[9] equal to 2
rank 2 set a[10] equal to 2
rank 2 set a[11] equal to 2
0    0
1    0
2    0
3    0
4    1
5    1
6    1
7    1
8    2
9    2
10    2
11    2

关于parallel-processing - MPI_Gather并行编程中的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4483178/

相关文章:

使用 doSMP 生成随机数

parallel-processing - 根据标志对 mpi 进程进行分组

ocaml - mpi + ocaml 中的非阻塞接收?

Selenium GRID 与 TestNG 并行

android - 在我的 WebView 上执行需要时间的任务而不需要缓慢的 Web 浏览 - 并行操作

java - 打印在网络论坛上发布大量问题和大量答案的前 10 位用户

c# - 用于测试多个项目并可能放弃的并行模式

c - 使用 MPI_Send 和 MPI_Recv 实现 MPI_Scatter 时出现问题

c++ - 本地发送者-接收者缩减操作 MPI

c++ - MPI_Isend : how to keep data safe until they're received?