refactor(autorouter/multilayer_reconfigurer): Move multilayer reconfiguration trigger code

This commit is contained in:
Mikolaj Wielgus 2025-10-27 22:55:53 +01:00
parent 813345863e
commit 81e27f0f60
5 changed files with 96 additions and 52 deletions

View File

@ -12,7 +12,9 @@ use crate::{
anterouter::{Anterouter, AnterouterOptions, AnterouterPlan}, anterouter::{Anterouter, AnterouterOptions, AnterouterPlan},
invoker::GetDebugOverlayData, invoker::GetDebugOverlayData,
planar_preconfigurer::PlanarAutoroutePreconfigurerInput, planar_preconfigurer::PlanarAutoroutePreconfigurerInput,
planar_reconfigurator::{PlanarAutorouteReconfigurator, PlanarReconfiguratorStatus}, planar_reconfigurator::{
PlanarAutorouteReconfigurator, PlanarAutorouteReconfiguratorStatus,
},
Autorouter, AutorouterError, PlanarAutorouteOptions, Autorouter, AutorouterError, PlanarAutorouteOptions,
}, },
board::edit::BoardEdit, board::edit::BoardEdit,
@ -66,7 +68,7 @@ impl MultilayerAutorouteExecutionStepper {
} }
} }
impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarReconfiguratorStatus> impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarAutorouteReconfiguratorStatus>
for MultilayerAutorouteExecutionStepper for MultilayerAutorouteExecutionStepper
{ {
type Error = AutorouterError; type Error = AutorouterError;
@ -74,7 +76,8 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarReconfigura
fn step( fn step(
&mut self, &mut self,
autorouter: &mut Autorouter<M>, autorouter: &mut Autorouter<M>,
) -> Result<ControlFlow<Option<BoardEdit>, PlanarReconfiguratorStatus>, AutorouterError> { ) -> Result<ControlFlow<Option<BoardEdit>, PlanarAutorouteReconfiguratorStatus>, AutorouterError>
{
match self.planar.step(autorouter) { match self.planar.step(autorouter) {
Ok(ControlFlow::Break(Some(edit))) => { Ok(ControlFlow::Break(Some(edit))) => {
self.anteroute_edit.merge(edit); self.anteroute_edit.merge(edit);

View File

@ -16,9 +16,13 @@ use crate::{
multilayer_preconfigurer::{ multilayer_preconfigurer::{
MultilayerAutoroutePreconfigurerInput, MultilayerPreconfigurer, MultilayerAutoroutePreconfigurerInput, MultilayerPreconfigurer,
}, },
multilayer_reconfigurer::MultilayerReconfigurer, multilayer_reconfigurer::{
MakeNextMultilayerAutorouteConfiguration, MultilayerAutorouteReconfigurer,
UniformRandomLayersMultilayerAutorouteReconfigurer,
},
planar_autoroute::PlanarAutorouteConfigurationStatus,
planar_preconfigurer::PlanarAutoroutePreconfigurerInput, planar_preconfigurer::PlanarAutoroutePreconfigurerInput,
planar_reconfigurator::PlanarReconfiguratorStatus, planar_reconfigurator::PlanarAutorouteReconfiguratorStatus,
Autorouter, AutorouterError, Autorouter, AutorouterError,
}, },
board::edit::BoardEdit, board::edit::BoardEdit,
@ -28,14 +32,13 @@ use crate::{
stepper::{Abort, EstimateProgress, ReconfiguratorStatus, Reconfigure, Step}, stepper::{Abort, EstimateProgress, ReconfiguratorStatus, Reconfigure, Step},
}; };
pub type MultilayerReconfiguratorStatus = ReconfiguratorStatus<(), PlanarReconfiguratorStatus>; pub type MultilayerReconfiguratorStatus =
ReconfiguratorStatus<(), PlanarAutorouteReconfiguratorStatus>;
pub struct MultilayerAutorouteReconfigurator { pub struct MultilayerAutorouteReconfigurator {
stepper: MultilayerAutorouteExecutionStepper, stepper: MultilayerAutorouteExecutionStepper,
reconfigurer: MultilayerReconfigurer, reconfigurer: MultilayerAutorouteReconfigurer,
options: MultilayerAutorouteOptions, options: MultilayerAutorouteOptions,
// TODO: Obviously, we need something more sophisticated here.
planar_autoroute_reconfiguration_count: u64,
} }
impl MultilayerAutorouteReconfigurator { impl MultilayerAutorouteReconfigurator {
@ -53,8 +56,13 @@ impl MultilayerAutorouteReconfigurator {
terminating_dot_map: BTreeMap::new(), terminating_dot_map: BTreeMap::new(),
}, },
}; };
let reconfigurer = let reconfigurer = MultilayerAutorouteReconfigurer::UniformRandomLayers(
MultilayerReconfigurer::new(autorouter, preconfiguration.clone(), &options); UniformRandomLayersMultilayerAutorouteReconfigurer::new(
autorouter,
preconfiguration.clone(),
&options,
),
);
Ok(Self { Ok(Self {
stepper: MultilayerAutorouteExecutionStepper::new( stepper: MultilayerAutorouteExecutionStepper::new(
@ -64,18 +72,27 @@ impl MultilayerAutorouteReconfigurator {
)?, )?,
reconfigurer, reconfigurer,
options, options,
planar_autoroute_reconfiguration_count: 0,
}) })
} }
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>
{ {
loop { loop {
let Some(configuration) = self.reconfigurer.next_configuration(autorouter) else { let configuration = match self
return Ok(ControlFlow::Break(None)); .reconfigurer
.next_configuration(autorouter, planar_result.clone())
{
ControlFlow::Continue(()) => {
return Ok(ControlFlow::Continue(ReconfiguratorStatus::Running(
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) {
@ -109,18 +126,9 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, MultilayerReconfi
))) )))
} }
Ok(ControlFlow::Continue(ReconfiguratorStatus::Reconfigured(status))) => { Ok(ControlFlow::Continue(ReconfiguratorStatus::Reconfigured(status))) => {
self.planar_autoroute_reconfiguration_count += 1; self.reconfigure(autorouter, Ok(status))
if self.planar_autoroute_reconfiguration_count >= 100 {
self.planar_autoroute_reconfiguration_count = 0;
self.reconfigure(autorouter)
} else {
Ok(ControlFlow::Continue(ReconfiguratorStatus::Running(
ReconfiguratorStatus::Reconfigured(status),
)))
}
} }
Err(_) => self.reconfigure(autorouter), Err(err) => self.reconfigure(autorouter, Err(err)),
} }
} }
} }

