我正在进行粒子模拟,需要将三个不同数组的某些部分发送到其他进程。如何使用 MPI 用户定义类型来做到这一点?
例如,假设我在进程1上有三个数据类型为double的矩阵,A、B和C。现在我想将A、B和C的前两行发送到进程2。那么如何发送使用 MPI 用户定义的类型来执行此操作,假设这些矩阵的 C 类型存储?谢谢。
目前,我正在将这些矩阵的前两行复制到单个缓冲区,然后执行 MPI 发送。这些基本上涉及以下步骤:
Copy the first two rows of A, B, and C to a send_buffer on Process 1.
Send the send_buffer from Process 1 to Process 2.
On Process 2, use recv_buffer to receive data from Process 1.
On Process 2, copy data from recv_buffer to A, B, C on Process 2.
我希望有更好的方法来做到这一点。谢谢。
最佳答案
在下面的代码中,定义了 MPI 数据类型来传达矩阵的一系列行。如果有三个矩阵,那么就会有三个发送/接收。您可以将下面的代码与您自己的代码进行比较,看看哪一个更好。
如果您认为逐个传输矩阵效率不高,那么您可以将所有矩阵放入一个结构体中并创建 MPI 数据类型或考虑使用 MPI_PACK
。
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
void make_layout(int row_begin, int row_end, int ncol, MPI_Datatype* mpi_dtype)
{
int nblock = 1;
int block_count = (row_end - row_begin + 1) * ncol;
MPI_Aint lb, extent;
MPI_Type_get_extent(MPI_DOUBLE, &lb, &extent);
MPI_Aint offset = row_begin * ncol * extent;
MPI_Datatype block_type = MPI_DOUBLE;
MPI_Type_create_struct(nblock, &block_count, &offset, &block_type, mpi_dtype);
MPI_Type_commit(mpi_dtype);
}
double** allocate(int nrow, int ncol)
{
double *data = (double *)malloc(nrow*ncol*sizeof(double));
double **array= (double **)malloc(nrow*sizeof(double*));
for (int i=0; i<nrow; i++)
array[i] = &(data[ncol*i]);
return array;
}
int main()
{
MPI_Init(NULL, NULL);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
// make 3x3 matrix.
int nrow = 3;
int ncol = 3;
double** A = allocate(nrow, ncol);
// make mpi datatype to send rows [0, 1] excluding row 2.
// you can send any range of rows i.e. rows [row_begin, row_end].
int row_begin = 0;
int row_end = 1; // inclusive.
MPI_Datatype mpi_dtype;
make_layout(row_begin, row_end, ncol, &mpi_dtype);
if (rank == 0)
MPI_Send(&(A[0][0]), 1, mpi_dtype, 1, 0, MPI_COMM_WORLD);
else
MPI_Recv(&(A[0][0]), 1, mpi_dtype, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
MPI_Type_free(&mpi_dtype);
MPI_Finalize();
return 0;
}
关于c - 三个不同矩阵的部分的 MPI 用户定义类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43258106/