add some more caching around the state file & geometry calculations

able to process a simulation in ~2 seconds in the optimistic path
This commit is contained in:
2022-02-01 18:31:47 -08:00
parent f0ab5ea29d
commit 0e98f8582a
3 changed files with 86 additions and 55 deletions

View File

@@ -134,7 +134,7 @@ struct Params {
pre_time: f32, // how long between set and clock
post_time: f32, // how long to wait after the clock
dump_frames: Option<u64>,
dump_frames: (u64, Option<u64>),
}
#[derive(Clone, Default, Serialize, Deserialize)]
@@ -337,33 +337,57 @@ fn derive_geometries(p: GeomParams) -> Option<Geometries> {
fn run_sim(id: u32, p: Params, g: Geometries) -> Results {
info!("run_sim {}: {:?}", id, p);
let m_to_um = |m: f32| (m * 1e6).round() as u32;
let feat_vol = p.geom.feat_size * p.geom.feat_size * p.geom.feat_size;
// mu_r=881.33, starting at H=25 to H=75.
let ferro_mat = mat::Ferroxcube3R1MH::new();
// let ferro_mat = mat::db::conductor(wire_conductivity);
let wire_mat = mat::IsomorphicConductor::new(p.wire_conductivity);
let mut driver: SpirvDriver<Mat> = Driver::new_spirv(g.dim, p.geom.feat_size);
driver.set_steps_per_stim(1000);
driver.fill_region(&g.ferro1_region, ferro_mat);
driver.fill_region(&g.ferro2_region, ferro_mat);
driver.fill_region(&g.set1_region, wire_mat);
driver.fill_region(&g.set2_region, wire_mat);
driver.fill_region(&g.coupling_region, wire_mat);
info!("boundary: {}um; {}um", m_to_um(p.geom.boundary_xy), m_to_um(p.geom.boundary_z));
info!("size: {:?}", g.dim);
info!("ferro1: {:?}", g.ferro1_region.center());
info!("ferro2: {:?}", g.ferro2_region.center());
driver.add_classical_boundary(Meters::new(p.geom.boundary_xy, p.geom.boundary_xy, p.geom.boundary_z));
// assert!(driver.test_region_filled(&g.ferro1_region, ferro_mat));
// assert!(driver.test_region_filled(&g.ferro2_region, ferro_mat));
// assert!(driver.test_region_filled(&g.set1_region, wire_mat));
// assert!(driver.test_region_filled(&g.set2_region, wire_mat));
// assert!(driver.test_region_filled(&g.coupling_region, wire_mat));
let base = format!("buffer5-{}", id);
let prefix = format!("out/{}/{}-{}-{}setmA-{}setps-{}clkmA-{}clkps-{}um-{}ferromaj-{}:{}wraps-{}:{}cov-{:?}clk",
base,
base,
*g.dim.to_index(p.geom.feat_size),
(p.peak_set_current * 1e3).round() as i64,
(p.set_duration * 1e12).round() as i64,
(p.peak_clock_current * 1e3).round() as i64,
(p.clock_duration * 1e12).round() as i64,
(p.geom.feat_size * 1e6).round() as i64,
p.geom.ferro_major,
p.geom.wraps1,
p.geom.wraps2,
p.geom.wrap1_coverage,
p.geom.wrap2_coverage,
p.clock_type,
);
let mut driver: SpirvDriver<Mat> = Driver::new_spirv(g.dim, p.geom.feat_size);
driver.set_steps_per_stim(1000);
if !driver.add_state_file(&*format!("{}/state.bc", prefix), 16000) {
// mu_r=881.33, starting at H=25 to H=75.
let ferro_mat = mat::Ferroxcube3R1MH::new();
// let ferro_mat = mat::db::conductor(wire_conductivity);
let wire_mat = mat::IsomorphicConductor::new(p.wire_conductivity);
driver.fill_region(&g.ferro1_region, ferro_mat);
driver.fill_region(&g.ferro2_region, ferro_mat);
driver.fill_region(&g.set1_region, wire_mat);
driver.fill_region(&g.set2_region, wire_mat);
driver.fill_region(&g.coupling_region, wire_mat);
driver.add_classical_boundary(Meters::new(p.geom.boundary_xy, p.geom.boundary_xy, p.geom.boundary_z));
// assert!(driver.test_region_filled(&g.ferro1_region, ferro_mat));
// assert!(driver.test_region_filled(&g.ferro2_region, ferro_mat));
// assert!(driver.test_region_filled(&g.set1_region, wire_mat));
// assert!(driver.test_region_filled(&g.set2_region, wire_mat));
// assert!(driver.test_region_filled(&g.coupling_region, wire_mat));
} else {
info!("loaded state file: skipping geometry calculations");
}
let add_drive_sine_pulse = |driver: &mut SpirvDriver<Mat>, region: &Torus, start: f32, duration: f32, amp: f32| {
let wave = Sinusoid1::from_wavelength(amp, duration * 2.0)
@@ -445,24 +469,6 @@ fn run_sim(id: u32, p: Params, g: Geometries) -> Results {
driver.add_measurement(meas::Current::new("couplingtop", g.coupling_wire_top.clone()));
driver.add_measurement(meas::Current::new("couplingbot", g.coupling_wire_bot.clone()));
let base = format!("buffer5-{}", id);
let prefix = format!("out/{}/{}-{}-{}setmA-{}setps-{}clkmA-{}clkps-{}um-{}ferromaj-{}:{}wraps-{}:{}cov-{:?}clk",
base,
base,
*driver.size(),
(p.peak_set_current * 1e3).round() as i64,
(p.set_duration * 1e12).round() as i64,
(p.peak_clock_current * 1e3).round() as i64,
(p.clock_duration * 1e12).round() as i64,
(p.geom.feat_size * 1e6).round() as i64,
p.geom.ferro_major,
p.geom.wraps1,
p.geom.wraps2,
p.geom.wrap1_coverage,
p.geom.wrap2_coverage,
p.clock_type,
);
if p.dry_run {
info!("bailing (dry run): {}", prefix);
return Results::default();
@@ -470,8 +476,8 @@ fn run_sim(id: u32, p: Params, g: Geometries) -> Results {
let _ = std::fs::create_dir_all(&prefix);
driver.add_state_file(&*format!("{}/state.bc", prefix), 16000);
driver.add_serializer_renderer(&*format!("{}/frame-", prefix), 32000, p.dump_frames);
let (frame_freq, frame_limit) = p.dump_frames;
driver.add_serializer_renderer(&*format!("{}/frame-", prefix), frame_freq, frame_limit);
let meas_csv = format!("{}/meas.csv", prefix);
let meas_sparse_csv = format!("{}/meas-sparse.csv", prefix);
driver.add_csv_renderer(&*meas_csv, 400, None);
@@ -526,23 +532,24 @@ fn main() {
// for (wrap1_cov, wrap2_cov) in [(0.8, 0.8), (0.8, 0.25), (0.25, 0.8)] {
let clock_domain = [
(25600.0, 5.0 * ns),
(6400.0, 5.0 * ns),
// (1600.0, 5.0 * ns), // low relevance for large cores
// (1600.0, 1.0 * ns), // very poor perf (0.05 m2_stable_m1_peak)
(25600.0, 1.0 * ns),
// (6400.0, 1.0 * ns), // low relevance for large cores
// (51200.0, 1.0 * ns),
(102400.0, 1.0 * ns),
// (409600.0, 1.0 * ns), // I(set1) shows significant underdamping => bad m2_stable_m1_peak
(12800.0, 5.0 * ns),
(51200.0, 5.0 * ns),
// (400.0, 25.0 * ns), // poor perf (0.28 m2_stable_m1_peak)
// (1600.0, 25.0 * ns), // mediocre perf (0.65 m2_stable_m1_peak)
(12800.0, 5.0 * ns),
// TODO: RE-ENABLE
// (6400.0, 25.0 * ns), // suspended because costly
(12800.0, 25.0 * ns), // suspended because costly
// (25600.0, 25.0 * ns), // suspended because costly
// (6400.0, 5.0 * ns), // low relevance for large cores (for >= 9mm rad, <0.5 m2_stable_m1_peak)
// (409600.0, 1.0 * ns), // I(set1) shows significant underdamping => bad m2_stable_m1_peak
// (400.0, 25.0 * ns), // poor perf (0.28 m2_stable_m1_peak)
// (1600.0, 25.0 * ns), // mediocre perf (0.65 m2_stable_m1_peak)
// (1600.0, 100.0 * ns),
// (6400.0, 100.0 * ns),
@@ -566,8 +573,10 @@ fn main() {
// 1680.0 * um
];
let wrap2_densities = [
-0.05,
-0.15,
-0.3,
-0.5,
// 0.3,
// 0.2,
// 0.15,
@@ -613,6 +622,12 @@ fn main() {
}
}
}
info!(
"evaluating {} variants ({} time increments of {} primitives)",
variants.len(),
post_times.len(),
variants.len() / post_times.len(),
);
let mut geom_cache = DiskCache::new_with_supplier(
&format!("out/buffer5-{}/.geom_cache", i),
@@ -656,7 +671,7 @@ fn main() {
pre_time: 1e-9,
post_time,
dump_frames: Some(256000),
dump_frames: (256000, Some(257000)),
};
let wraps1_choices: Vec<_> = (-120..120)
@@ -712,7 +727,7 @@ fn main() {
let mut params = base_params;
params.geom.wraps1 = wraps1;
params.geom.wraps2 = wraps2;
match derive_geometries(params.geom.clone()) {
match geom_cache.get_or_insert_from_supplier(params.geom.clone()) {
Some(geoms) => {
run_sim(i, params, geoms);
},