【发布时间】: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 看起来没有启动问题。第一个障碍是成功的(因为至少有一个等级已经越过了)。