remove gpu compute stuff (didn't work at all, might revisit later)
This commit is contained in:
parent
d36bec61f4
commit
e07aa5ca0a
@ -12,8 +12,6 @@ itertools = "0.10"
|
|||||||
rand = "0.8.3"
|
rand = "0.8.3"
|
||||||
rand_distr = "0.4"
|
rand_distr = "0.4"
|
||||||
rayon = "1.5"
|
rayon = "1.5"
|
||||||
arrayfire = {git = "https://github.com/arrayfire/arrayfire-rust.git"}
|
|
||||||
#arrayfire = "3.8.0"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.3"
|
criterion = "0.3"
|
||||||
|
|||||||
41
src/main.rs
41
src/main.rs
@ -2,17 +2,8 @@ use chrono::{DateTime, Utc};
|
|||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use physarum::model;
|
use physarum::model;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use arrayfire as af;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let gpu_compute: bool = false;
|
|
||||||
if gpu_compute {
|
|
||||||
backend_man();
|
|
||||||
// af::set_backend(af::Backend::CPU);
|
|
||||||
af::set_device(0);
|
|
||||||
af::info();
|
|
||||||
}
|
|
||||||
|
|
||||||
// let n_iterations = 16384;
|
// let n_iterations = 16384;
|
||||||
let n_iterations = 1024;
|
let n_iterations = 1024;
|
||||||
// let n_iterations = 100;
|
// let n_iterations = 100;
|
||||||
@ -38,11 +29,7 @@ fn main() {
|
|||||||
let mut model = model::Model::new(width, height, n_particles, n_populations, diffusivity);
|
let mut model = model::Model::new(width, height, n_particles, n_populations, diffusivity);
|
||||||
model.print_configurations();
|
model.print_configurations();
|
||||||
|
|
||||||
if gpu_compute {
|
|
||||||
model.run_cl(n_iterations);
|
|
||||||
} else {
|
|
||||||
model.run(n_iterations);
|
model.run(n_iterations);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
println!("Rendering all saved image data....");
|
println!("Rendering all saved image data....");
|
||||||
@ -50,31 +37,3 @@ fn main() {
|
|||||||
model.flush_image_data();
|
model.flush_image_data();
|
||||||
println!("Done!");
|
println!("Done!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn backend_man() {
|
|
||||||
let available = af::get_available_backends();
|
|
||||||
|
|
||||||
if available.contains(&af::Backend::CUDA) {
|
|
||||||
println!("Evaluating CUDA Backend...");
|
|
||||||
af::set_backend(af::Backend::CUDA);
|
|
||||||
println!("There are {} CUDA compute devices", af::device_count());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
if available.contains(&af::Backend::OPENCL) {
|
|
||||||
println!("Evaluating OpenCL Backend...");
|
|
||||||
af::set_backend(af::Backend::OPENCL);
|
|
||||||
println!("There are {} OpenCL compute devices", af::device_count());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if available.contains(&af::Backend::CPU) {
|
|
||||||
println!("Evaluating CPU Backend...");
|
|
||||||
af::set_backend(af::Backend::CPU);
|
|
||||||
println!("There are {} CPU compute devices", af::device_count());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
150
src/model.rs
150
src/model.rs
@ -12,7 +12,6 @@ use std::f32::consts::TAU;
|
|||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use rayon::iter::{ParallelIterator, IntoParallelIterator};
|
use rayon::iter::{ParallelIterator, IntoParallelIterator};
|
||||||
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle};
|
use indicatif::{ParallelProgressIterator, ProgressBar, ProgressStyle};
|
||||||
use arrayfire as af;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
/// A single Physarum agent. The x and y positions are continuous, hence we use floating point
|
/// A single Physarum agent. The x and y positions are continuous, hence we use floating point
|
||||||
@ -250,155 +249,6 @@ impl Model {
|
|||||||
pb.finish();
|
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_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);
|
|
||||||
|
|
||||||
let cos_angle_dis = af::mul(&cos_angles, &sensor_distance, false);
|
|
||||||
let sin_angle_dis = af::mul(&sin_angles, &sensor_distance, 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 = 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_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| {
|
|
||||||
let i: usize = agent.i;
|
|
||||||
|
|
||||||
let rotation_angle = rotation_angle_list[i];
|
|
||||||
let step_distance = rotation_angle_list[i];
|
|
||||||
|
|
||||||
let xc = xc[i];
|
|
||||||
let xl = xl[i];
|
|
||||||
let xr = xr[i];
|
|
||||||
let yc = yc[i];
|
|
||||||
let yl = yl[i];
|
|
||||||
let yr = yr[i];
|
|
||||||
|
|
||||||
let grid = &grids[agent.population_id];
|
|
||||||
let (width, height) = (grid.width, grid.height);
|
|
||||||
|
|
||||||
let trail_c = grid.get_buf(xc, yc);
|
|
||||||
let trail_l = grid.get_buf(xl, yl);
|
|
||||||
let trail_r = grid.get_buf(xr, yr);
|
|
||||||
|
|
||||||
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 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_vec<T:af::HasAfEnum+Default+Clone>(array: &af::Array<T>) -> Vec<T> {
|
|
||||||
let mut vec = vec!(T::default();array.elements());
|
|
||||||
array.host(&mut vec);
|
|
||||||
return vec;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn save_image_data(&mut self) {
|
fn save_image_data(&mut self) {
|
||||||
let grids = self.grids.clone();
|
let grids = self.grids.clone();
|
||||||
self.img_data_vec.push(ImgData::new(grids, self.palette, self.iteration));
|
self.img_data_vec.push(ImgData::new(grids, self.palette, self.iteration));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user