Я пытаюсь распараллелить небольшую часть моего python кода в Fortran90. Итак, для начала я пытаюсь понять, как работает функция порождения.
Во-первых, я пытался порождать дочерний процесс в python от python родителя. Я использовал пример управления процессами Dynami c из руководства mpi4py . Все работало нормально В этом случае, насколько я понимаю, используется только межкоммуникатор между родительским процессом и дочерним процессом.
Затем я перешел к примеру для порождения дочернего процесса в fortran90 из * 1026. * родитель. Для этого я использовал пример из предыдущего поста в 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)
) не будут выполняться в коде Fortran (и, следовательно, любые операторы после Команды разъединения в коде python также не выполняются), и мой код не завершится в терминале.
В этом случае, насколько я понимаю, интер-коммуникатор и интра-коммуникатор объединены так, что дочерние процессы и родительские процессы больше не две разные группы. И, кажется, есть некоторые проблемы при их отключении. Но я не могу найти решение. Я попытался воспроизвести код fortran90, где дочерние процессы создаются в C ++, а также в python, и столкнулись с той же проблемой. Любая помощь приветствуется. Спасибо.