feat(autorouter/multilayer_reconfigurator): Use our new trigger mechanism for reconfiguration

This commit is contained in:
Mikolaj Wielgus 2025-11-04 05:17:31 +01:00
parent 2e507b7cab
commit d3913dbdce
3 changed files with 36 additions and 38 deletions

View File

@ -74,7 +74,7 @@ impl MultilayerAutorouteReconfigurator {
preconfiguration, preconfiguration,
options, options,
)?, )?,
reconfiguration_trigger: SmaRateReconfigurationTrigger::new(4, 0.5, 0.5), reconfiguration_trigger: SmaRateReconfigurationTrigger::new(10, 0.5, 0.1),
reconfigurer, reconfigurer,
options, options,
}) })
@ -83,24 +83,15 @@ impl MultilayerAutorouteReconfigurator {
fn reconfigure<M: AccessMesadata>( fn reconfigure<M: AccessMesadata>(
&mut self, &mut self,
autorouter: &mut Autorouter<M>, autorouter: &mut Autorouter<M>,
planar_result: Result<PlanarAutorouteConfigurationStatus, AutorouterError>,
) -> Result<ControlFlow<Option<BoardEdit>, MultilayerReconfiguratorStatus>, AutorouterError> ) -> Result<ControlFlow<Option<BoardEdit>, MultilayerReconfiguratorStatus>, AutorouterError>
{ {
// Reset the reconfiguration trigger. // Reset the reconfiguration trigger.
self.reconfiguration_trigger = SmaRateReconfigurationTrigger::new(4, 0.5, 0.5); self.reconfiguration_trigger = SmaRateReconfigurationTrigger::new(10, 0.5, 0.1);
loop { loop {
self.reconfigurer
.process_planar_result(autorouter, planar_result.clone());
let configuration = match self.reconfigurer.next_configuration(autorouter) { let configuration = match self.reconfigurer.next_configuration(autorouter) {
ControlFlow::Continue(()) => { None => return Ok(ControlFlow::Break(None)),
return Ok(ControlFlow::Continue(ReconfiguratorStatus::Running( Some(configuration) => configuration,
ReconfiguratorStatus::Reconfigured(planar_result?),
)))
}
ControlFlow::Break(None) => return Ok(ControlFlow::Break(None)),
ControlFlow::Break(Some(configuration)) => configuration,
}; };
match self.stepper.reconfigure(autorouter, configuration) { match self.stepper.reconfigure(autorouter, configuration) {
@ -126,8 +117,12 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, MultilayerReconfi
autorouter: &mut Autorouter<M>, autorouter: &mut Autorouter<M>,
) -> Result<ControlFlow<Option<BoardEdit>, MultilayerReconfiguratorStatus>, AutorouterError> ) -> Result<ControlFlow<Option<BoardEdit>, MultilayerReconfiguratorStatus>, AutorouterError>
{ {
self.reconfiguration_trigger if !self
.update(*self.estimate_progress().value() as f64); .reconfiguration_trigger
.update(*self.estimate_progress().value() as f64)
{
return self.reconfigure(autorouter);
}
match self.stepper.step(autorouter) { match self.stepper.step(autorouter) {
Ok(ControlFlow::Break(maybe_edit)) => Ok(ControlFlow::Break(maybe_edit)), Ok(ControlFlow::Break(maybe_edit)) => Ok(ControlFlow::Break(maybe_edit)),
@ -137,9 +132,17 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, MultilayerReconfi
))) )))
} }
Ok(ControlFlow::Continue(ReconfiguratorStatus::Reconfigured(status))) => { Ok(ControlFlow::Continue(ReconfiguratorStatus::Reconfigured(status))) => {
self.reconfigure(autorouter, Ok(status)) self.reconfigurer
.process_planar_result(autorouter, Ok(status));
Ok(ControlFlow::Continue(
ReconfiguratorStatus::Reconfigured(()),
))
}
Err(err) => {
self.reconfigurer
.process_planar_result(autorouter, Err(err.clone()));
Err(err)
} }
Err(err) => self.reconfigure(autorouter, Err(err)),
} }
} }
} }

View File

