MPI之自己实现Alltoall()函数

来源:互联网 发布:java split函数 编辑:程序博客网 时间:2024/05/22 16:44

MPI_ALLTOALL是组内进程之间完全的消息交换,其中每一个进程都向其它所有的进程发送消息,同时,每一个进程都从其它所有的进程接收消息。本质上,它实现的效果就是矩阵的转置。

如果不调用系统的MPI_ALLTOALL()函数,只用sendrecv()、send()或recv()该如何实现呢?

事实上,只要明白ALLTOALL()函数的工作原理,是很容易实现的。

如:

#include "stdio.h"#include "mpi.h"#include "stdlib.h"int my_alltoall(void *aa, int inputlen, MPI_Datatype inputtype, void *bb, int outputlen, MPI_Datatype outputtype, MPI_Comm  comm, int size, int rank){int i,j;MPI_Status status;for(i=0 ; i<size; i++){MPI_Sendrecv(aa+i*sizeof(intputtype ), inputlen, inputtype, i, 123, bb+i*sizeof(outputtype ), outputlen, outputtype, i, 123, comm, &status);}MPI_Barrier(comm);return 0;}int main( int argc, char *argv[] ){    int rank;//iam    int size;//npint *a, *b;    MPI_Comm  mycomm ;          MPI_Init(&argc,&argv);    MPI_Comm_dup(MPI_COMM_WORLD, &mycomm);    MPI_Comm_rank(mycomm, &rank);    MPI_Comm_size(mycomm, &size);a = (int *)malloc(size*sizeof(int));b = (int *)malloc(size*sizeof(int));printf("rank=%d, a=", rank);for(int i=0; i<size; i++){a[i]=i+rank*size;printf(" %d", a[i]);}printf("\n");for(int i=0; i<size; i++){b[i]=0;}MPI_Barrier(mycomm);my_alltoall(a, 1, MPI_INT, b, 1, MPI_INT, mycomm,  size, rank);MPI_Barrier(mycomm);printf("rank=%d, b=", rank);for(int i=0; i<size; i++){printf(" %d", b[i]);}printf("\n");    MPI_Finalize();    return 0;}


编译运行,结果如下:

rank=0, a= 0 1 2rank=1, a= 3 4 5rank=2, a= 6 7 8rank=0, b= 0 3 6rank=1, b= 1 4 7rank=2, b= 2 5 8

可以看到结果确实实现了转置。

0 0