Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions cadence/src/genus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ use std::{fs, io};
use crate::{Checkpoint, MmmcConfig, MmmcCorner, SubmoduleInfo, Substep, mmmc};
use fs::File;
use indoc::formatdoc;
use rivet::Step;
use std::sync::Arc;
use rivet::{Step, StepRef};

/// Defines the Genus synthesis step subflow
#[derive(Debug, Clone)]
Expand All @@ -21,7 +20,7 @@ pub struct GenusStep {
pub pinned: bool,
pub start_checkpoint: Option<Checkpoint>,
pub endpoint: Option<String>,
pub dependencies: Vec<Arc<dyn Step>>,
pub dependencies: Vec<StepRef<dyn Step>>,
}

impl GenusStep {
Expand All @@ -30,7 +29,7 @@ impl GenusStep {
module: impl Into<String>,
steps: Vec<Substep>,
pinned: bool,
deps: Vec<Arc<dyn Step>>,
deps: Vec<StepRef<dyn Step>>,
) -> Self {
let dir = work_dir.into();
let modul = module.into();
Expand Down Expand Up @@ -182,7 +181,7 @@ impl Step for GenusStep {
}
}

fn deps(&self) -> Vec<Arc<dyn Step>> {
fn deps(&self) -> Vec<StepRef<dyn Step>> {
self.dependencies.clone()
}

Expand Down
9 changes: 4 additions & 5 deletions cadence/src/innovus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ use crate::MmmcCorner;
use crate::{Checkpoint, MmmcConfig, SubmoduleInfo, Substep, mmmc};
use fs::File;
use indoc::formatdoc;
use rivet::Step;
use rivet::{Step, StepRef};
use rust_decimal::Decimal;
use serde::Deserialize;
use serde::Serialize;
use std::sync::Arc;

/// Defines the Innovus place and route step subflow
#[derive(Debug, Clone)]
Expand All @@ -24,7 +23,7 @@ pub struct InnovusStep {
pub pinned: bool,
pub start_checkpoint: Option<Checkpoint>,
pub endpoint: Option<String>,
pub deps: Vec<Arc<dyn Step>>,
pub deps: Vec<StepRef<dyn Step>>,
pub synthesis: bool,
}

Expand All @@ -34,7 +33,7 @@ impl InnovusStep {
module: impl Into<String>,
substeps: Vec<Substep>,
pinned: bool,
deps: Vec<Arc<dyn Step>>,
deps: Vec<StepRef<dyn Step>>,
synthesis: bool,
) -> Self {
let dir = work_dir.into();
Expand Down Expand Up @@ -204,7 +203,7 @@ impl Step for InnovusStep {
}
}

fn deps(&self) -> Vec<Arc<dyn Step>> {
fn deps(&self) -> Vec<StepRef<dyn Step>> {
self.deps.clone()
}

Expand Down
9 changes: 4 additions & 5 deletions cadence/src/pegasus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@ use std::{fs, io};

use crate::Substep;
use fs::File;
use rivet::Step;
use std::sync::Arc;
use rivet::{Step, StepRef};

#[derive(Debug)]
pub struct PegasusStep {
pub work_dir: PathBuf,
pub func: String,
pub module: String,
pub pinned: bool,
pub dependencies: Vec<Arc<dyn Step>>,
pub dependencies: Vec<StepRef<dyn Step>>,
}

impl PegasusStep {
Expand All @@ -24,7 +23,7 @@ impl PegasusStep {
func: String,
module: String,
pinned: bool,
deps: Vec<Arc<dyn Step>>,
deps: Vec<StepRef<dyn Step>>,
) -> Self {
let dir = work_dir.into();
PegasusStep {
Expand Down Expand Up @@ -149,7 +148,7 @@ impl Step for PegasusStep {
}
}
}
fn deps(&self) -> Vec<Arc<dyn Step>> {
fn deps(&self) -> Vec<StepRef<dyn Step>> {
self.dependencies.clone()
}

Expand Down
20 changes: 10 additions & 10 deletions flows/sky130_cadence/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,9 +343,9 @@ pub fn sky130_scl_cadence_syn(config: SclSynConfig<'_>) -> GenusStep {
})
.collect();

let mut deps: Vec<Arc<dyn Step>> = dep_info
let mut deps: Vec<StepRef<dyn Step>> = dep_info
.iter()
.map(|(_module, flow)| Arc::new(flow.par.clone()) as Arc<dyn Step>)
.map(|(_module, flow)| flow.par.clone().into_dyn())
.collect();

let is_hierarchical = !submodules.is_empty();
Expand All @@ -360,13 +360,13 @@ pub fn sky130_scl_cadence_syn(config: SclSynConfig<'_>) -> GenusStep {
fs::create_dir_all(sram_work_dir).expect("Failed to create sram directory");
generate_compiler_script(&missing_srams, sram_work_dir)
.expect("Failed to generate SRAM compiler script");
let sram_compiler = Arc::new(BashStep::new(
let sram_compiler = StepRef::new(BashStep::new(
sram_work_dir.to_path_buf(),
"generate_sram",
module.as_str(),
vec![],
));
deps.push(sram_compiler);
deps.push(sram_compiler.into_dyn());
}

GenusStep::new(
Expand Down Expand Up @@ -578,7 +578,7 @@ pub fn sky130_scl_cadence_par(config: SclParConfig<'_>) -> InnovusStep {
),
],
matches!(pin_info, FlatPinInfo::PinPar(_)),
vec![Arc::new(syn_step) as Arc<dyn Step>],
vec![syn_step.into_dyn()],
false,
)
}
Expand Down Expand Up @@ -939,9 +939,9 @@ pub fn sky130_os_cadence_syn(config: OsSynConfig<'_>) -> GenusStep {
})
.collect();

let mut deps: Vec<Arc<dyn Step>> = dep_info
let mut deps: Vec<StepRef<dyn Step>> = dep_info
.iter()
.map(|(_module, flow)| Arc::new(flow.par.clone()) as Arc<dyn Step>)
.map(|(_module, flow)| flow.par.clone().into_dyn())
.collect();

let is_hierarchical = !submodules.is_empty();
Expand All @@ -956,13 +956,13 @@ pub fn sky130_os_cadence_syn(config: OsSynConfig<'_>) -> GenusStep {
fs::create_dir_all(sram_work_dir).expect("Failed to create sram directory");
generate_compiler_script(&missing_srams, sram_work_dir)
.expect("Failed to generate SRAM compiler script");
let sram_compiler = Arc::new(BashStep::new(
let sram_compiler = StepRef::new(BashStep::new(
sram_work_dir.to_path_buf(),
"generate_sram",
module.as_str(),
vec![],
));
deps.push(sram_compiler);
deps.push(sram_compiler.into_dyn());
}

GenusStep::new(
Expand Down Expand Up @@ -1152,7 +1152,7 @@ pub fn sky130_os_cadence_par(config: OsParConfig<'_>) -> InnovusStep {
),
],
matches!(pin_info, FlatPinInfo::PinPar(_)),
vec![Arc::new(syn_step) as Arc<dyn Step>],
vec![syn_step.into_dyn()],
false,
)
}
Expand Down
9 changes: 4 additions & 5 deletions rivet/src/bash.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
use crate::Step;
use crate::{Step, StepRef};
use std::fmt::Debug;
use std::fs::File;
use std::io::{BufRead, BufReader, Write};
use std::path::PathBuf;
use std::process::{Command, Stdio};
use std::sync::Arc;
use std::thread;

#[derive(Debug, Clone)]
pub struct BashStep {
pub work_dir: PathBuf,
pub name: String,
pub block: String,
pub deps: Vec<Arc<dyn Step>>,
pub deps: Vec<StepRef<dyn Step>>,
pub pinned: bool,
}

Expand All @@ -21,7 +20,7 @@ impl BashStep {
work_dir: impl Into<PathBuf>,
name: impl Into<String>,
block: impl Into<String>,
deps: Vec<Arc<dyn Step>>,
deps: Vec<StepRef<dyn Step>>,
) -> Self {
let dir = work_dir.into();
let file = name.into();
Expand Down Expand Up @@ -95,7 +94,7 @@ impl Step for BashStep {
}
}

fn deps(&self) -> Vec<Arc<dyn Step>> {
fn deps(&self) -> Vec<StepRef<dyn Step>> {
self.deps.clone()
}

Expand Down
117 changes: 69 additions & 48 deletions rivet/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use by_address::ByAddress;
use std::collections::{HashMap, HashSet};
use std::any::Any;
use std::collections::HashSet;
use std::fmt::Debug;
use std::sync::{Arc, Mutex, MutexGuard};
use std::ops::Deref;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};

pub mod bash;
pub mod rust;
Expand Down Expand Up @@ -60,45 +62,47 @@ impl<F: NamedNode> Dag<F> {
}
}

pub trait Step: Debug + Send + Sync {
fn deps(&self) -> Vec<Arc<dyn Step>>;
pub trait Step: Debug + Any + Send + Sync {
fn deps(&self) -> Vec<StepRef<dyn Step>>;
fn pinned(&self) -> bool;
fn execute(&self);
}

pub fn execute(target: impl Step + 'static) {
let target = Arc::new(target) as Arc<dyn Step>;

let mut executed = HashMap::<ByAddress<Arc<dyn Step>>, Arc<dyn Step>>::new();
execute_inner(target, &mut executed);
#[derive(Default)]
pub struct Executor {
executed: HashSet<ByAddress<StepRef<dyn Step>>>,
}

fn execute_inner(
step: Arc<dyn Step>,
executed: &mut HashMap<ByAddress<Arc<dyn Step>>, Arc<dyn Step>>,
) {
println!("Checking status of step {step:?}");
let step_addr = ByAddress(step.clone());
if executed.contains_key(&step_addr) {
println!("Step has already been executed, skipping");
return;
impl Executor {
pub fn new() -> Self {
Self::default()
}

if step.pinned() {
println!("Step is pinned, skipping");
executed.insert(step_addr, Arc::clone(&step));
return;
pub fn execute<T: Step>(mut self, step: StepRef<T>) -> Self {
self.execute_step(step.into_dyn());
self
}

println!("Executing step dependencies: {:?}", step.deps());
for dependency in step.deps() {
execute_inner(dependency, executed);
fn execute_step(&mut self, step: StepRef<dyn Step>) {
let step_addr = ByAddress(step.clone());
if self.executed.contains(&step_addr) {
return;
}
if step.read().pinned() {
self.executed.insert(step_addr);
return;
}
let deps = step.read().deps();
for dep in deps {
self.execute_step(dep);
}
step.read().execute();
self.executed.insert(ByAddress(step));
}
}

println!("Executing step {step:?}");
step.execute();

executed.insert(ByAddress(step.clone()), Arc::clone(&step));
pub fn execute(step: StepRef<impl Step + 'static>) {
Executor::new().execute(step);
}

pub fn hierarchical<M, F>(dag: &Dag<M>, flat_flow_gen: &impl Fn(&M, Vec<(&M, &F)>) -> F) -> Dag<F> {
Expand All @@ -123,42 +127,59 @@ pub fn hierarchical<M, F>(dag: &Dag<M>, flat_flow_gen: &impl Fn(&M, Vec<(&M, &F)
}
}

#[derive(Debug, Clone)]
pub struct StepRef<T: Step> {
inner: Arc<Mutex<T>>,
#[derive(Debug)]
pub struct StepRef<T: ?Sized> {
inner: Arc<RwLock<T>>,
}

impl<T: ?Sized> Clone for StepRef<T> {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}

impl<T: Step> StepRef<T> {
impl<T: ?Sized> Deref for StepRef<T> {
type Target = RwLock<T>;

fn deref(&self) -> &Self::Target {
&*self.inner
}
}

impl<T> StepRef<T> {
pub fn new(data: T) -> Self {
Self {
inner: Arc::new(Mutex::new(data)),
inner: Arc::new(RwLock::new(data)),
}
}
}

pub fn lock(&self) -> MutexGuard<'_, T> {
self.inner.lock().unwrap()
impl<T: ?Sized> StepRef<T> {
pub fn read(&self) -> RwLockReadGuard<'_, T> {
self.inner.read().unwrap()
}

pub fn write(&self) -> RwLockWriteGuard<'_, T> {
self.inner.write().unwrap()
}

pub fn get<R>(&self, get_fn: impl FnOnce(&T) -> R) -> R {
let inner = self.inner.lock().unwrap();
let inner = self.inner.read().unwrap();
get_fn(&inner)
}

pub fn update<R>(&self, update_fn: impl FnOnce(&mut T) -> R) -> R {
let mut inner = self.inner.lock().unwrap();
let mut inner = self.inner.write().unwrap();
update_fn(&mut inner)
}
}
impl<T: Step> Step for StepRef<T> {
fn execute(&self) {
self.lock().execute();
}

fn deps(&self) -> Vec<Arc<dyn Step>> {
self.lock().deps()
}

fn pinned(&self) -> bool {
self.lock().pinned()
impl<T: Step + 'static> StepRef<T> {
pub fn into_dyn(self) -> StepRef<dyn Step> {
StepRef {
inner: self.inner as Arc<RwLock<dyn Step>>,
}
}
}
Loading