-
Notifications
You must be signed in to change notification settings - Fork 17
refactor: add HugrView::scheduling_graph, deprecate region_portgraph #3015
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 33 commits
e010488
69eea12
b9f83a5
12a3fd5
3fcbbdc
4d1d0c8
b813360
87f0c36
d532d3c
514e23e
d767be2
fbc676e
04178e4
3818cfe
9cf4da8
242193e
ff2e0cc
ae1bf67
521319f
aadc6b2
4137aff
7525ac4
e1b6fca
db89b21
956f087
9ad9d74
20d2d95
d14bf1b
706ea1c
f7150f1
29ed2fb
3d42940
52a9dd9
a210440
16bbe5f
ea9f210
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,10 +7,12 @@ pub mod render; | |
| mod rerooted; | ||
| mod root_checked; | ||
| pub mod sibling_subgraph; | ||
| mod syn_edge; | ||
|
|
||
| #[cfg(test)] | ||
| mod tests; | ||
|
|
||
| use ::petgraph::visit as pv; | ||
| use serde::de::Deserialize; | ||
| use std::borrow::Cow; | ||
| use std::collections::HashMap; | ||
|
|
@@ -24,23 +26,22 @@ pub use rerooted::Rerooted; | |
| pub use root_checked::{InvalidSignature, RootChecked, check_tag}; | ||
| pub use sibling_subgraph::SiblingSubgraph; | ||
|
|
||
| use itertools::Itertools; | ||
| use itertools::{Either, Itertools}; | ||
| use portgraph::render::{DotFormat, MermaidFormat}; | ||
| use portgraph::{LinkView, PortView}; | ||
|
|
||
| use super::internal::{HugrInternals, HugrMutInternals}; | ||
| use super::validate::ValidationContext; | ||
| use super::{Hugr, HugrMut, Node, ValidationError}; | ||
| use crate::core::HugrNode; | ||
| use crate::extension::ExtensionRegistry; | ||
| use crate::hugr::internal::PortgraphNodeMap; | ||
| use crate::hugr::views::syn_edge::SynEdgeWrapper; | ||
| use crate::metadata::{Metadata, RawMetadataValue}; | ||
| use crate::ops::handle::NodeHandle; | ||
| use crate::ops::{OpParent, OpTag, OpTrait, OpType}; | ||
|
|
||
| use crate::ops::{OpParent, OpTag, OpTrait, OpType, handle::NodeHandle}; | ||
| use crate::types::{EdgeKind, PolyFuncType, Signature, Type}; | ||
| use crate::{Direction, IncomingPort, OutgoingPort, Port}; | ||
|
|
||
| use itertools::Either; | ||
| use super::internal::{HugrInternals, HugrMutInternals}; | ||
| use super::validate::ValidationContext; | ||
| use super::{Hugr, HugrMut, Node, ValidationError}; | ||
|
|
||
| /// A trait for inspecting HUGRs. | ||
| /// For end users we intend this to be superseded by region-specific APIs. | ||
|
|
@@ -391,10 +392,7 @@ pub trait HugrView: HugrInternals { | |
|
|
||
| /// Return a wrapper over the view that can be used in petgraph algorithms. | ||
| #[inline] | ||
| #[deprecated( | ||
| since = "0.26.0", | ||
| note = "Use hugr_core::internal::HugrInternals::region_portgraph instead." | ||
| )] | ||
| #[deprecated(since = "0.26.0", note = "Use HugrView::scheduling_graph instead.")] | ||
| #[expect(deprecated)] // Remove at same time as PetgraphWrapper | ||
| fn as_petgraph(&self) -> PetgraphWrapper<'_, Self> | ||
| where | ||
|
|
@@ -403,6 +401,22 @@ pub trait HugrView: HugrInternals { | |
| PetgraphWrapper { hugr: self } | ||
| } | ||
|
|
||
| /// A view of a flat region, including ordering constraints from nonlocal edges, | ||
| /// suitable for use with petgraph algorithms. | ||
| fn scheduling_graph(&self, parent: Self::Node) -> SchedulingGraph<'_, Self> { | ||
| #[expect(deprecated)] // Inline region_portgraph here when removing | ||
| let (region_view, region_nodes) = self.region_portgraph(parent); | ||
| let graph = SynEdgeWrapper { | ||
| region_view, | ||
| syn_edges: Vec::new(), | ||
| }; | ||
| SchedulingGraph { | ||
| graph, | ||
| node_map: region_nodes, | ||
| region_parent: parent, | ||
| } | ||
| } | ||
|
|
||
| /// Return the mermaid representation of the underlying hierarchical graph. | ||
| /// | ||
| /// The hierarchy is represented using subgraphs. Edges are labelled with | ||
|
|
@@ -552,6 +566,71 @@ impl<S: HugrNode> ExtractionResult<S> for HashMap<S, Node> { | |
| } | ||
| } | ||
|
|
||
| /// A graph of a flat region of a Hugr, including ordering constraints from nonlocal edges | ||
| pub struct SchedulingGraph<'a, V: HugrView + ?Sized + 'a> { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we could have |
||
| graph: SynEdgeWrapper<portgraph::view::FlatRegion<'a, V::RegionPortgraph<'a>>>, | ||
| node_map: V::RegionPortgraphNodes, | ||
| region_parent: V::Node, | ||
| } | ||
|
|
||
| impl<'a, V: HugrView + 'a> SchedulingGraph<'a, V> { | ||
| /// Get the parent node of the region represented by this scheduling graph | ||
| pub fn region_parent(&self) -> V::Node { | ||
| self.region_parent | ||
| } | ||
|
|
||
| /// Converts a `V::Node` index in the original Hugr into | ||
| /// an index in [Self::petgraph] | ||
| /// | ||
| /// # Panics | ||
| /// | ||
| /// If `n` is not a child of [Self::region_parent] | ||
| pub fn node_to_pg(&self, n: V::Node) -> portgraph::NodeIndex { | ||
| self.node_map.to_portgraph(n) | ||
| } | ||
|
|
||
| /// Converts the index of a node in [Self::petgraph] to the corresponding | ||
| /// `V::Node` of the original Hugr. | ||
| /// | ||
| /// # Panics | ||
| /// | ||
| /// If `n` is not a node in `Self::petgraph` | ||
| pub fn pg_to_node(&self, n: portgraph::NodeIndex) -> V::Node { | ||
| self.node_map.from_portgraph(n) | ||
| } | ||
|
|
||
| /// Extracts the map between `V::Node` and the [NodeIndex] used in [Self::petgraph], | ||
| /// discarding the rest of `self`. | ||
| /// | ||
| /// [NodeIndex]: portgraph::NodeIndex | ||
| pub fn into_node_map(self) -> V::RegionPortgraphNodes { | ||
| self.node_map | ||
| } | ||
|
|
||
| fn portgraph_no_syn_edges( | ||
| self, | ||
| ) -> ( | ||
| portgraph::view::FlatRegion<'a, V::RegionPortgraph<'a>>, | ||
| V::RegionPortgraphNodes, | ||
| ) { | ||
| // This may need to change when the SynEdgeWrapper actually has edges in it... | ||
| // or maybe we should keep the assert to prevent this being used any time it does. | ||
| assert!(self.graph.syn_edges.is_empty()); | ||
| (self.graph.region_view, self.node_map) | ||
| } | ||
|
|
||
| /// Access to the graph, sufficient to allow [pv::Topo] | ||
| pub fn petgraph( | ||
| &self, | ||
| ) -> impl pv::NodeCount | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this type is part of the hiding, and quite deliberate. It could be much more detailed (NodeId/EdgeId types etc.) |
||
| + pv::IntoNodeIdentifiers | ||
| + pv::IntoEdgeReferences | ||
| + pv::IntoNeighborsDirected | ||
| + pv::Visitable<NodeId = portgraph::NodeIndex> { | ||
| &self.graph | ||
| } | ||
| } | ||
|
|
||
| impl HugrView for Hugr { | ||
| #[inline] | ||
| fn entrypoint(&self) -> Self::Node { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name is very much up for grabs, I wasn't too keen on
region_petgraph(it also has to return a nodemap, and doesn't really say what it's about - edges not in the hugr).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like
scheduling_graph, it conveys well the causal order meaning.