@ -2,7 +2,7 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
use std::{collections::BTreeMap, ops::ControlFlow}; use std::collections::BTreeMap;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use specctra_core::mesadata::AccessMesadata; use specctra_core::mesadata::AccessMesadata;
@ -25,7 +25,7 @@ pub trait MakeNextMultilayerAutorouteConfiguration {
fn next_configuration( fn next_configuration(
&mut self, &mut self,
autorouter: &Autorouter<impl AccessMesadata>, autorouter: &Autorouter<impl AccessMesadata>,
) -> ControlFlow<Option<MultilayerAutorouteConfiguration>>; ) -> Option<MultilayerAutorouteConfiguration>;
} }
#[enum_dispatch(MakeNextMultilayerAutorouteConfiguration)] #[enum_dispatch(MakeNextMultilayerAutorouteConfiguration)]
@ -37,7 +37,6 @@ pub struct IncrementFailedRatlineLayersMultilayerAutorouteReconfigurer {
last_configuration: MultilayerAutorouteConfiguration, last_configuration: MultilayerAutorouteConfiguration,
maybe_last_planar_status: Option<PlanarAutorouteConfigurationStatus>, maybe_last_planar_status: Option<PlanarAutorouteConfigurationStatus>,
maybe_best_planar_status: Option<PlanarAutorouteConfigurationStatus>, maybe_best_planar_status: Option<PlanarAutorouteConfigurationStatus>,
planar_autoroute_reconfiguration_count: u64,
} }
impl IncrementFailedRatlineLayersMultilayerAutorouteReconfigurer { impl IncrementFailedRatlineLayersMultilayerAutorouteReconfigurer {
@ -50,7 +49,6 @@ impl IncrementFailedRatlineLayersMultilayerAutorouteReconfigurer {
last_configuration: preconfiguration, last_configuration: preconfiguration,
maybe_last_planar_status: None, maybe_last_planar_status: None,
maybe_best_planar_status: None, maybe_best_planar_status: None,
planar_autoroute_reconfiguration_count: 0,
} }
} }
} }
@ -63,8 +61,6 @@ impl MakeNextMultilayerAutorouteConfiguration
_autorouter: &Autorouter<impl AccessMesadata>, _autorouter: &Autorouter<impl AccessMesadata>,
planar_result: Result<PlanarAutorouteConfigurationStatus, AutorouterError>, planar_result: Result<PlanarAutorouteConfigurationStatus, AutorouterError>,
) { ) {
self.planar_autoroute_reconfiguration_count += 1;
let Ok(planar_status) = planar_result else { let Ok(planar_status) = planar_result else {
return; return;
}; };
@ -83,17 +79,11 @@ impl MakeNextMultilayerAutorouteConfiguration
fn next_configuration( fn next_configuration(
&mut self, &mut self,
autorouter: &Autorouter<impl AccessMesadata>, autorouter: &Autorouter<impl AccessMesadata>,
) -> ControlFlow<Option<MultilayerAutorouteConfiguration>> { ) -> Option<MultilayerAutorouteConfiguration> {
if self.planar_autoroute_reconfiguration_count < 10 {
return ControlFlow::Continue(());
}
self.planar_autoroute_reconfiguration_count = 0;
let mut new_anterouter_plan = self.last_configuration.plan.clone(); let mut new_anterouter_plan = self.last_configuration.plan.clone();
let Some(ref last_planar_status) = self.maybe_last_planar_status else { let Some(ref last_planar_status) = self.maybe_last_planar_status else {
return ControlFlow::Break(None); return None;
}; };
if let Some(ref best_planar_status) = self.maybe_best_planar_status { if let Some(ref best_planar_status) = self.maybe_best_planar_status {
@ -119,6 +109,6 @@ impl MakeNextMultilayerAutorouteConfiguration
}, },
}; };
ControlFlow::Break(Some(self.last_configuration.clone())) Some(self.last_configuration.clone())
} }
} }

View File

@ -122,7 +122,9 @@ pub struct SmaRateReconfigurationTrigger {
#[getter(skip)] #[getter(skip)]
last_instant: Instant, last_instant: Instant,
#[getter(skip)] #[getter(skip)]
last_value: f64, last_max_value: f64,
#[getter(skip)]
incoming_max_value: f64,
maybe_sma_rate_per_sec: Option<f64>, maybe_sma_rate_per_sec: Option<f64>,
#[getter(skip)] #[getter(skip)]
sample_buffer_size: usize, sample_buffer_size: usize,
@ -140,7 +142,8 @@ impl SmaRateReconfigurationTrigger {
Self { Self {
sample_buffer: VecDeque::new(), sample_buffer: VecDeque::new(),
last_instant: Instant::now(), last_instant: Instant::now(),
last_value: 0.0, last_max_value: 0.0,
incoming_max_value: 0.0,
maybe_sma_rate_per_sec: None, maybe_sma_rate_per_sec: None,
sample_buffer_size, sample_buffer_size,
sampling_interval_secs, sampling_interval_secs,
@ -149,17 +152,19 @@ impl SmaRateReconfigurationTrigger {
} }
pub fn update(&mut self, value: f64) -> bool { pub fn update(&mut self, value: f64) -> bool {
self.incoming_max_value = self.incoming_max_value.max(value);
let elapsed = self.last_instant.elapsed(); let elapsed = self.last_instant.elapsed();
let delta = value - self.last_value;
if elapsed.as_secs_f64() >= self.sampling_interval_secs { if elapsed.as_secs_f64() >= self.sampling_interval_secs {
let delta = self.incoming_max_value - self.last_max_value;
let count = (elapsed.as_secs_f64() / self.sampling_interval_secs) as usize; let count = (elapsed.as_secs_f64() / self.sampling_interval_secs) as usize;
let mut total_pushed = 0.0; let mut total_pushed = 0.0;
let mut total_popped = 0.0; let mut total_popped = 0.0;
for _ in 0..count { for _ in 0..count {
let pushed = delta.max(0.0) / count as f64; let pushed = delta / count as f64;
self.sample_buffer.push_back(delta.max(0.0) / count as f64); self.sample_buffer.push_back(delta / count as f64);
total_pushed += pushed; total_pushed += pushed;
if self.sample_buffer.len() > self.sample_buffer_size { if self.sample_buffer.len() > self.sample_buffer_size {
@ -178,7 +183,7 @@ impl SmaRateReconfigurationTrigger {
} }
self.last_instant = Instant::now(); self.last_instant = Instant::now();
self.last_value = value; self.last_max_value = self.incoming_max_value;
} }
if let Some(sma_rate_per_sec) = self.maybe_sma_rate_per_sec { if let Some(sma_rate_per_sec) = self.maybe_sma_rate_per_sec {