stuff
This commit is contained in:
29
src/main.rs
29
src/main.rs
@@ -5,7 +5,7 @@ use rand::Rng;
|
||||
use arrayfire as af;
|
||||
|
||||
fn main() {
|
||||
let gpu_compute: bool = true;
|
||||
let gpu_compute: bool = false;
|
||||
if gpu_compute {
|
||||
backend_man();
|
||||
// af::set_backend(af::Backend::CPU);
|
||||
@@ -14,16 +14,16 @@ fn main() {
|
||||
}
|
||||
|
||||
// let n_iterations = 16384;
|
||||
let n_iterations = 2048;
|
||||
let n_iterations = 100;
|
||||
// let n_iterations = 10;
|
||||
|
||||
// let (width, height) = (512, 512);
|
||||
let (width, height) = (1024, 1024);
|
||||
let (width, height) = (512, 512);
|
||||
// let (width, height) = (1024, 1024);
|
||||
// let (width, height) = (2048, 2048);
|
||||
|
||||
// let n_particles = 1 << 22;
|
||||
let n_particles = 1 << 24;
|
||||
let n_particles = 1 << 22;
|
||||
// let n_particles = 1 << 10;
|
||||
// let n_particles = 1 << 20;
|
||||
// let n_particles = 100;
|
||||
println!("n_particles: {}", n_particles);
|
||||
let diffusivity = 1;
|
||||
@@ -37,22 +37,9 @@ fn main() {
|
||||
model.print_configurations();
|
||||
|
||||
if gpu_compute {
|
||||
model.step_cl(n_iterations);
|
||||
model.run_cl(n_iterations);
|
||||
} else {
|
||||
let pb = ProgressBar::new(n_iterations as u64);
|
||||
pb.set_style(
|
||||
ProgressStyle::default_bar()
|
||||
.template(
|
||||
"{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta} {percent}%, {per_sec})",
|
||||
)
|
||||
.progress_chars("#>-"),
|
||||
);
|
||||
|
||||
for i in 0..n_iterations {
|
||||
model.step();
|
||||
pb.set_position(i as u64);
|
||||
}
|
||||
pb.finish();
|
||||
model.run(n_iterations);
|
||||
}
|
||||
|
||||
|
||||
|
||||
245
src/model.rs
245
src/model.rs
@@ -169,69 +169,10 @@ impl Model {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/// Perform a single simulation step.
|
||||
pub fn step(&mut self) {
|
||||
// Combine grids
|
||||
let grids = &mut self.grids;
|
||||
combine(grids, &self.attraction_table);
|
||||
/// Simulates `steps` # of steps
|
||||
pub fn run(&mut self, steps: usize) {
|
||||
let debug: bool = true;
|
||||
|
||||
// println!("Starting tick for all agents...");
|
||||
// let agents_tick_time = Instant::now();
|
||||
self.agents.par_iter_mut().for_each(|agent| {
|
||||
let grid = &grids[agent.population_id];
|
||||
let PopulationConfig {
|
||||
sensor_distance,
|
||||
sensor_angle,
|
||||
rotation_angle,
|
||||
step_distance,
|
||||
..
|
||||
} = grid.config;
|
||||
let (width, height) = (grid.width, grid.height);
|
||||
|
||||
let xc = agent.x + agent.angle.cos() * sensor_distance;
|
||||
let yc = agent.y + agent.angle.sin() * sensor_distance;
|
||||
|
||||
let agent_add_sens = agent.angle + sensor_angle;
|
||||
let agent_sub_sens = agent.angle - sensor_angle;
|
||||
|
||||
let xl = agent.x + agent_sub_sens.cos() * sensor_distance;
|
||||
let yl = agent.y + agent_sub_sens.sin() * sensor_distance;
|
||||
let xr = agent.x + agent_add_sens.cos() * sensor_distance;
|
||||
let yr = agent.y + agent_add_sens.sin() * sensor_distance;
|
||||
|
||||
// Sense. We sense from the buffer because this is where we previously combined data
|
||||
// from all the grid.
|
||||
let trail_c = grid.get_buf(xc, yc);
|
||||
let trail_l = grid.get_buf(xl, yl);
|
||||
let trail_r = grid.get_buf(xr, yr);
|
||||
|
||||
// Rotate and move
|
||||
let mut rng = rand::thread_rng();
|
||||
let direction = Model::pick_direction(trail_c, trail_l, trail_r, &mut rng);
|
||||
agent.rotate_and_move(direction, rotation_angle, step_distance, width, height);
|
||||
});
|
||||
/*
|
||||
let agents_tick_elapsed = agents_tick_time.elapsed().as_millis();
|
||||
let ms_per_agent: f64 = (agents_tick_elapsed as f64) / (self.agents.len() as f64);
|
||||
println!("Finished tick for all agents. took {}ms\nTime peragent: {}ms", agents_tick_time.elapsed().as_millis(), ms_per_agent);
|
||||
*/
|
||||
|
||||
// Deposit
|
||||
for agent in self.agents.iter() {
|
||||
self.grids[agent.population_id].deposit(agent.x, agent.y);
|
||||
}
|
||||
|
||||
// Diffuse + Decay
|
||||
let diffusivity = self.diffusivity;
|
||||
self.grids.par_iter_mut().for_each(|grid| {
|
||||
grid.diffuse(diffusivity);
|
||||
});
|
||||
|
||||
self.save_image_data();
|
||||
self.iteration += 1;
|
||||
}
|
||||
|
||||
pub fn step_cl(&mut self, steps: usize) {
|
||||
let pb = ProgressBar::new(steps as u64);
|
||||
pb.set_style(
|
||||
ProgressStyle::default_bar()
|
||||
@@ -241,38 +182,18 @@ impl Model {
|
||||
.progress_chars("#>-"),
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
let agents_list = &*self.agents.clone();
|
||||
|
||||
|
||||
let agent_num: usize = self.agents.len() as usize;
|
||||
let dims = af::Dim4::new(&[self.agents.len() as u64, 1, 1, 1]);
|
||||
|
||||
|
||||
|
||||
let mut sensor_distance_list: Vec<f32> = Vec::new();
|
||||
let mut sensor_angle_list: Vec<f32> = Vec::new();
|
||||
let mut rotation_angle_list: Vec<f32> = Vec::new();
|
||||
let mut step_distance_list: Vec<f32> = Vec::new();
|
||||
|
||||
let mut agent_angles_list: Vec<f32> = Vec::new();
|
||||
let mut agent_x_list: Vec<f32> = Vec::new();
|
||||
let mut agent_y_list: Vec<f32> = Vec::new();
|
||||
|
||||
for i in 0..steps {
|
||||
println!("Starting tick for all agents...");
|
||||
let agents_tick_time = Instant::now();
|
||||
if debug {println!("Starting tick for all agents..."));
|
||||
|
||||
// Combine grids
|
||||
let grids = &mut self.grids;
|
||||
combine(grids, &self.attraction_table);
|
||||
agent_angles_list = agents_list.iter().map(|agent| agent.angle).collect();
|
||||
agent_x_list = agents_list.iter().map(|agent| agent.x).collect();
|
||||
agent_y_list = agents_list.iter().map(|agent| agent.y).collect();
|
||||
let agents_tick_time = Instant::now();
|
||||
self.agents.par_iter_mut().for_each(|agent| {
|
||||
let i: usize = agent.i;
|
||||
|
||||
for agent in &*self.agents.clone() {
|
||||
let grid = &grids.clone()[agent.population_id];
|
||||
let grid = &grids[agent.population_id];
|
||||
let (width, height) = (grid.width, grid.height);
|
||||
let PopulationConfig {
|
||||
sensor_distance,
|
||||
sensor_angle,
|
||||
@@ -280,19 +201,121 @@ impl Model {
|
||||
step_distance,
|
||||
..
|
||||
} = grid.config;
|
||||
sensor_distance_list.push(sensor_distance);
|
||||
sensor_angle_list.push(sensor_angle);
|
||||
rotation_angle_list.push(rotation_angle);
|
||||
step_distance_list.push(step_distance);
|
||||
|
||||
let xc = agent.x + agent.angle.cos() * sensor_distance;
|
||||
let yc = agent.y + agent.angle.sin() * sensor_distance;
|
||||
|
||||
let agent_add_sens = agent.angle + sensor_angle;
|
||||
let agent_sub_sens = agent.angle - sensor_angle;
|
||||
|
||||
let xl = agent.x + agent_sub_sens.cos() * sensor_distance;
|
||||
let yl = agent.y + agent_sub_sens.sin() * sensor_distance;
|
||||
let xr = agent.x + agent_add_sens.cos() * sensor_distance;
|
||||
let yr = agent.y + agent_add_sens.sin() * sensor_distance;
|
||||
|
||||
// Sense. We sense from the buffer because this is where we previously combined data
|
||||
// from all the grid.
|
||||
let trail_c = grid.get_buf(xc, yc);
|
||||
let trail_l = grid.get_buf(xl, yl);
|
||||
let trail_r = grid.get_buf(xr, yr);
|
||||
|
||||
// Rotate and move
|
||||
let mut rng = rand::thread_rng();
|
||||
let direction = Model::pick_direction(trail_c, trail_l, trail_r, &mut rng);
|
||||
agent.rotate_and_move(direction, rotation_angle, step_distance, width, height);
|
||||
});
|
||||
|
||||
if debug {
|
||||
let agents_tick_elapsed = agents_tick_time.elapsed().as_millis();
|
||||
let ms_per_agent: f64 = (agents_tick_elapsed as f64) / (self.agents.len() as f64);
|
||||
println!("Finished tick for all agents. took {}ms\nTime per agent: {}ms\n", agents_tick_time.elapsed().as_millis(), ms_per_agent);
|
||||
}
|
||||
|
||||
|
||||
// Deposit
|
||||
for agent in self.agents.iter() {
|
||||
self.grids[agent.population_id].deposit(agent.x, agent.y);
|
||||
}
|
||||
|
||||
let sensor_distance = af::Array::new(&sensor_distance_list, dims);
|
||||
let sensor_angle = af::Array::new(&sensor_angle_list, dims);
|
||||
// Diffuse + Decay
|
||||
let diffusivity = self.diffusivity;
|
||||
self.grids.par_iter_mut().for_each(|grid| {
|
||||
grid.diffuse(diffusivity);
|
||||
});
|
||||
|
||||
self.save_image_data();
|
||||
self.iteration += 1;
|
||||
pb.set_position(i as u64);
|
||||
}
|
||||
pb.finish();
|
||||
}
|
||||
|
||||
// Currently VERY poorly implemented (allocates memory each iteration)
|
||||
// I need to learn more about gpu compute to tackle this one
|
||||
pub fn run_cl(&mut self, steps: usize) {
|
||||
let pb = ProgressBar::new(steps as u64);
|
||||
pb.set_style(
|
||||
ProgressStyle::default_bar()
|
||||
.template(
|
||||
"{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len} ({eta} {percent}%, {per_sec})",
|
||||
)
|
||||
.progress_chars("#>-"),
|
||||
);
|
||||
|
||||
// Combine grids
|
||||
let grids = &mut self.grids;
|
||||
combine(grids, &self.attraction_table);
|
||||
|
||||
let agents_list = &*self.agents.clone();
|
||||
|
||||
|
||||
let agent_num: usize = agents_list.len() as usize;
|
||||
let dims = af::Dim4::new(&[agent_num as u64, 1, 1, 1]);
|
||||
|
||||
|
||||
let mut sensor_distance_list: Vec<f32> = Vec::new();
|
||||
let mut sensor_angle_list: Vec<f32> = Vec::new();
|
||||
let mut rotation_angle_list: Vec<f32> = Vec::new();
|
||||
let mut step_distance_list: Vec<f32> = Vec::new();
|
||||
|
||||
// Need to fix, super slow
|
||||
for agent in &*self.agents.clone() {
|
||||
let PopulationConfig {
|
||||
sensor_distance,
|
||||
sensor_angle,
|
||||
rotation_angle,
|
||||
step_distance,
|
||||
..
|
||||
} = &grids.clone()[agent.population_id].config;
|
||||
sensor_distance_list.push(*sensor_distance);
|
||||
sensor_angle_list.push(*sensor_angle);
|
||||
rotation_angle_list.push(*rotation_angle);
|
||||
step_distance_list.push(*step_distance);
|
||||
}
|
||||
|
||||
let sensor_distance = af::Array::new(&sensor_distance_list, dims);
|
||||
let sensor_angle = af::Array::new(&sensor_angle_list, dims);
|
||||
|
||||
|
||||
|
||||
let mut agent_angles_list: Vec<f32> = Vec::new();
|
||||
let mut agent_x_list: Vec<f32> = Vec::new();
|
||||
let mut agent_y_list: Vec<f32> = Vec::new();
|
||||
|
||||
for i in 0..steps {
|
||||
let grids = &mut self.grids;
|
||||
combine(grids, &self.attraction_table);
|
||||
|
||||
println!("Starting tick for all agents...");
|
||||
let agents_tick_time = Instant::now();
|
||||
agent_angles_list = agents_list.iter().map(|agent| agent.angle).collect();
|
||||
agent_x_list = agents_list.iter().map(|agent| agent.x).collect();
|
||||
agent_y_list = agents_list.iter().map(|agent| agent.y).collect();
|
||||
|
||||
|
||||
let agent_angles = af::Array::new(&agent_angles_list, dims);
|
||||
let agent_x = af::Array::new(&agent_x_list, dims);
|
||||
let agent_y = af::Array::new(&agent_y_list, dims);
|
||||
|
||||
let agent_angles = af::Array::new(&agent_angles_list, dims);
|
||||
|
||||
let cos_angles = af::cos(&agent_angles);
|
||||
let sin_angles = af::sin(&agent_angles);
|
||||
@@ -300,19 +323,27 @@ impl Model {
|
||||
let cos_angle_dis = af::mul(&cos_angles, &sensor_distance, false);
|
||||
let sin_angle_dis = af::mul(&sin_angles, &sensor_distance, false);
|
||||
|
||||
let xc = Self::to_vec(&af::add(&agent_x, &cos_angle_dis, false));
|
||||
let yc = Self::to_vec(&af::add(&agent_y, &sin_angle_dis, false));
|
||||
let xc_array = &af::add(&agent_x, &cos_angle_dis, false);
|
||||
let yc_array = &af::add(&agent_y, &sin_angle_dis, false);
|
||||
|
||||
let xc = Self::to_vec(xc_array);
|
||||
let yc = Self::to_vec(yc_array);
|
||||
|
||||
let agent_add_sens = &agent_angles + &sensor_angle;
|
||||
let agent_sub_sens = &agent_angles - &sensor_angle;
|
||||
let agent_add_sens = af::add(&agent_angles, &sensor_angle, false);
|
||||
let agent_sub_sens = af::sub(&agent_angles, &sensor_angle, false);
|
||||
|
||||
let agent_add_sens_mul = af::mul(&agent_add_sens, &sensor_distance, false);
|
||||
let agent_sub_sens_mul = af::mul(&agent_sub_sens, &sensor_distance, false);
|
||||
|
||||
let xl = Self::to_vec(&af::add(&agent_x, &af::sin(&agent_sub_sens_mul), false));
|
||||
let yl = Self::to_vec(&af::add(&agent_y, &af::sin(&agent_sub_sens_mul), false));
|
||||
let xr = Self::to_vec(&af::add(&agent_x, &af::sin(&agent_add_sens_mul), false));
|
||||
let yr = Self::to_vec(&af::add(&agent_y, &af::sin(&agent_add_sens_mul), false));
|
||||
let xl_array = &af::add(&agent_x, &af::sin(&agent_sub_sens_mul), false);
|
||||
let yl_array = &af::add(&agent_y, &af::sin(&agent_sub_sens_mul), false);
|
||||
let xr_array = &af::add(&agent_x, &af::sin(&agent_add_sens_mul), false);
|
||||
let yr_array = &af::add(&agent_y, &af::sin(&agent_add_sens_mul), false);
|
||||
|
||||
let xl = Self::to_vec(xl_array);
|
||||
let yl = Self::to_vec(yl_array);
|
||||
let xr = Self::to_vec(xr_array);
|
||||
let yr = Self::to_vec(yr_array);
|
||||
|
||||
|
||||
self.agents.par_iter_mut().for_each(|agent| {
|
||||
@@ -340,11 +371,9 @@ impl Model {
|
||||
agent.rotate_and_move(direction, rotation_angle, step_distance, width, height);
|
||||
});
|
||||
|
||||
// /*
|
||||
let agents_tick_elapsed = agents_tick_time.elapsed().as_millis();
|
||||
let ms_per_agent: f64 = (agents_tick_elapsed as f64) / (self.agents.len() as f64);
|
||||
println!("Finished tick for all agents. took {}ms\nTime peragent: {}ms", agents_tick_time.elapsed().as_millis(), ms_per_agent);
|
||||
// */
|
||||
println!("Finished tick for all agents. took {}ms\nTime per agent: {}ms\n", agents_tick_time.elapsed().as_millis(), ms_per_agent);
|
||||
|
||||
// Deposit
|
||||
for agent in self.agents.iter() {
|
||||
|
||||
Reference in New Issue
Block a user