使用 MPI4PY 快速失败
Fail fast with MPI4PY
当 运行 使用 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 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()
我怎样才能得到我想要的行为(如果有任何进程失败则迅速失败)?
谢谢!
这似乎是 mpi4py 的一个已知问题。从 https://groups.google.com/forum/#!topic/mpi4py/RovYzJ8qkbc,我读到:
mpi4py initializes/finalizes MPI for you. The initialization occurs at
import time, and the finalization when the Python process is about to
finalize (I'm using Py_AtExit() C-API call to do this). As
MPI_Finalize() is collective and likely blocking in most MPI impls,
you get the deadlock.
一个解决方案是覆盖 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__
事实证明 mpi4py 可以 运行 作为解决此问题的模块(内部通过调用 Abort() 就像 jcgiret 说的):
mpirun --verbose -mca orte_abort_on_non_zero_status 1 -n 4 python -m mpi4py my_script.py
当 运行 使用 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 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()
我怎样才能得到我想要的行为(如果有任何进程失败则迅速失败)?
谢谢!
这似乎是 mpi4py 的一个已知问题。从 https://groups.google.com/forum/#!topic/mpi4py/RovYzJ8qkbc,我读到:
mpi4py initializes/finalizes MPI for you. The initialization occurs at import time, and the finalization when the Python process is about to finalize (I'm using Py_AtExit() C-API call to do this). As MPI_Finalize() is collective and likely blocking in most MPI impls, you get the deadlock.
一个解决方案是覆盖 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__
事实证明 mpi4py 可以 运行 作为解决此问题的模块(内部通过调用 Abort() 就像 jcgiret 说的):
mpirun --verbose -mca orte_abort_on_non_zero_status 1 -n 4 python -m mpi4py my_script.py