Fix RNG transmutation
CI / cargo test (push) Successful in 14m31s
CI / cargo test (GPU) (push) Successful in 12m49s
CI / cargo fmt (push) Successful in 28s

This commit is contained in:
2026-06-29 20:40:12 -04:00
parent 3c5563c940
commit 86ef0887e3
3 changed files with 42 additions and 8 deletions
+36 -3
View File
@@ -14,9 +14,42 @@ use rand_xoshiro::Xoshiro256StarStar;
/// This function assumes a properly-initialized state array;
/// output may silently degenerate if the initial state is all zeros,
/// so this module is private to the crate.
pub(crate) fn xoshiro_from_state(
_rng_state: <Xoshiro256StarStar as SeedableRng>::Seed,
pub(crate) fn xoshiro256starstar_from_seed(
rng_state: <Xoshiro256StarStar as SeedableRng>::Seed,
) -> Xoshiro256StarStar {
let rng_state_actual = [1u64, 2u64, 3u64, 4u64];
let mut rng_state_actual = [0u64; 4];
// NOTE: Bit shifting is bad, but we don't have great alternatives:
// - `chunks_exact` has issues with pointer casting
// - `u64::from_le_bytes` has issues with `OpBitcast` in SPIR-V validation
for i in 0..rng_state_actual.len() {
for j in 0..size_of::<u64>() {
rng_state_actual[i] |= (rng_state[i * size_of::<u64>() + j] as u64) << j * 8;
}
}
unsafe { core::mem::transmute(rng_state_actual) }
}
#[cfg(test)]
mod test {
use crate::rng::xoshiro256starstar_from_seed;
use core::iter::zip;
use rand::{RngExt, SeedableRng};
use rand_xoshiro::Xoshiro256StarStar;
#[test]
fn match_seeded() {
let mut seed: <Xoshiro256StarStar as SeedableRng>::Seed = [0u8; 32];
for i in 0..seed.len() {
seed[i] = i as u8;
}
let rng1 = Xoshiro256StarStar::from_seed(seed).random_iter::<u64>();
let rng2 = xoshiro256starstar_from_seed(seed).random_iter::<u64>();
zip(rng1, rng2)
.take(100)
.for_each(|(rng1_value, rng2_value)| assert_eq!(rng1_value, rng2_value));
}
}