use rand_xoshiro::Xoshiro256StarStar;
use rayon::prelude::*;
pub fn par_over_replicas(
spins: &mut [i8],
rngs: &mut [Xoshiro256StarStar],
temperatures: &[f32],
system_ids: &[usize],
n_spins: usize,
sequential: bool,
body: impl Fn(&mut [i8], &mut Xoshiro256StarStar, f32, usize) + Send + Sync,
) {
let chunks: Vec<(usize, usize)> = (0..system_ids.len())
.map(|temp_id| (system_ids[temp_id], temp_id))
.collect();
let sp = spins.as_mut_ptr() as usize;
let rp = rngs.as_mut_ptr() as usize;
let work = |&(system_id, temp_id): &(usize, usize)| unsafe {
let spin_slice =
std::slice::from_raw_parts_mut((sp as *mut i8).add(system_id * n_spins), n_spins);
let rng = &mut *(rp as *mut Xoshiro256StarStar).add(system_id);
let temp = temperatures[temp_id];
body(spin_slice, rng, temp, system_id);
};
if sequential {
chunks.iter().for_each(work);
} else {
chunks.par_iter().for_each(work);
}
}