我希望在使用mpi4py运行MPI脚本时出现以下行为:当任何进程引发异常时,mpirun(及其产生的进程)应立即以非零错误代码退出。但是,相反,我发现即使一个或多个进程抛出异常,执行仍会继续。
我正在将mpi4py 3.0.0与OpenMPI 2.1.2一起使用。我正在运行此脚本mpirun --verbose -mca orte_abort_on_non_zero_status 1 -n 4 python my_script.py
。我希望这会在睡眠被击中之前立即结束,但是,等级为== 0的进程将进入睡眠状态:
import time
import mpi4py
def main():
import mpi4py.MPI
mpi_comm = mpi4py.MPI.COMM_WORLD
if mpi_comm.rank == 0:
raise ValueError('Failure')
print('{} continuing to execute'.format(mpi_comm.rank))
time.sleep(10)
print('{} exiting'.format(mpi_comm.rank)
if __name__ == '__main__':
main()
如何获得所需的行为(如果任何进程失败,很快就会失败)?
谢谢!
最佳答案
这似乎是mpi4py的已知问题。从https://groups.google.com/forum/#!topic/mpi4py/RovYzJ8qkbc中,我读到:
mpi4py为您初始化/完成MPI。初始化发生在
导入时间,以及Python进程即将完成时的完成时间
完成(我正在使用Py_AtExit()C-API调用来执行此操作)。如
MPI_Finalize()是集体的,可能在大多数MPI隐含中阻塞,
你陷入僵局。
一种解决方案是覆盖sys.excepthook
并在其中显式调用MPI.COMM_WORLD.Abort
。
这是修改后的代码:
import sys
import time
import mpi4py.MPI
mpi_comm = mpi4py.MPI.COMM_WORLD
def mpiabort_excepthook(type, value, traceback):
mpi_comm.Abort()
sys.__excepthook__(type, value, traceback)
def main():
if mpi_comm.rank == 0:
raise ValueError('Failure')
print('{} continuing to execute'.format(mpi_comm.rank))
time.sleep(10)
print('{} exiting'.format(mpi_comm.rank))
if __name__ == "__main__":
sys.excepthook = mpiabort_excepthook
main()
sys.excepthook = sys.__excepthook__
关于openmpi - 使用MPI4PY快速失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49868333/