View File

@ -2,33 +2,73 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
use std::{collections::BTreeMap, time::SystemTime}; use std::{collections::BTreeMap, ops::ControlFlow, time::SystemTime};
use enum_dispatch::enum_dispatch;
use specctra_core::mesadata::AccessMesadata; use specctra_core::mesadata::AccessMesadata;
use crate::autorouter::{ use crate::autorouter::{
multilayer_autoroute::{MultilayerAutorouteConfiguration, MultilayerAutorouteOptions}, multilayer_autoroute::{MultilayerAutorouteConfiguration, MultilayerAutorouteOptions},
planar_autoroute::PlanarAutorouteConfigurationStatus,
planar_preconfigurer::PlanarAutoroutePreconfigurerInput, planar_preconfigurer::PlanarAutoroutePreconfigurerInput,
Autorouter, Autorouter, AutorouterError,
}; };
pub struct MultilayerReconfigurer { #[enum_dispatch]
preconfiguration: MultilayerAutorouteConfiguration, pub trait MakeNextMultilayerAutorouteConfiguration {
fn next_configuration(
&mut self,
autorouter: &Autorouter<impl AccessMesadata>,
planar_result: Result<PlanarAutorouteConfigurationStatus, AutorouterError>,
) -> ControlFlow<Option<MultilayerAutorouteConfiguration>>;
} }
impl MultilayerReconfigurer { #[enum_dispatch(MakeNextMultilayerAutorouteConfiguration)]
pub enum MultilayerAutorouteReconfigurer {
UniformRandomLayers(UniformRandomLayersMultilayerAutorouteReconfigurer),
}
pub struct UniformRandomLayersMultilayerAutorouteReconfigurer {
preconfiguration: MultilayerAutorouteConfiguration,
planar_autoroute_reconfiguration_count: u64,
}
impl UniformRandomLayersMultilayerAutorouteReconfigurer {
pub fn new( pub fn new(
_autorouter: &Autorouter<impl AccessMesadata>, _autorouter: &Autorouter<impl AccessMesadata>,
preconfiguration: MultilayerAutorouteConfiguration, preconfiguration: MultilayerAutorouteConfiguration,
_options: &MultilayerAutorouteOptions, _options: &MultilayerAutorouteOptions,
) -> Self { ) -> Self {
Self { preconfiguration } Self {
preconfiguration,
planar_autoroute_reconfiguration_count: 0,
}
} }
pub fn next_configuration( fn crude_random_bit() -> usize {
let duration_since_epoch = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap();
let timestamp_nanos = duration_since_epoch.as_nanos();
(timestamp_nanos % 2) as usize
}
}
impl MakeNextMultilayerAutorouteConfiguration
for UniformRandomLayersMultilayerAutorouteReconfigurer
{
fn next_configuration(
&mut self, &mut self,
_autorouter: &Autorouter<impl AccessMesadata>, _autorouter: &Autorouter<impl AccessMesadata>,
) -> Option<MultilayerAutorouteConfiguration> { planar_result: Result<PlanarAutorouteConfigurationStatus, AutorouterError>,
) -> ControlFlow<Option<MultilayerAutorouteConfiguration>> {
if self.planar_autoroute_reconfiguration_count < 100 {
self.planar_autoroute_reconfiguration_count += 1;
return ControlFlow::Continue(());
}
self.planar_autoroute_reconfiguration_count = 0;
let mut new_anterouter_plan = self.preconfiguration.plan.clone(); let mut new_anterouter_plan = self.preconfiguration.plan.clone();
new_anterouter_plan.layer_map = self new_anterouter_plan.layer_map = self
.preconfiguration .preconfiguration
@ -40,20 +80,12 @@ impl MultilayerReconfigurer {
.map(|(_, ratline)| (*ratline, Self::crude_random_bit())) .map(|(_, ratline)| (*ratline, Self::crude_random_bit()))
.collect(); .collect();
Some(MultilayerAutorouteConfiguration { ControlFlow::Break(Some(MultilayerAutorouteConfiguration {
plan: new_anterouter_plan, plan: new_anterouter_plan,
planar: PlanarAutoroutePreconfigurerInput { planar: PlanarAutoroutePreconfigurerInput {
ratlines: self.preconfiguration.planar.ratlines.clone(), ratlines: self.preconfiguration.planar.ratlines.clone(),
terminating_dot_map: BTreeMap::new(), terminating_dot_map: BTreeMap::new(),
}, },
}) }))
}
fn crude_random_bit() -> usize {
let duration_since_epoch = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap();
let timestamp_nanos = duration_since_epoch.as_nanos();
(timestamp_nanos % 2) as usize
} }
} }

View File

@ -62,7 +62,7 @@ pub struct PlanarAutorouteCosts {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct PlanarAutorouteConfigurationResult { pub struct PlanarAutorouteConfigurationStatus {
pub configuration: PlanarAutorouteConfiguration, pub configuration: PlanarAutorouteConfiguration,
pub costs: PlanarAutorouteCosts, pub costs: PlanarAutorouteCosts,
} }
@ -275,13 +275,13 @@ impl<M: AccessMesadata> Abort<Autorouter<M>> for PlanarAutorouteExecutionStepper
impl<M: AccessMesadata> Reconfigure<Autorouter<M>> for PlanarAutorouteExecutionStepper { impl<M: AccessMesadata> Reconfigure<Autorouter<M>> for PlanarAutorouteExecutionStepper {
type Configuration = PlanarAutorouteConfiguration; type Configuration = PlanarAutorouteConfiguration;
type Output = Result<PlanarAutorouteConfigurationResult, AutorouterError>; type Output = Result<PlanarAutorouteConfigurationStatus, AutorouterError>;
fn reconfigure( fn reconfigure(
&mut self, &mut self,
autorouter: &mut Autorouter<M>, autorouter: &mut Autorouter<M>,
new_configuration: PlanarAutorouteConfiguration, new_configuration: PlanarAutorouteConfiguration,
) -> Result<PlanarAutorouteConfigurationResult, AutorouterError> { ) -> Result<PlanarAutorouteConfigurationStatus, AutorouterError> {
let Some(new_index) = new_configuration let Some(new_index) = new_configuration
.ratlines .ratlines
.iter() .iter()
@ -291,7 +291,7 @@ impl<M: AccessMesadata> Reconfigure<Autorouter<M>> for PlanarAutorouteExecutionS
return Err(AutorouterError::NothingToUndoForReconfiguration); return Err(AutorouterError::NothingToUndoForReconfiguration);
}; };
let result = PlanarAutorouteConfigurationResult { let result = PlanarAutorouteConfigurationStatus {
configuration: std::mem::replace(&mut self.configuration, new_configuration), configuration: std::mem::replace(&mut self.configuration, new_configuration),
costs: PlanarAutorouteCosts { costs: PlanarAutorouteCosts {
lengths: vec![], // TODO. lengths: vec![], // TODO.

View File

@ -10,7 +10,7 @@ use crate::{
autorouter::{ autorouter::{
invoker::GetDebugOverlayData, invoker::GetDebugOverlayData,
planar_autoroute::{ planar_autoroute::{
PlanarAutorouteConfigurationResult, PlanarAutorouteContinueStatus, PlanarAutorouteConfigurationStatus, PlanarAutorouteContinueStatus,
PlanarAutorouteExecutionStepper, PlanarAutorouteExecutionStepper,
}, },
planar_preconfigurer::{ planar_preconfigurer::{
@ -27,8 +27,8 @@ use crate::{
stepper::{Abort, EstimateProgress, ReconfiguratorStatus, Reconfigure, Step}, stepper::{Abort, EstimateProgress, ReconfiguratorStatus, Reconfigure, Step},
}; };
pub type PlanarReconfiguratorStatus = pub type PlanarAutorouteReconfiguratorStatus =
ReconfiguratorStatus<PlanarAutorouteConfigurationResult, PlanarAutorouteContinueStatus>; ReconfiguratorStatus<PlanarAutorouteConfigurationStatus, PlanarAutorouteContinueStatus>;
pub struct PlanarAutorouteReconfigurator { pub struct PlanarAutorouteReconfigurator {
stepper: PlanarAutorouteExecutionStepper, stepper: PlanarAutorouteExecutionStepper,
@ -68,7 +68,7 @@ impl PlanarAutorouteReconfigurator {
} }
} }
impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarReconfiguratorStatus> impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarAutorouteReconfiguratorStatus>
for PlanarAutorouteReconfigurator for PlanarAutorouteReconfigurator
{ {
type Error = AutorouterError; type Error = AutorouterError;
@ -76,7 +76,8 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarReconfigura
fn step( fn step(
&mut self, &mut self,
autorouter: &mut Autorouter<M>, autorouter: &mut Autorouter<M>,
) -> Result<ControlFlow<Option<BoardEdit>, PlanarReconfiguratorStatus>, AutorouterError> { ) -> Result<ControlFlow<Option<BoardEdit>, PlanarAutorouteReconfiguratorStatus>, AutorouterError>
{
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)),
Ok(ControlFlow::Continue(status)) => { Ok(ControlFlow::Continue(status)) => {