Pour aller plus loin: petite application MPI

Le but ici n'est pas d'apprendre la programmation MPI, mais de se mettre dans la peau d'un utilisateur qui aura besoin de MPI pour son application afin de mieux comprendre ses problèmes. En effet, un utilisateur qui voudra utiliser une application MPI aura besoin de savoir comment lancer celle-ci au travers de SGE.

Hello World

L'application la plus classique quand on démarre un nouveau langage. On va utiliser une version en C. Copiez le contenu suivant en tant que toto dans le fichier helloMPI.c

#include <stdio.h>
#include <mpi.h>

#define MAX_LEN 25

int main(int argc, char **argv) {
        int rank, size;
        FILE *fp;
        char hostnm[MAX_LEN + 1];

        MPI_Init(&argc, &argv);  //initialisation MPI
        MPI_Comm_size(MPI_COMM_WORLD, &size);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        fp = popen("hostname", "r");
        while(fscanf(fp, "%[^\n]", hostnm))
                {
                printf("Hello, world. I am %d of %d. ( %s )\n", rank, size, hostnm);
                }

        pclose(fp);
        MPI_Finalize();  //fin de la communication MPI
        return 0;
}

La compilation de ce code se fait avec mpicc. Afin d'apprendre les aspects fondamentaux de MPI, je vous suggère de lire cet article du très bon site clustermonkey.

mpicc helloMPI.c -o helloMPI

Lancement du job MPI directement sans SGE

Ce qui suit est donné à titre informatif/pédagogique mais c'est à proscrire pour vos utilisateurs. Nous allons tester le job MPI sans passer par SGE.

De manière générale aucun job ne doit être lancé sur le noeud maître et tout doit être exécuté avec qsub. A la limite qrsh ou qlogin peuvent être utilisés pour faire des tests.

Il nous faut d'abord créer un fichier hostsfile (vous pouvez reprendre le fichier hosts.txt pour pssh du début) qui contiendra la liste de nos noeuds. Si vous n'avez qu'un seul noeud, ce n'est pas terrible, surtoût pour un job paralléliser par MPI (...), mais on fera avec (dans ce cas, ne pas mettre la deuxième ligne). Contenu du fichier hostsfile:

compute-0-0
compute-0-4
/opt/openmpi/bin/mpirun -np 25 -machinefile hostsfile /opt/mpi-tests/bin/mpi-ring

Que constatez-vous ?

/opt/openmpi/bin/mpirun -np 2 -machinefile hostsfile /opt/mpi-tests/bin/mpi-ring
/opt/openmpi/bin/mpirun -np 2 -machinefile hostsfile helloMPI

lancement du job MPI avec SGE

En principe, vous n'avez pas à vous préoccuper du fichier machines ou hostsfile dans notre cas. SGE s'en occupe pour vous. C'est par exemple le cas avec l'environnement parallèle mpi qui existe par défaut (la variable $pe_hostfile définit sur quels noeuds et sur combien de coeurs par noeud le job va tourner):

qconf -sp mpi
pe_name            mpi
slots              9999
user_lists         NONE
xuser_lists        NONE
start_proc_args    /opt/gridengine/mpi/startmpi.sh $pe_hostfile
stop_proc_args     /opt/gridengine/mpi/stopmpi.sh
allocation_rule    $fill_up
control_slaves     FALSE
job_is_first_task  TRUE
urgency_slots      min
accounting_summary TRUE

Cependant, en l'état actuel cet environnement parallèle ne fonctionnera pas pour le couple MPI/SGE. Il faut passer control_slaves à TRUE (en root) pour que SGE puisse gérer les noeuds d'exécution MPI !

Vous pouvez avoir la liste des environnements parallèles avec:

qconf -spl

et vérifier que cet environnement est disponible sur la queue voulue avec:

qconf -sq all.q |grep pe_
pe_list               make mpich mpi orte

Pour plus d'informations sur les environnements parallèles SGE: man sge_pe

Il est possible de regénérer un machinefile à partir de $PE_HOSTFILE à l'intérieur du script de soumission:

awk '{print $1}' $PE_HOSTFILE > sgemachines

Toutefois ce n'est pas utile puisque SGE va les gérer pour nous.

$PE_HOSTFILE fait partie des variables prédéfinies à l'intérieur d'un script SGE. Vous avez également $NSLOTS pour le nombre de coeurs alloués, etc...

Script de soumission:

#!/bin/bash
#$ -S /bin/bash
#$ -pe mpi 2
#$ -N hellompi
#$ -cwd

mpirun -np $NSLOTS helloMPI

results matching ""

    No results matching ""