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