Skip to content

Commit

Permalink
More work for demo
Browse files Browse the repository at this point in the history
  • Loading branch information
gussmith23 committed Apr 27, 2024
1 parent dd5cacf commit b3ef865
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 3 deletions.
6 changes: 6 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion churchroad-js/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions web-demo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ rev = "325814fd90767b5e43c72bc2eb65e14ff0b8746c"
wee_alloc = "0.4.5"
churchroad = {path = "../churchroad"}

egraph-serialize = "0.1"
indexmap = "2.0.0"
rustc-hash = "1.1.0"
ordered-float = "3"

log = "0.4.19"
wasm-logger = "0.2"

Expand Down
96 changes: 94 additions & 2 deletions web-demo/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#![allow(clippy::unused_unit)] // weird clippy bug with wasm-bindgen
#![allow(clippy::unused_unit)]
use egglog::SerializeConfig;
use egraph_serialize::{ClassId, NodeId};
use indexmap::IndexMap;
// weird clippy bug with wasm-bindgen
use log::{Level, Log, Metadata, Record};
use wasm_bindgen::prelude::*;
use web_sys::console;
Expand All @@ -18,8 +22,17 @@ pub fn run_program(input: &str) -> Result {
match egraph.parse_and_run_program(input) {
Ok(outputs) => {
let serialized = egraph.serialize_for_graphviz(false);
let serialized2 = egraph.serialize(SerializeConfig::default());
let choices = GreedyDagExtractor::default().extract(&serialized2, &[]);
let mut out = churchroad::to_verilog_egraph_serialize(&serialized2, &choices, "");

out.push_str("\n\nOutputs:\n");
for (i, output) in outputs.iter().enumerate() {
out.push_str(&format!("Output {}: {}\n", i, output));
}

Result {
text: outputs.join("<br>"),
text: out,
dot: serialized.to_dot(),
}
}
Expand Down Expand Up @@ -111,3 +124,82 @@ pub fn init() {
Err(e) => console::error_1(&JsValue::from(e.to_string())),
}
}


use rustc_hash::FxHashMap;

pub type Cost = ordered_float::NotNan<f64>;

struct CostSet {
costs: FxHashMap<ClassId, Cost>,
total: Cost,
choice: NodeId,
}

#[derive(Default)]
pub struct GreedyDagExtractor;
impl GreedyDagExtractor {
fn extract(&self, egraph: &egraph_serialize::EGraph, _roots: &[egraph_serialize::ClassId]) -> IndexMap<ClassId, NodeId>
{
let mut costs = FxHashMap::<ClassId, CostSet>::with_capacity_and_hasher(
egraph.classes().len(),
Default::default(),
);

let mut keep_going = true;

let mut i = 0;
while keep_going {
i += 1;
println!("iteration {}", i);
keep_going = false;

'node_loop: for (node_id, node) in &egraph.nodes {
let cid = egraph.nid_to_cid(node_id);
let mut cost_set = CostSet {
costs: Default::default(),
total: Cost::default(),
choice: node_id.clone(),
};

// compute the cost set from the children
for child in &node.children {
let child_cid = egraph.nid_to_cid(child);
if let Some(child_cost_set) = costs.get(child_cid) {
// prevent a cycle
if child_cost_set.costs.contains_key(cid) {
continue 'node_loop;
}
cost_set.costs.extend(child_cost_set.costs.clone());
} else {
continue 'node_loop;
}
}

// add this node
cost_set.costs.insert(cid.clone(), node.cost);

dbg!(node.cost);

cost_set.total = cost_set.costs.values().sum();

// if the cost set is better than the current one, update it
if let Some(old_cost_set) = costs.get(cid) {
if cost_set.total < old_cost_set.total {
costs.insert(cid.clone(), cost_set);
keep_going = true;
}
} else {
costs.insert(cid.clone(), cost_set);
keep_going = true;
}
}
}

let mut result = IndexMap::default();
for (cid, cost_set) in costs {
result.insert(cid, cost_set.choice);
}
result
}
}

0 comments on commit b3ef865

Please sign in to comment.