Example usage of `xorshiro` jump method
YuhanLiin opened this issue · comments
Many of the xorshiro
generators, such as Xorshiro256Plus
, have a method called jump
that allows the RNG to generate different sequences in parallel applications. However, I'm not sure how to actually use jump
for parallel computing, and the examples don't really show much. Can someone provide an example of the jump
API being used in parallel computing?
The xorshift
crate has an example with Rust's thread::spawn
: https://docs.rs/xorshift/latest/xorshift/#parallelism
I don't know of a clean way to do this with rayon
since for_each/etc_init
don't allow FnMut
. Perhaps some custom Clone
hack with for_each_with
is possible (but without mutable access? idk).
Though I suppose something like this is possible:
let mut rng = Xoshiro256PlusPlus::from_entropy();
let mut rngs: Vec<_> = data
.iter()
.map(|_| { rng.jump(); rng.clone() })
.collect();
data.par_iter()
.zip_eq(&mut rngs)
.for_each(|(elem, rng)| todo!());
But that has significant constraints
The xorshift
algorithm's jump
API takes a usize
, which I assume controls how many jumps are done. The jump
call in Xoshiro
doesn't take this parameter, so how would I replicate the effect of the usize
param? Do I just jump
in a for loop?
Without Copy
something like this works:
let seed = thread_rng().gen();
for i in 0..17 {
threads.push(std::thread::spawn(move || {
let mut r = Xoshiro256PlusPlus::from_seed(seed);
for _ in 0..i {
r.jump();
}
but that's a lot of repeated jumps. collecting the rngs like #38 (comment) might be better
Would it be cheaper to just construct multiple instances of the RNG with difference seeds? Xoshiro
initialization time is supposedly cheap.
I think using LXM generators and a custom Clone
implementation with rayon::map_with
is probably the state-of-the-art right now and also more convenient.
Turns out LXM generators still require mutable access to some parent RNG but there might be a safe way to dynamically seed them with thread_rng
.
I wonder if you could use a Mutex
or Arc
or something in a custom Clone
? Otherwise I don't know if a mutable version of rayon::map_with
is possible but it would be very helpful
I think I understand what I need to do. Thanks for your help.