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