web-dev-qa-db-fra.com

"désinscrire" un cluster doParallel

Si j'exécute foreach... %dopar% Sans enregistrer un cluster, foreach déclenche un avertissement et exécute le code séquentiellement:

library("doParallel")
foreach(i=1:3) %dopar%
  sqrt(i)

Rendements:

Warning message:
executing %dopar% sequentially: no parallel backend registered 

Cependant, si j'exécute ce même code après avoir démarré, enregistré et arrêté un cluster, il échoue:

cl <- makeCluster(2)
registerDoParallel(cl)
stopCluster(cl)
rm(cl)
foreach(i=1:3) %dopar%
  sqrt(i)

Rendements:

Error in summary.connection(connection) : invalid connection

Y a-t-il un opposé à registerDoParallel() qui nettoie l'enregistrement du cluster? Ou suis-je coincé avec le fantôme de l'ancien cluster jusqu'à ce que je redémarre ma session R?

/ edit: une recherche sur Google révèle la fonction bumphunter:::foreachCleanup() dans le paquet bumphunter Biocondoctor:

function () 
{
    if (exists(".revoDoParCluster", where = doParallel:::.options)) {
        if (!is.null(doParallel:::.options$.revoDoParCluster)) 
            stopCluster(doParallel:::.options$.revoDoParCluster)
        remove(".revoDoParCluster", envir = doParallel:::.options)
    }
}
<environment: namespace:bumphunter>

Cependant, cette fonction ne semble pas résoudre le problème.

library(bumphunter)
cl <- makeCluster(2)
registerDoParallel(cl)
stopCluster(cl)
rm(cl)
bumphunter:::foreachCleanup()
foreach(i=1:3) %dopar%
  sqrt(i)

Où foreach conserve-t-il les informations sur le cluster enregistré?

32
Zach

La seule façon officielle de "désinscrire" un backend foreach est d'enregistrer le backend séquentiel:

registerDoSEQ()

Cela a du sens pour moi parce que vous êtes censé déclarer quel backend utiliser, donc je ne vois aucun intérêt à fournir un moyen de "ne pas déclarer" quel backend utiliser. Au lieu de cela, vous déclarez que vous souhaitez utiliser le backend séquentiel, qui est la valeur par défaut.

Au départ, j'ai envisagé d'inclure une fonction "annuler l'enregistrement", mais comme je ne pouvais pas me convaincre qu'elle était utile, j'ai décidé de la laisser de côté car il est beaucoup plus facile d'ajouter une fonction que d'en supprimer une.

Cela étant dit, je pense que tout ce que vous devez faire est de supprimer toutes les variables de foreach:::.foreachGlobals où foreach garde tout son état:

unregister <- function() {
  env <- foreach:::.foreachGlobals
  rm(list=ls(name=env), pos=env)
}

Après avoir appelé cette fonction, tout backend parallèle sera désenregistré et l'avertissement sera de nouveau émis si %dopar% est appelé.

47
Steve Weston
    cl <- makeCluster(2)
    registerDoParallel(cl)
    on.exit(stopCluster(cl))

CA marchait bien pour moi.

3
Smit