memoize the region lookups for better perf

102s => 57s
This commit is contained in:
2022-01-11 16:21:05 -08:00
parent 3cbab61aa0
commit 8bda52d973
6 changed files with 63 additions and 14 deletions

View File

@@ -15,6 +15,7 @@ bincode = "1.3"
common_macros = "0.1" common_macros = "0.1"
crossterm = "0.20" crossterm = "0.20"
csv = "1.1" csv = "1.1"
dashmap = "5.0"
decorum = "0.3" decorum = "0.3"
dyn-clone = "1.0" dyn-clone = "1.0"
enum_dispatch = "0.3" enum_dispatch = "0.3"

View File

@@ -3,7 +3,7 @@
//! clock -> mem2 coupling //! clock -> mem2 coupling
use coremem::{Driver, mat, meas, SpirvDriver}; use coremem::{Driver, mat, meas, SpirvDriver};
use coremem::geom::{region, Cube, Dilate, Meters, Region, Spiral, SwapYZ, Torus, Translate, Wrap}; use coremem::geom::{region, Cube, Dilate, Memoize, Meters, Region, Spiral, SwapYZ, Torus, Translate, Wrap};
use coremem::stim::{CurlStimulus, Gated, Sinusoid1, TimeVarying1 as _}; use coremem::stim::{CurlStimulus, Gated, Sinusoid1, TimeVarying1 as _};
use log::info; use log::info;
@@ -71,7 +71,7 @@ fn run_sim(id: u32, p: Params) {
let set1_region = Torus::new_xz(set1_center, p.wire_set_major, p.wire_minor); let set1_region = Torus::new_xz(set1_center, p.wire_set_major, p.wire_minor);
let set2_region = Torus::new_xz(set2_center, p.wire_set_major, p.wire_minor); let set2_region = Torus::new_xz(set2_center, p.wire_set_major, p.wire_minor);
let coupling_region1 = Dilate::new( let coupling_region1 = Memoize::new(Dilate::new(
Wrap::new_about( Wrap::new_about(
Translate::new( Translate::new(
SwapYZ::new(region::and( SwapYZ::new(region::and(
@@ -85,9 +85,9 @@ fn run_sim(id: u32, p: Params) {
), ),
p.wire_wrap_dilation, p.wire_wrap_dilation,
p.wire_wrap_dilation / (p.wire_wrap_iters as f32), p.wire_wrap_dilation / (p.wire_wrap_iters as f32),
); ));
let coupling_region2 = Dilate::new( let coupling_region2 = Memoize::new(Dilate::new(
Wrap::new_about( Wrap::new_about(
Translate::new( Translate::new(
SwapYZ::new(region::and_not( SwapYZ::new(region::and_not(
@@ -101,7 +101,7 @@ fn run_sim(id: u32, p: Params) {
), ),
p.wire_wrap_dilation, p.wire_wrap_dilation,
p.wire_wrap_dilation / (p.wire_wrap_iters as f32), p.wire_wrap_dilation / (p.wire_wrap_iters as f32),
); ));
let coupling_wire_top = Cube::new_centered( let coupling_wire_top = Cube::new_centered(
ferro_center - Meters::new_y(p.ferro_major + 4.0*p.wire_wrap_minor + 12.0*p.feat_size), ferro_center - Meters::new_y(p.ferro_major + 4.0*p.wire_wrap_minor + 12.0*p.feat_size),
@@ -192,8 +192,6 @@ fn run_sim(id: u32, p: Params) {
p.feat_size, p.feat_size,
).unwrap()); ).unwrap());
return;
// mu_r=881.33, starting at H=25 to H=75. // mu_r=881.33, starting at H=25 to H=75.
let ferro_mat = mat::MHPgram::new(25.0, 881.33, 44000.0); let ferro_mat = mat::MHPgram::new(25.0, 881.33, 44000.0);
// let ferro_mat = mat::db::conductor(wire_conductivity); // let ferro_mat = mat::db::conductor(wire_conductivity);
@@ -279,6 +277,8 @@ fn run_sim(id: u32, p: Params) {
driver.add_measurement(meas::Current::new("couplingtop", coupling_wire_top.clone())); driver.add_measurement(meas::Current::new("couplingtop", coupling_wire_top.clone()));
driver.add_measurement(meas::Current::new("couplingbot", coupling_wire_bot.clone())); driver.add_measurement(meas::Current::new("couplingbot", coupling_wire_bot.clone()));
return;
let prefix = format!("out/{}/{}-{}-{}setmA-{}setps-{}clkmA-{}clkps-{}um-{}:{}wraps", let prefix = format!("out/{}/{}-{}-{}setmA-{}setps-{}clkmA-{}clkps-{}um-{}:{}wraps",
base, base,
base, base,

View File

@@ -8,9 +8,9 @@ mod vecu;
pub use line::Line2d; pub use line::Line2d;
pub use polygon::Polygon2d; pub use polygon::Polygon2d;
pub use region::{ pub use region::{
Cube, CylinderZ, Dilate, InvertedRegion, Region, Sphere, Spiral, SwapXZ, SwapYZ, Torus, Translate, Union, WorldRegion, Wrap Cube, CylinderZ, Dilate, InvertedRegion, Memoize, Region, Sphere, Spiral, SwapXZ, SwapYZ, Torus, Translate, Union, WorldRegion, Wrap
}; };
pub use units::{Coord, Meters, Index}; pub use units::{Coord, Meters, OrdMeters, Index};
pub use vec::{Vec2, Vec3}; pub use vec::{Vec2, Vec3};
pub use vecu::Vec3u; pub use vecu::Vec3u;

View File

@@ -1,10 +1,11 @@
use crate::geom::{Coord, Index, Meters}; use crate::geom::{Coord, Index, Meters, OrdMeters};
use dyn_clone::{self, DynClone}; use dyn_clone::{self, DynClone};
use log::info; use log::info;
use rayon::prelude::*; use rayon::prelude::*;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use std::collections::{BTreeMap, BTreeSet}; use std::collections::{BTreeMap, BTreeSet};
use std::sync::{Arc, RwLock};
mod primitives; mod primitives;
pub use primitives::*; pub use primitives::*;
@@ -257,8 +258,6 @@ impl Dilate {
#[typetag::serde] #[typetag::serde]
impl Region for Dilate { impl Region for Dilate {
fn contains(&self, p: Meters) -> bool { fn contains(&self, p: Meters) -> bool {
let small = p - Meters::new(self.rad, self.rad, self.rad);
let large = p + Meters::new(self.rad, self.rad, self.rad);
let rad_iters = (self.rad / self.res).ceil() as i32; let rad_iters = (self.rad / self.res).ceil() as i32;
let rad_range = -rad_iters..=rad_iters; let rad_range = -rad_iters..=rad_iters;
let rad_sq = self.rad * self.rad; let rad_sq = self.rad * self.rad;
@@ -280,6 +279,29 @@ impl Region for Dilate {
} }
} }
#[derive(Clone, Serialize, Deserialize)]
pub struct Memoize {
#[serde(skip)]
lut: Arc<dashmap::DashMap<OrdMeters, bool>>,
inner: Box<dyn Region>,
}
impl Memoize {
pub fn new<R: Region + 'static>(inner: R) -> Self {
Self {
lut: Arc::new(dashmap::DashMap::new()),
inner: Box::new(inner),
}
}
}
#[typetag::serde]
impl Region for Memoize {
fn contains(&self, p: Meters) -> bool {
*self.lut.entry(OrdMeters(p)).or_insert_with(|| self.inner.contains(p))
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;

View File

@@ -2,7 +2,9 @@ use crate::real::ToFloat;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use super::{Vec3, Vec3u}; use super::{Vec3, Vec3u};
use std::fmt::{self, Display}; use std::fmt::{self, Display};
use std::cmp::Ordering;
use std::ops::{Add, Deref, Div, Mul, Neg, Sub}; use std::ops::{Add, Deref, Div, Mul, Neg, Sub};
use std::hash::{Hash, Hasher};
pub trait Coord: Copy + Clone { pub trait Coord: Copy + Clone {
fn to_meters(&self, feature_size: f32) -> Meters; fn to_meters(&self, feature_size: f32) -> Meters;
@@ -15,7 +17,7 @@ pub trait Coord: Copy + Clone {
fn from_either(i: Index, m: Meters) -> Self; fn from_either(i: Index, m: Meters) -> Self;
} }
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct Meters(pub Vec3<f32>); pub struct Meters(pub Vec3<f32>);
impl Meters { impl Meters {
@@ -105,6 +107,30 @@ impl Display for Meters {
} }
} }
#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct OrdMeters(pub Meters);
impl Deref for OrdMeters {
type Target = Meters;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Ord for OrdMeters {
fn cmp(&self, other: &Self) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
impl Eq for OrdMeters { }
impl Hash for OrdMeters {
fn hash<H: Hasher>(&self, state: &mut H) {
let bits: (u32, u32, u32) = unsafe { std::mem::transmute(*self) };
bits.hash(state)
}
}
#[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, Default, Hash, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
pub struct Index(pub Vec3u); pub struct Index(pub Vec3u);

View File

@@ -134,7 +134,7 @@ impl<R: Real> Vec2<R> {
} }
} }
#[derive(Copy, Clone, Debug, Default, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct Vec3<R=f32> { pub struct Vec3<R=f32> {
pub(crate) x: R, pub(crate) x: R,
pub(crate) y: R, pub(crate) y: R,