c - 三个不同矩阵的部分的 MPI 用户定义类型

标签 c mpi

我正在进行粒子模拟,需要将三个不同数组的某些部分发送到其他进程。如何使用 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/

相关文章:

c++ - xterm 窗口无法在 Linux 上保持,它出现然后消失得非常快

c++ - 交错式 MPI Isend/Recv 的安全保证

c - 中子输运模型的难点

c++ - 更改带有循环等待图像的进度条

c - Lua - pcall "entry point"

c - 了解获取内存位置的两段代码

c++ - boost::iprobe 不返回正确的计数

c - 标记化来自 getline 的输入

c - *glibc 检测到双重释放或损坏 () * 消息!

arrays - 输出3D数组的算法