Generic Reproducible Parallel Backend for foreach Loops

Description

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.

Details

Package: doRNG
Type: Package
Version: 1.2.3
Date: 2012-03-30
License: GPL (>= 2)
LazyLoad: yes

References

L'Ecuyer P (1999). "Good parameters and implementations for combined multiple recursive random number generators." _Operations Research_, *47*(1). .

Examples


## Don't show: 
# roxygen generated flag
options(R_CHECK_RUNNING_EXAMPLES_=TRUE)
## End Don't show

# 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
## Don't show: 
 stopifnot(!identical(r1, r2)) 
## End Don't show

## %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
## Don't show: 
 stopifnot(identical(r1, r2)) 
## End Don't show

# 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
## Don't show: 
 stopifnot(identical(a1, a2) && identical(a1, r1)) 
## End Don't show

## 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
## Don't show: 
 stopifnot(identical(s1, r1) && !identical(s1, s2)) 
## End Don't show

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
## Don't show: 
 stopifnot(identical(s1, s1.2) && identical(s2, s2.2)) 
## End Don't show

## 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
## Don't show: 
 stopifnot(identical(s3, s1) && identical(s4, s2)) 
## End Don't show

stopCluster(cl)

See also

doRNG, RNGseq

Author

Renaud Gaujoux renaud@cbio.uct.ac.za, Maintainer: Renaud Gaujoux renaud@cbio.uct.ac.za,