How to Spawn Child RNGs with Random?

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 :slight_smile:

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.”

1 Like

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