MPI_Send 使用不同节点执行时卡住

MPI_Send getting stuck when executing with different nodes

我有一个非常简单的 MPI 程序,其中节点 0 向节点 1 发送一个字符,但是每当我使用两台或多台不同的机器时,发送和接收就会卡住。当我只在一台机器上使用多个进程时,程序运行良好。貌似是通讯问题,但是我怎么也想不通.....

代码如下:

int main(int argc, char *argv[]) {
    int numtasks, rank, tag = 1;
    char inmsg, outmsg = 'x';

    MPI_Status stat;
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &numtasks);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if ( rank == 0 ) {
        MPI_Send(&outmsg, 1, MPI_CHAR, 1, tag, MPI_COMM_WORLD);
    }

    else if ( rank == 1 ) {
        MPI_Recv(&inmsg, 1, MPI_CHAR, 0, tag, MPI_COMM_WORLD, &stat);
    }

    MPI_Finalize();
}

另外,这里有一些重要的注意事项:

  1. 我在 Google Compute Engine 中使用 2 个虚拟机集群:mpi-test-uaiwmpi-test-130b ;
  2. 我已经在两个虚拟机之间配置了无密码ssh,也就是说,从mpi-test-uaiw我可以直接输入ssh mpi-test-130b 并且工作正常(反之亦然);
  3. 使用 MPI 的简单 "Hello World" 适用于此集群,但它不包含任何发送或接收操作;
  4. 防火墙已停用。

如有任何帮助,我们将不胜感激。谢谢!

我找到了解决问题的方法:

我使用 MPICH,运行 我的程序使用 mpirun。从表面上看,问题在于 mpich 使用了错误的网络接口。每个节点有两个接口:loens4。从我在其他帖子中看到的,似乎 lo 用于将数据从一个节点传输到自身,而 ens4 用于与其他节点。我使用以下 ping 命令验证了这一点:

  • $ ifconfig -a:显示可用的接口;
  • 来自 mpi-test-uaiw:$ ping -I lo mpi-test-130b -> 失败
  • 来自 mpi-test-uaiw:$ ping -I ens4 mpi-test-130b -> 成功
  • 来自 mpi-test-uaiw:$ ping -I lo mpi-test-uaiw -> 成功
  • 来自 mpi-test-uaiw:$ ping -I ens4 mpi-test-uaiw -> 失败

可能的解决方案之一是使用 mpirun --mca btl_tcp_if_include ens4 确保 mpirun 使用 ens4 接口与其他节点通信。但这对我不起作用,因为 MPICH 无法识别 --mca 参数。因此,我做了以下操作:

  1. 删除了我用来安装 MPICH 的包(在两个节点中):$ sudo apt-get remove libcr-dev mpich mpich-doc
  2. 安装了 OpenMPI(在两个节点中):$ sudo apt install openmpi-bin openmpi-doc libopenmpi-dev

通过安装 OpenMPI,我的代码可以正常工作。希望对遇到同样问题的人有所帮助!