use super::mixed_size_placer::MixedSizePlacer;
use crate::place::mixed_size_placer::PlacementError;
use crate::place::placement_problem::PlacementProblem;
use crate::place::placement_problem_overlay::PlacementProblemOverlay;
use libreda_db::prelude as db;
use libreda_db::traits::*;
use log;
use std::collections::HashMap;
pub struct PlacerCascade<L: L2NBase> {
stages: Vec<Box<dyn MixedSizePlacer<L>>>,
}
impl<L: L2NBase> PlacerCascade<L> {
pub fn new(placers: Vec<Box<dyn MixedSizePlacer<L>>>) -> Self {
PlacerCascade { stages: placers }
}
}
impl<C: L2NBase> MixedSizePlacer<C> for PlacerCascade<C> {
fn name(&self) -> &str {
"CascadePlacer"
}
fn find_cell_positions_impl(
&self,
placement_problem: &dyn PlacementProblem<C>,
) -> Result<HashMap<C::CellInstId, db::SimpleTransform<C::Coord>>, PlacementError> {
log::debug!("Run placer cascade with {} placers.", self.stages.len());
let mut placement_problem = PlacementProblemOverlay::new(placement_problem);
for (i, stage) in self.stages.iter().enumerate() {
log::debug!("Run placement stage {}/{}.", i + 1, self.stages.len());
let solution = stage.find_cell_positions_impl(&placement_problem)?;
for (inst, pos) in solution {
placement_problem.initial_positions.insert(inst, pos);
}
}
log::debug!("Done.");
Ok(placement_problem.initial_positions)
}
}