C 发生异常时未调用MPI错误处理程序

C 发生异常时未调用MPI错误处理程序,c,mpi,fault-tolerance,C,Mpi,Fault Tolerance,在过去的几天里,我一直在尝试用MPI编写C语言的容错应用程序。我正在尝试学习如何将错误处理程序附加到MPI_COMM_WORLD communicator,以便在节点发生故障(可能是由于崩溃)并在不调用MPI_Finalize()的情况下退出时程序仍然可以从这种情况中恢复并继续计算 到目前为止,我遇到的问题是,在我将错误处理程序函数附加到通信之后,然后导致节点崩溃,MPI不会调用错误处理程序,而是强制所有线程退出 我认为这可能是我的应用程序的一个问题,所以我在线查找示例代码并尝试运行它,但情况是

在过去的几天里,我一直在尝试用MPI编写C语言的容错应用程序。我正在尝试学习如何将错误处理程序附加到MPI_COMM_WORLD communicator,以便在节点发生故障(可能是由于崩溃)并在不调用MPI_Finalize()的情况下退出时程序仍然可以从这种情况中恢复并继续计算

到目前为止,我遇到的问题是,在我将错误处理程序函数附加到通信之后,然后导致节点崩溃,MPI不会调用错误处理程序,而是强制所有线程退出

我认为这可能是我的应用程序的一个问题,所以我在线查找示例代码并尝试运行它,但情况是一样的。。。我当前尝试运行的示例代码如下。(我从这里得到的是pdf格式,对此表示歉意,但我没有编写它,因此我现在将相同的代码粘贴到下面):

显然,在我看到的输出中,
ccg\u mpi\u error\u handler()
中的
printf()
都没有被执行,因此我假设该处理程序根本没有被调用。我不确定这是否有任何帮助,但我正在运行UbuntuLinux12.04,我使用apt get安装了MPI。我用来编译程序的命令如下:

mpicc err_example.c -o example.exe
  Using built-in specs.
  COLLECT_GCC=/usr/bin/gcc
  COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
  Target: x86_64-linux-gnu
  Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
  Thread model: posix
  gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
另外,当我进行mpicc-v时,我得到以下信息:

mpicc err_example.c -o example.exe
  Using built-in specs.
  COLLECT_GCC=/usr/bin/gcc
  COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper
  Target: x86_64-linux-gnu
  Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
  Thread model: posix
  gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)

非常感谢您的帮助!谢谢……

MPI标准甚至不要求MPI实现能够优雅地处理错误。以下摘自MPI-3.0§8.3的内容说明了一切:

MPI实现无法或可能选择不处理过程中发生的某些错误 MPI呼叫。这些可能包括生成异常或陷阱的错误,例如浮点错误或访问冲突。MPI处理的错误集取决于实现。每个这样的错误都会生成一个MPI异常

上述文本优先于本文档中有关错误处理的任何文本。 具体而言,说明将处理错误的文本应按可能处理的方式读取

(保留原始格式,包括使用粗体和斜体)

原因有很多,但大多数都与性能和可靠性之间的某种权衡有关。在不同级别进行错误检查并优雅地处理错误条件会产生一些不太小的开销,并使库代码库非常复杂

也就是说,并非所有MPI库都是平等创建的。其中一些实现了比其他更好的容错性。例如,与“英特尔MPI 4.1”相同的代码:

。。。
进程5即将南下
进程5正在向0发送5
ccg\u mpi\u错误\u处理程序:条目
ccg\U mpi\U错误处理程序:错误代码=403287557
ccg\u mpi\u错误\u处理程序:错误\u字符串=无效的通信器,错误堆栈:
MPI_发送(186):MPI_发送(buf=0x7fffa32a7308,计数=1,MPI_INT,dest=0,tag=201,comm=0x0)失败
MPI_发送(87)。:无效的通信器
ccg\u mpi\u错误\u处理程序:退出
案例中错误消息的格式表明您正在使用OpenMPI。OpenMPI中的容错是一种实验性的(OMPI开发人员之一,即Jeff Squyres,不时访问堆栈溢出-他可以给出更明确的答案),必须在库构建时使用类似于
--enable ft=LAM
的选项显式启用

默认情况下,MPICH也无法处理以下情况:

进程5即将南下
进程5正在向0发送5
===================================================================================
=某个应用程序进程的错误终止
=退出代码:139
=清理剩余流程
=您可以忽略以下清理消息
===================================================================================
应用程序以退出字符串终止:分段错误(信号11)
这通常指的是应用程序的问题。
有关调试建议,请参见常见问题页面
请注意,当前MPI不能保证在检测到错误时程序状态保持一致:

检测到错误后,MPI的状态未定义。也就是说,使用用户定义的错误处理程序或MPI_ERRORS_RETURN不一定允许用户在检测到错误后继续使用MPI。这些错误处理程序的目的是允许用户在程序退出之前发出用户定义的错误消息,并采取与MPI无关的操作(例如刷新I/O缓冲区)。MPI实现可以自由地允许MPI在错误后继续,但不需要这样做

其中一个原因是,不可能在这种“坏”的通讯器上执行集体操作,许多内部MPI机制要求所有级别之间共享集体信息。MPI-3.0中提出了一种更好的容错机制,称为贯穿稳定(RTS),但它没有通过最终投票。在RTS中添加了一个新的MPI调用,该调用通过共同删除所有失败的进程,从一个损坏的通信器创建一个健康的通信器,然后剩余的进程可以继续在新的通信器中运行


免责声明:我不为英特尔工作,也不支持他们的产品。与openmpi和MPICH的默认构建配置相比,IMPI提供了更好的用户错误处理开箱即用实现。通过改变构建选项,在两种开源实现中都有可能达到可比的容错水平,或者未来可能会出现适当的FT(例如,在开放MPI中有一个RTS的原型实现)

尽管Hristo所提到的一切都是正确的,但前景并不那么暗淡。在默认情况下,几乎所有MPI实现中都不存在容错。然而,也有选择
mpiexec -n <num_procs> --disable-auto-cleanup <executable> <program args>