registerDoRNG(seed = NULL, once = TRUE)
registerDoRNG
registers the doRNG foreach backend.
Subsequent %dopar% loops are then performed using the
previously registered foreach backend, but are internally
performed as %dorng%
loops, making them
fully reproducible.
Briefly, the RNG is set, before each iteration, with seeds for L'Ecuyer's CMRG that overall generate a reproducible sequence of statistically independent random streams.
Note that (re-)registering a foreach backend other than
doRNG, after a call to registerDoRNG
disables
doRNG -- which then needs to be registered.
library(doParallel)cl <- makeCluster(2)registerDoParallel(cl)# One can make reproducible loops using the %dorng% operatorr1 <- foreach(i=1:4, .options.RNG=1234) %dorng% { runif(1) }# or convert %dopar% loops using registerDoRNGregisterDoRNG(1234)r2 <- foreach(i=1:4) %dopar% { runif(1) }identical(r1, r2)[1] TRUEstopCluster(cl)# Registering another foreach backend disables doRNGcl <- makeCluster(3)registerDoParallel(cl)set.seed(1234)s1 <- foreach(i=1:4) %dopar% { runif(1) }set.seed(1234)s2 <- foreach(i=1:4) %dopar% { runif(1) }identical(s1, s2)[1] FALSE# doRNG is re-nabled by re-registering itregisterDoRNG()set.seed(1234)r3 <- foreach(i=1:4) %dopar% { runif(1) }identical(r2, r3)[1] TRUE# NB: the results are identical independently of the task scheduling# (r2 used 2 nodes, while r3 used 3 nodes)# argument `once=FALSE` reseeds doRNG's seed at the beginning of each loopregisterDoRNG(1234, once=FALSE)r1 <- foreach(i=1:4) %dopar% { runif(1) }r2 <- foreach(i=1:4) %dopar% { runif(1) }identical(r1, r2)[1] TRUE# Once doRNG is registered the seed can also be passed as an option to %dopar%r1.2 <- foreach(i=1:4, .options.RNG=456) %dopar% { runif(1) }r2.2 <- foreach(i=1:4, .options.RNG=456) %dopar% { runif(1) }identical(r1.2, r2.2) && !identical(r1.2, r1)[1] TRUEstopCluster(cl)
%dorng%