【问题标题】:MPI_send and MPI_recv is hanging when count > 64 for MPI_FLOAT当 MPI_FLOAT 的 count > 64 时,MPI_send 和 MPI_recv 挂起
【发布时间】:2021-08-03 03:46:49
【问题描述】:

我在使用MPI_Send 和MPI_Recv 时遇到问题。当count <= 64的数量,整体问题运行没有任何问题,而对于count > 64,程序挂起。

有什么解决办法吗?该地址位于两个 GPU 上的全局内存地址上。

这是我使用的代码。当我设置 n<=64 时它可以工作,否则它会挂起。

#include <stdio.h>
#include <string.h>
#include <mpi.h>

int main(int argc, char *argv[])
{
    char *d_msg;
    int myrank, tag=99;
    MPI_Status status;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);

    const int n = 65; // <-- number of FLOATs
    const int num_GPUs = 2;

    cudaMalloc((void**)&d_msg, n*sizeof(float)); 

    MPI_Send(d_msg, n, MPI_FLOAT, (myrank + 1)%num_GPUs, tag, MPI_COMM_WORLD);
    MPI_Recv(d_msg, n, MPI_FLOAT, (myrank - 1 + num_GPUs)%num_GPUs, tag, MPI_COMM_WORLD, &status);

    MPI_Finalize();
    return 0;
}

【问题讨论】:

  • 嗨,尝试使用不同的发送和接收缓冲区,当计数> 64时它仍然挂起

标签: cuda mpi openmpi


【解决方案1】:

MPI_Send 是一个阻塞调用。您的进程都位于MPI_Send 中,等待对方调用MPI_Recv。 MPI_Send 可以对小消息进行非阻塞,这就是它适用于

可能的解决方案是:

  • 在交流中以交替顺序调用MPI_Send 和MPI_Recv
  • 使用MPI_Sendrecv
  • 使用非阻塞通信 (MPI_Isend/MPI_Irecv)

这里最简单的可能是只使用MPI_Sendrecv 并将MPI_Send 和MPI_Recv 调用替换为

MPI_Sendrecv(d_msg, n, MPI_FLOAT, (myrank + 1)%num_GPUs, tag,
             d_msg, n, MPI_FLOAT, (myrank - 1 + num_GPUs)%num_GPUs, tag, MPI_COMM_WORLD, &status);

【讨论】:

  • 非常感谢!它有效,我还有一个关于tag 的问题,我应该如何为不同的点对点通信设置它的值,它的值是否会潜在地触发阻塞?
  • MPI_Recv 仅匹配使用相同标签(或任何带有MPI_ANY_TAG 的标签)发送的消息。如果您不小心,您可能会触发死锁。实际上,许多程序不会为不同的通信设置不同的标签,而是将其设置为 0,而是依赖于消息顺序(MPI 保证来自具有相同标签的相同源的消息按照它们发送的确切顺序匹配) .
猜你喜欢
  • 2011-11-05
  • 2011-11-11
  • 2015-12-30
  • 2014-04-17
  • 2011-01-24
  • 2017-10-25
  • 1970-01-01
  • 2016-04-22
  • 2015-05-14
相关资源
最近更新 更多