From 54f784a0031d05f59c6504cd40c9d3a3f80c4654 Mon Sep 17 00:00:00 2001 From: Luca Mondada Date: Wed, 13 Dec 2023 19:03:40 +0000 Subject: [PATCH 1/3] feat!: use ConvexChecker trait --- Cargo.toml | 6 ++++- src/hugr/views/sibling_subgraph.rs | 37 +++++++++++++++--------------- 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9f5f098ee..5bfcb1f84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,11 @@ path = "src/lib.rs" [dependencies] thiserror = "1.0.28" -portgraph = { version = "0.10.0", features = ["serde", "petgraph"] } +# portgraph = { version = "0.10.0", features = ["serde", "petgraph"] } +portgraph = { git = "https://github.com/CQCL/portgraph", branch = "feat/convex-trait", features = [ + "serde", + "petgraph", +] } regex = "1.9.5" cgmath = { version = "0.18.0", features = ["serde"] } num-rational = { version = "0.4.1", features = ["serde"] } diff --git a/src/hugr/views/sibling_subgraph.rs b/src/hugr/views/sibling_subgraph.rs index 461083378..c6b5b30bf 100644 --- a/src/hugr/views/sibling_subgraph.rs +++ b/src/hugr/views/sibling_subgraph.rs @@ -13,6 +13,7 @@ use std::collections::HashSet; use std::mem; use itertools::Itertools; +use portgraph::algorithms::{ConvexChecker, TopoConvexChecker}; use portgraph::{view::Subgraph, Direction, PortView}; use thiserror::Error; @@ -156,7 +157,7 @@ impl SiblingSubgraph { outgoing: OutgoingPorts, hugr: &impl HugrView, ) -> Result { - let checker = ConvexChecker::new(hugr); + let checker = TopoConvexChecker::new(hugr.portgraph()); Self::try_new_with_checker(incoming, outgoing, hugr, &checker) } @@ -168,11 +169,11 @@ impl SiblingSubgraph { /// /// Refer to [`SiblingSubgraph::try_new`] for the full /// documentation. - pub fn try_new_with_checker<'c, 'h: 'c, H: HugrView>( + pub fn try_new_with_checker( inputs: IncomingPorts, outputs: OutgoingPorts, - hugr: &'h H, - checker: &'c ConvexChecker<'h, H>, + hugr: &impl HugrView, + checker: &impl ConvexChecker, ) -> Result { let pg = hugr.portgraph(); @@ -187,7 +188,7 @@ impl SiblingSubgraph { let nodes = subpg.nodes_iter().map_into().collect_vec(); validate_subgraph(hugr, &nodes, &inputs, &outputs)?; - if !subpg.is_convex_with_checker(&checker.0) { + if !subpg.is_convex_with_checker(checker) { return Err(InvalidSubgraph::NotConvex); } @@ -217,7 +218,7 @@ impl SiblingSubgraph { nodes: impl Into>, hugr: &impl HugrView, ) -> Result { - let checker = ConvexChecker::new(hugr); + let checker = TopoConvexChecker::new(hugr.portgraph()); Self::try_from_nodes_with_checker(nodes, hugr, &checker) } @@ -232,7 +233,7 @@ impl SiblingSubgraph { pub fn try_from_nodes_with_checker<'c, 'h: 'c, H: HugrView>( nodes: impl Into>, hugr: &'h H, - checker: &'c ConvexChecker<'h, H>, + checker: &impl ConvexChecker, ) -> Result { let nodes = nodes.into(); let nodes_set = nodes.iter().copied().collect::>(); @@ -447,17 +448,17 @@ fn combine_in_out<'a>( /// /// This can be used when constructing multiple sibling subgraphs to speed up /// convexity checking. -pub struct ConvexChecker<'g, Base: 'g + HugrView>( - portgraph::algorithms::ConvexChecker>, -); - -impl<'g, Base: HugrView> ConvexChecker<'g, Base> { - /// Create a new convexity checker. - pub fn new(base: &'g Base) -> Self { - let pg = base.portgraph(); - Self(portgraph::algorithms::ConvexChecker::new(pg)) - } -} +// pub struct ConvexChecker<'g, Base: 'g + HugrView>( +// portgraph::algorithms::TopoConvexChecker>, +// ); + +// impl<'g, Base: HugrView> ConvexChecker<'g, Base> { +// /// Create a new convexity checker. +// pub fn new(base: &'g Base) -> Self { +// let pg = base.portgraph(); +// Self(portgraph::algorithms::TopoConvexChecker::new(pg)) +// } +// } /// The type of all ports in the iterator. /// From ce84352321ee36a11308bb7d4b245a09ff13537d Mon Sep 17 00:00:00 2001 From: Agustin Borgna Date: Thu, 14 Dec 2023 14:05:01 +0000 Subject: [PATCH 2/3] Use the newly released portgraph --- Cargo.toml | 6 +----- src/hugr/views/sibling_subgraph.rs | 16 ---------------- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5bfcb1f84..b1acc0bd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,11 +24,7 @@ path = "src/lib.rs" [dependencies] thiserror = "1.0.28" -# portgraph = { version = "0.10.0", features = ["serde", "petgraph"] } -portgraph = { git = "https://github.com/CQCL/portgraph", branch = "feat/convex-trait", features = [ - "serde", - "petgraph", -] } +portgraph = { version = "0.11.0", features = ["serde", "petgraph"] } regex = "1.9.5" cgmath = { version = "0.18.0", features = ["serde"] } num-rational = { version = "0.4.1", features = ["serde"] } diff --git a/src/hugr/views/sibling_subgraph.rs b/src/hugr/views/sibling_subgraph.rs index c6b5b30bf..79a43fbdd 100644 --- a/src/hugr/views/sibling_subgraph.rs +++ b/src/hugr/views/sibling_subgraph.rs @@ -444,22 +444,6 @@ fn combine_in_out<'a>( .chain(outputs.iter().map(|(n, p)| (*n, (*p).into()))) } -/// Precompute convexity information for a HUGR. -/// -/// This can be used when constructing multiple sibling subgraphs to speed up -/// convexity checking. -// pub struct ConvexChecker<'g, Base: 'g + HugrView>( -// portgraph::algorithms::TopoConvexChecker>, -// ); - -// impl<'g, Base: HugrView> ConvexChecker<'g, Base> { -// /// Create a new convexity checker. -// pub fn new(base: &'g Base) -> Self { -// let pg = base.portgraph(); -// Self(portgraph::algorithms::TopoConvexChecker::new(pg)) -// } -// } - /// The type of all ports in the iterator. /// /// If the array is empty or a port does not exist, returns `None`. From 2e3ef9f016ba85d938a63c8dc703e66ed61960d2 Mon Sep 17 00:00:00 2001 From: Agustin Borgna Date: Thu, 14 Dec 2023 14:22:57 +0000 Subject: [PATCH 3/3] Add a TopoConvexChecker wrapper --- src/hugr/views/sibling_subgraph.rs | 33 +++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/hugr/views/sibling_subgraph.rs b/src/hugr/views/sibling_subgraph.rs index 79a43fbdd..6164d2e75 100644 --- a/src/hugr/views/sibling_subgraph.rs +++ b/src/hugr/views/sibling_subgraph.rs @@ -13,7 +13,7 @@ use std::collections::HashSet; use std::mem; use itertools::Itertools; -use portgraph::algorithms::{ConvexChecker, TopoConvexChecker}; +use portgraph::algorithms::ConvexChecker; use portgraph::{view::Subgraph, Direction, PortView}; use thiserror::Error; @@ -157,7 +157,7 @@ impl SiblingSubgraph { outgoing: OutgoingPorts, hugr: &impl HugrView, ) -> Result { - let checker = TopoConvexChecker::new(hugr.portgraph()); + let checker = TopoConvexChecker::new(hugr); Self::try_new_with_checker(incoming, outgoing, hugr, &checker) } @@ -218,7 +218,7 @@ impl SiblingSubgraph { nodes: impl Into>, hugr: &impl HugrView, ) -> Result { - let checker = TopoConvexChecker::new(hugr.portgraph()); + let checker = TopoConvexChecker::new(hugr); Self::try_from_nodes_with_checker(nodes, hugr, &checker) } @@ -444,6 +444,33 @@ fn combine_in_out<'a>( .chain(outputs.iter().map(|(n, p)| (*n, (*p).into()))) } +/// Precompute convexity information for a HUGR. +/// +/// This can be used when constructing multiple sibling subgraphs to speed up +/// convexity checking. +pub struct TopoConvexChecker<'g, Base: 'g + HugrView>( + portgraph::algorithms::TopoConvexChecker>, +); + +impl<'g, Base: HugrView> TopoConvexChecker<'g, Base> { + /// Create a new convexity checker. + pub fn new(base: &'g Base) -> Self { + let pg = base.portgraph(); + Self(portgraph::algorithms::TopoConvexChecker::new(pg)) + } +} + +impl<'g, Base: HugrView> ConvexChecker for TopoConvexChecker<'g, Base> { + fn is_convex( + &self, + nodes: impl IntoIterator, + inputs: impl IntoIterator, + outputs: impl IntoIterator, + ) -> bool { + self.0.is_convex(nodes, inputs, outputs) + } +} + /// The type of all ports in the iterator. /// /// If the array is empty or a port does not exist, returns `None`.