memoize the region lookups for better perf

102s => 57s
This commit is contained in:
Colin 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"
crossterm = "0.20"
csv = "1.1"
dashmap = "5.0"
decorum = "0.3"
dyn-clone = "1.0"
enum_dispatch = "0.3"

View File

@ -3,7 +3,7 @@
//! clock -> mem2 coupling
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 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 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(
Translate::new(
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_iters as f32),
);
));
let coupling_region2 = Dilate::new(
let coupling_region2 = Memoize::new(Dilate::new(
Wrap::new_about(
Translate::new(
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_iters as f32),
);
));
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),
@ -192,8 +192,6 @@ fn run_sim(id: u32, p: Params) {
p.feat_size,
).unwrap());
return;
// 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::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("couplingbot", coupling_wire_bot.clone()));
return;
let prefix = format!("out/{}/{}-{}-{}setmA-{}setps-{}clkmA-{}clkps-{}um-{}:{}wraps",
base,
base,

View File

@ -8,9 +8,9 @@ mod vecu;
pub use line::Line2d;
pub use polygon::Polygon2d;
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 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 log::info;
use rayon::prelude::*;
use serde::{Serialize, Deserialize};
use std::collections::{BTreeMap, BTreeSet};
use std::sync::{Arc, RwLock};
mod primitives;
pub use primitives::*;
@ -257,8 +258,6 @@ impl Dilate {
#[typetag::serde]
impl Region for Dilate {
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_range = -rad_iters..=rad_iters;
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)]
mod test {
use super::*;

View File

@ -2,7 +2,9 @@ use crate::real::ToFloat;
use serde::{Serialize, Deserialize};
use super::{Vec3, Vec3u};
use std::fmt::{self, Display};
use std::cmp::Ordering;
use std::ops::{Add, Deref, Div, Mul, Neg, Sub};
use std::hash::{Hash, Hasher};
pub trait Coord: Copy + Clone {
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;
}
#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)]
#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct Meters(pub Vec3<f32>);
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)]
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(crate) x: R,
pub(crate) y: R,