From 4a0242f81df3b1f7a8ea63d3c203de0ccaf3d892 Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Tue, 10 Dec 2024 12:26:07 +0000 Subject: [PATCH 1/4] test: failing test for subgraph with disconnected nodes --- hugr-core/src/hugr/views/sibling_subgraph.rs | 27 ++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/hugr-core/src/hugr/views/sibling_subgraph.rs b/hugr-core/src/hugr/views/sibling_subgraph.rs index 589e96968..ddb5859d9 100644 --- a/hugr-core/src/hugr/views/sibling_subgraph.rs +++ b/hugr-core/src/hugr/views/sibling_subgraph.rs @@ -785,9 +785,11 @@ mod tests { use cool_asserts::assert_matches; use crate::builder::inout_sig; + use crate::hugr::Rewrite; use crate::ops::Const; use crate::std_extensions::arithmetic::float_types::{self, ConstF64}; use crate::std_extensions::logic::{self, LogicOp}; + use crate::type_row; use crate::utils::test_quantum_extension::{self, cx_gate, rz_f64}; use crate::{ builder::{ @@ -1155,4 +1157,29 @@ mod tests { let subg = SiblingSubgraph::try_new_dataflow_subgraph(&view).unwrap(); assert_eq!(subg.nodes().len(), 2); } + + #[test] + fn test_unconnected() { + // test a replacement on a subgraph with a discarded output + let mut b = DFGBuilder::new(Signature::new(bool_t(), type_row![])).unwrap(); + let inw = b.input_wires().exactly_one().unwrap(); + let not_n = b.add_dataflow_op(LogicOp::Not, [inw]).unwrap(); + // Unconnected output, discarded + let mut h = b.finish_hugr_with_outputs([]).unwrap(); + + let subg = SiblingSubgraph::from_node(not_n.node(), &h); + + assert_eq!(subg.nodes().len(), 1); + // TODO create a valid replacement + let replacement = { + let mut rep_b = DFGBuilder::new(Signature::new_endo(bool_t())).unwrap(); + let inw = rep_b.input_wires().exactly_one().unwrap(); + + let not_n = rep_b.add_dataflow_op(LogicOp::Not, [inw]).unwrap(); + + rep_b.finish_hugr_with_outputs(not_n.outputs()).unwrap() + }; + let rep = subg.create_simple_replacement(&h, replacement).unwrap(); + rep.apply(&mut h).unwrap(); + } } From 52344d22f4304e9006352da667f689ae1b0510a4 Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Wed, 11 Dec 2024 15:04:12 +0000 Subject: [PATCH 2/4] fix: allow disconnected outputs in `SiblingSubgraph::from_node` --- hugr-core/src/hugr/views/sibling_subgraph.rs | 28 +++++++++++++++----- hugr/Cargo.toml | 1 - 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/hugr-core/src/hugr/views/sibling_subgraph.rs b/hugr-core/src/hugr/views/sibling_subgraph.rs index ddb5859d9..470cd762a 100644 --- a/hugr-core/src/hugr/views/sibling_subgraph.rs +++ b/hugr-core/src/hugr/views/sibling_subgraph.rs @@ -277,9 +277,6 @@ impl SiblingSubgraph { /// /// The subgraph signature will be given by signature of the node. pub fn from_node(node: Node, hugr: &impl HugrView) -> Self { - // TODO once https://github.com/CQCL/portgraph/issues/155 - // is fixed we can just call try_from_nodes here. - // Until then, doing this saves a lot of work. let nodes = vec![node]; let inputs = hugr .node_inputs(node) @@ -288,7 +285,17 @@ impl SiblingSubgraph { .collect_vec(); let outputs = hugr .node_outputs(node) - .filter_map(|p| hugr.is_linked(node, p).then_some((node, p))) + .filter_map(|p| { + // accept linked outputs or unlinked value outputs + { + hugr.is_linked(node, p) + || hugr + .get_optype(node) + .port_kind(p) + .is_some_and(|k| k.is_value()) + } + .then_some((node, p)) + }) .collect_vec(); Self { @@ -1161,7 +1168,12 @@ mod tests { #[test] fn test_unconnected() { // test a replacement on a subgraph with a discarded output - let mut b = DFGBuilder::new(Signature::new(bool_t(), type_row![])).unwrap(); + let mut b = DFGBuilder::new( + Signature::new(bool_t(), type_row![]) + // .with_prelude() + .with_extension_delta(crate::std_extensions::logic::EXTENSION_ID), + ) + .unwrap(); let inw = b.input_wires().exactly_one().unwrap(); let not_n = b.add_dataflow_op(LogicOp::Not, [inw]).unwrap(); // Unconnected output, discarded @@ -1172,7 +1184,11 @@ mod tests { assert_eq!(subg.nodes().len(), 1); // TODO create a valid replacement let replacement = { - let mut rep_b = DFGBuilder::new(Signature::new_endo(bool_t())).unwrap(); + let mut rep_b = DFGBuilder::new( + Signature::new_endo(bool_t()) + .with_extension_delta(crate::std_extensions::logic::EXTENSION_ID), + ) + .unwrap(); let inw = rep_b.input_wires().exactly_one().unwrap(); let not_n = rep_b.add_dataflow_op(LogicOp::Not, [inw]).unwrap(); diff --git a/hugr/Cargo.toml b/hugr/Cargo.toml index 534e88f27..d4f499ca0 100644 --- a/hugr/Cargo.toml +++ b/hugr/Cargo.toml @@ -44,4 +44,3 @@ bumpalo = { workspace = true, features = ["collections"] } [[bench]] name = "bench_main" harness = false - From 63314932d8c914b409ad0b3542c7fc66d03c885b Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Wed, 11 Dec 2024 15:04:29 +0000 Subject: [PATCH 3/4] refactor: use `from_node` in lowering --- hugr-passes/src/lower.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hugr-passes/src/lower.rs b/hugr-passes/src/lower.rs index cb95b1433..09e02c41d 100644 --- a/hugr-passes/src/lower.rs +++ b/hugr-passes/src/lower.rs @@ -67,7 +67,7 @@ pub fn lower_ops( replacements .into_iter() .map(|(node, replacement)| { - let subcirc = SiblingSubgraph::try_from_nodes([node], hugr)?; + let subcirc = SiblingSubgraph::from_node(node, hugr); let rw = subcirc.create_simple_replacement(hugr, replacement)?; let mut repls = hugr.apply_rewrite(rw)?; debug_assert_eq!(repls.len(), 1); From 6a0f4b50cd24a673445b35ee1c9cc3ff4b742939 Mon Sep 17 00:00:00 2001 From: Seyon Sivarajah Date: Wed, 11 Dec 2024 16:24:48 +0000 Subject: [PATCH 4/4] chore: clippy fix --- hugr-llvm/src/emit/test.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/hugr-llvm/src/emit/test.rs b/hugr-llvm/src/emit/test.rs index 52fce5154..253b41267 100644 --- a/hugr-llvm/src/emit/test.rs +++ b/hugr-llvm/src/emit/test.rs @@ -659,11 +659,9 @@ mod test_fns { .conditional_builder( ([type_row![], type_row![]], eq_0), vec![(just_input.clone(), loop_int_w)], - vec![HugrSumType::new(vec![ - vec![just_input.clone()].into(), - vec![], - ]) - .into()] + vec![ + HugrSumType::new(vec![vec![just_input.clone()], vec![]]).into() + ] .into(), ) .unwrap(); @@ -732,7 +730,7 @@ mod test_fns { ) { exec_ctx.add_extensions(add_int_extensions); assert_eq!( - input * 1 << (iters + 1), + input << (iters + 1), exec_ctx.exec_hugr_u64(terminal_loop, "main") ); }