代码之家  ›  专栏  ›  技术社区  ›  Andre

使用MPI4PY快速失败

  •  5
  • Andre  · 技术社区  · 8 年前

    在使用mpi4py运行MPI脚本时,我喜欢以下行为:当任何进程引发异常时,mpirun(及其派生的进程)应立即退出,并显示非零错误代码。但是,我发现即使一个或多个进程抛出异常,执行也会继续。

    我在OpenMPI 2.1.2中使用mpi4py 3.0.0。我正在运行此脚本 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()
    

    如何获得我想要的行为(如果任何进程失败,则快速失败)?

    非常感谢。

    2 回复  |  直到 8 年前
        1
  •  5
  •   jcgiret    8 年前

    这似乎是mpi4py的一个已知问题。从…起 https://groups.google.com/forum/#!topic/mpi4py/RovYzJ8qkbc ,我读到:

    mpi4py为您初始化/完成MPI。初始化发生在 导入时间,以及Python进程即将 finalize(我正在使用Py\u AtExit()C-API调用来完成此操作)。像 MPI\u Finalize()是集体的,在大多数MPI impl中可能是阻塞的, 你会陷入僵局。

    解决方案是覆盖 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__
    
        2
  •  0
  •   Gilles Gouaillardet    8 年前

    事实证明,mpi4py可以作为修复此问题的模块运行(在内部调用Abort(),如jcgiret所说):

    mpirun --verbose -mca orte_abort_on_non_zero_status 1 -n 4 python -m mpi4py my_script.py
    
    推荐文章