Le package snowfall: Calcul parallèle sous R

Auteur.e.s
Kiên Kiêu, Brigitte Schaeffer, Inra
Résumé

snowfall est un paquetage R permettant d’effectuer des calculs en parallèle sur plusieurs (coeurs de) processeurs.

Introduction

snowfall est un paquetage R permettant d’effectuer des calculs en parallèle sur plusieurs (coeurs de) processeurs. Pour utiliser snowfall, il faut commencer par écrire la tâche à paralléliser sous la forme :

monResultat <- lapply(listeDeDonnees, FUN = traitement)

Il s’agit donc d’une forme de parallélisation très simple. On a un traitement identique à appliquer indépendamment, à une série de jeux de données. Pour les cas où les calculs à faire en parallèle doivent communiquer entre eux, il faudra probablement utiliser des outils de plus bas niveau.

Le paquetage snow en est un exemple. Une autre fiche technique sur ce site est dédié au paquetage snow (voir la fiche Le package snow).

Cette fiche est une introduction simplifiée à l’utilisation du paquetage snowfall. Pour poursuivre, vous pouvez lire également la vignette Developing parallel programs using snowfall fournie avec la documentation de snowfall.

Un premier exemple très simple

Pour paralléliser le code ci-dessus, il suffit de l’enrober de quelques appels à des fonctions de snowfall :

library("snowfall")
listeDeDonnees <- list(...)
traitement <- function(x) {
    ...
}
sfInit(parallel = TRUE, cpus = 8, method = "SOCK")
monResultat <- sfApply(listeDeDonnees, fun = traitement)
sfStop()

Souvent, en calcul distribué, les processus ont des rôles. On a un processus maître et des processus esclaves. Dans le code ci-dessus, les 3 premières lignes sont exécutées par le maître. L’appel à la fonction sfInit() crée 8 processus esclaves. Le calcul parallèle proprement dit est effectué à la 5ème ligne avec la fonction sfApply(). Les 8 premiers éléments de listeDeDonnées sont traitées par les 8 esclaves. On passe ensuite aux 8 éléments suivants de listeDeDonnees etc… L’appel à la fonction sfStop() supprime les processus esclaves créés par sfInit().

Des esclaves ignorants

Un esclave est un processus R nu lancé par le maître. Chaque esclave effectue la tâche qui lui a été confiée indépendamment des autres esclaves. Un esclave n’a pas du tout accès à l’environnement du processus maître. Tout ce qu’il connaît c’est l’élément de listeDeDonnees qu’il a à traiter et la fonction (traitement) qu’il doit lui appliquer.

Or la fonction traitement peut avoir besoin de paquetages R et/ou d’accéder à des variables globales pour s’exécuter.

Considérons le code suivant :

library(snowfall)
library(packageA)
maVariableGlobale <- ...
listeDeDonnees <- list(...)
traitement <- function(x) {
    ...
}
sfInit(parallel = TRUE, cpus = 8, method = "SOCK")
monResultat <- sfApply(listeDeDonnees, fun = traitement)
sfStop()

où la fonction traitement utilise des fonctions fournies par le paquetage packageA et accède à la variable globale maVariable. Le code ci-dessus ne s’exécutera pas correctement car packageA n’est chargé que par le maître et la variable maVariable n’est définie que par le maître également. La bonne version est la suivante :

library(snowfall)
maVariableGlobale <- ...
listeDeDonnees <- list(...)
traitement <- function(x) {
    ...
}
sfInit(parallel = TRUE, cpus = 8, method = "SOCK")
sfLibrary(packageA)
sfExport(maVariable)
monResultat <- sfApply(listeDeDonnees, fun = traitement)
sfStop()

La fonction sfLibrary() charge un paquetage chez tous les esclaves, tandis que sfExport() exporte une ou des variables du maître vers tous les esclaves.

Voir aussi:

Le package snow (cf Le package snow)

Versions des outils utilisés
R version 3.4.2 (2017-09-28), snowfall version 1.84-6.1
Thèmes de la fiche
Thèmes