blob: 990655b1f3d3debf4440589269f83a68ba75ee4d [file] [log] [blame]
# File src/library/parallel/R/RngStream.R
# Part of the R package, https://www.R-project.org
#
# Copyright (C) 1995-2017 The R Core Team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of the GNU General Public License is available at
# https://www.R-project.org/Licenses/
nextRNGStream <- function(seed)
{
if(!is.integer(seed) || seed[1L] %% 100L != 7L)
stop(gettextf("invalid value of %s", "'seed'"), domain = NA)
.Call(C_nextStream, seed)
}
nextRNGSubStream <- function(seed)
{
if(!is.integer(seed) || seed[1L] %% 100L != 7L)
stop(gettextf("invalid value of %s", "'seed'"), domain = NA)
.Call(C_nextSubStream, seed)
}
## Different from snow's RNG code
clusterSetRNGStream <- function(cl = NULL, iseed = NULL)
{
cl <- defaultCluster(cl)
oldseed <-
if (exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE))
get(".Random.seed", envir = .GlobalEnv, inherits = FALSE)
else NULL
RNGkind("L'Ecuyer-CMRG")
if(!is.null(iseed)) set.seed(iseed)
nc <- length(cl)
seeds <- vector("list", nc)
seeds[[1L]] <- .Random.seed
for(i in seq_len(nc-1L)) seeds[[i+1L]] <- nextRNGStream(seeds[[i]])
## Reset the random seed in the master.
if(!is.null(oldseed))
assign(".Random.seed", oldseed, envir = .GlobalEnv)
else rm(.Random.seed, envir = .GlobalEnv)
for (i in seq_along(cl)) {
expr <- substitute(assign(".Random.seed", seed, envir = .GlobalEnv),
list(seed = seeds[[i]]))
sendCall(cl[[i]], eval, list(expr))
}
checkForRemoteErrors(lapply(cl, recvResult))
invisible()
}
RNGenv <- new.env()
mc.reset.stream <- function() {
if (RNGkind()[1L] == "L'Ecuyer-CMRG") {
if (!exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE))
sample.int(1L)
assign("LEcuyer.seed",
get(".Random.seed", envir = .GlobalEnv, inherits = FALSE),
envir = RNGenv)
}
}
## For use in the master before forking
mc.advance.stream <- function(reset = FALSE)
{
if (RNGkind()[1L] == "L'Ecuyer-CMRG") {
if (reset ||
!exists("LEcuyer.seed", envir = RNGenv, inherits = FALSE)) {
if (!exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE))
sample.int(1L)
assign("LEcuyer.seed",
get(".Random.seed", envir = .GlobalEnv, inherits = FALSE),
envir = RNGenv)
} else {
assign("LEcuyer.seed",
nextRNGStream(get("LEcuyer.seed", envir = RNGenv)),
envir = RNGenv)
}
}
}
## For use in the child
mc.set.stream <- function()
{
if (RNGkind()[1L] == "L'Ecuyer-CMRG") {
assign(".Random.seed", get("LEcuyer.seed", envir = RNGenv),
envir = .GlobalEnv)
} else {
## It is random to simply unset the seed
if (exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE))
rm(".Random.seed", envir = .GlobalEnv, inherits = FALSE)
}
}