【问题标题】:MPI_Barrier doesn't function properlyMPI_Barrier 无法正常工作
【发布时间】:2012-01-04 00:39:06
【问题描述】:

我编写了下面的 C 应用程序来帮助我理解 MPI,以及为什么 MPI_Barrier() 在我庞大的 C++ 应用程序中不起作用。但是,我能够使用更小的 C 应用程序在我的大型应用程序中重现我的问题。本质上,我在 for 循环中调用 MPI_Barrier(),并且 MPI_Barrier() 对所有节点都是可见的,但是在循环的 2 次迭代之后,程序变得死锁。有什么想法吗?

#include <mpi.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
    MPI_Init(&argc, &argv);
    int i=0, numprocs, rank, namelen;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Get_processor_name(processor_name, &namelen);
    printf("%s: Rank %d of %d\n", processor_name, rank, numprocs);
    for(i=1; i <= 100; i++) {
            if (rank==0) printf("Before barrier (%d:%s)\n",i,processor_name);
            MPI_Barrier(MPI_COMM_WORLD);
            if (rank==0) printf("After barrier (%d:%s)\n",i,processor_name);
    }

    MPI_Finalize();
    return 0;
}

输出:

alienone: Rank 1 of 4
alienfive: Rank 3 of 4
alienfour: Rank 2 of 4
alientwo: Rank 0 of 4
Before barrier (1:alientwo)
After barrier (1:alientwo)
Before barrier (2:alientwo)
After barrier (2:alientwo)
Before barrier (3:alientwo)

我正在使用 GCC 4.4,从 Ubuntu 10.10 存储库中打开 MPI 1.3。

另外,在我庞大的 C++ 应用程序中,MPI 广播不起作用。只有一半的节点接收到广播,其他的则卡住等待。

提前感谢您的任何帮助或见解!

更新:升级到 Open MPI 1.4.4,从源代码编译到 /usr/local/

更新:将 GDB 附加到正在运行的进程显示了一个有趣的结果。在我看来,MPI 系统在屏障处死机,但 MPI 仍然认为程序正在运行:

附加 GDB 会产生一个有趣的结果。似乎所有节点都在 MPI 屏障处死亡,但 MPI 仍然认为它们正在运行:

0x00007fc235cbd1c8 in __poll (fds=0x15ee360, nfds=8, timeout=<value optimized out>) at   ../sysdeps/unix/sysv/linux/poll.c:83
83  ../sysdeps/unix/sysv/linux/poll.c: No such file or directory.
    in ../sysdeps/unix/sysv/linux/poll.c
(gdb) bt
#0  0x00007fc235cbd1c8 in __poll (fds=0x15ee360, nfds=8, timeout=<value optimized out>) at ../sysdeps/unix/sysv/linux/poll.c:83
#1  0x00007fc236a45141 in poll_dispatch () from /usr/local/lib/libopen-pal.so.0
#2  0x00007fc236a43f89 in opal_event_base_loop () from /usr/local/lib/libopen-pal.so.0
#3  0x00007fc236a38119 in opal_progress () from /usr/local/lib/libopen-pal.so.0
#4  0x00007fc236eff525 in ompi_request_default_wait_all () from /usr/local/lib/libmpi.so.0
#5  0x00007fc23141ad76 in ompi_coll_tuned_sendrecv_actual () from /usr/local/lib/openmpi/mca_coll_tuned.so
#6  0x00007fc2314247ce in ompi_coll_tuned_barrier_intra_recursivedoubling () from /usr/local/lib/openmpi/mca_coll_tuned.so
#7  0x00007fc236f15f12 in PMPI_Barrier () from /usr/local/lib/libmpi.so.0
#8  0x0000000000400b32 in main (argc=1, argv=0x7fff5883da58) at barrier_test.c:14
(gdb) 

更新: 我也有这个代码:

#include <mpi.h>
#include <stdio.h>
#include <math.h>
int main( int argc, char *argv[] )  {
int n = 400, myid, numprocs, i;
double PI25DT = 3.141592653589793238462643;
double mypi, pi, h, sum, x;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
printf("MPI Rank %i of %i.\n", myid, numprocs);
while (1) {
    h   = 1.0 / (double) n;
    sum = 0.0;
    for (i = myid + 1; i <= n; i += numprocs) {
        x = h * ((double)i - 0.5);
        sum += (4.0 / (1.0 + x*x));
    }
    mypi = h * sum;
    MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
    if (myid == 0)
        printf("pi is approximately %.16f, Error is %.16f\n",  pi, fabs(pi - PI25DT));
}
MPI_Finalize();
return 0;
}

尽管有无限循环,但循环中的 printf() 只有一个输出:

