在使用 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 sleep 的进程:
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()
Run Code Online (Sandbox Code Playgroud)
我怎样才能获得我想要的行为(如果任何进程失败,则迅速失败)?
谢谢!
这似乎是 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__
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1010 次 |
| 最近记录: |