【问题标题】:Understanding buffer passing via MPI_Isend and MPI_Irecv了解通过 MPI_Isend 和 MPI_Irecv 传递的缓冲区
【发布时间】:2015-12-09 07:08:53
【问题描述】:

我想了解 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 中。我对吗?如果不是,谁能解释一下原因?

谢谢。

【问题讨论】:

  • 重要的是,在您的第二个代码段中,只有rank==MASTER 处理器调用MPI_Isend。此外,每个 rank==i` 处理器应该只调用一个 MPI_Irecv 来获取它的数组部分,而不是 12 个。您必须明确哪个处理器正在发送/接收什么;否则它们都将调用所有内容 - 导致您当前的代码成为死锁并访问空值。
  • 感谢您的这一部分(每个 rank==i 处理器应该只调用一个 MPI_Irecv 来获取它的数组部分)它解决了许多问题并启发了我的想法。

标签: c unix parallel-processing mpi openmpi


【解决方案1】:

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

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

最重要的是:MPI_Scatter涵盖了你描述的内容,不需要自己实现。如果希望一个进程向所有进程发送数据,请使用MPI_Bcast

【讨论】:

    猜你喜欢
    • 2020-03-09
    • 2011-08-01
    • 2015-05-27
    • 1970-01-01
    • 2014-09-02
    • 2017-01-21
    • 2017-08-02
    • 2017-08-20
    • 2018-09-13
    相关资源
    最近更新 更多