Utilisation du serveur de calcul du LSTA

Transcription

Utilisation du serveur de calcul du LSTA
Utilisation du serveur de calcul du LSTA
B. Michel
19 octobre 2012
Ce document contient les informations minimales à connaı̂tre pour utiliser R et Matlab sur le
serveur Mac à 24 coeurs du laboratoire (ou sur une machine personnelle). Toutes les remarques
et tous les commentaires permettant d’améliorer ce document sont les bienvenues !
1
Utilisation du logiciel Matlab au laboratoire
Pour pouvoir bénéficier de Matlab, vous devez contacter B. Michel. Notez qu’il ne s’agit pas
d’une installation Matlab standard, l’installation demande environ une demi-heure de manipulation, merci de ne demander cette installation que si vous en avez réellement besoin. Nous
disposons de :
– 5 licences flottantes Matlab ;
– 5 licences flottantes pour la toolbox Statistics ;
– 5 licences flottantes pour la toolbox Optimization ;
– 5 licences flottantes pour la toolbox Parallel Computing ;
– une licence Matlab Distributed Computing Server (MDCS) pour le serveur.
Vous pouvez télécharger le document pdf du guide complet d’utilisation du MDCS, vous y
trouverez en détail (plus de 700 pages !) les éléments résumés ci-dessous.
1.1
Utilisation de Matlab en local
Une fois Matlab installé sur votre machine, vous pouvez utiliser le logiciel en local (sur votre
machine), la session Matlab s’ouvre par défaut de cette façon. Pensez à fermer votre session
Matlab à la fin de vos calculs pour libérer les jetons de Matlab et ceux des autres toolboxs.
Si votre machine dispose de plusieurs coeurs, vous pouvez utiliser en local les fonctionnalités
de la toolbox Parallel Computing. Dans le code ci-dessous on utilise la boucle parfor pour
distribuer les itérations de la boucle sur plusieurs clusters.
% Ouverture d’un pool de 2 workers en local :
matlabpool open local 2
tic
parfor i=1:100
X = normrnd(0,1,10^6,1);
moy(i) = mean(X);
end
toc
% Fermeture du pool
matlabpool close
% Pour comparaison avec un simple boucle for
tic
1
for i=1:100
X = normrnd(0,1,10^6,1);
moy(i) = mean(X);
end
toc
Attention :
– vous ne pouvez évidemment remplacer une boucle for par une boucle parfor que si les
calculs effectués par une itération sont indépendants les uns des autres,
– il est évidemment inutile d’ouvrir plus de workers que votre machine dispose de coeurs.
1.2
Utilisation de Matlab sur le serveur
Si votre script Matlab n’a pas été écrit de façon à profiter du calcul en parallèle, l’exécution
de celui-ci sur le serveur ne mobilisera qu’un seul worker ; au finale le temps de calcul ne sera pas
moins long que sur votre machine personnelle. Il n’est pertinent d’utiliser Matlab sur le serveur
que :
– si votre code permet de distribuer les calculs sur plusieurs workers du serveur et diminuer
ainsi le temps de calcul ;
– si vous avez plusieurs procédures Matlab (indépendantes) à effectuer ;
– si vos calculs prennent du temps en local et vous empêchent de travailler pendant ce temps
sur votre machine.
L’utilisation de Matlab sur le serveur est un peu plus délicate car c’est un planificateur
( scheduler ou job manager ) qui va gérer la répartition des calculs sur les workers
disponibles. Une fois les calculs soumis au planificateur, il est alors possible de quitter la session
Matlab et on libère par la même occasion une licence Matlab.
Figure 1 – Schéma de fonctionnement de MDCS.
Le principe de fonctionnement s’appuie sur la manipulation de jobs Matlab que l’on
soumet au planificateur. Un job est composé de plusieurs tâches qui seront distribuées entre les
workers. Les workers disponibles effectuent les tâches de façon simultanée et sans communiquer
entre eux, dans le vocabulaire Matlab il s’agit de travaux distribués (distributed jobs, c.f. le
chap. 8 du manuel MDCS). Les tâches sont définies grâce à des fonctions. On soumet ensuite
le job au planificateur et les calculs sont effectués par les workers du serveur en respectant la
file d’attente des jobs soumis dans le planificateur (voir la figure 1). Le premier exemple cidessous est minimaliste pour comprendre le principe de fonctionnement du système, il utilise
des fonctions handle :
2
% Identification du planificateur du serveur LSTA :
planif = findResource(’scheduler’,’type’,’jobmanager’,’Name’,’serveurlsta’,
’LookupURL’,’serveurlsta’)
% Création d’un job :
Bertjob1 = createJob(planif)
% Création de t^
aches dans le Job :
Tache1 = createTask(Bertjob1, @rand, 1, {10,2});
Tache2 = createTask(Bertjob1, @sum, 1, {1:1000});
% Soumission au planificateur du job Bertjob1 :
submit(Bertjob1)
% Récupération des résultats sous la forme d’une cellule :
resultats1 = getAllOutputArguments(Bertjob1)
Le premier argument de CreateTask renseigne le nom du job auquel est attaché cette tâche, le
deuxième argument indique le nom de la fonction handle que l’on souhaite calculer, le troisième
argument donne le nombre d’arguments renvoyés par la fonction handle : ici un seul argument
dans les deux cas car on obtient une matrice 10 × 2 pourTache1 et un scalaire pour Tache2.
Le dernier argument de CreateTask correspond une cellule contenant tous les arguments de la
fonction handle. Consultez l’aide de Matlab pour une description plus complète de l’utilisation
des fonctions Jobs, createTask, etc.
Vous pouvez aussi sélectionner directement une configuration de ressources pré-enregistrée
depuis le menu Parallel, Selection Configuration de la barre d’outils de Matlab. Après avoir
sélectionné la configuration que vous désirez utiliser on l’active ensuite à l’aide de la commande
planif = findResource()
Nous donnons maintenant un exemple de code plus complet que vous pourrez utiliser comme
modèle pour vos propres calculs. Dans l’exemple suivant, la fonction fmoy est définie dans le
script fmoy.m, celle-ci calcule la moyenne de n variables aléatoires gaussiennes indépendantes
centrées en µ et de variance σ 2 .
function moy = fmoy(mu,sigma,n)
moy = mean( normrnd(mu,sigma,n));
Le code suivant permet de répartir 10 calculs de fmoy sur les workers du serveur :
% Identification du planificateur du serveur LSTA :
planif = findResource(’scheduler’,’type’,’jobmanager’,’Name’,’serveurlsta’,
’LookupURL’,’serveurlsta’)
% Creation d’un job de t^
aches pour le planificateur planif :
Bertjob2 = createJob(planif);
% Pour donner l’adresse de la fonction fmoy :
set(Bertjob2,’FileDependencies’,{’/Users/bertrand/MATLAB/fmoy.m’})
3
% Réglage des nombres maximal et minimal de workers à utiliser :
set(Bertjob2 , ’MaximumNumberOfWorkers’, 6,’MinimumNumberOfWorkers’, 1);
% Création d’une cellule répétant dans des cellules distinctes les arguments
% pour fmoy :
for i=1:10
A{i} = {0,1,50};
end
% A = { {0,1,50}, {0,1,50}, {0,1,50}, ... ,{0,1,50}} (répété 10 fois)
% Création d’une nouvelle t^
ache : chaque cellule de A correspond à évaluation
% de fmoy pour les paramètres donnés dans la cellule :
Tache =createTask(Bertjob2 , ’fmoy’, 1, A);
% Soumission du job :
submit(Bertjob2);
% Récupération des résultats sous la forme d’une cellule :
resultats2 = getAllOutputArguments(Bertjob2)
% Pour transformer la cellule en vecteur :
resultatsvec = cell2mat(resultats2);
% Exploitation des résultats :
boxplot(resultats)
Dans ce code, on limite volontairement le nombre de workers à utiliser pour ne pas mobiliser
toutes les ressources. En fonction de l’état de la file d’attente et de la durée de vos calculs, vous
choisirez raisonnablement le nombre de workers. Pour afficher les jobs déjà soumis et en attente
sur le planificateur utilisez la commande suivante :
% Pour voir tous les jobs déposés sur le planificateur :
findJob(planif)
Chaque job associé au planificateur est dans l’un des états suivants :
– pending : le job a été crée mais il n’a pas encore été soumis,
– queued : le job a été soumis mais il est en attente de traitement car tous les workers sont
déjà occupés,
– running : le job est en cours de traitement,
– finished : le job est terminé.
Pour finir, nous donnons quelques commandes supplémentaires dont vous aurez certainement
besoin. Avant de soumettre un job dans le planificateur, il est recommandé de le tester en local.
Pour cela, on utilisera le planificateur local qui s’identifie de la façon suivante :
MonPlanifLocal = findResource(’scheduler’,’type’,’local’);
Pour attendre que le job soit fini avant de continuer d’autres calculs, par exemple si les calculs à
suivre dépendent des résultats du job soumis (ne pas abuser de cette fonction car vous bloquez
des ressources pendant ce temps) :
waitForState(Bertjob2);
4
Pour effacer du planificateur un job en cours ou terminé :
destroy(Bertjob2);
Si votre code s’appuie sur de nombreux scripts .m, plutôt que de lister toutes les fonctions .m
dans le champ ’FileDependencies’ (cf l’exemple Bertjob2 ci-dessus), vous pouvez aussi indiquer
le chemin d’un (ou plusieurs) répertoires qui contiennent tous les fichiers .m que vous voulez
utiliser :
set(Bertjob2,’FileDependencies’,{’/Users/bertrand/MATLAB/MonDossier’})
Si vous avez fermé votre session et que vous relancez Matlab plus tard pour récupérer les résultats
de vos calculs, les jobs que vous avez crées dans le planificateur ne sont pas connus pour cette
nouvelle session. Voici comment vous pourrez récupérer vos résultats :
% Identification du planificateur du serveur LSTA (si vous l’avez sélectionné
% dans le menu Parallel) :
planif = findResource()
% Pour voir tous les jobs déposés sur le planificateur et conna^
ıtre leur état
findJob(planif)
% Si votre job est terminé, identifiez-le à l’aide de son ID (ici 125):
MonJobFini = findJob(planif,’ID’,125)
% Récupérez vos résultats :
Mesresultats = getAllOutputArguments(MonJobFini)
2
Utilisation du logiciel R sur le serveur
Comme pour Matlab, il n’est pertinent d’utiliser R sur le serveur que
– si les calculs que vous souhaitez effectuer prennent du temps et limitent pendant ce temps
les performances de votre machine,
– si vous avez plusieurs procédures R (indépendantes) à effectuer
– et / ou si vos calculs peuvent être parallélisés et que vous souhaitez utiliser plusieurs
coeurs du serveur pour diminuer le temps de calcul.
Notez bien que si votre script R n’est pas écrit de façon à permettre des calculs en parallèle,
l’exécution se déroulera sur un seul coeur et ne sera probablement pas plus rapide que sur votre
machine personnelle.
Pour utiliser R sur le serveur, vous devez disposer d’un compte (login et pass) sur cette
machine. Si ce n’est pas le cas, contactez B. Michel. On se connecte tout d’abord au serveur par
une connexion ssh :
– Depuis une machine Mac ou Linux : ouvrir un terminal (pour une machine Mac : Application puis Utilitaires) puis créer une connexion ssh vers le serveur comme suit :
ssh 134.157.52.120 -l monlogin
pass : monpass
– Windows ne possède pas de client ssh en natif, il faut donc en installer un : voir par exemple
http://www.commentcamarche.net/faq/80-se-logguer-a-distance-avec-ssh-windows.
Connectez-vous ensuite au serveur en ssh en utilisant l’IP donné ci-dessus, votre login et
votre mot de passe.
5
On lance ensuite R depuis le terminal et on travaille en lignes de commande. Attention, ce
mode de fonctionnement ne permet pas d’afficher des graphiques, l’exploitation visuelle de
vos procédures R n’est donc possible qu’en local (utilisez votre explorateur pour rapatrier vos
fichiers de résultats, ou utiliser les commandes ssh).
Si vous fermez la connexion ssh (en éteignant votre machine par exemple), votre procédure
R sera aussitôt fermée sur le serveur et vous perdrez vos résultats. Si vos calculs prennent
plusieurs heures, voire plusieurs jours, lancez un script R en tâche de fond sur le serveur grâce
à la commande :
nohup R CMD BATCH ./MonScript.R &
Les affichages éventuellement demandés par le script sont écrits dans le fichier MonScript.Rout.
Pour savoir si le protocole R est terminé ou non, ou pourra par exemple utiliser dans le terminal
la commande : ps -c.
Calculs en parallèle avec R : la library snowfall
La librairie snowfall de R permet d’effectuer des calculs en parallèle en distribuant les tâches
entre plusieurs coeurs, cette librairie est disponible sur le serveur. Son utilisation est relativement
simple car la syntaxe de la fonction sfLapply est identique à la fonction usuelle lapply. Voici
un exemple de script que l’on pourra utiliser comme modèle élémentaire :
# Chargement du package snowfall :
library(snowfall)
# Nombre de coeurs utilisés (ici 4) :
sfInit(parallel=TRUE, cpus=4)
X <- rnorm(100000,0,1)
grille <- seq(-10,10,0.01)
# Fonction de répartition empirique de la loi de X calculée au point x :
cdf.emp <- function(x){
return( mean(X < x) )
}
# Chargement des objets R nécessaires pour que chaque coeur puisse effectuer
# les calculs. Ici on charge tout l’environnement de la session R en cours :
sfExport(list = ls())
# Calcul de la fonction cdf.emp aux points de grille. Les calculs sont
# distribués sur 4 coeurs :
y <- sfLapply(grille,cdf.emp)
# Arr^
et des coeurs lancés :
sfStop()
Remarques importantes :
– N’oubliez pas de libérer les coeurs à la fin de vos calculs avec la commande sfStop().
– Pour le moment, aucun planificateur de tâches général n’a été installé sur le serveur pour
gérer la fil d’attente des protocoles R soumis au serveur (et d’autres applications que
Matlab). Il est donc essentiel que les utilisateurs n’accaparent pas toutes les ressources du
serveur en mobilisant un grand nombres de coeurs pour leurs calculs personnels. Utiliser
par exemple la commande unix ps aux -c pour afficher dans une console tous les processus
en cours.
6