MPI#U屏障不';不能正常工作 我写了下面的C应用程序来帮助我理解MPI,以及为什么MPIIBARILRIER()在我的巨大C++应用程序中不起作用。然而,我能够用一个小得多的C应用程序在我庞大的应用程序中重现我的问题。本质上,我在for循环中调用MPI_Barrier(),所有节点都可以看到MPI_Barrier(),但是在循环的两次迭代之后,程序就会死锁。有什么想法吗 #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; }

MPI#U屏障不';不能正常工作 我写了下面的C应用程序来帮助我理解MPI,以及为什么MPIIBARILRIER()在我的巨大C++应用程序中不起作用。然而,我能够用一个小得多的C应用程序在我庞大的应用程序中重现我的问题。本质上,我在for循环中调用MPI_Barrier(),所有节点都可以看到MPI_Barrier(),但是在循环的两次迭代之后,程序就会死锁。有什么想法吗 #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; },c++,c,mpi,openmpi,C++,C,Mpi,Openmpi,我使用的是GCC4.4,从Ubuntu10.10存储库中打开MPI1.3 也在我的巨型C++应用程序中,MPI广播不起作用。只有一半的节点接收到广播,其他节点则在等待广播 提前感谢您提供的任何帮助或见解 更新:升级到OpenMPI 1.4.4,从源代码编译到/usr/local/ 更新:将GDB附加到正在运行的进程显示了一个有趣的结果。在我看来,MPI系统在屏障处死亡,但MPI仍然认为程序正在运行: 附加GDB会产生一个有趣的结果。似乎所有节点都已在MPI屏障处死亡,但MPI仍认为它们正在运行:

我使用的是GCC4.4,从Ubuntu10.10存储库中打开MPI1.3

也在我的巨型C++应用程序中,MPI广播不起作用。只有一半的节点接收到广播,其他节点则在等待广播

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

更新:升级到OpenMPI 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) 

有什么想法吗?

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

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

#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;
}
此外,OpenMPI是模块化的——有许多模块提供实现各种集合操作的算法。您可以尝试使用MCA参数来处理它们,例如,您可以通过传递
mpirun
类似于
--MCA btl\u base\u 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)
在这种情况下,某些(或所有)节点具有多个已配置的网络接口,但并非所有节点都可以通过所有接口访问。这种情况可能会发生,例如,如果节点运行最新的Linux发行版,并支持默认的Xen支持(RHEL?),或者在节点上安装了其他虚拟化软件,以提供虚拟网络接口

默认情况下,OpenMPI是惰性的,即根据需要打开连接。如果选择了正确的接口,则第一次发送/接收通信可能会成功,但后续操作可能会选择一条备用路径,以最大化带宽。如果另一个节点无法通过第二个接口到达,则可能会出现超时,而通信将失败,因为开放MPI将考虑另一个节点下降或问题。 解决方案是使用TCP
btl
模块的MCA参数隔离非连接网络或网络接口:

  • 强制打开MPI仅使用特定IP网络进行通信:
    --mca btl\u tcp\u如果包含192.168.2.0/24
  • 强制Open MPI仅使用已知可提供完整网络连接的部分网络接口:
    --mca btl\u tcp\u如果包含eth0、eth1
  • 强制打开MPI以使用已知为专用/虚拟或属于其他未连接节点的网络的网络接口(如果您选择这样做,必须排除环回
    lo
    ):
    --mca btl\u tcp\u如果排除lo,virt0

有关更多详细信息,请参阅。

发布的代码在我的系统上可以正常工作,无需修改。我在RHEL5.3、OpenMPI1.4.2和GCC4.1.2上运行。在每个列组上附加一个调试器,并获得一个回溯跟踪,以找出进程中每个列组的位置。这几乎总是一个配置问题。其他机器是否在相同位置和默认路径中安装了相同版本的OpenMPI?和/或是否安装了其他MPI?@Jon,所有MPI都安装了相同的openmpi软件包,因为它们运行Ubuntu 10.10,而我是从同一个Ubuntu存储库安装它们的。没有安装其他MPI实现。请尝试删除循环和MPI_屏障,然后让每个列组打印“Hello World”。这将有助于诊断基本的启动、权限和连接问题。@看起来没有启动问题。第一个障碍是成功的(因为至少有一个等级已经越过了它)。在MPI_Reduce之后有一个printf语句,该printf语句只有一个输出。为什么不继续打印?哇!这修复了一年前的问题。有几个网络接口是虚拟的或由docker创建的,并将其明确指定为
eth0
修复了它。谢谢!
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
[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)