2016-05-09 9 views
1

Ich versuche, zwei 3D-Arrays mit paralleler Berechnung in R zu verarbeiten. Ich habe eine Funktion, die zwei Vektoren als Eingabe nimmt, also muss ich die Zeilen und Spalten meiner Arrays durchlaufen. Dies in seriellem Code zu tun ist einfach zu langsam und R bleibt stecken, da die Arrays groß sind.R paralleler Code für zwei Arrays

Ich habe keine Lösung gefunden, dies mit parallelen Funktionen zu tun, und würde mich über Vorschläge freuen. Ich habe versucht, parApply, aber nicht wissen, wie eine zweite Eingabe und mcmapply zu integrieren, aber es ist schwierig, über Zeilen/Spalten zu verwenden. Idealerweise sollte die Ausgabe auch ein Array derselben Dimension sein.

Unten ist ein reproduzierbares Beispiel für das, was ich in seriellem Code versuche. Jede Hilfe, wie dies parallel geschrieben werden könnte, wäre sehr willkommen!

fun <- function(a,b) 
{ 
    a*b 
} 

input1 <- array(data=1:1000, dim=c(10,10,10)) 
input2 <- array(data=2:1001, dim=c(10,10,10)) 

result <- array(data=NA, dim=c(10,10,10)) 

for(i in 1:nrow(mat1)) 
{ for(j in 1:ncol(mat1)) { 
    result[,i,j] <- fun(input1[,i,j], input2[,i,j]) 
}} 
+0

Da die parallele Verarbeitung in R ein sehr heikles (das heißt nicht lösbares) Toppic ist, sollten Sie sich die [foreach vignette] ansehen (https://cran.r-project.org/web/packages/foreach/ Vignetten/foreach.pdf). Dann können Sie wahrscheinlich einen ersten Entwurf erstellen und ihn zu der Frage hinzufügen. Ein weiterer Tipp könnte die [verschachtelte foreach loop vignette] sein (https://cran.r-project.org/web/packages/foreach/vignettes/nested.pdf). – loki

+0

Kleiner Vorschlag bezüglich Ihres Seriencodes: Versuchen Sie, die Reihenfolge Ihrer Schleifen umzukehren, da R Spaltenspalte ist. – Gabe

Antwort

0

Hier ist ein Weg, um es mit dem foreach-Paket zu tun:

library(doSNOW) 
library(abind) 
cl <- makeSOCKcluster(parallel::detectCores()) 
registerDoSNOW(cl) 

fun <- function(a,b) a*b 
input1 <- array(rnorm(60), dim=c(4,5,3)) 
input2 <- array(rnorm(60), dim=c(4,5,3)) 
rdim <- dim(input1)[1:2] 
comb <- function(...) abind(..., along=3) 
result <- 
    foreach(i1=iapply(input1, 3), i2=iapply(input2, 3), 
      .multicombine=TRUE, .combine='comb') %dopar% { 
    r <- array(data=NA, dim=rdim) 
    for (i in 1:ncol(i1)) { 
     r[,i] <- fun(i1[,i], i2[,i]) 
    } 
    r 
    } 

Die „iapply“ -Funktion aus dem Paket Iteratoren verwendet wird, um die 3D-Eingabefelder in 2D-Matrizen zu spalten. Die Ergebnismatrizen werden mit der Funktion "abind" aus dem abind-Paket zu einem 3D-Array zusammengefasst.

Beachten Sie, dass ich speziell das Parallel-Backend "doSNOW" verwende, da es Daten von den beiden "iapply" -Iteratoren an die Worker sendet und die Ergebnisse während des Betriebs verarbeitet. Dies reduziert den Speicherbedarf des Master-Prozesses. Das Back-End "doParallel" kann nicht direkt arbeiten, da das Paket "parallel" die notwendigen Funktionen nicht exportiert.