Browse Source

rayon parallel sort is not actually parallel. but i still made the parallelism work.

main
Thomas Johnson 11 months ago
parent
commit
1775709b34
  1. 10
      src/genetic.rs
  2. 2
      src/main.rs
  3. 17
      src/map.rs

10
src/genetic.rs

@ -48,13 +48,19 @@ impl<T: Genetic> Arena<T> {
}
impl <T: Genetic> Arena<T> where
T: Sync,
T: Send + Sync,
T::Configuration: Sync,
{
pub fn par_process<F: Fn(&mut T, &T::Configuration) + Sync>(&mut self, f: F) {
self.set.par_iter_mut().for_each(|x| f(x, &self.config));
let config = &self.config;
self.set.par_iter_mut().for_each(|x| f(x, config));
}
}
impl<T: Genetic> Arena<T> where
T: Send,
T::Configuration: Sync,
{
pub fn par_cull(&mut self) {
let config = &self.config;
let set = &mut self.set;

2
src/main.rs

@ -30,7 +30,7 @@ fn main() {
for i in 0..50 {
println!("iteration {}", i);
arena.generate(&mut rng);
// arena.par_process(|map, cfg| { map.cost(cfg); });
arena.par_process(|map, cfg| { map.cost(cfg); });
arena.par_cull();
let map = &arena.set[0];

17
src/map.rs

@ -1,6 +1,5 @@
use crate::{transform::{Transform, NCOLORS}, genetic::Genetic};
use core::fmt::Debug;
use core::cell::Cell;
use std::sync::RwLock;
use rand::{Rng, distributions::{Uniform, WeightedIndex}};
use rand_distr::{Distribution, Bernoulli};
@ -10,14 +9,14 @@ use image::{Rgb, GenericImage, ImageBuffer};
pub struct Map
{
transforms: Vec<Transform>,
cached_cost: Cell<Option<f32>>,
cached_cost: RwLock<Option<f32>>,
}
impl Clone for Map {
fn clone(&self) -> Self {
Self {
transforms: self.transforms.clone(),
cached_cost: Cell::new(None),
cached_cost: RwLock::new(None),
}
}
}
@ -38,8 +37,8 @@ impl Map {
}
pub fn cost(&self, cfg: &MapGeneticConfig) -> f32 {
println!("computing cost in thread {:?}", std::thread::current().id());
if let Some(c) = self.cached_cost.get() {
let cached = { *self.cached_cost.read().unwrap() };
if let Some(c) = cached {
c
} else {
let mut input = ImageBuffer::from_fn(cfg.dims.0, cfg.dims.1, |_, _| Rgb([0.0, 0.0, 0.0]));
@ -60,13 +59,13 @@ impl Map {
let variance = a_a / cfg.ndof as f32 - sum_a * sum_a / (cfg.ndof * cfg.ndof) as f32;
if denom == 0.0 || variance > 50.0 {
// if the image is entirely zero or it doesn't appear to converge, return infinite cost
self.cached_cost.set(Some(f32::INFINITY));
*self.cached_cost.write().unwrap() = Some(f32::INFINITY);
f32::INFINITY
} else {
let a_x = image_dot_product(&input, &cfg.goal_image);
let numer = a_x * a_x * cfg.ndof as f32 - 2.0 * a_x * sum_a * cfg.goal_sum + cfg.goal_sum * cfg.goal_sum * a_a;
let cost = cfg.goal_dot - numer / denom;
self.cached_cost.set(Some(cost));
*self.cached_cost.write().unwrap() = Some(cost);
cost
}
}
@ -113,7 +112,7 @@ impl Genetic for Map
}
Map {
transforms: new_tfs,
cached_cost: Cell::new(None),
cached_cost: RwLock::new(None),
}
}
1 => {
@ -183,7 +182,7 @@ impl MapGeneticConfig {
}
Map {
transforms,
cached_cost: Cell::new(None),
cached_cost: RwLock::new(None),
}
}

Loading…
Cancel
Save