Запуск MPI-программы с использованием подпроцесса Popen

#python #mpi #mpi4py

#python #mpi #mpi4py

Вопрос:

У меня есть код на python, который запускает другое приложение, используя subprocess.Popen и mpirun . Будет ли код отлично работать на одной машине, на другой я столкнусь с проблемами. Но у меня также есть более старая среда conda, где она работает. Минимальный код для воспроизведения следующий:

 from subprocess import Popen
from mpi4py import MPI

proc = Popen("mpirun -n 2 echo 1".split())
  

На этой строке proc немедленно завершается и proc.poll() возвращается 1 . Скрипт python фактически не использует MPI, он просто запускается как python script.py , однако это зависит от другой программы, вызывающей MPI. Мне нужно повторно запускать другой код с mpirun помощью (конечно, я на самом деле не выполняю echo 1 ).

Я предполагаю, что это зависит от установленного MPI:

Работает:

 $ conda list -n ForkTPS | grep mpi
WARNING: The conda.compat module is deprecated and will be removed in a future release.
fftw                      3.3.8           mpi_mpich_hc19caf5_1012    conda-forge
h5py                      2.10.0          nompi_py38h7442b35_105    conda-forge
hdf5                      1.10.6          mpi_mpich_hc096b2c_1010    conda-forge
mpi                       1.0                       mpich    conda-forge
mpi4py                    3.0.3            py38h4a80816_2    conda-forge
mpich                     3.3.2                hc856adb_2    conda-forge
  

а также

 conda list | grep mpi
dask-mpi                  2.21.0                   pypi_0    pypi
fftw                      3.3.8           mpi_mpich_h3f9e1be_1011    conda-forge
hdf5                      1.10.5          mpi_mpich_ha7d0aea_1004    conda-forge
impi_rt                   2019.8                intel_254    intel
libnetcdf                 4.7.4           mpi_mpich_h755db7c_1    conda-forge
mpi                       1.0                       mpich  
mpi4py                    3.0.3            py37hf484d3e_7    intel
mpich                     3.3.2                hc856adb_0    conda-forge
netcdf4                   1.5.3           mpi_mpich_py37h91af3bc_3    conda-forge
  

Не работает:

 conda list | grep mpi
fftw                      3.3.8           mpi_openmpi_h6dd7431_1011    conda-forge
hdf5                      1.10.6          mpi_openmpi_hac320be_1    conda-forge
mpi                       1.0                     openmpi    conda-forge
mpi4py                    3.0.3            py38h246a051_2    conda-forge
openmpi                   4.0.5                hdf1f1ad_1    conda-forge
  

Есть ли разумный и воспроизводимый способ избежать этой проблемы? Я должен сделать свой код доступным для нескольких сотрудников. На первый взгляд, я бы сказал, что разница заключается в использовании MPICH vs OpenMPI .

Комментарии:

1. что, если вы просто запустите mpirun -np 1 echo 1 из командной строки? а потом mpirun -np 2 echo 1 ?

2. Если я просто выполняю команду вручную, я получаю правильные результаты ‘1’ ‘1 n1’.

Ответ №1:

По крайней мере, с открытым MPI вы не можете использовать forkamp;exec mpirun из программы MPI.

Поскольку вы from mpi4py import MPI , скрипт python выполняется в одноэлементном режиме, и, следовательно, вы не можете Popen(["mpirun", ...)

Удаление mpi4py строки должно устранить вашу проблему.

Комментарии:

1. Да, очевидно, что удаление from mpi4py import MPI решает проблему, но сопряжено с очень большими затратами на поддержание частной вилки очень сложного проекта. Ваш ответ указывает, что действительно важно избегать OpenMPI и вместо этого использовать, например MPICHI .

2. «Сценарий python фактически не использует MPI» было неправильным утверждением, которое некоторые могли бы счесть очевидным, но не сочли нужным его указывать. В любом случае, не читайте неправильно между строк: Open MPI alone здесь вам не подойдет, но не делайте вывод MPICH , что всегда будет работать. Вы можете рассмотреть возможность запуска вашего скрипта на python с mpi4py помощью built поверх Open MPI и вызывать mpirun из MPICH. Или наоборот. Канонический способ решения этой проблемы — использовать MPI_Comm_spawn() вместо forkamp;exec mpirun .