2016-02-09 1 views
0

Cela fonctionne normalement sur mon ordinateur:Code Foreach travaille pour% ne% mais pas pour% dopar%

registerDoSNOW(makeCluster(2, type = "SOCK")) 

foreach(i = 1:M,.combine = "c") %dopar% { 

    sum(rnorm(M)) 
    } 

Je peux donc dire que je peux exécuter du code parallélisé sur cet ordinateur, non?

Ok. J'ai un morceau de code que je souhaite exécuter en parallèle avec foreach. Il fonctionne parfaitement lorsqu'il est écrit avec% do%, mais ne fonctionne pas correctement quand je le change en% dopar%. (PS: Je l'ai déjà initialisé le cluster avec registerDoSNOW(makeCluster(2, type = "SOCK")) de la même manière que précédemment.)

Mon intérêt principal dans le code devient le vecteur u.varpred. Je comprends bien avec% do%, mais quand je le lance avec% dopar%, le vecteur se présente comme une valeur NULL.

Voici la boucle avec le code nécessaire pour l'exécuter correctement. Il utilise les fonctions du package geoR.

#you can pretty much ignore all this, it's just preparation for the loop 
N=20 
NN=10 

set.seed(111); 
datap <- grf(N, cov.pars=c(20, 5),nug=1) 

grid.o <- expand.grid(seq(0, 1, l=100), seq(0, 1, l=100)) 
grid.c <- expand.grid(seq(0, 1, l=NN), seq(0,1, l=NN)) 

beta1=mean(datap$data) 
emv<- likfit(datap, ini=c(10,0.4), nug=1) 
krieging <- krige.conv(datap, loc=grid.o, 
         krige=krige.control(type.krige="SK", trend.d="cte", 
              beta =beta1, cov.pars=emv$cov.pars)) 



names(grid.c) = names(as.data.frame(datap$coords)) 
list.geodatas<-list() 
valores<-c(datap$data,0) 
list.dataframes<-list() 

list.krigings<-list(); i=0; u.varpred=NULL; 

#here is the foreach code 
t<-proc.time() 
foreach(i=1:length(grid.c[,1]), .packages='geoR') %do% { 
    list.dataframes[[i]] <- rbind(datap$coords,grid.c[i,]); 
    list.geodatas[[i]] <- as.geodata(data.frame(cbind(list.dataframes[[i]],valores))) 
    list.krigings[[i]] <- krige.conv(list.geodatas[[i]], loc=grid.o, 
            krige=krige.control(type.krige="SK", trend.d="cte", 
                 beta =beta1, cov.pars=emv$cov.pars)); 
    u.varpred[i] <- mean(krieging$krige.var - list.krigings[[i]]$krige.var) 
    list.dataframes[[i]]<-0 #i dont need those objects anymore but since they 
    # are lists i dont want to put <-NULL as it'll ruin their ordering 
    list.krigings[[i]]<- 0 
    list.geodatas[[i]] <-0 
} 
t<-proc.time()-t 
t 

Vous pouvez vérifier que cela fonctionne bien (à condition que vous avez les packages suivants: Geor, foreach et doSNOW). Mais une fois que j'utilise registerDoSNOW(......) et %dopar%, u.varpred vient comme une valeur NULL.

Pourriez-vous s'il vous plaît essayer de voir si j'ai fait une erreur dans le foreach déclaration/processus ou si c'est juste le code qui ne peut pas être parallèle? (Je pensais que cela pourrait, parce que toute itération donnée ne dépend pas de l'une des itérations avant elle ..)

Je suis désolé à la fois le code et cette question sont si longs. Merci d'avance de prendre le temps de le lire.

Répondre

1

Mon ami m'a aidé directement. Voici une façon dont il fonctionne:

u.varpred <- foreach(i = 1:length(grid.c[,1]), .packages = 'geoR', .combine = "c") %dopar% { 
    list.dataframes[[i]] <- rbind(datap$coords,grid.c[i,]); 
    list.geodatas[[i]] <- as.geodata(data.frame(cbind(list.dataframes[[i]],valores))); 
    list.krigings[[i]] <- krige.conv(list.geodatas[[i]], loc = grid.o, 
         krige = krige.control(type.krige = "SK", trend.d = "cte", 
         beta = beta1, cov.pars = emv$cov.pars)); 
    u.varpred <- mean(krieging$krige.var - list.krigings[[i]]$krige.var); 
    list.dataframes[[i]] <- 0; 
    list.krigings[[i]] <- 0; 
    list.geodatas[[i]] <- 0; 
    u.varpred #this makes the results go into u.varpred 
} 

Il m'a donné un exemple pourquoi cela fonctionne:

a <- NULL 
foreach(i = 1:10) %dopar% { 
    a <- 5 
} 
print(a) 
# a is still NULL 

a <- NULL 
a <- foreach(i = 1:10) %dopar% { 
    a <- 5 
    a 
} 
print(a) 
#now it works 

Hope this helps personne.