2012-02-22 5 views
6

¿Hay algún problema al acceder/escribir en variables globales al usar el paquete doSNOW en múltiples núcleos?escribiendo a variables globales al usar doSNOW y haciendo la paralelización en R?

En el siguiente programa, cada uno de los MyCalculations (ii) escribe en la columna II-ésima de la matriz "GLOBALVariable" ...

¿Cree que el resultado será correcto? ¿Habrá capturas ocultas?

¡Muchas gracias!

p.s. Tengo que escribir en la variable global porque este es un ejemplo simplificado, de hecho, tengo muchos resultados que deben transportarse desde los bucles paralelos ... por lo tanto, probablemente la única forma es escribir en variables globales. ..

library(doSNOW) 
MaxSearchSpace=44*5 
globalVariable=matrix(0, 10000, MaxSearchSpace) 
cl<-makeCluster(7) 
registerDoSNOW(cl) 
foreach (ii = 2:nMaxSearchSpace, .combine=cbind, .verbose=F) %dopar% 
    { 
    MyCalculations(ii) 
    } 

stopCluster(cl) 

ps Estoy preguntando: dentro del marco de DoSnow, existe el peligro de acceder/escribir variables globales ... thx

+1

Puede considerar el uso de [doRedis] (https://github.com/bwlewis/doRedis) que resolvería su problema con la necesidad de acceder a las variables globales. – daroczig

Respuesta

7

Dado que esta pregunta tiene un par de meses, espero que ya haya encontrado una respuesta. Sin embargo, en caso de que todavía esté interesado en recibir comentarios, hay algo que considerar:

Al usar foreach con un servidor paralelo, no podrá asignar variables en el entorno global de R en la forma en que lo intenta (probablemente habrás notado esto). Utilizando un secuencial backend, la asignación funcionará, pero no utilizando un paralelo como uno con doSNOW.

En su lugar, guarde todos los resultados de sus cálculos para cada iteración en una lista y devuélvalos a un objeto, para que pueda extraer los resultados apropiados después de que se hayan completado todos los cálculos.

Mi sugerencia comienza de manera similar a su ejemplo:

library(doSNOW) 
MaxSearchSpace <- 44*5 
cl <- makeCluster(parallel::detectCores()) 

# do not create the globalVariable object 

registerDoSNOW(cl) 

# Save the results of the `foreach` iterations as 
# lists of lists in an object (`theRes`) 

theRes <- foreach (ii = 2:MaxSearchSpace, .verbose=F) %dopar% 
    { 
# do some calculations 
    theNorms <- rnorm(10000) 
    thePois <- rpois(10000, 2) 
# store the results in a list 
    list(theNorms, thePois) 
    } 

Después de todas las iteraciones se han completado, obtener los resultados de theRes y guardarlas como objetos (por ejemplo, globalVariable, globalVariable2, etc.)

globalVariable1 <- do.call(cbind, lapply(theRes, "[[", 1)) 
globalVariable2 <- do.call(cbind, lapply(theRes, "[[", 2)) 

Teniendo esto en cuenta, si está realizando cálculos con cada iteración que dependen de los resultados de los cálculos de iteraciones anteriores, entonces este tipo de computación paralela no es el apropiado. ach para tomar.