use rustsim::prelude::*;
#[derive(Debug, Clone)]
struct Particle {
id: AgentId,
x: f32,
vx: f32,
}
impl Agent for Particle {
fn id(&self) -> AgentId {
self.id
}
}
impl SoaExtractable for Particle {
fn num_columns() -> usize {
2
}
fn column_names() -> Vec<&'static str> {
vec!["x", "vx"]
}
fn extract_row(&self, columns: &mut [Vec<f32>]) {
columns[0].push(self.x);
columns[1].push(self.vx);
}
fn write_back_row(&mut self, columns: &[&[f32]], row: usize) {
self.x = columns[0][row];
self.vx = columns[1][row];
}
}
fn integrate_cpu(columns: &mut [Vec<f32>], n: usize) {
let (x_col, rest) = columns.split_at_mut(1);
let x = &mut x_col[0];
let vx = &rest[0];
for i in 0..n {
x[i] += vx[i] * 0.5;
}
}
fn run_cpu_batch_replay() -> Vec<(AgentId, f32)> {
let mut store = VecStore::new();
for id in 1..=5 {
store.insert(Particle {
id,
x: id as f32,
vx: (id as f32) * 0.25,
});
}
for _ in 0..8 {
cpu_batch_step::<Particle, _, _>(&store, integrate_cpu);
}
(1..=5).map(|id| (id, store.get(id).unwrap().x)).collect()
}
#[test]
fn cpu_batch_step_replay_is_deterministic() {
let run1 = run_cpu_batch_replay();
let run2 = run_cpu_batch_replay();
assert_eq!(run1, run2);
}