MPI_SEND 在 MPI_BARRIER 之后停止工作

Posted

技术标签:

【中文标题】MPI_SEND 在 MPI_BARRIER 之后停止工作【英文标题】:MPI_SEND stops working after MPI_BARRIER 【发布时间】:2012-05-15 00:26:55 【问题描述】:

我正在使用 C/MPI 构建分布式 Web 服务器,在我的代码中的第一个 MPI_BARRIER 之后,点对点通信似乎完全停止工作。标准 C 代码在屏障之后工作,所以我知道每个线程都会通过屏障。点对点通信在障碍之前也可以正常工作。但是,当我将与屏障之前的行相同的代码复制粘贴到屏障之后的行中时,它会完全停止工作。 SEND 将永远等待。当我尝试改用 ISEND 时,它会通过线路,但从未收到过消息。我一直在谷歌上搜索这个问题,每个对 MPI_BARRIER 有问题的人都被告知屏障正常工作,他们的代码是错误的,但我终生无法弄清楚为什么我的代码是错误的。什么可能导致这种行为?

下面是一个演示这个的示例程序:

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

int main(int argc, char *argv[])

  int procID;
  int val;
  MPI_Status status;

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &procID);
  MPI_Barrier(MPI_COMM_WORLD);

  if (procID == 0)
  
    val = 4;
    printf("Before send\n");
    MPI_Send(&val, 1, MPI_INT, 1, 4, MPI_COMM_WORLD);
    printf("after send\n");
  

  if (procID == 1)
  
    val = 1;
    printf("before: val = %d\n", val);
    MPI_Recv(&val, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
    printf("after: val = %d\n", val);
  

  MPI_Finalize();
  return 0;

将两个if 语句移到屏障前会导致该程序正确运行。

编辑 - 似乎第一次通信,无论类型如何,都有效,并且所有未来的通信都失败了。这比我一开始想的要笼统得多。不管第一次通信是障碍还是其他消息,以后的通信都不会正常工作。

【问题讨论】:

您发布的代码对我来说看起来不错。您使用的是哪个版本的 MPI? 使用 openmpi 1.5.5 对我来说很好。 我知道它是 openmpi,但我似乎无法弄清楚是什么版本号。有命令告诉你吗? mpirun --version 会给你openmpi的版本 @TEOUltimus:“当两者在同一台机器上时它可以工作,而当它们在不同的机器上时会中断。”这听起来像是网络配置错误,消息无法到达目标机器。 【参考方案1】:

Open MPI 在使用 TCP/IP 进行通信时有一个已知功能:它会尝试使用所有配置的处于“UP”状态的网络接口。如果无法通过所有这些接口访问其他一些节点,则会出现问题。这是 Open MPI 采用的贪婪通信优化的一部分,有时,就像您的情况一样,会导致问题。

似乎至少第二个节点有多个接口处于启动状态,并且这一事实在协商阶段被引入第一个节点:

一个配置了 128.2.100.167 一个配置了 192.168.109.1(你的机器上有隧道或 Xen 运行吗?)

屏障通信发生在第一个网络上,然后下一个MPI_Send 尝试通过显然不连接所有节点的第二个网络发送到第二个地址。

最简单的解决方案是告诉 Open MPI 仅使用连接节点的网络。您可以使用以下 MCA 参数告诉它这样做:

--mca btl_tcp_if_include 128.2.100.0/24

(或任何你的通信网络)

你也可以指定网络接口列表,如果它在所有机器上都相同,例如

--mca btl_tcp_if_include eth0

或者您可以告诉 Open MPI 专门排除某些接口(但如果这样做,您必须始终告诉它排除环回“lo”):

--mca btl_tcp_if_exclude lo,virt0

希望对您和其他在 SO 周围似乎有同样问题的人有所帮助。看起来最近几乎所有 Linux 发行版都开始默认提供各种网络接口,这可能会导致 Open MPI 出现问题。

附:请把这些节点放在防火墙后面!

【讨论】:

谢谢!您推荐的第二个修复(指定网络接口)效果很好。此外,我运行它的集群位于我学校的防火墙后面。我很确定他们知道自己在做什么。 :D

以上是关于MPI_SEND 在 MPI_BARRIER 之后停止工作的主要内容,如果未能解决你的问题,请参考以下文章

MPI_Barrier 在循环中不起作用

MPI_Barrier - 只有一些进程通过屏障

为啥 MPI_Barrier 在 C++ 中会导致分段错误

测试 MPI_Barrier C++

MPI_BARRIER 不工作

对 MPI_Barrier 的调用是不是会影响 MPI 进程中的每个线程?