mpirun -n 24 --machinefile /etc/machines a.out 
MPI Rank 0 of 24.
MPI Rank 3 of 24.
MPI Rank 1 of 24.
MPI Rank 4 of 24.
MPI Rank 17 of 24.
MPI Rank 15 of 24.
MPI Rank 5 of 24.
MPI Rank 7 of 24.
MPI Rank 16 of 24.
MPI Rank 2 of 24.
MPI Rank 11 of 24.
MPI Rank 9 of 24.
MPI Rank 8 of 24.
MPI Rank 20 of 24.
MPI Rank 23 of 24.
MPI Rank 19 of 24.
MPI Rank 12 of 24.
MPI Rank 13 of 24.
MPI Rank 21 of 24.
MPI Rank 6 of 24.
MPI Rank 10 of 24.
MPI Rank 18 of 24.
MPI Rank 22 of 24.
MPI Rank 14 of 24.
pi is approximately 3.1415931744231269, Error is 0.0000005208333338

有什么想法吗?

【问题讨论】:

  • 发布的代码无需修改即可在我的系统上运行。我在 RHEL 5.3、OpenMPI 1.4.2 和 gcc 4.1.2 上运行。将调试器附加到每个等级并获取回溯以找出每个等级在进程中的位置。
  • 这几乎总是一个配置问题。其他机器是否在相同位置和默认路径中安装了相同版本的 OpenMPI?和/或是否安装了其他 MPI?
  • @Jon,都安装了相同的 openmpi 包,因为它们运行 Ubuntu 10.10,我从同一个 Ubuntu 存储库安装它们。未安装其他 MPI 实现。
  • 尝试移除循环和 MPI_Barrier,让每个等级打印“Hello World”。这将有助于诊断基本的启动、权限和连接问题。
  • @semiuseless 看起来没有启动问题。第一个障碍是成功的(因为至少有一个等级已经越过了)。

标签: c++ c mpi openmpi


【解决方案1】:

OpenMPI 中的 MPI_Barrier() 有时会在进程在最后一个障碍之后经过的不同时间遇到障碍时挂起,但正如我所见,这不是你的情况。无论如何,尝试使用 MPI_Reduce() 代替或在真正调用 MPI_Barrier() 之前使用。这并不直接等同于屏障,但是任何几乎没有负载的同步调用都应该像屏障一样工作。我没有在 LAM/MPI 或 MPICH2 甚至 WMPI 中看到 MPI_Barrier() 的这种行为,但这是 OpenMPI 的一个真正问题。

【讨论】:

  • 我有一个 PI 计算器,它的 MPI_Reduce 在无限循环中,while(1)。在 MPI_Reduce 之后有一个 printf 语句,并且该 printf 语句只有一个输出。为什么不继续打印?
【解决方案2】:

你有什么互连?它是像 InfiniBand 或 Myrinet 这样的专用设备,还是您只是在以太网上使用普通 TCP?如果使用 TCP 传输运行,您是否配置了多个网络接口?

此外,Open MPI 是模块化的——有许多模块提供了实现各种集合操作的算法。您可以尝试使用 MCA 参数来摆弄它们,例如您可以通过传递mpirun 之类的--mca btl_base_verbose 30 来开始调试应用程序的行为,从而增加btl 组件的详细程度。寻找类似的东西:

[node1:19454] btl: tcp: attempting to connect() to address 192.168.2.2 on port 260
[node2:29800] btl: tcp: attempting to connect() to address 192.168.2.1 on port 260
[node1:19454] btl: tcp: attempting to connect() to address 192.168.109.1 on port 260
[node1][[54886,1],0][btl_tcp_endpoint.c:638:mca_btl_tcp_endpoint_complete_connect] connect() to 192.168.109.1 failed: Connection timed out (110)

在这种情况下,一些(或所有)节点具有多个已配置的网络接口,但并非所有节点都可以通过所有接口访问。这可能会发生,例如如果节点运行具有默认启用的 Xen 支持(RHEL?)的最新 Linux 发行版,或者在其上安装了其他虚拟化软件,以提供虚拟网络接口。

默认情况下,Open MPI 是惰性的,即按需打开连接。如果选择正确的接口,第一次发送/接收通信可能会成功,但后续操作可能会选择一条备用路径以最大化带宽。如果通过第二个接口无法访问另一个节点,则可能会发生超时并且通信将失败,因为 Open MPI 将认为另一个节点已关闭或有问题。

解决方案是使用 TCP btl 模块的 MCA 参数隔离非连接网络或网络接口:

  • 强制 Open MPI 仅使用特定 IP 网络进行通信:--mca btl_tcp_if_include 192.168.2.0/24
  • 强制 Open MPI 仅使用某些已知可提供完整网络连接的网络接口:--mca btl_tcp_if_include eth0,eth1
  • 强制 Open MPI使用已知为私有/虚拟或属于不连接节点的其他网络的网络接口(如果您选择这样做,您必须排除环回lo): --mca btl_tcp_if_exclude lo,virt0

有关详细信息,请参阅Open MPI run-time TCP tuning FAQ

【讨论】:

  • 哇!这解决了一年前的问题。几个网络接口是虚拟的或由 docker 创建并明确指定为 eth0 修复它。谢谢!
猜你喜欢
  • 2023-04-07
  • 2016-12-01
  • 2011-06-21
  • 1970-01-01
  • 2016-09-01
  • 2012-07-11
  • 2018-04-08
  • 2017-04-20
  • 2018-10-02
相关资源
最近更新 更多