Différences entre versions de « Snow »

 
(41 versions intermédiaires par 4 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
 
Le package '''snow''' (Simple Network Of Workstations) offre la possibilité d'exécuter du code [[R|R]] en parallèle sur plusieurs ordinateurs. Les calculs statistiques lourds peuvent ainsi être accélérés de manière significative.
 
Le package '''snow''' (Simple Network Of Workstations) offre la possibilité d'exécuter du code [[R|R]] en parallèle sur plusieurs ordinateurs. Les calculs statistiques lourds peuvent ainsi être accélérés de manière significative.
 +
__TOC__
  
 +
=== Configuration ===
 +
{|
 +
|rowspan="1"|[[Image:Attention.png|40px]]
 +
|
 +
Avant d'entreprendre des simulations numériques sur les machines du Département, vous êtes encouragé à consulter la page [[Simulations|Simulations]], en particulier la section traitant des [[Simulations#Consignes_à_respecter|consignes à respecter]].
 +
|}
  
__TOC__
+
Ci-dessous, vous trouverez les instructions pour la configuration initiale de <tt>snow</tt> pour votre compte au DMS.
  
=== Lancer le script «snowdms» au DMS ===
+
* Tapez
* Ouvrez un terminal de [[Commandes_élémentaires|commandes]].
 
* Tapez  
 
 
<pre>
 
<pre>
 
makeKey.sh
 
makeKey.sh
 
</pre>
 
</pre>
dans le terminal. La ligne précédente est pour empêcher le SSH de vous demander votre mot de passe à chaque fois que vous tentez de vous connecter à d'autres machines du réseau.
+
dans un terminal de [[Commandes_élémentaires|commandes]]. La ligne précédente exécute le script <tt>makeKey.sh</tt> qui configure le système [[La_commande_ssh|<tt>ssh</tt>]] afin que vous puissiez vous brancher à d'autres machines du Département sans qu'on vous demande votre mot de passe.
 
 
* Si la question suivante apparaît, répondez par «y»&nbsp;:
 
  
 +
* Si la question
 
<pre>
 
<pre>
 
Generating public/private rsa key pair.
 
Generating public/private rsa key pair.
Ligne 19 : Ligne 23 :
 
Overwrite (y/n)?  
 
Overwrite (y/n)?  
 
</pre>
 
</pre>
 +
apparaît, répondez par &laquo;&nbsp;y&nbsp;&raquo;.
  
* Faites juste «Enter» lorsque vous voyez&nbsp;:
+
* Appuyez sur <tt>Entrée</tt> (''Enter'') lorsque vous apercevez les messages
 
 
 
<pre>
 
<pre>
 
Enter passphrase (empty for no passphrase):  
 
Enter passphrase (empty for no passphrase):  
 +
</pre>
 +
et
 +
<pre>
 +
Enter same passphrase again:
 
</pre>
 
</pre>
  
* De nouveau faites juste «Enter» lorsque vous voyez&nbsp;:
+
Pour démarrer [[R|R]] dans un terminal, tapez
 
+
<pre>
 +
R
 +
</pre>
 +
pour la version non-graphique (ligne de commandes), ou encore
 
<pre>
 
<pre>
Enter same passphrase again:
+
xR
 
</pre>
 
</pre>
 +
pour la version à interface graphique.
  
Pour démarrer la version 3.0 de R (qui inclut le package <tt>snow</tt>), entrez
+
*Installation de snow sur votre compte DMS : À la première utilisation, snow n'est probablement pas intallé. Pour vérifier, appelez dans [[R|R]]
 
<pre>
 
<pre>
/usr/local/stat/R/R-3.0.0/bin/R
+
require(snow)
 
</pre>
 
</pre>
dans un terminal. Ceci lance R en mode ligne de commandes. Pour la version &laquo;&nbsp;graphique&nbsp;&raquo;, entrez plutôt
+
et si snow n'est pas installé, un message d'erreur s'affichera
 
<pre>
 
<pre>
/usr/local/stat/R/R-3.0.0/lib64/R/library/JGR/scripts/run
+
Le chargement a nécessité le package : snow
 +
Warning message:
 +
In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE,  :
 +
  aucun package nommé ‘snow’ n'est trouvé
 
</pre>
 
</pre>
 +
Vous pouvez aussi appeler <code>library()</code> et parcourir la liste pour voir si snow s'y trouve.
 +
 +
L'installation se fait en appelant
 +
<pre>
 +
install.packages("snow")
 +
</pre>
 +
Ensuite [[R|R]] vous demandera si vous voulez installer snow dans une librairie personnelle et s'il peut l'installer dans un certain répertoire (probablement dans <code>/home/usager/R/x86_64-pc-linux-gnu-library</code> ). Répondez oui aux deux questions. Vous devrez par la suite choisir un miroir CRAN; prenez-en un près d'où vous êtes (probablement USA (NY)). L'installation devrait se terminer après quelques instants. Vous pouvez maintenant appeler snow par <code>require(snow)</code>.
  
 
=== Exemple ===
 
=== Exemple ===
Dans l'exemple suivant, on fait des calculs de deux manières. La première fois, on lance les calculs sur la machine qu'on se trouve présentement; par la suite on fait la même chose sur plusieurs CPUs (ex. nbcpus <- 10, 15, 20 ou 80).  Une fois dans R, tapez les commandes suivantes&nbsp;:
+
L'exemple qui suit a pour but de montrer comment utiliser les fonctions du package <tt>snow</tt> afin de lancer des calculs en parallèle. Les calculs sont d'abord effectués localement, c'est-à-dire sur la machine de l'utilisateur, puis effectués par plusieurs ordinateurs (''cluster'').
 +
 
 +
Pour tester l'exemple par vous-même, &laquo;&nbsp;copiez-collez&nbsp;&raquo; les commandes suivantes dans [[R|R]]&nbsp;:
  
 
<pre>
 
<pre>
 
require(snow)
 
require(snow)
 +
 +
# La fonction myfunc définie ci-dessous exécute en boucle de courts calculs. Il est
 +
# important de noter que les itérations de la boucle sont indépendantes les unes des
 +
# autres : c'est ce qui permet la parallélisation.
  
 
myfunc <- function(M=1000) {
 
myfunc <- function(M=1000) {
Ligne 56 : Ligne 84 :
 
}
 
}
  
 +
# Ci-dessous, on chronomètre le temps d'exécution de la fonction "myfunc".
  
 
system.time({
 
system.time({
Ligne 63 : Ligne 92 :
 
})
 
})
  
# Temps de calcul: 814s
+
# Temps d'exécution : 814 s (~ 14 min.).
# Comme on constate ici, avec un seul CPU le processus prend 814s c.-à-d. environ 14 minutes
+
 
 +
# Les calculs sont maintenant divisés sur plusieurs ordinateurs (10 dans cet exemple).
 +
# Avant de lancer les calculs, le script "snowdms.sh" est appelé afin de dresser une
 +
# liste de machines à utiliser pour les calculs.
  
 
nbcpus <- 10
 
nbcpus <- 10
 
cpus <- strsplit(system(paste("snowdms.sh ",nbcpus),intern=TRUE),split=" ")[[1]]
 
cpus <- strsplit(system(paste("snowdms.sh ",nbcpus),intern=TRUE),split=" ")[[1]]
write(cpus, file="~/cpus.csv", 10, append=TRUE, "\t")      # La liste des machines choisies est enregistrée dans "cpus.csv".
 
  
 +
  # La liste des machines (cpus) est enregistrée dans "cpus.csv".
 +
write(cpus, file="~/cpus.csv", 10, append=TRUE, "\t") 
 
system.time({
 
system.time({
   cl <- makeCluster(cpus, type = "SOCK") #Fonctions pour démarrer un cluster de Snow.
+
  # Fonction pour démarrer un "cluster" snow.
   clusterSetupSPRNG(cl)         #Initialisation de flux de nombres aléatoires uniformes indépendantes pour un cluster de Snow
+
   cl <- makeCluster(cpus, type = "SOCK")
 +
  # Initialisation d'un flux de nombres aléatoires pour le cluster.            
 +
   clusterSetupSPRNG(cl)                                
 
   M <- 6000000                   
 
   M <- 6000000                   
   out <- clusterCall(cl, myfunc, round(M/nbcpus)) #Fonctions pour le calcul sur un cluster de Snow
+
 
   stopCluster(cl)               #Fonctions pour arrêter un cluster de Snow.
+
  # La fonction "myfunc" est appelée sur chaque machine de la liste, avec
 +
  # round(M/nbcpus) comme argument. "out[[i]]" contient les résultats
 +
   out <- clusterCall(cl, myfunc, round(M/nbcpus))      
 +
  # obtenus par la i-ème machine.                                                       
 +
 
 +
  # Arrêt du cluster.
 +
   stopCluster(cl)                                      
 
   decision <- 0
 
   decision <- 0
 
   for (cpus in 1:nbcpus) {
 
   for (cpus in 1:nbcpus) {
Ligne 83 : Ligne 124 :
 
})
 
})
  
# Avec nbcpus <- 10: 111s
+
# Quelques temps obtenus selon le nb de cpus
# Avec nbcpus <- 15: 84s
+
 
# Avec nbcpus <- 20: 70s
+
# nbcpus <- 10 : 111 s
# Avec nbcpus <- 80: 58s
+
# nbcpus <- 15 : 84 s
# On voit ici qu'au fur et à mesure qu'on augmente le nombre de CPUs le processus va plus vite.  
+
# nbcpus <- 20 : 70 s
 +
# nbcpus <- 80 : 58 s
 +
 
 +
# Les calculs s'effectuent plus rapidement avec un grand nombre de machines.
 
</pre>
 
</pre>
  
'''Remarques&nbsp;:'''
+
==== Remarques ====
* Des messages tels que&nbsp;:
+
 
 +
* Des messages tels que
 
<pre>
 
<pre>
 
The authenticity of host 'leopard (132.204.53.53)' can't be established.
 
The authenticity of host 'leopard (132.204.53.53)' can't be established.
Ligne 97 : Ligne 142 :
 
Are you sure you want to continue connecting (yes/no)?
 
Are you sure you want to continue connecting (yes/no)?
 
</pre>
 
</pre>
peuvent apparaître. Il faut alors répondre par «yes». Ces messages n'apparaîtont qu'une seule fois (pour une machine donnée).
+
apparaissent lors d'une première connexion à une machine. Répondez par &laquo;&nbsp;yes&nbsp;&raquo; pour mémoriser la clé d'identification de la machine.
  
* La liste des machines choisies par le script <tt>snowdms.sh</tt> est enregistrée dans un fichier dans le compte de l'usager (<tt>~/cpus.csv</tt>). Ainsi, si vous avez démarrées des simulations par erreur, vous savez sur quelles machines vous brancher (par [[La_commande_ssh|<tt>ssh</tt>]]) afin de tuer vos simulations (commande [[Commandes_élémentaires#kill|<tt>kill</tt>]]).
+
* La liste des machines choisies par le script <tt>snowdms.sh</tt> est enregistrée dans un fichier dans le compte de l'usager (<tt>~/cpus.csv</tt>). Ainsi, si vous avez démarrées des simulations par erreur, vous savez sur quelles machines vous brancher (par [[La_commande_ssh|<tt>ssh</tt>]]) afin de stopper ces simulations (commande [[Commandes_élémentaires#kill|<tt>kill</tt>]]).
  
* La fonction <tt>clusterCall</tt> ne permet pas de faire varier l'argument passé à la fonction, c'est-à-dire que chaque machine de la liste exécutera la ''même fonction'' avec le ''même argument''. Cependant, d'autres fonctions, comme <tt>clusterApply</tt> par exemple, offrent cette possibilité. Pour plus de détails, consultez le [http://cran.r-project.org/web/packages/snow/snow.pdf manuel du package].
+
* La fonction <tt>clusterCall</tt> ne permet pas de faire varier l'argument passé à la fonction&nbsp;: chaque machine de la liste exécutera la ''même fonction'' avec le ''même argument''. D'autres fonctions, comme <tt>clusterApply</tt> par exemple, offrent la possibilité de varier l'argument. Pour plus de détails, consultez le [http://cran.r-project.org/web/packages/snow/snow.pdf manuel du package].
  
== Nombre de CPUs ==
+
* Lorsque le package snow est utilisé pour paralléliser une fonction sur <tt>n</tt> CPUs, il faut imaginer que <tt>n</tt> nouvelles sessions de R indépendantes sont ainsi démarrées. Il est donc nécessaire d'inclure la définition de ''toutes'' les fonctions à employer à l'intérieur de la fonction parallélisée. Ceci est aussi vrai pour les packages qu'il convient de relancer avec <tt>library()</tt> (ou encore <tt>require()</tt>). Finalement, une situation similaire se produit pour le répertoire actif (''working directory''), puisque celui par défaut sera utilisé pour chaque nouvelle session. Dans le doute, utilisez les chemins complets.
Le rendement en terme du temps de calcul dépend du type de processus que vous allez lancer sur les machines. On voit dans l'exemple que plus on utilise de CPUs, plus vite iront les calculs. Mais il faut faire attention puisque, tout dépendamment du type de calculs à réaliser, le gain risque de changer. Il ne faut pas oublier que l'envoi des calculs sur plusieurs CPUs prend du temps, alors il faut que votre processus vaille le coup d'être envoyer sur plusieurs CPUs (c.-à-d. votre programme est bien parallélisable). Sinon, c'est mieux de lancer un programme qui est pas trop grand sur une seule machine.  
 
  
'''Exemple de tous les jours&nbsp;:''' Disons qu'on veut écrire une lettre de deux lignes. À la place de l'écrire, vous vous déplacer 3 étages du Pavillon André-Aisenstadt pour aller voir votre ami au troisième étage pour lui demander de l'aide. Pendant ce temps-là vous auriez pu avoir déjà écrit votre lettre de deux lignes. Mais, par exemple si vous avez une lettre de 20 page à écrire, en ce moment-là cela vaut la peine de se déplacer trois étages pour allez demander de l'aide à son ami.    
+
<!--* Lorsqu'on lance le package '''snow''', par exemple sur 4 CPUs,  on peut imaginer qu'on a en fait lancé 4 nouvelles sessions de R sur 4 machines différentes. Il faut donc tout inclure(réinitialiser). C'est-à-dire, si la fonction qui est parallélisée appelle («''call''») une autre fonction qui a été définie auparavant il faut qu'elle soit définie à l’intérieure de la fonction principale! (en d'autre mot il faut la sourcer). C'est ainsi pour les «''packages''» où il faut les relancer avec library() ( ou require() ). Aussi, il ne faut pas oublier que c'est la même situation pour le «''working directory''».-->
 +
=== Nombre de CPUs ===
 +
Le rendement en terme de temps de calcul dépend du type de processus que vous lancez sur les machines.  
  
=== Générer des nombres aléatoires ===
+
Dans l'exemple ci-haut, on observe que plus on utilise de CPUs, plus vite s'effectuent les calculs. Mais il faut faire attention puisque, d'un calcul à l'autre, le gain risque de changer. En d'autres termes, les calculs ne sont pas toujours facilement parallélisables.
  
Les générateurs des nombres aléatoires par défaut sont susceptibles d'être très corrélés. Par exemple&nbsp;:
+
Il ne faut pas oublier que l'envoi de calculs sur plusieurs machines prend du temps (communication / transfert), donc il faut préalablement vous assurer que l'effort en vaille la chandelle&nbsp;: effectuez quelques tests d'abord avant de démarrer vos calculs lourds. Parfois, il est préférable de lancer un programme qui n'est pas trop lourd sur une seule machine.
 +
 
 +
==== Exemple de tous les jours ====
 +
Disons qu'on veut écrire une lettre de deux lignes. À la place de l'écrire, vous vous déplacer 3 étages du Pavillon André-Aisenstadt pour aller voir votre ami au troisième étage pour lui demander de l'aide. Pendant ce temps-là vous auriez pu avoir déjà écrit votre lettre de deux lignes. Mais, par exemple si vous avez une lettre de 20 page à écrire, en ce moment-là cela vaut la peine de se déplacer trois étages pour allez demander de l'aide à son ami.   
 +
 
 +
=== Génération de nombres aléatoires ===
 +
Lorsque vous générez des nombres aléatoires pour plusieurs machines, vous devez vous assurez que chaque machine emploie une suite de nombres différente, sans quoi les résultats de toutes les machines seront identiques.
 +
 
 +
Pour ce faire, vous pourriez être tentés de procéder comme suit&nbsp;:
 
<pre>
 
<pre>
> clusterCall(cl, runif, 3)
+
# Génération de trois nombres aléatoires avec "runif".
 +
 
 +
clusterCall(cl, runif, 3)
 +
 
 
[[1]]
 
[[1]]
 
[1] 0.08496597 0.35232298 0.60300751
 
[1] 0.08496597 0.35232298 0.60300751
Ligne 118 : Ligne 175 :
 
[[2]]
 
[[2]]
 
[1] 0.08496597 0.35232298 0.60300751
 
[1] 0.08496597 0.35232298 0.60300751
 +
</pre>
  
# Génération de trois nombres aléatoires avec «runif»
+
Mais, comme on l'aperçoit, la suite générée est identique sur toutes les machines (ici <tt>cl</tt> est configuré pour 2 machines).
</pre>
 
  
Une façon rapide (mais pas propre) d'aborder ce problème est de faire&nbsp;:
+
Pour régler ce problème, la démarche à suivre est d'utiliser la fonction <tt>clusterSetupSPRNG</tt> prévue à cet effet, comme dans [[Snow#Exemple|l'exemple]] ci-haut. Avec cette fonction, les suites générées par les machines sont différentes&nbsp;:
 
<pre>
 
<pre>
clusterApply(cl, runif(length(cl),max=10000000), set.seed)
+
# Génération de trois nombres aléatoires avec "runif" et "clusterSetupSPRNG".
</pre>
 
 
 
Une meilleure démarche est d'utiliser un «package» générateur de nombre aléatoire parallèle; comme l'exemple explicatif ci-haut.  
 
  
Un petit exemple&nbsp;:
+
clusterSetupSPRNG(cl)
 +
clusterCall(cl, runif, 3)
  
<pre>
 
> clusterSetupRNG(cl)
 
> clusterCall(cl, runif, 3)
 
 
[[1]]
 
[[1]]
 
[1] 0.749391854 0.007316102 0.152742874
 
[1] 0.749391854 0.007316102 0.152742874
Ligne 139 : Ligne 191 :
 
[[2]]
 
[[2]]
 
[1] 0.8424790 0.8896625 0.2256776
 
[1] 0.8424790 0.8896625 0.2256776
 
# Ici clusterSetupRNG(cl), initialise le flux de nombres aléatoires uniformes indépendantes pour un cluster de snow. 
 
 
</pre>
 
</pre>
Pour la source de cette section et plus de détails consulter les références externes ci-dessous.  
+
Pour plus de détails, consultez les [[Snow#Références_externes|références externes]] ci-dessous.  
  
 
== Voir aussi ==
 
== Voir aussi ==
  
 
=== Articles connexes ===
 
=== Articles connexes ===
 
+
<div class="inline">
 
* [[Simulations|Simulations]]
 
* [[Simulations|Simulations]]
 
* [[R|R]]
 
* [[R|R]]
 
* [[Logiciels|Logiciels au Département]]
 
* [[Logiciels|Logiciels au Département]]
 +
</div>
  
 
=== Références externes ===
 
=== Références externes ===
 +
<div class="inline">
 
* http://cran.r-project.org/web/packages/snow/snow.pdf
 
* http://cran.r-project.org/web/packages/snow/snow.pdf
 
* http://homepage.stat.uiowa.edu/~luke/R/cluster/cluster.html
 
* http://homepage.stat.uiowa.edu/~luke/R/cluster/cluster.html
 
* http://www.sfu.ca/~sblay/R/snow.html
 
* http://www.sfu.ca/~sblay/R/snow.html
 +
</div>

Version actuelle datée du 3 décembre 2020 à 20:54

Le package snow (Simple Network Of Workstations) offre la possibilité d'exécuter du code R en parallèle sur plusieurs ordinateurs. Les calculs statistiques lourds peuvent ainsi être accélérés de manière significative.

Configuration

Attention.png

Avant d'entreprendre des simulations numériques sur les machines du Département, vous êtes encouragé à consulter la page Simulations, en particulier la section traitant des consignes à respecter.

Ci-dessous, vous trouverez les instructions pour la configuration initiale de snow pour votre compte au DMS.

  • Tapez
makeKey.sh

dans un terminal de commandes. La ligne précédente exécute le script makeKey.sh qui configure le système ssh afin que vous puissiez vous brancher à d'autres machines du Département sans qu'on vous demande votre mot de passe.

  • Si la question
Generating public/private rsa key pair.
/home/bayani/.ssh/id_rsa already exists.
Overwrite (y/n)? 

apparaît, répondez par « y ».

  • Appuyez sur Entrée (Enter) lorsque vous apercevez les messages
Enter passphrase (empty for no passphrase): 

et

Enter same passphrase again:

Pour démarrer R dans un terminal, tapez

R 

pour la version non-graphique (ligne de commandes), ou encore

xR

pour la version à interface graphique.

  • Installation de snow sur votre compte DMS : À la première utilisation, snow n'est probablement pas intallé. Pour vérifier, appelez dans R
require(snow)

et si snow n'est pas installé, un message d'erreur s'affichera

Le chargement a nécessité le package : snow
Warning message:
In library(package, lib.loc = lib.loc, character.only = TRUE, logical.return = TRUE,  :
  aucun package nommé ‘snow’ n'est trouvé

Vous pouvez aussi appeler library() et parcourir la liste pour voir si snow s'y trouve.

L'installation se fait en appelant

install.packages("snow")

Ensuite R vous demandera si vous voulez installer snow dans une librairie personnelle et s'il peut l'installer dans un certain répertoire (probablement dans /home/usager/R/x86_64-pc-linux-gnu-library ). Répondez oui aux deux questions. Vous devrez par la suite choisir un miroir CRAN; prenez-en un près d'où vous êtes (probablement USA (NY)). L'installation devrait se terminer après quelques instants. Vous pouvez maintenant appeler snow par require(snow).

Exemple

L'exemple qui suit a pour but de montrer comment utiliser les fonctions du package snow afin de lancer des calculs en parallèle. Les calculs sont d'abord effectués localement, c'est-à-dire sur la machine de l'utilisateur, puis effectués par plusieurs ordinateurs (cluster).

Pour tester l'exemple par vous-même, « copiez-collez » les commandes suivantes dans R :

require(snow)

# La fonction myfunc définie ci-dessous exécute en boucle de courts calculs. Il est 
# important de noter que les itérations de la boucle sont indépendantes les unes des 
# autres : c'est ce qui permet la parallélisation.

myfunc <- function(M=1000) {
  decision <- 0
  for (i in 1:M) {
    x <- rnorm(100)
    if (shapiro.test(x)$p < 0.05) decision <- decision + 1
  }
  return(decision)
}

# Ci-dessous, on chronomètre le temps d'exécution de la fonction "myfunc".

system.time({
  M <- 6000000
  decision <- myfunc(M)
  print(decision/M)
})

# Temps d'exécution : 814 s (~ 14 min.).

# Les calculs sont maintenant divisés sur plusieurs ordinateurs (10 dans cet exemple).
# Avant de lancer les calculs, le script "snowdms.sh" est appelé afin de dresser une 
# liste de machines à utiliser pour les calculs.

nbcpus <- 10
cpus <- strsplit(system(paste("snowdms.sh ",nbcpus),intern=TRUE),split=" ")[[1]]

  # La liste des machines (cpus) est enregistrée dans "cpus.csv".
write(cpus, file="~/cpus.csv", 10, append=TRUE, "\t")   
system.time({
  # Fonction pour démarrer un "cluster" snow.
  cl <- makeCluster(cpus, type = "SOCK")  
  # Initialisation d'un flux de nombres aléatoires pour le cluster.              
  clusterSetupSPRNG(cl)                                 
  M <- 6000000                   

  # La fonction "myfunc" est appelée sur chaque machine de la liste, avec 
  # round(M/nbcpus) comme argument. "out[[i]]" contient les résultats
  out <- clusterCall(cl, myfunc, round(M/nbcpus))       
  # obtenus par la i-ème machine.                                                        

  # Arrêt du cluster.
  stopCluster(cl)                                       
  decision <- 0
  for (cpus in 1:nbcpus) {
    decision <- decision + out[[cpus]]
  }
  print(decision/(round(M/nbcpus)*nbcpus))
})

# Quelques temps obtenus selon le nb de cpus

# nbcpus <- 10 : 111 s
# nbcpus <- 15 : 84 s
# nbcpus <- 20 : 70 s
# nbcpus <- 80 : 58 s

# Les calculs s'effectuent plus rapidement avec un grand nombre de machines.

Remarques

  • Des messages tels que
The authenticity of host 'leopard (132.204.53.53)' can't be established.
RSA key fingerprint is a6:a3:80:c8:52:22:d8:de:be:5a:d8:f4:04:cf:2c:01.
Are you sure you want to continue connecting (yes/no)?

apparaissent lors d'une première connexion à une machine. Répondez par « yes » pour mémoriser la clé d'identification de la machine.

  • La liste des machines choisies par le script snowdms.sh est enregistrée dans un fichier dans le compte de l'usager (~/cpus.csv). Ainsi, si vous avez démarrées des simulations par erreur, vous savez sur quelles machines vous brancher (par ssh) afin de stopper ces simulations (commande kill).
  • La fonction clusterCall ne permet pas de faire varier l'argument passé à la fonction : chaque machine de la liste exécutera la même fonction avec le même argument. D'autres fonctions, comme clusterApply par exemple, offrent la possibilité de varier l'argument. Pour plus de détails, consultez le manuel du package.
  • Lorsque le package snow est utilisé pour paralléliser une fonction sur n CPUs, il faut imaginer que n nouvelles sessions de R indépendantes sont ainsi démarrées. Il est donc nécessaire d'inclure la définition de toutes les fonctions à employer à l'intérieur de la fonction parallélisée. Ceci est aussi vrai pour les packages qu'il convient de relancer avec library() (ou encore require()). Finalement, une situation similaire se produit pour le répertoire actif (working directory), puisque celui par défaut sera utilisé pour chaque nouvelle session. Dans le doute, utilisez les chemins complets.

Nombre de CPUs

Le rendement en terme de temps de calcul dépend du type de processus que vous lancez sur les machines.

Dans l'exemple ci-haut, on observe que plus on utilise de CPUs, plus vite s'effectuent les calculs. Mais il faut faire attention puisque, d'un calcul à l'autre, le gain risque de changer. En d'autres termes, les calculs ne sont pas toujours facilement parallélisables.

Il ne faut pas oublier que l'envoi de calculs sur plusieurs machines prend du temps (communication / transfert), donc il faut préalablement vous assurer que l'effort en vaille la chandelle : effectuez quelques tests d'abord avant de démarrer vos calculs lourds. Parfois, il est préférable de lancer un programme qui n'est pas trop lourd sur une seule machine.

Exemple de tous les jours

Disons qu'on veut écrire une lettre de deux lignes. À la place de l'écrire, vous vous déplacer 3 étages du Pavillon André-Aisenstadt pour aller voir votre ami au troisième étage pour lui demander de l'aide. Pendant ce temps-là vous auriez pu avoir déjà écrit votre lettre de deux lignes. Mais, par exemple si vous avez une lettre de 20 page à écrire, en ce moment-là cela vaut la peine de se déplacer trois étages pour allez demander de l'aide à son ami.

Génération de nombres aléatoires

Lorsque vous générez des nombres aléatoires pour plusieurs machines, vous devez vous assurez que chaque machine emploie une suite de nombres différente, sans quoi les résultats de toutes les machines seront identiques.

Pour ce faire, vous pourriez être tentés de procéder comme suit :

# Génération de trois nombres aléatoires avec "runif".

clusterCall(cl, runif, 3)

[[1]]
[1] 0.08496597 0.35232298 0.60300751

[[2]]
[1] 0.08496597 0.35232298 0.60300751

Mais, comme on l'aperçoit, la suite générée est identique sur toutes les machines (ici cl est configuré pour 2 machines).

Pour régler ce problème, la démarche à suivre est d'utiliser la fonction clusterSetupSPRNG prévue à cet effet, comme dans l'exemple ci-haut. Avec cette fonction, les suites générées par les machines sont différentes :

# Génération de trois nombres aléatoires avec "runif" et "clusterSetupSPRNG".

clusterSetupSPRNG(cl)
clusterCall(cl, runif, 3)

[[1]]
[1] 0.749391854 0.007316102 0.152742874

[[2]]
[1] 0.8424790 0.8896625 0.2256776

Pour plus de détails, consultez les références externes ci-dessous.

Voir aussi

Articles connexes

Références externes


La dernière modification de cette page a été faite le 3 décembre 2020 à 20:54.