#![cfg(feature = "simd")]
use rustsim_crowd::broadphase::Scratch;
use rustsim_crowd::common::{Pedestrian, WallSegment};
fn seed() -> Vec<Pedestrian> {
(0..32)
.map(|i| {
let lane = (i % 4) as f64;
let col = (i / 4) as f64;
let dir = if i % 2 == 0 { 1.0 } else { -1.0 };
Pedestrian::new(
[col * 0.8, lane * 0.6],
[dir * 0.5, 0.0],
0.25,
1.34,
[dir * 50.0, lane * 0.6],
)
})
.collect()
}
fn walls() -> Vec<WallSegment> {
vec![
WallSegment {
a: [-20.0, -1.0],
b: [20.0, -1.0],
},
WallSegment {
a: [-20.0, 3.0],
b: [20.0, 3.0],
},
]
}
#[test]
fn sfm_step_scratch_simd_matches_scalar_within_tolerance() {
use rustsim_crowd::social_force::{neighbor_cutoff, step_scratch, step_scratch_simd, Params};
let mut peds_scalar = seed();
let mut peds_simd = seed();
let walls = walls();
let params = Params::default();
let dt = 0.05;
let mut scr_scalar = Scratch::new(neighbor_cutoff(¶ms));
let mut scr_simd = Scratch::new(neighbor_cutoff(¶ms));
step_scratch(&mut peds_scalar, &walls, ¶ms, dt, &mut scr_scalar);
step_scratch_simd(&mut peds_simd, &walls, ¶ms, dt, &mut scr_simd);
for (i, (a, b)) in peds_scalar.iter().zip(peds_simd.iter()).enumerate() {
let dx = (a.pos[0] - b.pos[0]).abs();
let dy = (a.pos[1] - b.pos[1]).abs();
let dvx = (a.vel[0] - b.vel[0]).abs();
let dvy = (a.vel[1] - b.vel[1]).abs();
assert!(
dx < 1.0e-9 && dy < 1.0e-9,
"SFM agent {i} pos diverged: scalar={:?} simd={:?}",
a.pos,
b.pos
);
assert!(
dvx < 1.0e-9 && dvy < 1.0e-9,
"SFM agent {i} vel diverged: scalar={:?} simd={:?}",
a.vel,
b.vel
);
}
}
#[test]
fn gcf_step_scratch_simd_matches_scalar_within_tolerance() {
use rustsim_crowd::generalized_centrifugal_force::{
neighbor_cutoff, step_scratch, step_scratch_simd, Params,
};
let mut peds_scalar = seed();
let mut peds_simd = seed();
let walls = walls();
let params = Params::default();
let dt = 0.05;
let mut scr_scalar = Scratch::new(neighbor_cutoff(¶ms));
let mut scr_simd = Scratch::new(neighbor_cutoff(¶ms));
step_scratch(&mut peds_scalar, &walls, ¶ms, dt, &mut scr_scalar);
step_scratch_simd(&mut peds_simd, &walls, ¶ms, dt, &mut scr_simd);
for (i, (a, b)) in peds_scalar.iter().zip(peds_simd.iter()).enumerate() {
let dx = (a.pos[0] - b.pos[0]).abs();
let dy = (a.pos[1] - b.pos[1]).abs();
let dvx = (a.vel[0] - b.vel[0]).abs();
let dvy = (a.vel[1] - b.vel[1]).abs();
assert!(
dx < 1.0e-9 && dy < 1.0e-9,
"GCF agent {i} pos diverged: scalar={:?} simd={:?}",
a.pos,
b.pos
);
assert!(
dvx < 1.0e-9 && dvy < 1.0e-9,
"GCF agent {i} vel diverged: scalar={:?} simd={:?}",
a.vel,
b.vel
);
}
}
#[test]
fn cfs_step_scratch_simd_matches_scalar_within_tolerance() {
use rustsim_crowd::collision_free_speed::{
neighbor_cutoff, step_scratch, step_scratch_simd, Params,
};
let mut peds_scalar = seed();
let mut peds_simd = seed();
let walls = walls();
let params = Params::default();
let dt = 0.05;
let mut scr_scalar = Scratch::new(neighbor_cutoff(¶ms));
let mut scr_simd = Scratch::new(neighbor_cutoff(¶ms));
step_scratch(&mut peds_scalar, &walls, ¶ms, dt, &mut scr_scalar);
step_scratch_simd(&mut peds_simd, &walls, ¶ms, dt, &mut scr_simd);
for (i, (a, b)) in peds_scalar.iter().zip(peds_simd.iter()).enumerate() {
let dx = (a.pos[0] - b.pos[0]).abs();
let dy = (a.pos[1] - b.pos[1]).abs();
let dvx = (a.vel[0] - b.vel[0]).abs();
let dvy = (a.vel[1] - b.vel[1]).abs();
assert!(
dx < 1.0e-9 && dy < 1.0e-9,
"CFS agent {i} pos diverged: scalar={:?} simd={:?}",
a.pos,
b.pos
);
assert!(
dvx < 1.0e-9 && dvy < 1.0e-9,
"CFS agent {i} vel diverged: scalar={:?} simd={:?}",
a.vel,
b.vel
);
}
}
#[test]
fn avm_step_scratch_simd_matches_scalar_within_tolerance() {
use rustsim_crowd::anticipation_velocity::{
neighbor_cutoff, step_scratch, step_scratch_simd, Params,
};
let mut peds_scalar = seed();
let mut peds_simd = seed();
let walls = walls();
let params = Params::default();
let dt = 0.05;
let mut scr_scalar = Scratch::new(neighbor_cutoff(¶ms));
let mut scr_simd = Scratch::new(neighbor_cutoff(¶ms));
step_scratch(&mut peds_scalar, &walls, ¶ms, dt, &mut scr_scalar);
step_scratch_simd(&mut peds_simd, &walls, ¶ms, dt, &mut scr_simd);
for (i, (a, b)) in peds_scalar.iter().zip(peds_simd.iter()).enumerate() {
let dx = (a.pos[0] - b.pos[0]).abs();
let dy = (a.pos[1] - b.pos[1]).abs();
let dvx = (a.vel[0] - b.vel[0]).abs();
let dvy = (a.vel[1] - b.vel[1]).abs();
assert!(
dx < 1.0e-9 && dy < 1.0e-9,
"AVM agent {i} pos diverged: scalar={:?} simd={:?}",
a.pos,
b.pos
);
assert!(
dvx < 1.0e-9 && dvy < 1.0e-9,
"AVM agent {i} vel diverged: scalar={:?} simd={:?}",
a.vel,
b.vel
);
}
}