【问题标题】:MPI4Py comm.Barrier() not blocking on MSMPI?MPI4Py comm.Barrier() 没有阻塞 MSMPI?
【发布时间】:2019-07-06 15:53:29
【问题描述】:

在 Windows 10 上的 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()的用法,还是我的环境有问题?

【问题讨论】:

标签: python windows mpi4py ms-mpi


【解决方案1】:

它们似乎以错误的顺序打印的原因是收集消息的 MPI 后端。所有子进程的标准输出流都没有直接连接到终端窗口,因为这不可能跨多台计算机。

相反,MPI 后端收集来自每个进程的所有消息。然后,它使用标准 MPI 调用在 rank 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 级。因此,有一个竞争条件基本上决定了打印的顺序。因此,为了让事情按正确的顺序排列,您需要混合应用同步和睡眠调用,这样刷新事件的调用频率就会足够低,以避免出现竞争条件。

我怀疑发生在您身上的是输出仅在进程结束时被刷新。由于它同时发生在所有进程中,那么您所看到的就是这场通信竞赛的结果。

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-04
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多