Some features of the %dorng% foreach operator


  
library(doRNG)
library(doParallel)
registerDoParallel(cores=2)
# single %dorng% loops are reproducible
r1 <- foreach(i=1:4, .options.RNG=1234) %dorng% { runif(1) }
r2 <- foreach(i=1:4, .options.RNG=1234) %dorng% { runif(1) }
identical(r1, r2)
[1] TRUE
# the sequence os RNG seed is stored as an attribute
attr(r1, 'rng')
[[1]] [1] 407 -305383241 69318028 -1161659107 -348804806 -1127582349 -343284712 [[2]] [1] 407 1222430165 -1386318120 1144759979 748500427 690571908 329037778 [[3]] [1] 407 215137210 -1421031558 1452323561 -2060097535 712279522 -278425444 [[4]] [1] 407 -1017432992 1583835527 1997665660 821136125 1282044776 1045008570
# sequences of %dorng% loops are reproducible
set.seed(1234)
s1 <- foreach(i=1:4) %dorng% { runif(1) }
s2 <- foreach(i=1:4) %dorng% { runif(1) }
# two consecutive (unseed) %dorng% loops are not identical
identical(s1, s2)
[1] FALSE
# But the whole sequence of loops is reproducible
set.seed(1234)
s1.2 <- foreach(i=1:4) %dorng% { runif(1) }
s2.2 <- foreach(i=1:4) %dorng% { runif(1) }
identical(s1, s1.2) && identical(s2, s2.2)
[1] TRUE
# it gives the same result as with .options.RNG
identical(r1, s1)
[1] TRUE
# Works with SNOW-like and MPI clusters
# SNOW-like cluster
cl <- makeCluster(2)
registerDoParallel(cl)
s1 <- foreach(i=1:4, .options.RNG=1234) %dorng% { runif(1) }
s2 <- foreach(i=1:4, .options.RNG=1234) %dorng% { runif(1) }
identical(s1, s2)
[1] TRUE
stopCluster(cl)
registerDoSEQ()
# MPI cluster
library(doMPI)
Loading required package: Rmpi
cl <- startMPIcluster(2)
2 slaves are spawned successfully. 0 failed.
registerDoMPI(cl)
s1 <- foreach(i=1:4, .options.RNG=1234) %dorng% { runif(1) }
s2 <- foreach(i=1:4, .options.RNG=1234) %dorng% { runif(1) }
identical(s1, s2)
[1] TRUE
closeCluster(cl)
registerDoSEQ()