rustsim 0.0.1

High-performance agent-based modelling engine - top-level orchestration crate
Documentation
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);
}