2012-06-24 5 views
8

Я использую gcc и OpenMPI. Обычно я запускать программы MPI с использованием mpirun обертки - например,Запуск программы OpenMPI без 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)?

+0

Это можно сделать, хотя я не знаю, как из-за моей головы. Я знаю пару программ, с которыми я столкнулся, чтобы это сделать. Там нет настоящей магии, это просто куча вещей за кулисами, которые вы также можете сделать сами. –

+0

Правильно ли я понимаю - вы хотите пропустить 'mpirun' или хотите как-то автоматически называть' mpirun'? –

+0

@Hristo Iliev: Было бы неплохо, если бы у меня был один статический бинарный файл. – Jay

ответ

6

Если я его правильно, вы хотите самостоятельно запускать MPI исполняемый файл. Как я написал в своем комментарии, вы можете пойти со специальным вариантом, который заставляет ваш код выполнять mpirun, если он указан, например. -launchmpi. С Open 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 статически (не рекомендуется, см. here), вам все равно понадобится mpirun, чтобы иметь возможность запускать задания MPI. AFAIK не может встроить функции mpirun в вашу программу, по крайней мере, в Open MPI.

+0

Спасибо за ваш ответ - это действительно полезно! – Jay

1

Вы можете сделать это с помощью Баш скрипт:

 
# 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 "[email protected]" 
+1

Вы почти определенно хотите '' $ @ "', а не '$ *', иначе вы будете калечить args на wordplitting. –

+0

Спасибо @ChrisDown Я исправил свой ответ. – RSFalcon7

+1

Ваши аргументы все равно будут искалечены. Важные цитаты. –