Вызов mpi бинарного в последовательном как подпроцесс mpi приложения
У меня есть большое параллельное (с использованием MPI) приложение моделирования, которое производит большие объемы данных. Для оценки этих данных я использую скрипт на python.
Теперь мне нужно выполнить это приложение большое количество раз (> 1000) и рассчитать статистические свойства на основе полученных данных.
Мой подход до сих пор заключается в том, чтобы скрипт Python работал параллельно (используя mpi4py, используя 48 узлов), вызывая код моделирования с помощьюsubprocess.check_call
. Мне нужен этот вызов для запуска приложения симуляции mpi в серийном режиме. Мне не нужно, чтобы симуляция также работала параллельно в этом случае. Затем скрипт python может анализировать данные параллельно и после его завершения запустит новый прогон симуляции, пока не будет накоплено большое количество прогонов.
Цели
не сохраняет весь набор данных от 2000 запусковхранение промежуточных данных в памятиЗаглушка MWE:
файлmulti_call_master.py
:from mpi4py import MPI
import subprocess
print "Master hello"
call_string = 'python multi_call_slave.py'
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
print "rank %d of size %d in master calling: %s" % (rank, size, call_string)
std_outfile = "./sm_test.out"
nr_samples = 1
for samples in range(0, nr_samples):
with open(std_outfile, 'w') as out:
subprocess.check_call(call_string, shell=True, stdout=out)
# analyze_data()
# communicate_results()
файлmulti_call_slave.py
(это будет код симуляции C):from mpi4py import MPI
print "Slave hello"
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
print "rank %d of size %d in slave" % (rank, size)
Это не будет работать. Результирующий вывод вstdout
:
Master hello
rank 1 of size 2 in master calling: python multi_call_slave_so.py
Master hello
rank 0 of size 2 in master calling: python multi_call_slave_so.py
[cli_0]: write_line error; fd=7 buf=:cmd=finalize
:
system msg for write_line failure : Broken pipe
Fatal error in MPI_Finalize: Other MPI error, error stack:
MPI_Finalize(311).....: MPI_Finalize failed
MPI_Finalize(229).....:
MPID_Finalize(150)....:
MPIDI_PG_Finalize(126): PMI_Finalize failed, error -1
[cli_1]: write_line error; fd=8 buf=:cmd=finalize
:
system msg for write_line failure : Broken pipe
Fatal error in MPI_Finalize: Other MPI error, error stack:
MPI_Finalize(311).....: MPI_Finalize failed
MPI_Finalize(229).....:
MPID_Finalize(150)....:
MPIDI_PG_Finalize(126): PMI_Finalize failed, error -1
Результирующий вывод вsm_test.out
:
Slave hello
rank 0 of size 2 in slave
Причина в том, что подпроцесс предполагает запуск в качестве параллельного приложения, в то время как я намерен запускать его как последовательное приложение. В качестве очень «хакерского» обходного пути я сделал следующее:
Скомпилируйте все необходимые библиотеки, поддерживающие mpi, с конкретным дистрибутивом mpi, то есть intel mpiСкомпилируйте код симуляции с другой библиотекой mpi, т.е. openmpiЕсли бы я сейчас запустил свой параллельный скрипт на python с использованием intel mpi, базовая симуляция не знала бы об окружающей параллельной среде, поскольку она использовала другую библиотеку.
Некоторое время это работало нормально, но, к сожалению, не очень переносимо и его трудно поддерживать в разных кластерах по разным причинам.
Я мог бы
поместите цикл вызова подпроцесса в сценарий оболочки, используяsrun
Будет ли требовать буферизации результатов на HDиспользовать какой-тоMPI_Comm_spawn
техника в питонене предназначен для такого использованиятрудно определить, закончен ли подпроцессвозможно изменения в коде CКаким-то образом обмануть подпроцесс, чтобы не пересылать информацию MPIпопытался манипулировать переменными среды безрезультатнотакже не предназначен для использования в таком видес помощьюmpirun -n 1
или жеsrun
для вызова подпроцесса не помогаетЕсть ли какой-нибудь элегантный, официальный способ сделать это? Я действительно вне идей и ценю любой вклад!