2012-06-24 2 views
8

Sto usando gcc e OpenMPI. Di solito corro programmi MPI utilizzando l'involucro mpirun - per esempio,Esecuzione del programma OpenMPI senza mpirun

mpirun -np 4 myprogram 

per avviare 4 processi.

Tuttavia, mi chiedevo se è possibile generare facilmente un binario che lo farà automaticamente (magari con alcune opzioni hardcoded come -np 4 sopra).

So che posso scrivere un wrapper C che chiama il mio programma, come il seguente:

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

ma questo sembra un po 'goffo e io alla fine con due file eseguibili invece di uno.

ho cercato di collegare in modo esplicito le librerie MPI, come

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

ma quando corro risultante eseguibile, MPI_Comm_size set zero come la dimensione del gruppo (come se avessi dato -np 0 come argomento). Posso usare una variabile d'ambiente o qualcos'altro per superare la dimensione del gruppo? Oppure esiste un altro modo per creare un programma MPI a esecuzione singola (utilizzando Linux e gcc)?

+0

Si può fare, anche se non so come dalla parte superiore della mia testa. Conosco un paio di programmi in cui mi sono imbattuto. Non c'è vera magia lì dentro, solo un sacco di cose dietro le quinte che puoi anche fare da te. –

+0

Ho capito bene - vuoi saltare 'mpirun' o vuoi in qualche modo chiamare' mpirun'? –

+0

@Hristo Iliev: Sarebbe bello se avessi un singolo binario statico. – Jay

risposta

6

Se ho capito bene, si desidera un auto-lancio MPI eseguibile. Come ho scritto nel mio commento, puoi utilizzare un'opzione speciale che consente al codice di eseguire mpirun se fornito, ad es. -launchmpi. Con Open MPI è ancora più semplice poiché esporta variabili di ambiente speciali per avviare i processi MPI, ad es. OMPI_COMM_WORLD_RANK. Se questa variabile esiste nell'ambiente, allora sai che il programma è stato lanciato da mpirun e non direttamente. È possibile combinare entrambi i metodi in un unico assegno questo:

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

Se si desidera controllare il numero di processi nel lavoro MPI, è possibile fornire come un arugment aggiuntiva, per esempio -launchmpi 12 o in una variabile di ambiente e utilizzare il suo valore anziché "4" nel codice precedente.

Si noti che gli eseguibili MPI non possono essere generalmente avviati senza mpirun. Quest'ultimo è parte integrante del tempo di esecuzione MPI e fa molto di più che solo lanciando più copie dell'eseguibile MPI. Inoltre si collega sempre esplicitamente alla libreria MPI durante la compilazione con uno qualsiasi dei wrapper del compilatore MPI (provare mpicc -showme). Sebbene sia possibile collegare staticamente le librerie MPI (sconsigliato, vedere here), sarà comunque necessario mpirun per poter eseguire i lavori MPI: AFAIK non è possibile incorporare la funzionalità mpirun nel proprio programma, almeno non in Open MPI.

+0

Grazie per la vostra risposta - è davvero utile! – Jay

1

È possibile farlo con uno script 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

Quasi sicuramente vuoi '" $ @ "', non '$ *', altrimenti manterrai argomenti su wordsplitting. –

+0

Grazie a @ChrisDown ho corretto la mia risposta. – RSFalcon7

+1

I tuoi argomenti saranno ancora storpiati. Le virgolette sono importanti. –