python - MPI4Py comm.Barrier() 没有阻塞 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。因此,存在一个竞争条件,它本质上决定了打印内容的顺序。因此,为了以正确的顺序处理事情,您需要混合使用同步和 sleep 调用,这样刷新事件的调用频率就足以避免竞争条件。

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

希望对您有所帮助。

https://stackoverflow.com/questions/54659608/

相关文章:

oracle - 使用sqlplus命令行隐藏明文密码

haskell - OverloadedStrings 语言扩展如何工作?

kubernetes - 定时任务 : unknown field "configMapRef"

python-3.x - 为什么在 python 中允许 for else

reactjs - 为什么我的 GlobalStyles 在使用样式化组件部署后不起作用?

php - 如何仅在 Laravel 中出现日期时才验证日期

google-apps-script - 调试由发布请求触发的 Google Apps 脚本?

sql-server - TRY_PARSE 但更快

c# - 调用多个相互依赖的异步方法

reactjs - 将映射数据传递给 Material-UI 模态