MPI4Py comm.Barrier () не блокируется на MSMPI? - PullRequest
0 голосов
/ 13 февраля 2019

При реализации параллельного алгоритма в Python 3.7.0 с использованием MPI4PY 3.0.0 в MSMPI в Windows 10 у меня были проблемы с тем, что 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() или в моей среде что-то не так?

1 Ответ

0 голосов
/ 11 мая 2019

Причина, по которой они отображаются в неправильном порядке, заключается в том, что серверная часть 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. Таким образом, существует условие гонки, которое по существу определяет порядок, в котором вещи печатаются.Таким образом, чтобы привести вещи в правильный порядок, вам необходимо применить сочетание синхронизирующих и спящих вызовов, чтобы события сброса вызывались достаточно редко, чтобы избежать условий гонки.

Я подозреваю, что с вами происходитчто вывод сбрасывается только в конце процесса.Поскольку это происходит со всеми процессами одновременно, то вы видите результаты этой гонки коммуникации.

Надеюсь, это поможет.

...