diff --git a/fud2/src/lib.rs b/fud2/src/lib.rs index 0e7912d374..4595daffe9 100644 --- a/fud2/src/lib.rs +++ b/fud2/src/lib.rs @@ -287,6 +287,11 @@ pub fn build_driver(bld: &mut DriverBuilder) { "cider.exe", "$calyx-base/target/debug/cider", )?; + e.config_var_or( + "cider-converter", + "cider-converter.exe", + "$calyx-base/target/debug/cider-data-converter", + )?; e.rule( "cider", "$cider-exe -l $calyx-base --raw --data data.json $in > $out", @@ -311,6 +316,21 @@ pub fn build_driver(bld: &mut DriverBuilder) { &["$sim_data"], &["interp-dat.py"], )?; + + e.rule( + "cider2", + "$cider-exe -l $calyx-base --data data.dump $in flat > $out", + )?; + + e.rule("dump-to-interp", "$cider-converter --to cider $in > $out")?; + e.rule("interp-to-dump", "$cider-converter --to json $in > $out")?; + e.build_cmd( + &["data.dump"], + "dump-to-interp", + &["$sim_data"], + &["$cider-converter"], + )?; + Ok(()) }); bld.op( @@ -330,6 +350,23 @@ pub fn build_driver(bld: &mut DriverBuilder) { Ok(()) }, ); + bld.op( + "interp-flat", + &[sim_setup, calyx_setup, cider_setup], + calyx, + dat, + |e, input, output| { + let out_file = "interp_out.dump"; + e.build_cmd(&[out_file], "cider2", &[input], &["data.dump"])?; + e.build_cmd( + &[output], + "interp-to-dump", + &[out_file], + &["$sim_data", "$cider-converter"], + )?; + Ok(()) + }, + ); bld.op( "debug", &[sim_setup, calyx_setup, cider_setup], diff --git a/fud2/tests/snapshots/tests__emit@calyx_debug.snap b/fud2/tests/snapshots/tests__emit@calyx_debug.snap index 643ea325f2..ae6294e1d9 100644 --- a/fud2/tests/snapshots/tests__emit@calyx_debug.snap +++ b/fud2/tests/snapshots/tests__emit@calyx_debug.snap @@ -31,6 +31,7 @@ rule calyx-pass # Cider interpreter cider-exe = $calyx-base/target/debug/cider +cider-converter = $calyx-base/target/debug/cider-data-converter rule cider command = $cider-exe -l $calyx-base --raw --data data.json $in > $out rule cider-debug @@ -43,6 +44,13 @@ rule dat-to-interp rule interp-to-dat command = $python interp-dat.py --from-interp $in $sim_data > $out build data.json: dat-to-interp $sim_data | interp-dat.py +rule cider2 + command = $cider-exe -l $calyx-base --data data.dump $in flat > $out +rule dump-to-interp + command = $cider-converter --to cider $in > $out +rule interp-to-dump + command = $cider-converter --to json $in > $out +build data.dump: dump-to-interp $sim_data | $cider-converter # build targets build _pseudo_debug: cider-debug stdin | data.json diff --git a/fud2/tests/snapshots/tests__emit@calyx_interp_dat.snap b/fud2/tests/snapshots/tests__emit@calyx_interp_dat.snap index 6b29b41ac6..4f52d3e7bf 100644 --- a/fud2/tests/snapshots/tests__emit@calyx_interp_dat.snap +++ b/fud2/tests/snapshots/tests__emit@calyx_interp_dat.snap @@ -31,6 +31,7 @@ rule calyx-pass # Cider interpreter cider-exe = $calyx-base/target/debug/cider +cider-converter = $calyx-base/target/debug/cider-data-converter rule cider command = $cider-exe -l $calyx-base --raw --data data.json $in > $out rule cider-debug @@ -43,6 +44,13 @@ rule dat-to-interp rule interp-to-dat command = $python interp-dat.py --from-interp $in $sim_data > $out build data.json: dat-to-interp $sim_data | interp-dat.py +rule cider2 + command = $cider-exe -l $calyx-base --data data.dump $in flat > $out +rule dump-to-interp + command = $cider-converter --to cider $in > $out +rule interp-to-dump + command = $cider-converter --to json $in > $out +build data.dump: dump-to-interp $sim_data | $cider-converter # build targets build interp_out.json: cider stdin | data.json diff --git a/interp/Cargo.toml b/interp/Cargo.toml index 2a1224f7f2..a9ed9cd2da 100644 --- a/interp/Cargo.toml +++ b/interp/Cargo.toml @@ -3,7 +3,7 @@ name = "interp" version = "0.1.1" authors = ["The Calyx authors"] edition = "2021" -rust-version.workspace = true +rust-version = "1.73" [lib] doctest = false # Don't run doc tests diff --git a/interp/src/flatten/structures/environment/env.rs b/interp/src/flatten/structures/environment/env.rs index 22907eca5a..97378842d4 100644 --- a/interp/src/flatten/structures/environment/env.rs +++ b/interp/src/flatten/structures/environment/env.rs @@ -158,13 +158,17 @@ impl CellLedger { } #[must_use] - pub(crate) fn as_primitive(&self) -> Option<&dyn Primitive> { - if let Self::Primitive { cell_dyn } = self { - Some(&**cell_dyn) - } else { - None + pub fn as_primitive(&self) -> Option<&dyn Primitive> { + match self { + Self::Primitive { cell_dyn } => Some(&**cell_dyn), + _ => None, } } + + pub fn unwrap_primitive(&self) -> &dyn Primitive { + self.as_primitive() + .expect("Unwrapped cell ledger as primitive but received component") + } } impl Debug for CellLedger { @@ -485,6 +489,10 @@ impl<'a> Simulator<'a> { &self.env.ports[port_idx] } + pub(crate) fn get_root_component(&self) -> &ComponentLedger { + self.env.cells.first().unwrap().as_comp().unwrap() + } + /// Attempt to find the parent cell for a port. If no such cell exists (i.e. /// it is a hole port, then it returns None) fn _get_parent_cell( @@ -578,10 +586,10 @@ impl<'a> Simulator<'a> { // program counter as the size let mut leaf_nodes = vec![]; - let mut par_map = std::mem::take(self.env.pc.par_map_mut()); let mut new_nodes = vec![]; + let (vecs, par_map) = self.env.pc.mut_refs(); - self.env.pc.vec_mut().retain_mut(|node| { + vecs.retain_mut(|node| { // just considering a single node case for the moment match &self.env.ctx.primary[node.control_node_idx] { ControlNode::Seq(seq) => { @@ -702,8 +710,6 @@ impl<'a> Simulator<'a> { // insert all the new nodes from the par into the program counter self.env.pc.vec_mut().extend(new_nodes); - // return the par map to the program counter - *self.env.pc.par_map_mut() = par_map; self.undef_all_ports(); @@ -939,15 +945,15 @@ impl<'a> Simulator<'a> { let entrypoint_secondary = &ctx.secondary[ctx.entry_point]; let mut dump = DataDump::new_empty_with_top_level( - ctx.secondary[entrypoint_secondary.name].clone(), + ctx.lookup_string(entrypoint_secondary.name).clone(), ); - let root = self.env.cells.first().unwrap().as_comp().unwrap(); + let root = self.get_root_component(); for (offset, idx) in entrypoint_secondary.cell_offset_map.iter() { let cell_info = &ctx.secondary[*idx]; let cell_index = &root.index_bases + offset; - let name = ctx.secondary[cell_info.name].clone(); + let name = ctx.lookup_string(cell_info.name).clone(); if let CellPrototype::Memory { width, dims, .. } = &cell_info.prototype { @@ -957,8 +963,7 @@ impl<'a> Simulator<'a> { dims.size(), dims.as_serializing_dim(), self.env.cells[cell_index] - .as_primitive() - .unwrap() + .unwrap_primitive() .dump_memory_state() .unwrap(), ) diff --git a/interp/src/flatten/structures/environment/program_counter.rs b/interp/src/flatten/structures/environment/program_counter.rs index c67c5d51e5..bd3daf0731 100644 --- a/interp/src/flatten/structures/environment/program_counter.rs +++ b/interp/src/flatten/structures/environment/program_counter.rs @@ -369,13 +369,24 @@ impl ProgramCounter { &mut self.vec } - pub fn par_map_mut(&mut self) -> &mut HashMap { + pub fn _par_map_mut(&mut self) -> &mut HashMap { &mut self.par_map } pub fn _par_map(&self) -> &HashMap { &self.par_map } + + /// returns mutable references to both vec and par_map. + /// This is useful for when you need to mutate both at the same time. + pub fn mut_refs( + &mut self, + ) -> ( + &mut Vec, + &mut HashMap, + ) { + (&mut self.vec, &mut self.par_map) + } } impl<'a> IntoIterator for &'a ProgramCounter { diff --git a/tools/cider-data-converter/Cargo.toml b/tools/cider-data-converter/Cargo.toml index e189c34052..b1862de0a5 100644 --- a/tools/cider-data-converter/Cargo.toml +++ b/tools/cider-data-converter/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "cider-data-converter" authors.workspace = true -rust-version.workspace = true +rust-version = "1.73" edition.workspace = true version = "0.1.0"