首页 > 解决方案 > 当 MPI_FLOAT 的 count > 64 时,MPI_send 和 MPI_recv 挂起

问题描述

MPI_Send使用and时遇到问题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;
}

标签: cudampiopenmpi

解决方案


MPI_Send是阻塞调用。您的进程都在MPI_Send等待对方调用MPI_RecvMPI_Send 对于小消息可以是非阻塞的,这就是它适用于 <= 64 个元素的原因。

可能的解决方案是:

  • 呼叫MPI_SendMPI_Recv在交流队伍中交替排列
  • 采用MPI_Sendrecv
  • 使用非阻塞通信 ( MPI_Isend/ MPI_Irecv)

这里最简单的可能只是使用MPI_Sendrecv和替换MPI_SendandMPI_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);

推荐阅读