ImmutableRNGs.jl

ImmutableRNGs provides small immutable random keys and explicit sequential RNG state for Julia. A key never advances. Derive keys for addressed or parallel work. Place a key in an RNGCursor when call order defines one reproducible sequence.

The package depends only on Julia's Random and Serialization standard libraries. Optional extensions provide ecosystem and accelerator support.

Experimental stream format

This is 0.1.0-DEV software. Stream IDs and checkpoint codecs identify compatible replay data.

Installation

import Pkg
Pkg.add(url="https://github.com/BJMCox/ImmutableRNGsTestbed.jl")

Three interfaces

NeedInterfaceState rule
Parallel, indexed, or addressed workimmutable keys with splitrng, subrng, generate, or @keyedA key remains unchanged
Pure sequential or device-local workRNGCursor and cursor nextrand* methodsEach call returns the next cursor
Code expecting Random.AbstractRNGMutableRNG, mutably, or @mutablyOne wrapper owns one cursor
using ImmutableRNGs, Random

key = Philox4x32(42)
left, right = splitrng(key, Val(2))

cursor = RNGCursor(right)
noise, cursor = nextrandn(cursor, Float64)

rng = MutableRNG(cursor)
sample = rand(rng, 1:6)
checkpoint = freeze(rng)

(rand(key) == rand(key), left != right,
 cursor_position(checkpoint) > cursor_position(cursor))

# output

(true, true, true)

Core rules

  1. The same key and call reproduce the same result.
  2. Derive every independent key before starting sequential consumption.
  3. Keep one live cursor or wrapper continuation for each sequential chain.

MutableRNG(key) starts at position zero. Resume from freeze(rng), an RNGCursor, or a validated cursor_checkpoint. A bare key does not contain sequential position.

Further reading