12 votes

Exécution du programme OpenMPI sans mpirun

J'utilise gcc y OpenMPI . En général, j'exécute les programmes MPI à l'aide de la fonction mpirun par exemple,

mpirun -np 4 myprogram

pour lancer 4 processus.

Cependant, je me demandais s'il était possible de générer facilement un binaire qui ferait cela automatiquement (peut-être avec quelques options codées en dur comme -np 4 ci-dessus).

Je sais que je peux écrire un wrapper C qui appelle mon programme, tel que le suivant :

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

mais cela semble un peu maladroit et je me retrouve avec deux exécutables au lieu d'un.

J'ai essayé de lier explicitement les bibliothèques MPI, comme par exemple

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

mais lorsque j'exécute l'exécutable qui en résulte, MPI_Comm_size fixe à zéro la taille du groupe (comme si j'avais indiqué -np 0 comme argument). Puis-je utiliser une variable d'environnement ou quelque chose d'autre pour transmettre la taille du groupe ? Ou existe-t-il un autre moyen de construire un programme MPI exécutable en une seule fois (en utilisant Linux et gcc ) ?

12voto

Hristo Iliev Points 29262

Si je comprends bien, vous voulez un exécutable MPI qui se lance tout seul. Comme je l'ai écrit dans mon commentaire, vous pouvez utiliser une option spéciale qui fait que votre code s'exécute. mpirun s'il est fourni, par exemple -launchmpi . Avec Open MPI, c'est encore plus facile puisqu'il exporte des variables d'environnement spéciales pour lancer les processus MPI, par exemple OMPI_COMM_WORLD_RANK . Si cette variable existe dans l'environnement, vous savez que le programme a été lancé à partir de mpirun et non directement. Vous pouvez combiner les deux méthodes en un seul contrôle :

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

Si vous souhaitez contrôler le nombre de processus dans le travail MPI, vous pouvez le fournir en tant qu'argument supplémentaire, par exemple -launchmpi 12 ou dans une variable d'environnement et utiliser sa valeur à la place de "4" dans le code ci-dessus.

Il est à noter que les exécutables MPI ne peuvent généralement pas être lancés sans l'aide de la mpirun . Ce dernier fait partie intégrante du temps d'exécution MPI et il fait bien plus que lancer plusieurs copies de l'exécutable MPI. De plus, vous liez toujours explicitement à la bibliothèque MPI lorsque vous compilez avec l'un des compilateurs MPI (essayez mpicc -showme ). Bien que vous puissiez lier les bibliothèques MPI de manière statique (ce qui n'est pas recommandé, voir aquí ), vous aurez toujours besoin de mpirun afin de pouvoir exécuter des tâches MPI - AFAIK il n'y a pas de moyen d'incorporer le mpirun dans votre programme, du moins pas dans Open MPI.

2voto

RSFalcon7 Points 542

Vous pouvez le faire avec un script de 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 "$@"

0voto

Je ne connais pas MPI, mais la commande MPI peut engendrer des tâches enfants, vous pourriez l'utiliser pour engendrer des tâches à partir de votre application de niveau supérieur.

https://www.open-mpi.org/doc/v4.1/man3/MPI_Comm_spawn.3.php

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X