Запуск программы 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 "$@"