Introduction
Dans cet exemple, on veut calculer des temps-fréquence pour 3 sujets, dans 2 conditions. Pour celà, nous utilisons le programme temps-frequence qui prend 2 paramètres en entrée: un fichier de données et un nom de marker qui identifie une condition dans le fichier de données. Nous avons donc 3 x 2 = 6 calculs à faire que l'on peut lancer avec l'un des deux scripts suivants (sujet1 désigne le fichier de données du premier sujet et marker1 identifie la première condition):
#! /bin/bash temps-frequence sujet1 marker1 >& sujet1_marker1.log temps-frequence sujet1 marker2 >& sujet1_marker2.log temps-frequence sujet2 marker1 >& sujet2_marker1.log temps-frequence sujet2 marker2 >& sujet2_marker2.log temps-frequence sujet3 marker1 >& sujet3_marker1.log temps-frequence sujet3 marker2 >& sujet3_marker2.log
#! /bin/bash for sujet in "sujet1 sujet2 sujet3" do for marker in "marker1 marker2" do temps-frequence $sujet $marker >& sujet${sujet}_${marker}.log done done
Les calculs étant complètement indépendants les uns des autres (sujets/markers), on va profiter des noeuds du cluster pour répartir les calculs.
Prérequis pour utiliser le cluster de l'ICM
Il faut posséder un compte ICM (voir avec votre correspondant informatique) puis demander à Romain de créer un compte sur le cluster de l'ICM.
Toutes les données utilisées par les calculs (les fichiers de données de chaque sujet) doivent être copiées sur votre compte (rsync).
Les programmes utilisés (temps-frequence) doivent être accessibles depuis votre compte: soit ils sont déjà installés pour les plus utilisés (matlab), soit vous pouvez demander une installation (spm), soit vous devez les copier vous-même sur votre compte (temps-frequence).
Par la suite, on considére que l'on se trouve dans un répertoire qui contient les fichiers de données sujet1, sujet2, sujet3 et un répertoire vide cluster_jobs destiné à contenir tous les scripts permettant de lancer les calculs sur le cluster et les fichiers créés par le cluster contenant des informations sur le déroulement des calculs.
Principes
Le but est d'envoyer tous les calculs au cluster qui se charge ensuite de répartir l'exécution des calculs sur ses différents noeuds.
Chaque calcul est envoyé au cluster avec la commande suivante:
qsub -l //options_de_cluster// -o //fichier_de_log// -e //fichier_d_erreur// //fichier_de_calcul//
qsub -l nodes=1:ppn=4 -o cluster_jobs/sujet1_marker1_cluster.log -e cluster_jobs/sujet1_marker1_cluster.err cluster_jobs/sujet1_marker1.bash
nodes=1:ppn=4 est une liste d'options transmises au scheduler du cluster: paramétrage du nombre de noeuds (nodes=1) et de processeurs par noeuds (ppn=4) demandés au cluster pour faire le calcul).
cluster_jobs/sujet1_marker1_cluster.log est un fichier créé par le cluster contenant des infos sur les ressources utilisées par le calcul:
############################### # EPILOGUE : RESSOURCES # ############################### Ressources demandees (hh:mm:ss): 10000:00:00 Ressources utilisees (hh:mm:ss): 00:05:07
cluster_jobs/sujet1_marker1_cluster.err est un fichier créé par le cluster qui est vide si le calcul s'est bien déroulé au niveau du cluster. Il faut toujours vérifier sa taille pour détecter d'éventuelles erreurs survenues au niveau de la gestion du calcul par le cluster (dépassement du temps maximum autorisé pour le calcul).
cluster_jobs/sujet1_marker1.bash contient la commande de calcul à effectuer:
#! /bin/bash temps-frequence sujet1 marker1 >& cluster_jobs/sujet1_marker1.bash.log
Tous les calculs peuvent être adressés au cluster en une seule fois et regroupés dans submit_cluster.bash:
#! /bin/bash qsub -l nodes=1:ppn=4 -o cluster_jobs/sujet1_marker1_cluster.log -e cluster_jobs/sujet1_marker1_cluster.err cluster_jobs/sujet1_marker1.bash sleep 1 qsub -l nodes=1:ppn=4 -o cluster_jobs/sujet1_marker2_cluster.log -e cluster_jobs/sujet1_marker2_cluster.err cluster_jobs/sujet1_marker2.bash sleep 1 qsub -l nodes=1:ppn=4 -o cluster_jobs/sujet2_marker1_cluster.log -e cluster_jobs/sujet2_marker1_cluster.err cluster_jobs/sujet2_marker1.bash sleep 1 qsub -l nodes=1:ppn=4 -o cluster_jobs/sujet2_marker2_cluster.log -e cluster_jobs/sujet2_marker2_cluster.err cluster_jobs/sujet2_marker2.bash sleep 1 qsub -l nodes=1:ppn=4 -o cluster_jobs/sujet3_marker1_cluster.log -e cluster_jobs/sujet3_marker1_cluster.err cluster_jobs/sujet3_marker1.bash sleep 1 qsub -l nodes=1:ppn=4 -o cluster_jobs/sujet3_marker2_cluster.log -e cluster_jobs/sujet3_marker2_cluster.err cluster_jobs/sujet3_marker2.bash sleep 1
Note: La création des scripts submit_cluster.bash et cluster_jobs/sujet1_marker1.bash, cluster_jobs/sujet1_marker2.bash, cluster_jobs/sujet2_marker1.bash, cluster_jobs/sujet2_marker2.bash, cluster_jobs/sujet3_marker1.bash et cluster_jobs/sujet3_marker2.bash peut être automatisée avec le script :create_submit_cluster.py|
.
Exécuter le script submit_cluster.bash pour envoyer la liste des calculs au cluster: la liste des identifiants associant chaque calcul à un job sur le cluster est affichée.
Le cluster répartit ensuite les jobs sur ses noeuds/processeurs, en fonction des ressources disponibles.
Contrôles
Pour consulter l'état des jobs sur le cluster (en train de tourner sur un noeud, en attente, ...), utiliser la commande:
qstat -a -n -1
Un job est terminé quand il disparaît de la liste.
Pour vérifier que tous les jobs ont bien été effectués par le cluster, il faut vérifier que les fichiers d'erreur sont vides: :list_non_empty_files.py|
cluster_jobs/*cluster.err
La liste des fichiers d'erreur non vides correspondant aux jobs en erreur sur le cluster est affichée.
On peut aussi classer les jobs par vitesse d'exécution en utilisant les fichiers de log du cluster: :sort_cluster_log.py|
cluster_jobs/*cluster.log
Les jobs et leur vitesse d'exécution sont affichés par ordre croissant:
[lemarechal@blade4 ]$ sort_cluster_log.py cluster_jobs/*cluster.log sujet1_marker2_cluster.log : 00:02:27 sujet2_marker1_cluster.log : 00:02:46 sujet2_marker2_cluster.log : 00:03:28 sujet1_marker1_cluster.log : 00:03:32 sujet3_marker2_cluster.log : 00:05:07 sujet3_marker1_cluster.log : 00:05:24
Stratégies de répartitions
Plusieurs stratégies de répartitions sont possibles.
Si le programme temps-frequence est capable d'utiliser plusieurs processeurs en parallèle, on peut lancer un calcul sur un noeud du cluster = 1 job en l'autorisant à utiliser plusieurs processeurs du noeud (par exemple, pour allouer 4 proc: ppn=4). Sinon, il faut lui interdire d'utiliser plusieurs processeurs (ppn=1) pour éviter de réserver inutilement des ressources processeurs sur ce noeud.
Regles de bonne conduite
Le cluster est une ressource PARTAGEE: vous devez faire en sorte de ne pas monopoliser les ressources.
Pour essayer de partager "equitablement" les ressources entre utilisateurs, des priorites sont attribuees aux jobs en attente en fonction de l historique recent de chaque utilisateur associe. Plus vous avez utilise de ressources cluster recemment et moins vos jobs seront prioritaires.
Attention, ce systeme de priorite n est pas suffisant pour l instant. Si a un moment donne, le cluster est completement libre, rien ne vous empechera de lancer des calculs sur tous les noeuds et en utilisant tous les processeurs (comme vous etes le seul utilisateur, les priorites n auront aucun role). Si chaque calcul dure plusieurs jours (plusieurs semaines?), c est le cluster entier qui est monopolise pendant plusieurs jours (plusieurs semaines) !!!
Avant de lancer de gros calculs, verifier bien les parametres, ...
Il est plus efficace de lancer un seul calcul, de verifier que ca s est bien passe, d avoir une idee du temps de calcul avant de lancer les 99 suivants!!!
Il est tres important de pouvoir etre capable d estimer le temps de chaque calcul.
Il est tres important de savoir exactement comment va se faire la repartition.