memoize the region lookups for better perf
102s => 57s
This commit is contained in:
@@ -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"
|
||||||
|
@@ -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,
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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::*;
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user