2017-09-12 4 views
0

J'ai essayé pendant un certain temps de paralléliser ce code, en vain. Je reçois des erreurs ou rien ne fonctionne. Quelqu'un a des idées?R - paralléliser ldply et les fonctions répliquées

cal_Ops <- function(n, dtm, ratio = 0.1) { 
    print(n) 
    selVect <- sample(nrow(dtm), nrow(dtm) * ratio) 
    holdout <- dtm[selVect,] 
    training <- dtm[-selVect,] 
    topModel <- LDA(training, n, control = list(estimate.alpha = FALSE)) 
    return(c(n, perplexity(topModel, holdout), as.numeric(logLik(topModel)))) 
} 

require(plyr) 

replication <- 1000 

sequ <-seq(5,100,5) 

perplex <- ldply(sequ, function(x, dtm) { 
    t(replicate(replication, cal_Ops(x, dtm))) } , dtm = DTM_to_use) 

La durée de l'exécution est très longue. Merci d'avance.

J'ai essayé d'utiliser cet exemple comme une version parallèle de répliquées - mais, j'ai eu beaucoup d'erreurs: https://stackoverflow.com/a/19281611/8598566

+0

Dans quelle machine allez-vous? Les fenêtres? Linux/Mac? – CPak

+0

J'effectue des tests sur Windows, mais en fin de compte cela fonctionnera sur un petit cluster HPC exécutant CentOS 6.6 – Max

Répondre

0

Votre exemple n'est pas reproductible, par exemple DTM_to_use ne définit pas, ce qui rend difficile d'aider les autres que « le suivant devraient-travail » suggestion:

La fonction plyr::ldply(x) prend l'argument .parallel = TRUE, qui traitera x en morceaux distribués à tout ce que nombre de travailleurs que vous avez. Cela utilise le cadre foreach en interne pour le traitement parallèle. Avec cela, vous pouvez utiliser l'un des "do" -packages. Voici un exemple d'utilisation future backends:

library("doFuture") 
registerDoFuture() 

## Utilize all cores available to this R session 
plan(multiprocess) 

replication <- 1000 
sequ <-seq(from = 5, to = 100, by = 5) 
perplex <- plyr::ldply(sequ, function(x) { 
    t(replicate(replication, c(a = x, b = sqrt(x)))) 
}, .parallel = TRUE) 

str(perplex) 
'data.frame': 20000 obs. of 2 variables: 
$ a: num 5 5 5 5 5 5 5 5 5 5 ... 
$ b: num 2.24 2.24 2.24 2.24 2.24 ... 

Puisque vous avez mentionné que HPC est votre cible: Si vous avez un groupe ad-hoc sans un planificateur de travail, mais où vous pouvez SSH sur chaque nœud, vous pouvez utiliser:

plan(cluster, workers = c("node1", "node2", "node2", "node3")) 

pour exécuter un noyau sur chaque node1 et node3 et deux noyaux sur node2. Si vous avez un vrai planificateur de tâches, par exemple SGE, vous pouvez utiliser:

library("future.batchtools") 
plan(batchtools_sge) 

et chaque élément sequ sera traité comme un travail individuel sur la file d'attente (ce qui correspond effectivement à avoir un nombre infini de ouvriers). Si vous voulez le réduire, vous pouvez limiter le nombre de travailleurs (= emplois), par ex.

plan(batchtools_sge, workers = 200) 

Votre script aura l'air identique quel que soit le backend utilisé.