Parallelize measurements

This commit is contained in:
2020-12-15 15:14:39 -08:00
parent 6362b5a60e
commit d911b8cf34
2 changed files with 26 additions and 13 deletions

View File

@@ -50,7 +50,11 @@ impl AbstractMeasurement for Label {
} }
} }
fn sum_over_region<T: Default + Sum<T>, F: Fn(Meters, &Cell) -> T>(state: &dyn GenericSim, r: &dyn Region, f: F) -> T { fn sum_over_region<T, F>(state: &dyn GenericSim, r: &dyn Region, f: F) -> T
where
T: Sum<T> + Default + Send,
F: Fn(Meters, &Cell) -> T + Sync,
{
state.map_sum_enumerated(|coord, cell| { state.map_sum_enumerated(|coord, cell| {
if r.contains(coord) { if r.contains(coord) {
f(coord, cell) f(coord, cell)

View File

@@ -6,6 +6,7 @@ use dyn_clone::{self, DynClone};
use log::trace; use log::trace;
use ndarray::{Array3, Zip}; use ndarray::{Array3, Zip};
use rayon::prelude::*;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use std::convert::From; use std::convert::From;
use std::iter::Sum; use std::iter::Sum;
@@ -56,22 +57,26 @@ impl<'a> dyn GenericSim + 'a {
/// Apply `F` to each Cell, and sum the results. /// Apply `F` to each Cell, and sum the results.
pub fn map_sum<F, Ret>(&self, f: F) -> Ret pub fn map_sum<F, Ret>(&self, f: F) -> Ret
where where
F: Fn(&Cell<mat::Static>) -> Ret, F: Fn(&Cell<mat::Static>) -> Ret + Sync,
Ret: Sum<Ret>, Ret: Sum<Ret> + Send,
{ {
self.map_sum_enumerated(|_at: Index, cell| f(cell)) self.map_sum_enumerated(|_at: Index, cell| f(cell))
} }
pub fn map_sum_enumerated<C, F, Ret>(&self, f: F) -> Ret pub fn map_sum_enumerated<C, F, Ret>(&self, f: F) -> Ret
where C: Coord, where C: Coord,
F: Fn(C, &Cell<mat::Static>) -> Ret, F: Fn(C, &Cell<mat::Static>) -> Ret + Sync,
Ret: Sum<Ret> Ret: Sum<Ret> + Send,
{ {
let (w, h, d) = (self.width(), self.height(), self.depth()); let (w, h, d) = (self.width(), self.height(), self.depth());
(0..d).map(|z| (0..h).map(|y| (0..w).map(|x| { (0..d).into_par_iter().map(
|z| (0..h).into_par_iter().map_with(z,
|&mut z, y| (0..w).into_par_iter().map_with((z, y),
|&mut (z, y), x|
{
let at = Index(Vec3u::new(x, y, z)); let at = Index(Vec3u::new(x, y, z));
f(C::from_index(at, self.feature_size()), &self.get(at)) f(C::from_index(at, self.feature_size()), &self.get(at))
}).sum()).sum()).sum() }))).flatten().flatten().sum()
} }
pub fn volume_of_region<R: Region>(&self, region: &R) -> u32 { pub fn volume_of_region<R: Region>(&self, region: &R) -> u32 {
@@ -81,8 +86,8 @@ impl<'a> dyn GenericSim + 'a {
/// Apply `F` to each Cell, and sum the results. /// Apply `F` to each Cell, and sum the results.
pub fn map_sum_over<F, Ret, Reg>(&self, region: &Reg, f: F) -> Ret pub fn map_sum_over<F, Ret, Reg>(&self, region: &Reg, f: F) -> Ret
where where
F: Fn(&Cell<mat::Static>) -> Ret, F: Fn(&Cell<mat::Static>) -> Ret + Sync,
Ret: Sum<Ret> + Default, Ret: Sum<Ret> + Default + Send,
Reg: Region Reg: Region
{ {
self.map_sum_over_enumerated(region, |_at: Index, cell| f(cell)) self.map_sum_over_enumerated(region, |_at: Index, cell| f(cell))
@@ -90,12 +95,16 @@ impl<'a> dyn GenericSim + 'a {
pub fn map_sum_over_enumerated<C, F, Ret, Reg>(&self, region: &Reg, f: F) -> Ret pub fn map_sum_over_enumerated<C, F, Ret, Reg>(&self, region: &Reg, f: F) -> Ret
where C: Coord, where C: Coord,
F: Fn(C, &Cell<mat::Static>) -> Ret, F: Fn(C, &Cell<mat::Static>) -> Ret + Sync,
Ret: Sum<Ret> + Default, Ret: Sum<Ret> + Default + Send,
Reg: Region, Reg: Region,
{ {
let (w, h, d) = (self.width(), self.height(), self.depth()); let (w, h, d) = (self.width(), self.height(), self.depth());
(0..d).map(|z| (0..h).map(|y| (0..w).map(|x| { (0..d).into_par_iter().map(
|z| (0..h).into_par_iter().map_with(z,
|&mut z, y| (0..w).into_par_iter().map_with((z, y),
|&mut (z, y), x|
{
let at = Index(Vec3u::new(x, y, z)); let at = Index(Vec3u::new(x, y, z));
let meters = at.to_meters(self.feature_size()); let meters = at.to_meters(self.feature_size());
if region.contains(meters) { if region.contains(meters) {
@@ -103,7 +112,7 @@ impl<'a> dyn GenericSim + 'a {
} else { } else {
Default::default() Default::default()
} }
}).sum()).sum()).sum() }))).flatten().flatten().sum()
} }
pub fn current<C: Coord>(&self, c: C) -> Vec3 { pub fn current<C: Coord>(&self, c: C) -> Vec3 {