Gui*_*mos 3 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;
}
Run Code Online (Sandbox Code Playgroud)
对于此代码,我的目标是收集在每个进程中生成的子数组中的值,并将其保存在数组a中.然后让进程0打印它.
首先,我将数组中的所有值初始化为100
然后,我计算每个过程的起始索引和结束索引(在这种情况下,过程的数量多为12的倍数)
接下来,我将值赋给等于它的数组
接下来,我收集它
最后,我将它打印在屏幕上
这是3个大小= 3的过程的输出
等级2设置[8]等于2
等级2设置[9]等于2
等级2设置[10]等于2
等级2设置[11]等于2
等级1设置[4]等于1
等级1设置[5]等于1
等级1设置[6]等于1
等级1设置[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
11 100
如您所见,聚集只收集第一长度的数据,我该如何解决它.
先感谢您.
恭喜你,你第一次尝试时几乎得到了它.
您需要将您的MPI_Gather行更改为
MPI_Gather(&a[start],12/size,MPI_INT,a,12/size,MPI_INT,0,MPI_COMM_WORLD);
Run Code Online (Sandbox Code Playgroud)
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 )
Run Code Online (Sandbox Code Playgroud)
所以,你有sendbuf,sendtype,recvbuf,recvtype,root,和comm正确的; 问题是重要的.你想发送不是12/size*rank,也就是start整数; 你想发送12/size,或只是end-start整数,并从每个进程中接收那么多.
MPI_Gather要求每个进程发送相同数量的信息(如果不是,则要使用MPI_Gatherv()).在你的情况下,第一个进程被告知发送0,第二个发送4,第三个发送8; 标准没有说明在这种情况下该做什么,看起来最终没有发送任何东西.(或者肯定没有收到;你的根进程0被告知发送0个整数,所以它可能预计会有0个intg来自其他任务).所以你剩下的就是在聚集之前0级的成绩; 到处都是100,除了它自己的值,它们都是0.
通过纠正聚集,您应该得到正确的结果:
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
Run Code Online (Sandbox Code Playgroud)