Запуск программы OpenMPI без mpirun
Я использую gcc
и openmpi с. Обычно я запускаю программы MPI с помощью mpirun
фантик-например,
mpirun -np 4 myprogram
запуск 4 процессов.
однако мне было интересно, можно ли легко создать двоичный файл, который будет делать это автоматически (возможно, с некоторыми жестко закодированными опциями, такими как -np 4
выше).
Я знаю, что могу написать оболочку C, которая вызывает мою программу, например:
#include <stdlib.h>
#include <unistd.h>
int main() {
char *options[] = { "mpirun", "-np", "4", "myprogram" };
execvp("mpirun", options);
/* Ignoring return value to keep example simple */
return EXIT_SUCCESS;
}
но это кажется немного неуклюжий, и я получаю два исполняемых файла вместо одного.
Я попытался явно связать библиотеки MPI, например
gcc -o myprogram -I/usr/lib/openmpi/include/
-lmpi -L/usr/lib/openmpi/lib/ myprogram.c
но когда я запускаю результирующий исполняемый файл,MPI_Comm_size
устанавливает ноль в качестве размера группы (как если бы я дал -np 0
в качестве аргумента). Могу ли я использовать переменную среды или что-то еще для передачи размера группы? Или есть другой способ создать единственную исполняемую программу MPI (используя Linux и gcc
)?
2 ответов
если я правильно понял, вам нужен исполняемый файл MPI для самостоятельного запуска. Как я написал в своем комментарии, Вы можете пойти со специальной опцией, которая заставляет ваш код выполнять mpirun
если поставить, например,-launchmpi
. С открытым MPI это еще проще, так как он экспортирует специальные переменные среды для запуска процессов MPI, например OMPI_COMM_WORLD_RANK
. Если эта переменная существует в среде, то вы знаете, что программа была запущена из mpirun
и не напрямую. Оба метода можно объединить в одной проверке это:
int main (int argc, char **argv)
{
int perform_launch = 0;
// Scan argv[] for special option like "-launchmpi"
// and set perform_launch if found
if (perform_launch || getenv("OMPI_COMM_WORLD_RANK") == NULL)
{
// #args = argc + 3 ("mpirun -np 4" added) + NULL
// #args should be reduced by one if "-launchmpi" is present
char **args = (char **)calloc(
argc + (perform_launch ? 3 : 4),
sizeof(char *));
args[0] = "mpirun";
args[1] = "-np";
args[2] = "4";
// Copy the entire argv to the rest of args but skip "-launchmpi"
execvp("mpirun", args);
return EXIT_SUCCESS;
}
// Proceed as regular MPI code
MPI_Init(&argc, &argv);
...
// Magic happens here
...
MPI_Finalize();
return EXIT_SUCCESS;
}
если вы хотите контролировать количество процессов в задании MPI, вы можете предоставить его в качестве дополнительного arugment, например -launchmpi 12
, или в переменной среды и использовать его вместо "4"
в коде выше.
обратите внимание, что исполняемые файлы MPI не могут быть запущены без mpirun
. Последний является неотъемлемой частью времени выполнения MPI, и он делает гораздо больше, чем просто запуск нескольких копий исполняемого файла MPI. Также вы всегда связываете явно в библиотеку MPI при компиляции с любой из оболочек компилятора MPI (попробуйте mpicc -showme
). Хотя вы можете связать библиотеки MPI статически (не рекомендуется, см. здесь), вам все равно нужно mpirun
чтобы иметь возможность запускать задания MPI-AFAIK, нет способа встроить mpirun
функциональность в вашей программе, по крайней мере, не в открытом MPI.
вы можете сделать это с помощью bash-скрипт:
# If you change this script has executable (chmod +x script_name) # and if you have the current path in the PATH variable (add export PATH=.:$PATH in your .bashrc) #Then, you can run this has: script_name program_args mpirun -np 4 your_executable_name "$@"