In Python I can spawn independent child RNGs with numpy.random.Generator.spawn. How can I do this in Julia?
Hi alegresor, welcome to the Julia discourse!
I’m not sure that Julia has an explicit splittable RNG, but the TaskLocalRNG automatically spawns and seeds independent RNGs from the parent RNG in a per-task way.
The Xoshiro RNG (which you can read about here) will also implicitly spawn independent RNGs when doing bulk random number generation (see here).
If you still need to be able to split the RNG, then I would recommend writing the “jump” function described in the first link I sent, and then writing a “split” method that copies the parent Xoshiro, then jumps the parent state using the jump method.
I’ll see if I can offer a concrete example later on if you still need a solution
Here is a concrete example for my earlier reply
using Random
function jump!(rng::Xoshiro)
JUMP = [
0x180ec6d33cfd0aba,
0xd5a61266f0c9392c,
0xa9582618e03fc9aa,
0x39abdc4529b1661c
]
s0 = zero(UInt64)
s1 = zero(UInt64)
s2 = zero(UInt64)
s3 = zero(UInt64)
for j in JUMP
for b in 0:63
if (j & one(UInt64) << b) > 0
s0 ⊻= rng.s0
s1 ⊻= rng.s1
s2 ⊻= rng.s2
s3 ⊻= rng.s3
end
rand(rng)
end
end
rng.s0 = s0
rng.s1 = s1
rng.s2 = s2
rng.s3 = s3
return rng
end
function spawn!(rng::Xoshiro)
child_rng = copy(rng)
jump!(rng)
return child_rng
end
The jump!
method is equivalent to 2^128 calls to the rand()
function. So an independent RNG can be spawned from the parent Xoshiro by first cloning the parent RNG, then jumping its state to 2^128 places later in the sequence. Using this process, you can generate 2^128 “non-overlapping subsequences for parallel computations.”
Some of the code and pointers in this previous discussion may be of interest: Does Julia have any utility to "split" RNGs for later use in parallel? - #4 by marius311
Excellent, thanks!
I think this should be rng.s3 = s3