了解通过 MPI_Isend 和 MPI_Irecv 传递的缓冲区

Understanding buffer passing via MPI_Isend and MPI_Irecv

我想了解MPI是如何处理发送和接收的。假设我按如下方式分配 [12][50] 个元素的缓冲区:

int **buf= malloc(12 * sizeof(int *));
for (i = 0; i < 12; i++)
{
    buf[i] = malloc(50 * sizeof(int));

    // Immediatly fill each row by 1s for testing purpose. 
    for (j = 0; j < 50; j++)
    {
         buf[i][j] = 1;
    }
}

现在,我想使用非阻塞 MPI_IsendMPI_Irecv 将每一行发送到 P = 12 处理器,如下所示:

for (i = 0; i < 12; i++)
{
    MPI_Isend(buf[i], 50, MPI_INT, i, TAG_0, MPI_COMM_WORLD, &req[i]); 
    MPI_Wait(&req[i], &status[i]);
}

    for (i = 0; i < 12; i++)
    {
        MPI_Irecv(bufRecv[i], 50, MPI_INT, MASTER, TAG_0, MPI_COMM_WORLD, &req[i]);
        MPI_Wait(&req[i], &status[i]);
    }

据我所知,MPI_Isend 发送每个第 i 行,后跟 50 个连续元素,从存储在 but[i] 中的内存地址开始,而 MPI_Irecv 接收相应的第 i 行和将其存储在 MPI_Irecv 中。我对吗?如果不是,有人可以解释为什么吗?

谢谢。

是的,你是对的。 MPI_Irecv 会将消息接收到 bufRecv。但是,您的代码并没有真正意义。首先,直接等待的非阻塞通信调用与阻塞调用基本相同。

然后应该在不同的进程上调用接收部分,根据您的描述,每个接收方只会调用 MPI_Irecv 一次,而不是 12 次。或者,如果每个进程都要接收所有行,则发送方必须为每个进程调用 send number of rows 次。

最重要的是:MPI_Scatter, no need to implement it yourself. If you want one process to send data to all processes, use MPI_Bcast涵盖了您描述的内容。