Барьер после порождения процесса mpi4py

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

Проблема в том, что все вызовы исполняемого файла mpi запускаются немедленно.

Кажется, что нет никакого способа использовать барьер, чтобы предотвратить это. Кто-нибудь знает, правильно ли это, и если да, то есть ли у кого-нибудь блестящая идея, чтобы получить нужный мне результат.

#!/usr/bin/env python
from mpi4py import MPI
import numpy
import sys
import os

rank = MPI.COMM_WORLD.Get_rank()
new_comm = MPI.COMM_WORLD.Split(color=rank, key=rank)
print(new_comm.Get_rank())

cwd=os.getcwd()
directory=os.path.join(cwd,str(rank))
print(rank,directory)
os.chdir(directory)


new_comm.Spawn("SOME_F90_MPI_EXECUTABLE",
                  args=None,
                           maxprocs=4)

'''I want to pause here until the spawned processes finish running...'''
new_comm.Barrier()
MPI.COMM_WORLD.Barrier()

print(new_comm.Get_rank())

cwd=os.getcwd()
directory=os.path.join(cwd,str(rank))
print(rank,directory)
os.chdir(directory+"_2")


new_comm.Spawn("SOME_F90_MPI_EXECUTABLE",
                  args=["> output"],
                           maxprocs=4)

new_comm.Disconnect()

print("All finished here.....")

Спасибо!


person abinitio    schedule 21.09.2016    source источник


Ответы (1)


Вы должны использовать интеркоммуникатор, возвращенный Spawn:

child_comm = MPI.COMM_WORLD.Spawn("./spawnchild.py", args=None, maxprocs=2)
child_comm.Barrier()

Для дочернего элемента получите родительский интеркоммуникатор (аналогично на Фортране):

parent = MPI.COMM_WORLD.Get_parent()
assert(parent != MPI.COMM_NULL)
parent.Barrier();

Обратите внимание, что интеркоммуникатор, состоящий из процессов из двух групп, ведет себя иначе, чем традиционный интеркоммуникатор. Например. для Барьера применяется следующая семантика:

Если comm является интеркоммуникатором, MPI_BARRIER включает две группы. Вызов возвращается на процессы в одной группе (группе А) интеркоммуникатора только после того, как все члены другой группы (группы Б) вошли в вызов (и наоборот). Процесс может вернуться из вызова до того, как все процессы в его собственной группе присоединятся к вызову.

(Стандарт MPI 3.1, 5.3)

person Zulan    schedule 22.09.2016
comment
Отлично - спасибо, Зулан. Если я зацикливался на процессе создания, нужно ли мне отключать/освобождать интеркоммуникатор, возвращаемый спавном, прежде чем войти в цикл во второй раз? - person abinitio; 22.09.2016
comment
Я считаю, что вам следует отключить интеркоммуникатор, но я не совсем уверен, что это указано в стандарте. - person Zulan; 22.09.2016
comment
Я не уверен, почему, но исполняемый файл f90, кажется, зависает после создания, несмотря на то, что он, казалось бы, закончен, т.е. весь вывод сделан. Когда я запускаю исполняемый файл f90, не вызывая его из скрипта Python, это должно занять доли секунды, но когда он запускается путем порождения, он зависает на несколько минут. Это то, что вы замечали раньше? - person abinitio; 23.09.2016
comment
Это на одном узле или в распределенной системе? - person Zulan; 23.09.2016
comment
Одиночный узел - когда я использую разъединение(), проблема исчезает. - person abinitio; 23.09.2016