web-dev-qa-db-fra.com

en utilisant le parLapply de parallèle: impossible d'accéder aux variables dans le code parallèle

J'ai récemment obtenu un ordinateur avec plusieurs cœurs et j'apprends à utiliser l'informatique parallèle. Je suis assez compétent avec lapply et on m'a dit que parLapply fonctionne de manière très similaire. Je ne le fais pas fonctionner correctement cependant. Il semble que je doive tout mettre explicitement à l'intérieur du parLapply pour le faire fonctionner (c'est-à-dire les fonctions à utiliser, les variables etc.). Avec lapply, il lit à partir de l'environnement parent et parLapply ne semble pas faire cela. Donc, dans mon exemple ci-dessous, je pourrais tout faire fonctionner en plaçant toutes les informations dans parLapply mais si j'utilise ceci dans une fonction définie par l'utilisateur, je ne peux pas mettre explicitement text.var à l'intérieur de parLapply.

library(parallel)
text.var <- rep("I like cake and ice cream so much!", 20)
ntv <- length(text.var)
gc.rate <- 10

pos <-  function(i) {
    paste(sapply(strsplit(tolower(i), " "), nchar), collapse=" | ")
}

lapply(seq_len(ntv), function(i) {
        x <- pos(text.var[i])
        if (i%%gc.rate==0) gc()
        return(x)
    }

)

#doesn't work
cl <- makeCluster(mc <- getOption("cl.cores", 4))
parLapply(cl, seq_len(ntv), function(i) {
        x <- pos(text.var[i])
        if (i%%gc.rate==0) gc()
        return(x)
    }

)

#does work but have to specify all the stuff inside parLapply
cl <- makeCluster(mc <- getOption("cl.cores", 4))
parLapply(cl, seq_len(ntv), function(i) {
        ######stuff I have to put inside parLapply##########
        text.var <- rep("I like cake and ice cream so much!", 20)
        ntv <- length(text.var)
        gc.rate <- 10
        pos <-  function(i) {
            paste(sapply(strsplit(tolower(i), " "), nchar), collapse=" | ")
        }
        ######stuff I have to put inside parLapply##########
        x <- pos(text.var[i])
        if (i%%gc.rate==0) gc()
        return(x)
    }
)

Comment puis-je passer text.var, ntv, gc.rate et pos à parLapply sans les mettre explicitement à l'intérieur? (Je suppose que vous les passez en quelque sorte sous forme de liste)

Machine PS Windows 7 donc je dois utiliser parLapply je pense

36
Tyler Rinker

Vous devez exporter ces variables vers les autres processus R du cluster:

cl <- makeCluster(mc <- getOption("cl.cores", 4))
clusterExport(cl=cl, varlist=c("text.var", "ntv", "gc.rate", "pos"))
44
Andy

Une méthode alternative fournie par Martin Morgan fonctionnerait également ici.

Cette méthode fournit les objets à chaque nœud du cluster directement dans l'appel parLapply sans avoir besoin d'utiliser l'exportation de cluster:

library(parallel)
text.var <- rep("I like cake and ice cream so much!", 20)
ntv <- length(text.var)
gc.rate <- 10

pos <-  function(i) {
    paste(sapply(strsplit(tolower(i), " "), nchar), collapse=" | ")
}

cl <- makeCluster(mc <- getOption("cl.cores", 4))
parLapply(cl, seq_len(ntv), function(i, pos, text.var, ntv, gc.rate) {
        x <- pos(text.var[i])
        if (i%%gc.rate==0) gc()
        return(x)
    }, pos, text.var, ntv, gc.rate
)
11
Tyler Rinker