2012-06-24 17 views
8

Używam gcc i OpenMPI. Zazwyczaj uruchomić programy MPI za pomocą mpirun opakowania - npUruchamianie programu OpenMPI bez mpirun

mpirun -np 4 myprogram 

rozpocząć 4 procesy.

Jednak zastanawiałem się, czy można łatwo wygenerować plik binarny, który zrobi to automatycznie (może z niektórymi zakodowanymi opcjami, takimi jak -np 4 powyżej).

wiem, że mogę napisać otoki C, która wywołuje mój program, takich jak:

#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; 
} 

ale ten wydaje się nieco niezdarny i kończy się z dwóch plików wykonywalnych, zamiast jednego.

starałem się wyraźnie odwołuje się bibliotek MPI, jak

gcc -o myprogram -I/usr/lib/openmpi/include/ \ 
    -lmpi -L/usr/lib/openmpi/lib/ myprogram.c 

ale gdy uruchamiam wynikające wykonywalnego, MPI_Comm_size zestawy zera jako wielkości grupy (tak jakbym dał -np 0 jako argument). Czy mogę użyć zmiennej środowiskowej lub czegoś innego do przekazania rozmiaru grupy? Czy istnieje inny sposób na zbudowanie pojedynczego pliku wykonywalnego MPI (używając Linuksa i gcc)?

+0

Można to zrobić, chociaż nie wiem jak z góry mojej głowy. Znam kilka programów, na które natknąłem się na to. Nie ma tam prawdziwej magii, po prostu robi wiele rzeczy za kulisami, które możesz zrobić samemu. –

+0

Czy rozumiem poprawnie - chcesz pominąć 'mpirun' lub chcesz jakoś automatycznie wywołać' mpirun'? –

+0

@Hristo Iliev: Byłoby miło, gdybym miał pojedynczy statyczny plik binarny. – Jay

Odpowiedz

6

Jeśli dostanę go poprawnie, chcesz samodzielne uruchomienie MPI wykonywalny. Jak napisałem w swoim komentarzu, możesz skorzystać ze specjalnej opcji, która sprawia, że ​​Twój kod jest wykonywany pod warunkiem, że jest on dostarczony, np. mpirun, np. -launchmpi. Dzięki Open MPI jest jeszcze łatwiej, ponieważ eksportuje specjalne zmienne środowiskowe do uruchomionych procesów MPI, np. OMPI_COMM_WORLD_RANK. Jeśli ta zmienna istnieje w środowisku, to wiesz, że program został uruchomiony od mpirun, a nie bezpośrednio. Można połączyć obie metody w jednym czeku to:

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; 
} 

Jeśli chcesz kontrolować liczbę procesów w pracy MPI, można dostarczyć go jako dodatkowy arugment, np -launchmpi 12 lub w zmiennej środowiskowej i użyj jej wartości zamiast "4" w powyższym kodzie.

Należy zauważyć, że pliki wykonywalne MPI nie mogą być generalnie uruchamiane bez mpirun. Ta ostatnia jest integralną częścią czasu pracy MPI i ma o wiele więcej niż uruchamianie wielu kopii pliku wykonywalnego MPI. Ponadto zawsze kompilujesz bezpośrednio do biblioteki MPI podczas kompilacji z dowolnym opakowaniem kompilatora MPI (spróbuj mpicc -showme). Chociaż możesz statycznie połączyć biblioteki MPI (niezalecane, zobacz here), nadal będziesz potrzebować mpirun, aby móc wykonywać zadania MPI - AFAIK nie ma możliwości wbudowania funkcji mpirun w twoim programie, przynajmniej nie w Open MPI.

+0

Dzięki za odpowiedź - to naprawdę przydatne! – Jay

1

Można to zrobić za pomocą skryptu 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 "[email protected]" 
+1

Prawie na pewno chcesz '" $ @ "', a nie '$ *', w przeciwnym razie będziesz mieszał args na słowie. –

+0

Dzięki @ChrisDown Poprawiłem swoją odpowiedź. – RSFalcon7

+1

Twoje argumenty będą nadal zniekształcone. Cytaty są ważne. –

Powiązane problemy