MPI发送数组数组

好的,所以我试图通过MPI发送这样的结构

struct BColumns { double **B; int offset; }; 

如果我只是像这样做一些BS分配数据

  bSet.offset = myRank; bSet.B = (double **) calloc(2, sizeof(double *)); bSet.B[0] = (double *) calloc(1, sizeof(double)); bSet.B[1] = (double *) calloc(1, sizeof(double)); bSet.B[0][0] = 1; bSet.B[1][0] = 2; if(myRank == 0){ MPI_Send(&bSet,sizeof(struct BColumns), MPI_BYTE, 1, 1, MPI_COMM_WORLD); }else{ MPI_Recv(&recvBuf, sizeof(struct BColumns), MPI_BYTE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status ); } 

而且我假设它不能很好地工作,因为如果我发送这个结构,它只会在B中发送指针并且该指针不指向另一个处理器上的任何东西,那么我将如何发送数据像这在MPI中。

正如suszterpatt指出的那样,你真的想在一个大块中分配你的B块; 这对于性能来说可能更好,但它确实需要任何通信,因此你不会在任何地方追逐指针。 而且我认为你可能不得不以不同的方式发送它 – 发送大小信息,然后将数据放在一个块中 – 尽管你可以为这些中的每一个创建和删除不同的MPI_Type_struct发送。 但是每个对象使用多个发送并不是很难:

 #include  #include  #include  typedef struct BColumns { double **B; int offset; } bc; double **alloc2d(int n, int m) { double *data = malloc(n*m*sizeof(double)); double **array = malloc(n*sizeof(double *)); for (int i=0; ioffset = 1; send->B = alloc2d(ncols, colsize); for (int i=0; iB[i][j] = i*j; const int dest = 1; MPI_Send(&ncols, 1, MPI_INT, dest, tag, MPI_COMM_WORLD); MPI_Send(&colsize, 1, MPI_INT, dest, tag, MPI_COMM_WORLD); MPI_Send(&(send->offset), 1, MPI_INT, dest, tag, MPI_COMM_WORLD); MPI_Send(&(send->B[0][0]), ncols*colsize, MPI_DOUBLE, dest, tag, MPI_COMM_WORLD); printf("Rank %d: sent structure B\n", rank); free2d(send->B); free(send); } if (rank == 1) { MPI_Status status; const int src=0; int rncols, rcolsize; bc *recv; MPI_Recv(&rncols, 1, MPI_INT, src, tag, MPI_COMM_WORLD, &status); MPI_Recv(&rcolsize, 1, MPI_INT, src, tag, MPI_COMM_WORLD, &status); printf("Rank %d: Received: rncols = %d rcolsize=%d\n", rank, rncols, rcolsize); recv = malloc(sizeof(bc)); recv->B = alloc2d(rncols, rcolsize); MPI_Recv(&(recv->offset), 1, MPI_INT, src, tag, MPI_COMM_WORLD, &status); MPI_Recv(&(recv->B[0][0]), rncols*rcolsize, MPI_DOUBLE, src, tag, MPI_COMM_WORLD, &status); printf("Rank %d: Received: offset = %d\n", rank, recv->offset); for (int i=0; iB[i][j]); printf("\n"); } free2d(recv->B); free(recv); } MPI_Finalize(); return 0; } 

然后运行它:

 $ mpirun -np 3 ./bstruct Rank 0: sent structure B Rank 1: Received: rncols = 3 rcolsize=5 Rank 1: Received: offset = 1 1: Column 0/3: 0.000000 0.000000 0.000000 0.000000 0.000000 1: Column 1/3: 0.000000 1.000000 2.000000 3.000000 4.000000 1: Column 2/3: 0.000000 2.000000 4.000000 6.000000 8.000000 

如果您想要通过手动或使用MPI函数调用或数据类型来避免多次发送的延迟(并且如果您事先知道Barrays的最大大小),则可以将该数据编组为一条消息,但您仍然可以必须以类似的方式做到这一点。

最简单的方法是使用单个数组以行/列主要顺序存储您的值,以便它在内存中都是连续的。 然后你只需要定义一个描述结构内存布局的MPI数据类型(很多双精度数和一个int)。