From 885b3e484b8d2a001c1fe7633e3439e4f4d1761a Mon Sep 17 00:00:00 2001 From: Griffin Berlstein Date: Fri, 14 Jun 2024 12:15:24 -0400 Subject: [PATCH] [Cider 2] Multi-comp bug and more tests (#2148) * enable the invoke comp test suite * ensure done ports are being set low appropriately * add in the ref cells and fully structural * add TCAM and reconfigure MRXL stuff * add the "complex" tests --- .../cider2-tests/complex/unsigned-div.expect | 8 + .../complex/unsigned-dot-product.expect | 63 +++++++ interp/cider2-tests/runt.toml | 154 +++++++++--------- .../src/flatten/structures/environment/env.rs | 26 ++- 4 files changed, 174 insertions(+), 77 deletions(-) create mode 100644 interp/cider2-tests/complex/unsigned-div.expect create mode 100644 interp/cider2-tests/complex/unsigned-dot-product.expect diff --git a/interp/cider2-tests/complex/unsigned-div.expect b/interp/cider2-tests/complex/unsigned-div.expect new file mode 100644 index 0000000000..6ed76fa238 --- /dev/null +++ b/interp/cider2-tests/complex/unsigned-div.expect @@ -0,0 +1,8 @@ +{ + "reg_q": [ + 11 + ], + "reg_r": [ + 1 + ] +} diff --git a/interp/cider2-tests/complex/unsigned-dot-product.expect b/interp/cider2-tests/complex/unsigned-dot-product.expect new file mode 100644 index 0000000000..8149168761 --- /dev/null +++ b/interp/cider2-tests/complex/unsigned-dot-product.expect @@ -0,0 +1,63 @@ +{ + "counter": [ + 4 + ], + "mem0": [ + [ + 12, + 0, + 0, + 0 + ], + [ + 10, + 0, + 0, + 0 + ], + [ + 20, + 0, + 0, + 0 + ], + [ + 34, + 0, + 0, + 0 + ] + ], + "mem1": [ + [ + 16, + 0, + 0, + 0 + ], + [ + 32, + 0, + 0, + 0 + ], + [ + 8, + 0, + 0, + 0 + ], + [ + 24, + 0, + 0, + 0 + ] + ], + "r_2": [ + 1376 + ], + "t": [ + 1488 + ] +} diff --git a/interp/cider2-tests/runt.toml b/interp/cider2-tests/runt.toml index e884ad1c4e..a61f56d3b6 100644 --- a/interp/cider2-tests/runt.toml +++ b/interp/cider2-tests/runt.toml @@ -27,14 +27,15 @@ timeout = 10 # """ # timeout = 10 -# [[tests]] -# name = "complex" -# paths = ["tests/complex/*.futil"] +[[tests]] +name = "complex" +paths = ["../tests/complex/*.futil"] -# cmd = """ -# ../target/debug/cider {} | jq . --sort-keys -# """ -# timeout = 10 +cmd = """ + ../../target/debug/cider {} -l ../../ flat --dump-registers | ../../target/debug/cider-data-converter --to json | jq --sort-keys +""" +timeout = 10 +expect_dir = "complex" [[tests]] name = "primitives" @@ -72,25 +73,26 @@ fud2 {} --from calyx --to dat --through cider -s sim.data={}.data -s calyx.args= timeout = 10 expect_dir = "invoke" -# [[tests]] -# name = "invoke comp" -# paths = ["../tests/control/invoke/*.futil"] -# cmd = """ -# fud2 {} --from calyx --to dat --through interp-flat -s calyx.flags=" -p compile-invoke" -s sim.data={}.data | jq --sort-keys -# """ +[[tests]] +name = "invoke comp" +paths = ["../tests/control/invoke/*.futil"] +cmd = """ +fud2 {} --from calyx --to dat --through cider -s calyx.flags=" -p compile-invoke" -s sim.data={}.data -s calyx.args="--log off" | jq --sort-keys +""" +expect_dir = "invoke" -# [[tests]] -# name = "fully structural" -# paths = [ -# "tests/control/*.futil", -# # Disabled iteration tests due to bug -# # "tests/control/iteration/*.futil" -# ] -# cmd = """ -# ../target/debug/calyx {} -d pre-opt -d post-opt -p simplify-with-control -l ../ | ../target/debug/cider | jq .memories --sort-keys -# """ -# expect_dir = "tests/lowered/" -# # timeout = 10 +[[tests]] +name = "fully structural" +paths = [ + "../tests/control/*.futil", + # Disabled iteration tests due to bug + "../tests/control/iteration/*.futil", +] +cmd = """ +../../target/debug/calyx {} -d pre-opt -d post-opt -p simplify-with-control -l ../../ --log off | ../../target/debug/cider -l ../../ flat --dump-registers | ../../target/debug/cider-data-converter --to json | jq --sort-keys +""" +expect_dir = "control" +# timeout = 10 [[tests]] name = "fully structural static" @@ -112,49 +114,54 @@ fud2 --from calyx --to dat \ {} | jq --sort-keys """ -# [[tests]] -# name = "correctness ref cells" -# paths = ["../tests/correctness/ref-cells/*.futil"] -# cmd = """ -# fud exec --from calyx --to jq \ -# --through interpreter-out \ -# -s calyx.flags "-p compile-invoke" \ -# -s verilog.data {}.data \ -# -s interpreter.flags " --raw" \ -# -s jq.expr ".main" \ -# -s jq.flags "--sort-keys " \ -# {} -q -# """ +[[tests]] +name = "correctness ref cells" +paths = ["../../tests/correctness/ref-cells/*.futil"] +cmd = """ +fud2 --from calyx --to dat \ + --through cider \ + -s sim.data={}.data \ + -s calyx.args="--log off" \ + {} | jq --sort-keys +""" -# [[tests]] -# name = "numeric types correctness and parsing" -# paths = [ -# "../tests/correctness/numeric-types/parsing/*.futil", -# "../tests/correctness/numeric-types/bitnum/*.futil", -# "../tests/correctness/numeric-types/fixed-point/*.futil", -# ] -# cmd = """ -# fud exec --from calyx --to jq \ -# --through interpreter-out \ -# -s interpreter.flags "--raw " \ -# -s verilog.data {}.data \ -# -s jq.expr ".main" \ -# -s jq.flags "--sort-keys " \ -# {} -q -# """ +[[tests]] +name = "correctness ref cells compiled" +paths = ["../../tests/correctness/ref-cells/*.futil"] +cmd = """ +fud2 --from calyx --to dat \ + --through cider \ + -s sim.data={}.data \ + -s calyx.args="--log off" \ + -s calyx.flags=" -p compile-invoke" \ + {} | jq --sort-keys +""" -# [[tests]] -# name = "[frontend] tcam testing" -# paths = ["../tests/correctness/tcam/*.futil"] -# cmd = """ -# fud exec --from calyx --to jq \ -# --through interpreter-out \ -# -s interpreter.flags "--raw " \ -# -s verilog.data {}.data \ -# -s jq.expr ".main" \ -# -s jq.flags "--sort-keys " \ -# {} -q -# """ +[[tests]] +name = "numeric types correctness and parsing" +paths = [ + "../../tests/correctness/numeric-types/parsing/*.futil", + "../../tests/correctness/numeric-types/bitnum/*.futil", + "../../tests/correctness/numeric-types/fixed-point/*.futil", +] +cmd = """ +fud2 --from calyx --to dat \ + --through cider \ + -s sim.data={}.data \ + -s calyx.args="--log off" \ + {} | jq --sort-keys +""" + +[[tests]] +name = "[frontend] tcam testing" +paths = ["../../tests/correctness/tcam/*.futil"] +cmd = """ +fud2 --from calyx --to dat \ + --through cider \ + -s calyx.args="--log off" \ + -s sim.data={}.data \ + {} | jq --sort-keys +""" # [[tests]] # name = "[frontend] systolic array correctness" @@ -183,16 +190,17 @@ fud2 --from calyx --to dat \ # expect_dir = "tests/ntt-results/" +# The MRXL tests cannot run because their data is in a different format than the +# others and there is no tool to convert it # [[tests]] # name = "[frontend] mrxl correctness" -# paths = ["../frontends/mrxl/test/*.mrxl"] +# paths = ["../../frontends/mrxl/test/*.mrxl"] # cmd = """ -# fud e -q {} --from mrxl --to jq \ -# --through interpreter-out \ -# -s interpreter.flags "--raw " \ -# -s verilog.data {}.data \ -# -s jq.flags "--sort-keys " \ -# -s jq.expr ".main" +# fud2 {} --from mrxl --to dat \ +# --through cider \ +# -s sim.data={}.data \ +# -s calyx.args="--log off" \ +# | jq --sort-keys # """ # [[tests]] diff --git a/interp/src/flatten/structures/environment/env.rs b/interp/src/flatten/structures/environment/env.rs index b620a6a750..226eb6565e 100644 --- a/interp/src/flatten/structures/environment/env.rs +++ b/interp/src/flatten/structures/environment/env.rs @@ -28,6 +28,8 @@ use crate::{ serialization::data_dump::{DataDump, Dimensions}, values::Value, }; +use ahash::HashSet; +use ahash::HashSetExt; use itertools::Itertools; use std::{fmt::Debug, iter::once}; @@ -895,7 +897,8 @@ impl<'a> Simulator<'a> { // buffers. Can pick anything from zero to the number of nodes in the // program counter as the size let mut leaf_nodes = vec![]; - let mut set_done = vec![]; + let mut set_done_high = vec![]; + let mut set_done_low: HashSet = HashSet::new(); let mut new_nodes = vec![]; let (mut vecs, mut par_map, mut with_map) = self.env.pc.take_fields(); @@ -905,8 +908,15 @@ impl<'a> Simulator<'a> { vecs.retain_mut(|node| { let comp_go = self.env.get_comp_go(node.comp); let comp_done = self.env.get_comp_done(node.comp); + + // if the done is not high & defined, we need to set it to low + if !self.env.ports[comp_done].as_bool().unwrap_or_default() { + set_done_low.insert(comp_done); + } + if !self.env.ports[comp_go].as_bool().unwrap_or_default() || self.env.ports[comp_done].as_bool().unwrap_or_default() { - // if the go port is low or the done port is high, we skip the node without doing anything + // if the go port is low or the done port is high, we skip the + // node without doing anything return true; } @@ -1073,7 +1083,10 @@ impl<'a> Simulator<'a> { // either we are not a par node, or we are the last par node (!matches!(&self.env.ctx.primary[node.control_node_idx], ControlNode::Par(_)) || !par_map.contains_key(node)) { - set_done.push(self.env.get_comp_done(node.comp)); + let done_port = self.env.get_comp_done(node.comp); + set_done_high.push(done_port); + // make sure we don't set this port low + set_done_low.remove(&done_port); let comp_ledger = self.env.cells[node.comp].unwrap_comp(); *node = node.new_retain_comp(self.env.ctx.primary[comp_ledger.comp_id].control.unwrap()); true @@ -1090,10 +1103,14 @@ impl<'a> Simulator<'a> { self.undef_all_ports(); self.set_root_go_high(); - for port in set_done { + for port in set_done_high { self.env.ports[port] = PortValue::new_implicit(Value::bit_high()); } + for port in set_done_low { + self.env.ports[port] = PortValue::new_implicit(Value::bit_low()); + } + for node in &leaf_nodes { match &self.env.ctx.primary[node.control_node_idx] { ControlNode::Enable(e) => { @@ -1154,6 +1171,7 @@ impl<'a> Simulator<'a> { /// Evaluate the entire program pub fn run_program(&mut self) -> InterpreterResult<()> { while !self.is_done() { + // self._print_env(); self.step()? } Ok(())