I updated to the latest CRAN versions of 'rlecuyer', 'Rmpi', and 'snow':
,----[ sessionInfo() ]
| ...
| other attached packages:
| [1] rlecuyer_0.3-3 Rmpi_0.6-1 snow_0.3-10
| ...
`----
But I still obtain:
,----
| Error in .lec.SetPackageSeed(seed) :
| Seed[1] >= -1065242851, Seed is not set.
`----
when executing
,----
| library(snow)
| RNGkind("L'Ecuyer-CMRG")
| cl <- makeCluster(parallel::detectCores(), type="MPI")
| .t <- snow::clusterSetupRNG(cl, seed=.Random.seed[2:7])
| stopCluster(cl)
`----
How to construct a valid seed for l'Ecuyer's method with given .Random.seed?
5 messages · Marius Hofert, Hana Sevcikova, Daniel Nordlund
Since clusterSetupRNG() calls clusterSetupRNGstream() and this calls .lec.SetPackageSeed(), I could further minimalize the problem:
set.seed(1)
RNGkind("L'Ecuyer-CMRG") # => .Random.seed is of length 7 (first number encodes the rng kind)
(seed <- .Random.seed[2:7]) # should give a valid seed for l'Ecuyer's RNG
require(rlecuyer) # latest version 0.3-3
.lec.SetPackageSeed(seed)
The last line fails with:
,----
| Error in .lec.SetPackageSeed(seed) :
| Seed[0] >= -767742437, Seed is not set.
`----
Looking at .lec.SetPackageSeed, "seed" seems to pass .lec.CheckSeed() [the check
could probably be improved here (but further checking is done in the C code; see
below)]:
,----
| > .lec.SetPackageSeed
| function (seed = rep(12345, 6))
| {
| if (!exists(".lec.Random.seed.table", envir = .GlobalEnv))
| .lec.init()
| seed <- .lec.CheckSeed(seed) # => bad check since it's passed
| .Call("r_set_package_seed", as.double(seed), PACKAGE = "rlecuyer") # => this fails!
| return(seed)
| }
| <environment: namespace:rlecuyer>
`----
Going into the C code, r_set_package_seed calls RngStream_SetPackageSeed which in turn calls CheckSeed(seed). The relevant part of CheckSeed is this:
,----
| for (i = 0; i < 3; ++i) {
| if (seed[i] >= m1) {
| /* HS 01-25-2012 */
| error("Seed[%1d] >= %d, Seed is not set.\n", i,m1);
| /* original code
| fprintf (stderr, "****************************************\n"
| "ERROR: Seed[%1d] >= m1, Seed is not set.\n"
| "****************************************\n\n", i);
| return (-1);
| */
| }
| }
`----
Note that seed[0] in this (C-)code corresponds to the first element of my
variable "seed", which is -1535484873. This should definitely be smaller than m1
since m1 is defined as 4294967087.0 on line 34 in ./src/RngStream.c of the package 'rlecuyer'.
Why is seed[i] then >= m1??? This is strange. Indeed, as you can see from the
error message above, m1 is taken as -767742437 in my case (why?). Still (and even more
confusing), -1535484873 >= -767742437 is FALSE (!) but the if(){} is entered
anyways...
Cheers,
Marius
Marius, I looked it up in the original L'Ecuyer's paper: The seed must be larger than 0. Thus, the function defines the seed variable as unsigned long integer. You're passing a negative number, so I think there is some overflow going on. The internal L'Ecuyer RNG is a modification of the original one (and I'm not familiar with it), but they seem to relax that restriction. Hana
On 1/23/13 1:01 AM, Marius Hofert wrote:
Since clusterSetupRNG() calls clusterSetupRNGstream() and this calls .lec.SetPackageSeed(), I could further minimalize the problem:
set.seed(1)
RNGkind("L'Ecuyer-CMRG") # => .Random.seed is of length 7 (first number encodes the rng kind)
(seed <- .Random.seed[2:7]) # should give a valid seed for l'Ecuyer's RNG
require(rlecuyer) # latest version 0.3-3
.lec.SetPackageSeed(seed)
The last line fails with:
,----
| Error in .lec.SetPackageSeed(seed) :
| Seed[0] >= -767742437, Seed is not set.
`----
Looking at .lec.SetPackageSeed, "seed" seems to pass .lec.CheckSeed() [the check
could probably be improved here (but further checking is done in the C code; see
below)]:
,----
| > .lec.SetPackageSeed
| function (seed = rep(12345, 6))
| {
| if (!exists(".lec.Random.seed.table", envir = .GlobalEnv))
| .lec.init()
| seed <- .lec.CheckSeed(seed) # => bad check since it's passed
| .Call("r_set_package_seed", as.double(seed), PACKAGE = "rlecuyer") # => this fails!
| return(seed)
| }
| <environment: namespace:rlecuyer>
`----
Going into the C code, r_set_package_seed calls RngStream_SetPackageSeed which in turn calls CheckSeed(seed). The relevant part of CheckSeed is this:
,----
| for (i = 0; i < 3; ++i) {
| if (seed[i] >= m1) {
| /* HS 01-25-2012 */
| error("Seed[%1d] >= %d, Seed is not set.\n", i,m1);
| /* original code
| fprintf (stderr, "****************************************\n"
| "ERROR: Seed[%1d] >= m1, Seed is not set.\n"
| "****************************************\n\n", i);
| return (-1);
| */
| }
| }
`----
Note that seed[0] in this (C-)code corresponds to the first element of my
variable "seed", which is -1535484873. This should definitely be smaller than m1
since m1 is defined as 4294967087.0 on line 34 in ./src/RngStream.c of the package 'rlecuyer'.
Why is seed[i] then >= m1??? This is strange. Indeed, as you can see from the
error message above, m1 is taken as -767742437 in my case (why?). Still (and even more
confusing), -1535484873 >= -767742437 is FALSE (!) but the if(){} is entered
anyways...
Cheers,
Marius
Dear Hana,
Thanks for helping.
I am still wondering, why m1 (which should be 2^32-209 [see line 34 in
./src/RngStream.c]) is -767742437 in my case and why the minimal example you
gave was working for you but isn't for me.
Apart from that, ?.Random.seed -> "L'Ecuyer-CMRG" says:
,----
| The 6 elements of the seed are internally regarded as 32-bit
| unsigned integers. Neither the first three nor the last
| three should be all zero, and they are limited to less than
| ?4294967087? and ?4294944443? respectively.
`----
=> .Random.seed provides a *signed* integer. I tried to convert it to an
unsigned integer:
RNGkind()
set.seed(1)
.Random.seed[-1]
RNGkind("L'Ecuyer-CMRG")
.Random.seed[-1] # => unsigned
seed <- .Random.seed[-1] + 2^32 # => shifting
require(rlecuyer)
.lec.SetPackageSeed(seed)
... but it fails with
,----
| Error in .lec.SetPackageSeed(seed) : Seed[1] >= 14, Seed is not set.
`----
=> so there seem to be the requirement that the second element of the seed is <
14 (???).
I might have done the conversion to a signed integer incorrectly, though.
It would be great if the seed was checked *precisely* (not just basic length
checks) in R, maybe in .lec.CheckSeed(). That would rule out further problems
and strange error messages from C, which are harder to debug.
What are the precise conditions for the seed in 'rlecuyer'? Judging from the
above error, the second element must be < 14. But, additionally,... ?
I hope there is a solution to the problem of "how to convert .Random.seed to get
a valid seed for 'rlecuyer'"... we need that in a package.
Cheers,
Marius
Hana Sevcikova <hanas at uw.edu> writes:
Marius, I looked it up in the original L'Ecuyer's paper: The seed must be larger than 0. Thus, the function defines the seed variable as unsigned long integer. You're passing a negative number, so I think there is some overflow going on. The internal L'Ecuyer RNG is a modification of the original one (and I'm not familiar with it), but they seem to relax that restriction. Hana
-------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 835 bytes Desc: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20130123/c79c5366/attachment.bin>
-----Original Message-----
From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org]
On Behalf Of Marius Hofert
Sent: Wednesday, January 23, 2013 2:24 PM
To: Hana Sevcikova
Cc: R-help
Subject: Re: [R] How to construct a valid seed for l'Ecuyer's method
withgiven .Random.seed?
Dear Hana,
Thanks for helping.
I am still wondering, why m1 (which should be 2^32-209 [see line 34 in
./src/RngStream.c]) is -767742437 in my case and why the minimal example
you
gave was working for you but isn't for me.
Apart from that, ?.Random.seed -> "L'Ecuyer-CMRG" says:
,----
| The 6 elements of the seed are internally regarded as 32-bit
| unsigned integers. Neither the first three nor the last
| three should be all zero, and they are limited to less than
| ?4294967087? and ?4294944443? respectively.
`----
=> .Random.seed provides a *signed* integer. I tried to convert it to an
unsigned integer:
RNGkind()
set.seed(1)
.Random.seed[-1]
RNGkind("L'Ecuyer-CMRG")
.Random.seed[-1] # => unsigned
seed <- .Random.seed[-1] + 2^32 # => shifting
require(rlecuyer)
.lec.SetPackageSeed(seed)
... but it fails with
,----
| Error in .lec.SetPackageSeed(seed) : Seed[1] >= 14, Seed is not set.
`----
=> so there seem to be the requirement that the second element of the seed
is <
14 (???).
I might have done the conversion to a signed integer incorrectly, though.
It would be great if the seed was checked *precisely* (not just basic
length
checks) in R, maybe in .lec.CheckSeed(). That would rule out further
problems
and strange error messages from C, which are harder to debug.
What are the precise conditions for the seed in 'rlecuyer'? Judging from
the
above error, the second element must be < 14. But, additionally,... ?
I hope there is a solution to the problem of "how to convert .Random.seed
to get
a valid seed for 'rlecuyer'"... we need that in a package.
Cheers,
Marius
Hana Sevcikova <hanas at uw.edu> writes:
Marius, I looked it up in the original L'Ecuyer's paper: The seed must be larger
than
0. Thus, the function defines the seed variable as unsigned long
integer. You're
passing a negative number, so I think there is some overflow going on. The internal L'Ecuyer RNG is a modification of the original one (and I'm
not
familiar with it), but they seem to relax that restriction. Hana
I apologize if this message is posted twice. I am having email problems. I think the confusion about negative numbers is that R represents the seed values as signed integers, but the underlying C code interprets those values as unsigned integers. At least that is how I read the documentation on .Random.seed Hope this is helpful, Dan Daniel Nordlund Bothell, WA USA