通过MPI发送和接收二维数组

我想解决的问题如下:

我已经计算了一个大的2Dmatrix的C ++串行代码。 为了优化这个过程,我想分割这个大的2Dmatrix,并使用MPI在4个节点(比如说)上运行。 节点之间发生的唯一通信是在每个时间步骤结束时共享边缘值。 每个节点与其邻居共享边缘arrays数据A [i] [j]。

在阅读MPI的基础上,我有以下的计划来实施。

if (myrank == 0) { for (i= 0 to x) for (y= 0 to y) { C++ CODE IMPLEMENTATION .... MPI_SEND(A[x][0], A[x][1], A[x][2], Destination= 1.....) MPI_RECEIVE(B[0][0], B[0][1]......Sender = 1.....) MPI_BARRIER } if (myrank == 1) { for (i = x+1 to xx) for (y = 0 to y) { C++ CODE IMPLEMENTATION .... MPI_SEND(B[x][0], B[x][1], B[x][2], Destination= 0.....) MPI_RECEIVE(A[0][0], A[0][1]......Sender = 1.....) MPI BARRIER } 

我想知道如果我的方法是正确的,也将不胜感激其他MPIfunction的任何指导也考虑实施。

谢谢,Ashwin。

只是为了扩大Joel的观点:

如果你分配你的数组以使它们连续(这是C的“multidimensional array”不会自动给你的:)

 int **alloc_2d_int(int rows, int cols) { int *data = (int *)malloc(rows*cols*sizeof(int)); int **array= (int **)malloc(rows*sizeof(int*)); for (int i=0; i<rows; i++) array[i] = &(data[cols*i]); return array; } /*...*/ int **A; /*...*/ A = alloc_2d_init(N,M); 

然后,您可以使用发送和接收整个NxM数组

 MPI_Send(&(A[0][0]), N*M, MPI_INT, destination, tag, MPI_COMM_WORLD); 

当你完成后,释放内存

 free(A[0]); free(A); 

另外, MPI_Recv是一个阻塞接收,而MPI_Send可以是阻塞发送。 按照乔尔的观点,有一件事意味着你肯定不需要障碍。 而且,这意味着如果你有上述的发送/接收模式,你可以陷入僵局 – 每个人都在发送,没有人接收。 更安全的是:

 if (myrank == 0) { MPI_Send(&(A[0][0]), N*M, MPI_INT, 1, tagA, MPI_COMM_WORLD); MPI_Recv(&(B[0][0]), N*M, MPI_INT, 1, tagB, MPI_COMM_WORLD, &status); } else if (myrank == 1) { MPI_Recv(&(A[0][0]), N*M, MPI_INT, 0, tagA, MPI_COMM_WORLD, &status); MPI_Send(&(B[0][0]), N*M, MPI_INT, 0, tagB, MPI_COMM_WORLD); } 

另一种更一般的方法是使用MPI_Sendrecv

 int *sendptr, *recvptr; int neigh = MPI_PROC_NULL; if (myrank == 0) { sendptr = &(A[0][0]); recvptr = &(B[0][0]); neigh = 1; } else { sendptr = &(B[0][0]); recvptr = &(A[0][0]); neigh = 0; } MPI_Sendrecv(sendptr, N*M, MPI_INT, neigh, tagA, recvptr, N*M, MPI_INT, neigh, tagB, MPI_COMM_WORLD, &status); 

或非阻塞发送和/或接收。

首先,你不需要那么多的障碍其次,你应该真的把你的数据作为一个单一的块发送,因为多次发送/接收阻塞他们的方式会导致不良的performance。