API reference
This page lists the exported and public package interface. It omits internal helpers.
ImmutableRNGs.ImmutableRNGsImmutableRNGs.ARS5ImmutableRNGs.AbstractCursorCodecImmutableRNGs.AbstractDeviceProfileImmutableRNGs.AbstractImmutableRNGImmutableRNGs.IncompatibleCheckpointImmutableRNGs.MutableRNGImmutableRNGs.MutablyFailureImmutableRNGs.MutablySuccessImmutableRNGs.Philox4x32ImmutableRNGs.Philox4x32ImmutableRNGs.Philox4x32R7ImmutableRNGs.Philox4x32R7ImmutableRNGs.RNGCursorImmutableRNGs.ReseedUnsupportedImmutableRNGs.Squares64ImmutableRNGs.StreamExhaustedImmutableRNGs.SupportedDeviceProfileImmutableRNGs.Threefry2x32ImmutableRNGs.UnregisteredDeviceProfileImmutableRNGs.UnsupportedDeviceProfileImmutableRNGs.advance_cursorImmutableRNGs.advance_cursorImmutableRNGs.bitsImmutableRNGs.cursor_ad_inactive_supportedImmutableRNGs.cursor_blockImmutableRNGs.cursor_checkpointImmutableRNGs.cursor_checkpoint_codecImmutableRNGs.cursor_codec_idImmutableRNGs.cursor_core_supportedImmutableRNGs.cursor_device_profileImmutableRNGs.cursor_familiesImmutableRNGs.cursor_family_idImmutableRNGs.cursor_generator_idImmutableRNGs.cursor_max_blockImmutableRNGs.cursor_owner_uuidImmutableRNGs.cursor_positionImmutableRNGs.cursor_positionImmutableRNGs.cursor_remainingImmutableRNGs.cursor_reseedImmutableRNGs.cursor_reseed_supportedImmutableRNGs.decode_cursor_keyImmutableRNGs.encode_cursor_keyImmutableRNGs.freezeImmutableRNGs.generateImmutableRNGs.generate!ImmutableRNGs.is_poisonedImmutableRNGs.is_readyImmutableRNGs.issuccessImmutableRNGs.mutablyImmutableRNGs.nextrandImmutableRNGs.nextrandImmutableRNGs.nextrandexpImmutableRNGs.nextrandexpImmutableRNGs.nextrandnImmutableRNGs.nextrandnImmutableRNGs.packed_bitrandImmutableRNGs.packed_bitrand!ImmutableRNGs.rand_native!ImmutableRNGs.randn_native!ImmutableRNGs.register_cursor_codec!ImmutableRNGs.register_cursor_family!ImmutableRNGs.register_device_profile!ImmutableRNGs.restore!ImmutableRNGs.restore!ImmutableRNGs.restore_cursorImmutableRNGs.restore_cursorImmutableRNGs.splitrngImmutableRNGs.stream_idImmutableRNGs.subrngImmutableRNGs.try_advance_cursorImmutableRNGs.try_mutablyImmutableRNGs.try_nextrandImmutableRNGs.try_nextrandexpImmutableRNGs.try_nextrandnImmutableRNGs.unsafe_cursorImmutableRNGs.unwrapImmutableRNGs.@generateImmutableRNGs.@keyedImmutableRNGs.@mutably
ImmutableRNGs.ImmutableRNGs — Module
ImmutableRNGsImmutable RNG keys for Julia. A draw is a pure function of its key. Use splitrng or subrng to derive new random work. The contract guarantees tagged address separation between draw families and derivation, not mathematical independence. MutableRNG implements AbstractRNG for code that needs mutable state.
ImmutableRNGs.ARS5 — Type
ARS5(seed::Integer)
ARS5(; key_word0, key_word1, key_word2, key_word3)
ARS5(key::NTuple{4,UInt32})An immutable ARS-5 key with a 128-bit key and 128-bit counter space. ARS uses the AES round function with a non-cryptographic Weyl key schedule. The package makes no cryptographic or statistical-quality claim beyond its generator checks.
The labeled constructor preserves Random123's native word order: key_word0 is the least-significant 32-bit word, followed by words 1, 2, and 3.
ARS5 requires a host with an AES round instruction. Module initialization checks this capability once through OS and CPU feature queries. The check does not execute an AES intrinsic. The constructor throws when AES is unavailable and provides no software fallback.
Raw and serialized ARS5 values require an AES-capable host. A serialized value can bypass constructors during restoration. Use it only when ImmutableRNGs._has_aes() is true.
ImmutableRNGs.AbstractCursorCodec — Type
AbstractCursorCodecSupertype for cursor-key codec tokens. Token types select durable key encodings without relying on function or closure identity.
ImmutableRNGs.AbstractDeviceProfile — Type
Supertype for cursor device-profile query results.
ImmutableRNGs.AbstractImmutableRNG — Type
AbstractImmutableRNGRoot type for immutable RNG keys. It is not a subtype of Random.AbstractRNG. Mutable code may draw twice from one object, which would silently replay an immutable key. Passing a key where an AbstractRNG is required therefore raises MethodError. Use MutableRNG for that interface.
Subtypes are key-only isbits structs. The generator core contract is
bits(rng, counter::UInt64) -> NTuple{N,UInt32}a pure function suitable for GPU kernels.
ImmutableRNGs.IncompatibleCheckpoint — Type
IncompatibleCheckpoint(checkpoint, reason; compatibility_fields...)An exception raised for an incompatible sequential cursor checkpoint. Optional fields record known compatibility details. An immutable key cannot encode a mutable cursor position, so the legacy-key form leaves these fields as nothing.
ImmutableRNGs.MutableRNG — Type
MutableRNG(key::AbstractImmutableRNG) <: Random.AbstractRNG
MutableRNG(cursor::RNGCursor) <: Random.AbstractRNGA host-side sequential adapter for immutable RNG keys. The wrapper advances one raw-word cursor. freeze returns that cursor without mutation. Wrappers compare by object identity. Compare frozen cursors to find overlapping replay aliases. The private cache and Reactant slot are not logical cursor state.
ImmutableRNGs.MutablyFailure — Type
MutablyFailure(exception, backtrace, cursor, cursor_uncertain)A failed try_mutably result. If cursor_uncertain is true, resuming from cursor replays an unknown span.
ImmutableRNGs.MutablySuccess — Type
MutablySuccess(result, cursor)A successful try_mutably result. Its stable fields are result and cursor, and callers may destructure them.
ImmutableRNGs.Philox4x32 — Type
Philox4x32(seed::Integer)
Philox4x32(; key_hi, key_lo)
Philox4x32((key_hi, key_lo))An immutable Philox4x32-10 key with a 64-bit key and internal 128-bit counter space. cuRAND, PyTorch, and TensorFlow use Philox on GPUs. The labeled and tuple raw-key constructors preserve native (key_hi, key_lo) order.
ImmutableRNGs.Philox4x32 — Method
Philox4x32(r::Random.AbstractRNG)
Threefry2x32(r::Random.AbstractRNG)Seed a key with 64 bits drawn from r. This call advances r. It is equivalent to Philox4x32(rand(r, UInt64)), or the corresponding Threefry2x32 call. If r is a MutableRNG, the draw advances its cursor.
ImmutableRNGs.Philox4x32R7 — Type
Philox4x32R7(seed::Integer)
Philox4x32R7(; key_hi, key_lo)
Philox4x32R7(key::NTuple{2,UInt32})An immutable Philox4x32-7 key. It uses the Philox4x32 core with 7 rounds instead of 10. R7 uses the published minimum tested round count. It has a smaller safety margin than R10 and performs roughly 30% less work per block. The labeled and tuple raw-key constructors preserve native (key_hi, key_lo) order.
ImmutableRNGs.Philox4x32R7 — Method
Philox4x32R7(r::Random.AbstractRNG)
ARS5(r::Random.AbstractRNG)
Squares64(r::Random.AbstractRNG)Seed a key with 64 bits drawn from r. This call advances r. If r is a MutableRNG, the draw advances its cursor.
ImmutableRNGs.RNGCursor — Type
RNGCursor(key::AbstractImmutableRNG)
RNGCursor(key::AbstractImmutableRNG; block::Integer, lane::Integer)
RNGCursor(key::AbstractImmutableRNG; position::Integer)An immutable position in a key's sequential raw-word stream. A normal state identifies a block and lane. The single terminal state is the lane after the final word of the final block.
ImmutableRNGs.ReseedUnsupported — Type
ReseedUnsupported(generator_type)An exception raised when a cursor-capable generator does not implement integer reseeding for MutableRNG.
ImmutableRNGs.Squares64 — Type
Squares64(seed::Integer)
Squares64(; key::Integer)An experimental Squares64 key from Widynski (2020). Each block is one 64-bit middle-square output after five rounds. The package exports Squares64 for experimentation. It is not a default generator and has no validated external statistical-quality claim.
Squares requires a specific hexadecimal digit structure. Squares64(seed) therefore does not use the seed as its key. It mixes the seed through one Philox4x32 block and repairs the result. The resulting map is deterministic, non-injective, non-surjective, and not externally validated. Pass a raw key as Squares64(key = k). This form rejects keys that do not meet the paper's structure.
ImmutableRNGs.StreamExhausted — Type
StreamExhausted(requested, block, lane, block_width, maximum_block)An exception raised when a positive cursor advance passes the final raw word. It records the requested word count, starting block and lane, block width, and maximum valid block.
ImmutableRNGs.SupportedDeviceProfile — Type
SupportedDeviceProfile(; operations)Immutable descriptor for tested (operation, element_type) pairs. Reserved operations are :cursor_step, :rand_fill, :randn_fill, :randexp_fill, and :range_fill. Hardware, dependency, transform, revision, and measurement metadata belongs in an external acceptance manifest.
ImmutableRNGs.Threefry2x32 — Type
Threefry2x32(seed::Integer)
Threefry2x32(; key_hi, key_lo)
Threefry2x32((key_hi, key_lo))An immutable Threefry2x32 key with a 64-bit key. JAX uses Threefry by default, which permits bit-level checks against JAX streams. The labeled and tuple raw-key constructors preserve native (key_hi, key_lo) order.
ImmutableRNGs.UnregisteredDeviceProfile — Type
UnregisteredDeviceProfile()Result for a concrete backend with no registered cursor profile.
ImmutableRNGs.UnsupportedDeviceProfile — Type
UnsupportedDeviceProfile(; reason)Result for an unsupported generator and backend pair on a registered backend. reason is a stable symbolic code. Consumers must accept unknown codes.
ImmutableRNGs.advance_cursor — Method
advance_cursor(m::MutableRNG, words::Integer) -> mCheck and apply the complete raw-word skip, then clear the private block cache. A poisoned or inflight wrapper raises an error.
ImmutableRNGs.advance_cursor — Method
advance_cursor(cursor::RNGCursor, words::Integer) -> RNGCursorSkip words raw words without drawing and return the new cursor. Zero is an exact no-op. Negative counts raise ArgumentError. Requests beyond capacity raise StreamExhausted.
ImmutableRNGs.bits — Function
bits(rng::AbstractImmutableRNG, counter::UInt64) -> NTuple{N,UInt32}Return the raw generator block at counter. The method is pure, allocation-free, and kernel safe. blockwords(typeof(rng)) gives the number of words N in each block.
counter addresses a block rather than an element. One block may supply several elements. The mapping depends on the generator. Philox uses the FAMILY_BITS layout. Threefry uses the full raw counter, although family draws reserve its top byte. Squares masks the counter to 56 bits. bits does not define a portable draw-family layout.
ImmutableRNGs.cursor_ad_inactive_supported — Method
cursor_ad_inactive_supported(::Type{R}) -> BoolReturn whether R contains no differentiable data and is safe to mark inactive in AD integrations. The default is false.
ImmutableRNGs.cursor_block — Function
cursor_block(rng, family, block) -> NTuple{W,UInt32}Return a raw cursor block through the extension interface. W must equal blockwords(typeof(rng)). Words follow canonical increasing-lane order.
ImmutableRNGs.cursor_checkpoint — Method
cursor_checkpoint(cursor::RNGCursor) -> NamedTupleReturn the canonical ordered, data-only version-one cursor record. It contains the complete key and stream position, so treat it as sensitive and unauthenticated. It provides no authentication, confidentiality, substitution protection, or corruption recovery. Exact ecosystem replay also needs a caller-owned replay manifest. Package, machine, backend, and provenance data belong in that manifest rather than this record.
ImmutableRNGs.cursor_checkpoint_codec — Method
cursor_checkpoint_codec(::Type{R}) -> Union{Nothing,Type{<:AbstractCursorCodec}}Return the durable-key codec token for R. Return nothing when R does not support logical checkpoints. Core cursor support does not imply checkpoint support.
ImmutableRNGs.cursor_codec_id — Function
cursor_codec_id(::Type{C}) -> StringReturn the stable identifier for cursor codec token type C within its owner's namespace.
ImmutableRNGs.cursor_core_supported — Method
cursor_core_supported(::Type{R}) -> BoolReturn whether immutable key type R implements the cursor core protocol. The default is false. An extension opts in after defining the required traits.
ImmutableRNGs.cursor_device_profile — Method
cursor_device_profile(::Type{R}, ::Type{B}) -> AbstractDeviceProfileQuery the registry without mutation for generator R and concrete backend B. The result distinguishes an unregistered backend, an unsupported pair, and a supported descriptor. Extensions register data instead of defining query methods.
ImmutableRNGs.cursor_families — Method
cursor_families(::Type{R}) -> NTuple{N,UInt32}Return the compile-time family tuple for a cursor-capable key type. The empty default admits no family.
ImmutableRNGs.cursor_family_id — Method
cursor_family_id(::Val{name}) -> UInt32Return a published version-one cursor family identifier. The package owns these identifiers. Extensions cannot add methods to this function.
ImmutableRNGs.cursor_generator_id — Function
cursor_generator_id(::Type{R}) -> StringReturn the stable generator identifier within the namespace from cursor_owner_uuid.
ImmutableRNGs.cursor_max_block — Method
cursor_max_block(::Type{R}) -> UInt64Return the largest raw-output block address available to an RNGCursor for generator type R. Bundled generators use their draw counter bound. Third-party generators may define a more specific method.
ImmutableRNGs.cursor_owner_uuid — Function
cursor_owner_uuid(::Type{R}) -> StringReturn the canonical lowercase UUID of the package that owns cursor-capable generator type R. Extensions define this trait without a runtime registry.
ImmutableRNGs.cursor_position — Method
cursor_position(m::MutableRNG) -> UInt128Return the wrapper's current raw-word position without invalidating its cache.
ImmutableRNGs.cursor_position — Method
cursor_position(cursor::RNGCursor) -> UInt128Return the zero-based global raw-word position. The terminal cursor has the total stream capacity as its position.
ImmutableRNGs.cursor_remaining — Method
cursor_remaining(cursor::RNGCursor) -> UInt128Return the number of raw words from cursor through the final word. The terminal cursor has zero remaining words.
ImmutableRNGs.cursor_reseed — Function
cursor_reseed(::Type{R}, seed::Integer) -> RConstruct a reseeded key of type R. Define this method only when cursor_reseed_supported returns true.
ImmutableRNGs.cursor_reseed_supported — Method
cursor_reseed_supported(::Type{R}) -> BoolReturn whether R supports deterministic integer reseeding. Core cursor support does not imply reseeding support.
ImmutableRNGs.decode_cursor_key — Function
decode_cursor_key(::Type{C}, ::Type{R}, words) -> RDecode canonical logical key words for generator type R. The method must check the word count, exact integer widths, and generator key invariants.
ImmutableRNGs.encode_cursor_key — Function
encode_cursor_key(::Type{C}, key) -> TupleEncode an immutable generator key as the canonical tuple of logical key words for codec token C.
ImmutableRNGs.freeze — Method
freeze(m::MutableRNG) -> RNGCursorReturn the current logical cursor without mutation. A poisoned or inflight wrapper has no trusted checkpoint and raises an error.
ImmutableRNGs.generate — Function
generate(f, rng, T, dims...; scheduler=:serial) -> Array{T}
generate(f, rng) -> f(subrng(rng, 0))Build an array of T with f(subrng(rng, i - 1)) at linear index i. The same arguments return the same array within one package version. Assignment converts the return value of f to the explicit element type T.
f receives a bare key rather than a MutableRNG. Each element owns an address-isolated key. f may draw any number of values without changing another element's address. The resulting streams are intended as independent pseudorandom streams. Tagged domains guarantee address separation, not mathematical independence. The function accepts do-block syntax:
generate(rng, Float64, 100) do k
k1, k2 = splitrng(k)
rand(k1) < 0.5 ? randn(k2) : 0.0
endTwo draws from the same key address the same element slot in two families. Call splitrng for each draw that needs a separate stream.
The no-dimension form applies f to the key of element 0, so generate(f, rng) == generate(f, rng, T, 1)[1] up to the conversion to T.
CPU and device contract
On an Array, f may wrap its key (f = k -> rand(MutableRNG(k), 1:100)), call packages that expect a Random.AbstractRNG, allocate memory, or use rejection sampling with a data-dependent draw count.
On a device array, such as a CuArray filled by the KernelAbstractions extension, f runs inside a GPU kernel. It must use pure key draws, allocate no memory, create no MutableRNG, and capture no mutable state. Hardware imposes this CPU and device distinction. JAX uses the same boundary.
See also generate!.
Set scheduler=:polyester after loading Polyester to use its @batch scheduler on CPU arrays. The element addresses and results remain unchanged.
ImmutableRNGs.generate! — Function
generate!(f, rng, A; scheduler=:serial) -> AFill A in place. Linear index i receives f(subrng(rng, i - 1)), converted to eltype(A). generate documents the full contract on f, including the CPU and device distinction.
A::Array uses a plain loop by default. Set scheduler=:polyester after loading Polyester for a parallel @batch loop. Both paths use the same addresses and values. Other array types use scheduler=:backend through the KernelAbstractions extension and reject CPU scheduler names.
ImmutableRNGs.is_poisoned — Method
is_poisoned(m::MutableRNG) -> BoolReturn whether a dispatched operation left m with an uncertain cursor. Recover it with restore!, copy!, or supported Random.seed!.
ImmutableRNGs.is_ready — Method
is_ready(m::MutableRNG) -> BoolReturn whether m has a cursor that can be read or continued.
ImmutableRNGs.issuccess — Method
issuccess(result) -> BoolReturn whether a scoped mutable result completed normally.
ImmutableRNGs.mutably — Method
mutably(f, key_or_cursor) -> (result, next_cursor)Run scoped mutable work and return its value with the ending RNGCursor. Rethrow exceptions unchanged.
ImmutableRNGs.nextrand — Method
nextrand(rng, args...) -> (value, rng′)Split rng, draw rand(child, args...) from one child, and return the other child as rng′. Scalar draws are pure and allocation-free.
k = Philox4x32(42)
for _ in 1:3
x, k = nextrand(k)
endargs... passes to pure rand, including ranges, element types, and dimensions. Key continuations use splitting and differ from sequential MutableRNG draws. Use an RNGCursor to match mutable draws.
ImmutableRNGs.nextrand — Method
nextrand(cursor::RNGCursor, [T | range], [dims...]) -> (value, next_cursor)Draw from the strict sequential cursor stream. Unlike the key method, this method walks raw cursor words and matches owned scalar and Array MutableRNG draws. These overloads do not capture generic samplers or distributions.
ImmutableRNGs.nextrandexp — Method
nextrandexp(rng, args...) -> (value, rng′)randexp counterpart of nextrand.
ImmutableRNGs.nextrandexp — Method
nextrandexp(cursor::RNGCursor, [T], [dims...]) -> (value, next_cursor)Draw an exponential value from the strict sequential cursor stream. Key-based nextrandexp continues to split once per call.
ImmutableRNGs.nextrandn — Method
nextrandn(rng, args...) -> (value, rng′)randn counterpart of nextrand.
ImmutableRNGs.nextrandn — Method
nextrandn(cursor::RNGCursor, [T], [dims...]) -> (value, next_cursor)Draw a normal value from the strict sequential cursor stream. Key-based nextrandn continues to split once per call.
ImmutableRNGs.packed_bitrand! — Method
packed_bitrand!(rng::MutableRNG, bits::BitArray) -> bitsFill bits with one aligned UInt64 cursor slot for each packed storage chunk. Logical BitArray filling instead consumes one raw word for each element and matches scalar Bool draws.
ImmutableRNGs.packed_bitrand — Method
packed_bitrand(rng::MutableRNG, dims::Integer...) -> BitArrayAllocate and fill a packed BitArray. Allocation and dimension errors occur before cursor reservation.
ImmutableRNGs.rand_native! — Function
ImmutableRNGs.rand_native!(rng::AbstractImmutableRNG, A) -> AFill A with the device-native RNG path. The GPUArrays extension defines this method for A::AbstractGPUArray. Without the extension, or for a host Array, the call raises MethodError. There is no CPU fallback.
For a fixed device and backend version, rng determines the result. The stream is not portable across devices and is unrelated to the package's pure rand, randn, and randexp streams for the same key. Use Random.rand! through KernelAbstractions for the portable counter-indexed stream.
ImmutableRNGs.randn_native! — Function
ImmutableRNGs.randn_native!(rng::AbstractImmutableRNG, A) -> AFill A with normal values under the same contract as rand_native!.
ImmutableRNGs.register_cursor_codec! — Method
register_cursor_codec!(::Type{R}, ::Type{C}) -> Type{C}Register the current checkpoint traits for record-to-type lookup. A lock protects the registry. Repeating the same owner, generator type, codec token, and identifiers is safe. Cursor sampling does not consult this registry. External packages call this function from __init__.
ImmutableRNGs.register_cursor_family! — Method
register_cursor_family!(owner_uuid, name, id) -> UInt32Register a literal third-party family ID in the 0x80:0xbf band. Repeating the same normalized UUID, name, and ID is safe. Registration does not enter cursor sampling dispatch.
ImmutableRNGs.register_device_profile! — Method
register_device_profile!(::Type{R}, ::Type{B}, descriptor)Register a supported or unsupported profile for generator R and concrete backend B. Repeating an identical registration is safe. A different value for the same pair raises an error. Extensions call this function from __init__.
ImmutableRNGs.restore! — Method
restore!(m::MutableRNG, key::AbstractImmutableRNG)Reject a retired key-only checkpoint. A key names a fresh stream and contains no sequential position.
ImmutableRNGs.restore! — Method
restore!(m::MutableRNG{R}, cursor::RNGCursor{R}) -> mReplace the wrapper's logical cursor. This operation can recover a poisoned destination but rejects an inflight destination.
ImmutableRNGs.restore_cursor — Method
restore_cursor(key::AbstractImmutableRNG)Reject a retired key-only checkpoint. An immutable key starts a fresh cursor and cannot encode sequential position.
ImmutableRNGs.restore_cursor — Method
restore_cursor(record)
restore_cursor(record, ::Type{R})Validate and restore a canonical cursor record. The explicit-type form skips reverse type lookup but still checks every owner, generator, stream, codec, key-word, and cursor field. Restoration accepts and discards unknown extension metadata. Version 0.1.0 does not execute historical stream laws.
ImmutableRNGs.splitrng — Function
splitrng(rng, n=2) -> NTuple{n,typeof(rng)} or VectorDerive n child keys in a tagged domain outside the draw families. The children are intended as independent pseudorandom streams. The tags guarantee address separation, not mathematical independence. The same rng and call return the same children. Val(n) returns an NTuple, while integer n returns a Vector. This operation corresponds to JAX's split.
ImmutableRNGs.stream_id — Function
stream_id(::Type{R}) -> StringReturn the current cursor stream-law identifier for generator type R. A stream ID ends in -vN, where N is positive decimal without a leading zero.
ImmutableRNGs.subrng — Method
subrng(rng, data::Integer) -> typeof(rng)Derive a child key from rng and an integer, such as a loop or worker index. The child is intended as an independent pseudorandom stream. The tag separates its address from other domains, but injectivity holds only up to generator collisions. This operation corresponds to JAX's fold_in.
ImmutableRNGs.try_advance_cursor — Method
try_advance_cursor(cursor::RNGCursor, words::Integer) -> (next, ok)Advance without throwing. A negative or exhausted request returns the canonical terminal cursor and false. A valid request returns the advanced cursor and true.
ImmutableRNGs.try_mutably — Method
try_mutably(f, key_or_cursor) -> Union{MutablySuccess,MutablyFailure}Run f with a temporary mutable wrapper. On success, retain the final cursor. On failure, retain the exception and backtrace. A poisoned or inflight failure returns the caller's checkpoint and marks it uncertain.
ImmutableRNGs.try_nextrand — Method
try_nextrand(cursor, [T | range]) -> (value, next_cursor, ok)Draw a supported scalar primitive or nonempty integer range without throwing on exhaustion. Failure returns a typed sentinel, the terminal cursor, and false without reading a raw block.
ImmutableRNGs.try_nextrandexp — Method
try_nextrandexp(cursor, [T]) -> (value, next_cursor, ok)Draw an exponential value without throwing on exhaustion. Failure returns a quiet NaN, the terminal cursor, and false without reading a raw block.
ImmutableRNGs.try_nextrandn — Method
try_nextrandn(cursor, [T]) -> (value, next_cursor, ok)Draw a normal value without throwing on exhaustion. Failure returns a quiet NaN, the terminal cursor, and false without reading a raw block.
ImmutableRNGs.unsafe_cursor — Method
unsafe_cursor(key, block, lane) -> RNGCursorConstruct a cursor without validation. The caller must prove that the state is valid. This function supports total local cursor operations in device work.
ImmutableRNGs.unwrap — Method
unwrap(result) -> (value, cursor)Return a successful result or throw the saved exception at the unwrap call. Julia has no stable public API that attaches an arbitrary saved backtrace to a later throw. MutablyFailure retains the backtrace for diagnostics.
ImmutableRNGs.@generate — Macro
@generate name = key T dims... bodyCall generate with one MutableRNG for each element:
@generate rng = key Float64 100 begin
x = randn()
x < 0 ? 0.0 : x
endexpands to
generate(key, Float64, 100) do k
local rng = MutableRNG(k)
x = randn(rng)
x < 0 ? 0.0 : x
endInside body, the macro inserts rng into bare rand, randn, and randexp calls and calls qualified by literal Random. It does not modify a call that already passes an immutable key or mutable Random.AbstractRNG. Aliases, other qualified names, and unrelated macro bodies remain unchanged.
Element i receives subrng(key, i - 1), so it retains the purity, addressing, and shape rules of generate. Draws within one element use cursor order. Swapping two draws in body changes their values.
ImmutableRNGs.@keyed — Macro
@keyed name = key for i in iter
...
endGive each loop iteration an address-isolated MutableRNG bound to name. The macro applies the @generate draw rewrite to the body. Bare rand, randn, and randexp calls receive name as their first argument.
@keyed rng = key for i in 1:n
out[i] = library_call(rng) + randn()
endEach iteration starts from subrng(key, i), using the value of the loop variable rather than an execution counter. Scheduling does not change this address. A scheduler macro may wrap the loop:
@keyed rng = key Threads.@threads for i in 1:n
out[i] = randn()
endPlace the scheduler inside the macro call because macros expand from the outside inward. Threads.@spawn needs no special handling. The wrapper is bound before the spawn, so each task captures its own wrapper. Loading Polyester also permits Polyester.@batch in the same position.
Two rules follow from the index derivation:
- A plain loop variable must be an
Integerat run time.subrngaccepts only integers, so another type raisesMethodError. - A destructuring loop variable uses its first element as the index. In
for (i, batch) in enumerate(batches), makeiunique.
Repeated iteration values intentionally replay the same substream. Use enumerate(iter) and destructure (i, value) when each occurrence needs a distinct address.
ImmutableRNGs.@mutably — Macro
@mutably name = key bodyBind a MutableRNG for key to name, run body, and return (result, cursor′). The returned cursor′ is the frozen RNGCursor.
total, cursor2 = @mutably rng = key sum(rand(100))The macro applies the @generate draw rewrite to body. Bare rand, randn, and randexp calls receive rng as their first argument. Continue sequential work from cursor′ rather than a key.