web-dev-qa-db-fra.com

Comment paralléliser en r sur windows - exemple?

Comment faire pour que la parallélisation du code fonctionne dans r dans Windows? Incluez un exemple simple. Publier cette question auto-répondue parce que c'était plutôt désagréable de travailler. Vous constaterez que le package parallèle ne fonctionne PAS seul, mais le package snow fonctionne très bien.

23
Carbon

Publier ceci parce que cela m'a pris à jamais pour comprendre. Voici un exemple simple de parallélisation dans r qui vous permettra de tester si les choses fonctionnent bien pour vous et de vous mettre sur la bonne voie.

library(snow)
z=vector('list',4)
z=1:4
system.time(lapply(z,function(x) Sys.sleep(1)))
cl<-makeCluster(###YOUR NUMBER OF CORES GOES HERE ###,type="SOCK")
system.time(clusterApply(cl, z,function(x) Sys.sleep(1)))
stopCluster(cl)

Vous devez également utiliser la bibliothèque doSNOW pour vous inscrire à chaque groupe de neige, cela entraînera la parallélisation automatique de nombreux packages. La commande à enregistrer est registerDoSNOW(cl) (avec cl étant la valeur de retour de makeCluster()), la commande qui annule l'enregistrement est registerDoSEQ(). N'oubliez pas de désactiver vos clusters.

31
Carbon

Cela a fonctionné pour moi, j'ai utilisé le package doParallel, il fallait 3 lignes de code:

# process in parallel
library(doParallel) 
cl <- makeCluster(detectCores(), type='PSOCK')
registerDoParallel(cl)

# turn parallel processing off and run sequentially again:
registerDoSEQ()

Le calcul d'une forêt aléatoire est passé de 180 à 120 secondes (sur un ordinateur Windows avec 4 cœurs).

12

Sur la base des informations ici J'ai pu convertir le code suivant en une version parallélisée qui fonctionnait sous R Studio sur Windows 7.

Code d'origine:

#
# Basic elbow plot function
#
wssplot <- function(data, nc=20, seed=1234){
    wss <- (nrow(data)-1)*sum(apply(data,2,var))
    for (i in 2:nc){
        set.seed(seed)
        wss[i] <- sum(kmeans(data, centers=i, iter.max=30)$withinss)}
    plot(1:nc, wss, type="b", xlab="Number of clusters", 
       ylab="Within groups sum of squares")
}

Code parallélisé:

library("parallel")

workerFunc <- function(nc) {
  set.seed(1234)
  return(sum(kmeans(my_data_frame, centers=nc, iter.max=30)$withinss)) }

num_cores <- detectCores()
cl <- makeCluster(num_cores)
clusterExport(cl, varlist=c("my_data_frame")) 
values <- 1:20 # this represents the "nc" variable in the wssplot function
system.time(
  result <- parLapply(cl, values, workerFunc) )  # paralel execution, with time wrapper
stopCluster(cl)
plot(values, unlist(result), type="b", xlab="Number of clusters", ylab="Within groups sum of squares")

Ne suggérant pas que c'est parfait ou même meilleur, juste un débutant démontrant que le parallèle semble fonctionner sous Windows. J'espère que cela aide.

4
Mark

Je poste une réponse multiplateforme ici parce que toutes les autres réponses que j'ai trouvées étaient trop compliquées pour ce que j'avais besoin d'accomplir. J'utilise un exemple où je lis dans toutes les feuilles d'un classeur Excel.

# read in the spreadsheet 
parallel_read <- function(file){

    # detect available cores and use 70%
    numCores  = round(parallel::detectCores() * .70)

    # check if os is windows and use parLapply
    if(.Platform$OS.type == "windows") {

        cl <- makePSOCKcluster(numCores)
        parLapply(cl, file, readxl::read_Excel)
        stopCluster(cl)

        return(dfs)

    # if not Windows use mclapply
    } else {

        dfs <-parallel::mclapply(Excel_sheets(file), 
                         readxl::read_Excel, 
                         path = file,
                         mc.cores=numCores)

        return(dfs)

   }
}
0
SummerEla