[R-es] foreach doParallel

Guillermo@Vi@ue m@ili@g off uv@es Guillermo@Vi@ue m@ili@g off uv@es
Mar Jul 24 11:43:25 CEST 2018


Hola,

Estoy desarrollando un algoritmo para bases de datos grandes. Básicamente es un algoritmo con varias iteraciones en el que comparo el valor de la iteración actual y lo comparo con el de la anterior. Si es menor, lo reemplazo. Si no, no.

He escrito la versión simple con un bucle for y la versión en paralelo usando un bucle foreach paralelizando en varios núcleos para tratar de reducir el tiempo de computación. Lo que pasa es que no obtengo los mismos resultados con ambos algoritmos. Y es que no consigo entender bien cómo actua foreach usando varios núcleos, por lo que quisiera pediros vuestra ayuda.

Un ejemplo sencillo es el siguiente:

En primer lugar, la versión for:
set.seed(10)
vect <- c()
err <- Inf
for (i in 1:3) {
  vect <- c(vect, sample(-10:10, 1))
  if (vect[i] < err) {
    err <- vect[i]
  }
}
vect
#[1] 0 -4 -2
err
#[1] -4
Efectivamente, el error obtenido es el menor valor.

Ahora la versión foreach sin paralelizar (por ello aparece un warning, según se indica en la viñeta de doParallel):
library(foreach)
comb <- function(a, b) { 
  if (a < b) {
    return(a)
  }else{
    return(b)   
  } 
}
set.seed(10)
vect <- c()
err <- Inf
d1 <- foreach(i = 1:3, .combine = "rbind") %dopar% {
  vect <- c(vect, sample(-10:10, 1))
  err <- comb(vect[i], err)
  data.frame(cand = vect[i], err = err)
}
d1 
#  cand err
#1    0   0
#2   -4  -4
#3   -2  -4
De nuevo nos aparece que el error es -4.

Por último, la versión foreach con doParallel, en la que no consigo obtener los mismos resultados:
library(doParallel)
library(doRNG)
no_cores <- detectCores() - 1
no_cores 
#[1] 3
cl <- makeCluster(no_cores)
registerDoParallel(cl)
registerDoRNG(10)
vect <- c()
d1 <- foreach(i = 1:3, .combine = "rbind") %dopar% {
  err <- Inf
  comb <- function(a, b) { 
    if (a < b) {
      return(a)
    }else{
      return(b)   
    } 
  }
  vect <- sample(-10:10, 1)
  err <- comb(vect, err)
  data.frame(cand = vect, err = err)
}
d1
#  cand err
#1   10  10
#2    4   4
#3    6   6
stopCluster(cl)

Parece que cada iteración se ha ido a un núcleo diferente y no se comparan entre sí, sino cada una con el valor inicial Inf. ¿Sabéis cómo conseguir la comparación entre sucesivos valores en el caso del foreach paralelo?

Muchas gracias de antemano.

Saludos,

Guillermo



Más información sobre la lista de distribución R-help-es