繁体   English   中英

MPI4Py comm.Barrier()在MSMPI上没有阻止?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM