Я пытаюсь распараллелить небольшую часть моего кода Python в Fortran90. Итак, для начала я пытаюсь понять, как работает функция нереста.
Во-первых, я попытался создать дочерний процесс в python из родительского процесса python. Я использовал пример динамического управления процессами из учебника по mpi4py. Все работало нормально. В этом случае, насколько я понимаю, используется только интеркоммуникатор между родительским процессом и дочерним процессом.
Затем я перешел к примеру порождения дочернего процесса в fortran90 из родительского процесса на python. Для этого я использовал пример из одного из предыдущий пост в stackoverflow. Код Python (master.py), порождающий дочерний элемент fortran, выглядит следующим образом:
from mpi4py import MPI
import numpy
'''
slavef90 is an executable built starting from slave.f90
'''
# Spawing a process running an executable
# sub_comm is an MPI intercommunicator
sub_comm = MPI.COMM_SELF.Spawn('slavef90', args=[], maxprocs=1)
# common_comm is an intracommunicator accross the python process and the spawned process.
# All kind sof collective communication (Bcast...) are now possible between the python process and the c process
common_comm=sub_comm.Merge(False)
print('parent in common_comm ', common_comm.Get_rank(), ' of ', common_comm.Get_size())
data = numpy.arange(1, dtype='int32')
data[0]=42
print("Python sending message to fortran: {}".format(data))
common_comm.Send([data, MPI.INT], dest=1, tag=0)
print("Python over")
# disconnecting the shared communicators is required to finalize the spawned process.
sub_comm.Disconnect()
common_comm.Disconnect()
Соответствующий код fortran90 (slave.f90), в котором порождаются дочерние процессы, выглядит следующим образом:
program test
!
implicit none
!
include 'mpif.h'
!
integer :: ierr,s(1),stat(MPI_STATUS_SIZE)
integer :: parentcomm,intracomm
!
call MPI_INIT(ierr)
call MPI_COMM_GET_PARENT(parentcomm, ierr)
call MPI_INTERCOMM_MERGE(parentcomm, 1, intracomm, ierr)
call MPI_RECV(s, 1, MPI_INTEGER, 0, 0, intracomm,stat, ierr)
print*, 'fortran program received: ', s
call MPI_COMM_DISCONNECT(intracomm, ierr)
call MPI_COMM_DISCONNECT(parentcomm, ierr)
call MPI_FINALIZE(ierr)
endprogram test
Я скомпилировал код fortran90, используя mpif90 slave.f90 -o slavef90 -Wall
. Я обычно запускал код Python, используя python master.py
. Я могу получить желаемый результат, но порожденные процессы не будут отключены, т. е. любые операторы после команд Disconnect (call MPI_COMM_DISCONNECT(intracomm, ierr)
и call MPI_COMM_DISCONNECT(parentcomm, ierr)
) не будут выполняться в коде фортрана (и, следовательно, любые операторы после команд Disconnect в код Python также не выполняется), и мой код не завершается в терминале.
В этом случае, насколько я понимаю, интеркоммуникатор и интракоммуникатор сливаются, так что дочерние процессы и родительские процессы больше не являются двумя разными группами. И, кажется, есть некоторые проблемы при их отключении. Но я не могу найти решение. Я попытался воспроизвести код fortran90, в котором дочерние процессы порождаются как на C++, так и на python, и столкнулся с той же проблемой. Любая помощь приветствуется. Спасибо.
use mpi
вместо включения файлаmpif.h
. Тогда компилятор может проверить многие вещи и предупредить вас или остановить вас от неправильных действий. - person Vladimir F   schedule 25.04.2020MPI_Comm_free()
используете внутренний (также известный как объединенный) коммуникатор иMPI_Comm_discomnect()
только интеркоммуникатор? - person Gilles Gouaillardet   schedule 25.04.2020mpirun -np 1 python master.py
- person Gilles Gouaillardet   schedule 25.04.2020mpirun
предложение. К сожалению, это не сработало. Мне все еще нужно написать спаунер на C. Я также нашел открытый вопрос в той же теме. Мне это не очень помогло. К счастью, (пока) я могу распараллелить свой код без использованияMerge()
. Все работает гладко, пока родительский и дочерний процессы хранятся как отдельная группа. - person AdhityaRavi   schedule 26.04.2020mpi4py
? - person Gilles Gouaillardet   schedule 27.04.2020