The doRNG package provides functions to perform reproducible parallel foreach loops, using independent random streams as generated by L'Ecuyer's combined multiple-recursive generator [L'Ecuyer (1999)]. It enables to easily convert standard fully reproducible loops, independently of the number of workers, the task scheduling strategy, or the chosen parallel environment and associated foreach backend. It has been tested with the following foreach backend: doMC, doSNOW, doMPI.
Package: | doRNG |
Type: | Package |
Version: | 1.2.3 |
Date: | 2012-03-30 |
License: | GPL (>= 2) |
LazyLoad: | yes |
L'Ecuyer P (1999). "Good parameters and implementations
for combined multiple recursive random number
generators." _Operations Research_, *47*(1).
# register parallel backend
library(doParallel)
## Loading required package: iterators
## Loading required package: parallel
cl <- makeCluster(2)
registerDoParallel(cl)
## standard %dopar% loop are not reproducible
set.seed(123)
r1 <- foreach(i=1:4) %dopar%{ runif(1) }
set.seed(123)
r2 <- foreach(i=1:4) %dopar%{ runif(1) }
identical(r1, r2)
## [1] FALSE
## %dorng% loops _are_ reproducible
set.seed(123)
r1 <- foreach(i=1:4) %dorng%{ runif(1) }
set.seed(123)
r2 <- foreach(i=1:4) %dorng%{ runif(1) }
identical(r1, r2)
## [1] TRUE
# alternative way of seeding
a1 <- foreach(i=1:4, .options.RNG=123) %dorng%{ runif(1) }
a2 <- foreach(i=1:4, .options.RNG=123) %dorng%{ runif(1) }
identical(a1, a2) && identical(a1, r1)
## [1] TRUE
## sequences of %dorng% loops _are_ reproducible
set.seed(123)
s1 <- foreach(i=1:4) %dorng%{ runif(1) }
s2 <- foreach(i=1:4) %dorng%{ runif(1) }
identical(s1, r1) && !identical(s1, s2)
## [1] TRUE
set.seed(123)
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
## Non-invasive way of converting %dopar% loops into reproducible loops
registerDoRNG(123)
s3 <- foreach(i=1:4) %dopar%{ runif(1) }
s4 <- foreach(i=1:4) %dopar%{ runif(1) }
identical(s3, s1) && identical(s4, s2)
## [1] TRUE
stopCluster(cl)
doRNG
, RNGseq