MPI_GATHER(sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root , comm) sendbuf 发送消息缓冲区的起始地址(可变) sendcount 发送消息缓冲区中的数据个数(整型) sendtype 发送消息缓冲区中的数据类型(句柄) recvbuf 接收消息缓冲区的起始地址(可变,仅对于根进程) recvcount 待接收的元素个数(整型,仅对于根进程) recvtype 接收元素的数据类型(句柄,仅对于根进程) root 接收进程的序列号(整型) comm 通信子(句柄)函数声明为
int MPI_Gather(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm)
每个进程(包括根进程)将其发送缓冲区中的内容发送到根进程,根进程根据发送这些数据的进程的序列号将它们依次存放到自已的消息缓冲区中.其结果就象一个组中的n个进程(包括根进程在内)都执行了一个调用:
MPI_Send(sendbuf, sendcount, sendtype, root, ...),
同时根进程执行了n次调用:
MPI_Recv(recvbuf+i*recvcount*extent(recvtype), recvcount, recvtype, i,...),
此处extent(recvtype)是调用函数MPI_Type_extent()所返回的类型,另外一种描述就象是组中的n个进程发送的n条消息按照它们的序列号连接起来,根进程通过调用MPI_RECV(recvbuf, recvcount*n, recvtype,...) 来将结果消息接收过来.
对于所有非根进程,接收消息缓冲区被忽略。
下面的的例子中,每个进程对一个大小为10的数组进行了赋值,0进程调用了Gather()操作,并将接受到的数据打印出来。
#include "stdio.h"
#include "mpi.h"
#include "stdlib.h"
int main(int argc,char **argv)
{
int size,rank;
static int max=20;
int send[10];
int *recv;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
for(int i=0;i<10;i++)
send[i]=i+rank;
if(rank==0)
{
recv=(int *)malloc(size*10*sizeof(int));
}
MPI_Gather(send,10,MPI_INT,recv,10,MPI_INT,0,MPI_COMM_WORLD);
if(rank==0)
{
for(int i=0;i
0
1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
11
3
4
5
6
7
8
9
10
11
12