Wywoływanie mpi binarnie szeregowo jako podproces aplikacji mpi

Mam dużą równoległą (za pomocą MPI) aplikację symulacyjną, która wytwarza duże ilości danych. Aby ocenić te dane, używam skryptu Pythona.

Teraz muszę uruchomić tę aplikację wiele razy (> 1000) i obliczyć właściwości statystyczne z uzyskanych danych.

Do tej pory moim podejściem było równoległe uruchamianie skryptu Pythona (przy użyciu mpi4py, np. 48 węzłów) wywołanie kodu symulacji przy użyciusubprocess.check_call. Potrzebuję tego połączenia, aby uruchomić aplikację do symulacji mpi w trybie szeregowym. W tym przypadku nie potrzebuję symulacji, aby również działać równolegle. Skrypt Pythona może następnie analizować dane równolegle i po zakończeniu uruchamia nową symulację, aż do zgromadzenia dużej liczby przebiegów.

Cele są

nie zapisuje całego zestawu danych z 2000 uruchomieńutrzymywanie pośrednich danych w pamięci

Stub MWE:

plikmulti_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()
plikmulti_call_slave.py (byłby to kod symulacji 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)

To nie zadziała. Wynikowe wyjściestdout:

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

Wynikowe wyjściesm_test.out:

Slave hello
rank 0 of size 2 in slave

Powodem jest to, że podproces zakłada uruchomienie jako aplikacja równoległa, podczas gdy ja zamierzam uruchomić go jako aplikację szeregową. Jako bardzo „hacky” obejście zrobiłem co następuje:

Skompiluj wszystkie potrzebne biblioteki świadome mpi z określoną dystrybucją mpi, tj. Intel mpiSkompiluj kod symulacyjny z inną biblioteką mpi, tj. Openmpi

Gdybym teraz uruchamiał mój równoległy skrypt Pythona używając intel mpi, podstawowa symulacja nie byłaby świadoma otaczającego środowiska równoległego, ponieważ korzystała z innej biblioteki.

Przez jakiś czas działało to dobrze, ale niestety nie jest bardzo przenośne i trudne do utrzymania na różnych klastrach z różnych powodów.

mógłbym

umieść pętlę wywołującą podproces w skrypcie powłoki za pomocąsrunCzy wymagałoby buforowania wyników w HDużyj jakiegoś rodzajuMPI_Comm_spawn technika w pytonienie ma być tak używanytrudno się dowiedzieć, czy proces podprocesu został zakończonyprawdopodobnie konieczne zmiany w kodzie C.W jakiś sposób oszukać podproces w nie przesyłaniu informacji MPIpróbowałem manipulować zmiennymi środowiskowymi bezskutecznierównież nie powinien być używany w ten sposóbza pomocąmpirun -n 1 lubsrun dla wywołania podprocesu nie pomaga

Czy jest jakiś elegancki, oficjalny sposób na zrobienie tego? Naprawdę nie mam pomysłów i doceniam każdy wkład!

questionAnswers(1)

yourAnswerToTheQuestion