driver: all the user to configure the number of steps to go between stimulus application

This commit is contained in:
2022-08-21 18:22:11 -07:00
parent a414bd77d4
commit 6c9a6e1ffa
2 changed files with 21 additions and 3 deletions

View File

@@ -308,12 +308,13 @@ fn main() {
driver.add_stimulus(s);
}
let prefix = "out/applications/multi_core_inverter/20-4ns-1e7A/";
let prefix = "out/applications/multi_core_inverter/23-4ns-1e7A/";
let _ = std::fs::create_dir_all(&prefix);
driver.add_state_file(&*format!("{}state.bc", prefix), 6400);
driver.add_serializer_renderer(&*format!("{}frame-", prefix), 6400, None);
// driver.add_csv_renderer(&*format!("{}meas-detailed.csv", prefix), 100, None);
driver.add_csv_renderer(&*format!("{}meas.csv", prefix), 800, None);
driver.set_steps_per_stimulus(100);
driver.step_until(duration);
}

View File

@@ -129,6 +129,15 @@ impl<S: AbstractSim, Stim> Driver<S, Stim> {
}
}
impl<S, Stim> Driver<S, Stim> {
/// when we step the simulation N times, we do so with a constant stimulus over those N frames.
/// lower-resolution quantization of stimuli lets us batch more step calls (critical to perf)
/// but at the cost of precision.
pub fn set_steps_per_stimulus(&mut self, steps: u64) {
self.stimuli.steps_per_stimulus = steps;
}
}
impl<S: AbstractSim, Stim> Driver<S, Stim> {
pub fn fill_region<Reg: Region, M: Into<S::Material> + Clone>(&mut self, region: &Reg, mat: M) {
self.state.fill_region(region, mat);
@@ -258,7 +267,10 @@ where
}
let mut can_step = 1;
while can_step < at_most && !self.renderer.any_work_for_frame(start_step + can_step as u64) {
while can_step < at_most
&& !self.renderer.any_work_for_frame(start_step + can_step as u64)
&& !self.stimuli.any_work_for_frame(start_step + can_step as u64)
{
can_step += 1;
}
@@ -310,7 +322,7 @@ where
self.sim_end_time = Some(sim_end_time);
let mut stepped = false;
while self.state.step_no() < *sim_end_time {
self.step_multiple(100);
self.step_multiple(1000);
stepped = true;
}
if stepped {
@@ -439,6 +451,7 @@ pub type ModulatedStaticField<T> = ModulatedVectorField<DimSlice<Vec<Fields>>, T
/// come back and re-request that time later, expecting that it's been evaluated in the background.
struct StimAccess<T> {
stim: Arc<Mutex<T>>,
steps_per_stimulus: u64,
diag: SyncDiagnostics,
/// is the background thread doing work (or, has it completed work and placed it on the return
/// queue)?
@@ -456,6 +469,7 @@ impl<T> StimAccess<T> {
fn new(diag: SyncDiagnostics, stim: T) -> Self {
Self {
stim: Arc::new(Mutex::new(stim)),
steps_per_stimulus: 1,
diag,
outstanding: Cell::new(false),
response_channel: sync_channel(0),
@@ -467,6 +481,9 @@ impl<T> StimAccess<T> {
// with the worker joined, there should be no outstanding handles on the arc.
Arc::try_unwrap(self.stim).ok().unwrap().into_inner().unwrap()
}
fn any_work_for_frame(&self, frame: u64) -> bool {
frame % self.steps_per_stimulus == 0
}
/// used internally.
/// waits for an outstanding job (if any).