【问题标题】:Simple MPI program fail with large number of processes简单的 MPI 程序因大量进程而失败
【发布时间】:2014-06-07 20:34:00
【问题描述】:

这是我的代码:

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

int main (int argc, char** argv) {

   int  numtasks, rank; 

   MPI_Init(&argc,&argv);

   MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
   MPI_Comm_rank(MPI_COMM_WORLD,&rank);
   // the code fail with or without printf
   printf ("Number of tasks= %d My rank= %d\n", numtasks,rank);

   MPI_Barrier(MPI_COMM_WORLD);
   MPI_Finalize();
   return 0;
}

这就是我运行它和输出的方式:

$ mpirun -n 160 ./mpi_example1
[proxy:0:0@ubuntu] send_cmd_downstream (./pm/pmiserv/pmip_pmi_v1.c:80): assert (!closed) failed
[proxy:0:0@ubuntu] fn_get (./pm/pmiserv/pmip_pmi_v1.c:349): error sending PMI response
[proxy:0:0@ubuntu] pmi_cb (./pm/pmiserv/pmip_cb.c:327): PMI handler returned error
[proxy:0:0@ubuntu] HYDT_dmxu_poll_wait_for_event (./tools/demux/demux_poll.c:77): callback returned error status
[proxy:0:0@ubuntu] main (./pm/pmiserv/pmip.c:226): demux engine error waiting for event
[mpiexec@ubuntu] control_cb (./pm/pmiserv/pmiserv_cb.c:215): assert (!closed) failed
[mpiexec@ubuntu] HYDT_dmxu_poll_wait_for_event (./tools/demux/demux_poll.c:77): callback returned error status
[mpiexec@ubuntu] HYD_pmci_wait_for_completion (./pm/pmiserv/pmiserv_pmci.c:181): error waiting for event
[mpiexec@ubuntu] main (./ui/mpich/mpiexec.c:405): process manager error waiting for completion

当我使用 -n 128 或更低的代码运行代码时,它运行良好。我还尝试在 32 核 x 8 节点计算机上运行代码,并且能够运行到 -n 192,当我尝试 -n 224 时它失败了......

有什么建议吗?谢谢。

【问题讨论】:

  • 您的根进程(等级 0)在所有其他进程正常启动之前就退出了,我相信。如果是这样的话,在MPI_Finalize(); 之前添加MPI_Barrier(MPI_COMM_WORLD); 应该可以解决它。请你试试看好吗?
  • 谢谢,我会尽快回复的!
  • @Nominal Animal 可悲的是,我尝试了您建议的方法,但出现了同样的错误... :(
  • @NominalAnimal MPI_Finalize 不隐式调用 BarrierCray materials 说有,但可能是实现细节。
  • @luk32 我个人认为 MPI_Finalize 也应该这样做。所以我真的不知道这里发生了什么。有什么建议吗?

标签: c linux mpi


【解决方案1】:

问题可能与您的 shell 可以生成的最大进程数有关。如何修改此设置取决于外壳的类型和操作系统。如果您使用的是 cshell 或 tcshell,您可以使用公共行中的“limit”命令来验证您的当前设置。可以在用户级别或根级别更改设置(有软限制和硬限制)。

【讨论】:

  • 我在 ubuntu 终端上尝试了 ulimit -n 2048,并且似乎该命令本身有效(当我尝试 ulimit -n 256 并且程序无法使用 -n 128 运行时,错误代码是“打开文件限制”)。但是问题并没有解决……
  • 然后,您可能还需要修改文件描述符的最大数量的设置:尝试(对于 c 和 tc shell)限制描述符 24576 之类的设置。
  • 我也希望是这个问题,但是我必须在我学校的超级计算机上运行代码,并且我只允许在那台计算机上使用一些命令(因为我的教授不希望学生对计算机造成任何损坏)。当我问他这个问题时,他只说代码应该在计算机上工作。我完全迷失了......
【解决方案2】:

这不是一个确定的答案,但它的评论太长了。

我查看了失败断言的来源。 codebase 略有不同,但我认为它足够接近。你的错误说断言在第 80 行失败,而here,断言HYDU_ASSERT(!closed, status); 在第 82 行。

违规调用位于第 77 行:

status = HYDU_sock_write(fd, cmd, strlen(cmd), &amp;sent, &amp;closed, HYDU_SOCK_COMM_MSGWAIT);

现在,HYDU_sock_write 的代码表明closed 标志将被设置并且函数将在以下情况下中止操作

write(fd, (char *) buf + *sent, maxlen - *sent); @line 278 失败并显示errno == ECONNRESET

现在this write 的文档说:"[ECONNRESET] 尝试在未连接的套接字上写入。”

您确定网络工作正常吗?似乎套接字已断开连接。

【讨论】:

  • 上述错误是由于在 Ubuntu VMWare(2 个处理器,每个 2 核)上运行代码,而不是在 32 核 x 8 节点超级计算机上运行的。这和问题有关系吗?因为我不明白网络是如何导致这里出现问题的。
  • 而且,当我以低进程数运行代码时(我的计算机上为 128 及以下),无论我运行代码多少次,它总是正确执行...
  • 对我来说它看起来像系统/硬件错误。我不知道为什么套接字会断开连接,但看起来这是程序失败的根源。我不确定什么会导致ECONNRESET。也许您可以在 hydra 开发者论坛/列表上询问一些专家。毕竟是 hydra 调用失败了。
猜你喜欢
  • 2011-08-22
  • 1970-01-01
  • 2011-07-06
  • 2021-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-09
  • 1970-01-01
相关资源
最近更新 更多