[英]MPI4Py comm.Barrier() not blocking on MSMPI?
在Windows 10的MSMPI上使用MPI4PY 3.0.0在Python 3.7.0中实现并行算法时,我遇到了Gatherv无法收集所有内容的问题...当检查各种位的打印时,似乎执行顺序错误。
我写了一些重复这个问题的代码:
from mpi4py import MPI
from time import sleep
import random
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
if rank == 0:
sleep(2)
print("head finished sleeping")
comm.Barrier()
sleep(random.uniform(0, 2))
print(rank, 'finished sleeping ')
comm.Barrier()
if rank == 0:
print("All done!")
如果我正确理解comm.Barrier()
,应该会产生
head finished sleeping
2 finished sleeping
0 finished sleeping
3 finished sleeping
1 finished sleeping
4 finished sleeping
All done!
中间的位以某种顺序排列,对吗? 但是当我实际运行mpiexec -n 5 python .\\blocking_test.py
我得到如下信息:
2 finished sleeping
1 finished sleeping
3 finished sleeping
head finished sleeping
0 finished sleeping
All done!
4 finished sleeping
我是否误解了comm.Barrier()
的用法,或者我的环境有问题吗?
它们似乎以错误的顺序打印的原因是由于MPI后端收集消息。 所有子进程的标准输出流没有直接连接到终端窗口,因为这在多台计算机上是不可能的。
相反,MPI后端从每个进程收集所有消息。 然后,它使用标准MPI调用在等级0的后端收集这些消息。正是在这种通信中,消息的顺序变得混乱。
通常,在MPI流程中不会优先处理标准输出,因此,以正确的顺序打印输出几乎不费力。 通常,输出保存在正在运行的进程的输出缓冲区中。 仅在发生以下事件时打印输出(可能更多):
1) The end of the process
2) When there is a buffer over-flow (i.e. large amount of data is printed to the output)
3) flush is called on the output buffer (i.e. 'sys.stdout.flush()')
因此,您可以在打印时刷新标准输出来帮助自己:
1) print('my message'); sys.stdout.flush()
2) print('my message on newer version of python', flush=True)
但是,实际上很难使其正常工作。 如果多个MPI进程同时发生刷新事件。 然后,多个进程将发送消息到等级0。因此,存在一个竞争条件,该竞争条件从根本上决定了事物的打印顺序。 因此,为了使事情按正确的顺序进行,您需要同时应用同步和睡眠调用,因此很少调用flush事件,从而避免了竞争情况。
我怀疑发生了什么事,只是在过程结束时才刷新输出。 由于它同时发生在所有流程中,因此您所看到的就是这次通信竞赛的结果。
希望对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.