Skip to content
Open
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
e010488
Add (local to views) mod syn_edge with SynEdgeWrapper
acl-cqc Mar 14, 2026
69eea12
Remove commented-out GetAdjacencyMatrix
acl-cqc Mar 31, 2026
b9f83a5
Move SiblingSubgraph tests into new file
acl-cqc Mar 31, 2026
12a3fd5
add petgraph convexity checker
acl-cqc Mar 31, 2026
3fcbbdc
Define scheduling_graph in HugrView
acl-cqc Mar 14, 2026
4d1d0c8
Add small test that implements expected traits
acl-cqc Mar 31, 2026
b813360
SchedulingGraph: rename node(s=>_map), add fn graph() -> impl... for …
acl-cqc Mar 31, 2026
87f0c36
Deprecate region_portgraph, switch all uses except sibling_subgraph (…
acl-cqc Mar 31, 2026
d532d3c
Fix TopoConvexChecker `where`, add test that we can use on Scheduling…
acl-cqc Mar 31, 2026
514e23e
WIP add SchedGraphChecker and try to impl HugrConvexChecker for it
acl-cqc Mar 31, 2026
d767be2
WIP2 any closer?
acl-cqc Mar 31, 2026
fbc676e
Reimplement petgraph traits conditioning on T: LinkView, except Visit…
acl-cqc Apr 8, 2026
04178e4
More tests of what compiles
acl-cqc Apr 1, 2026
3818cfe
fix sibling_subgraph??
acl-cqc Apr 8, 2026
9cf4da8
and generalize TopoConvexChecker
acl-cqc Apr 8, 2026
242193e
Deprecate stuff in sibling_subgraph, move over...some tricky region_p…
acl-cqc Apr 9, 2026
ff2e0cc
update tests to avoid deprecation
acl-cqc Apr 9, 2026
ae1bf67
Revert "More tests of what compiles"
acl-cqc Apr 9, 2026
521319f
Rename SchedulingGraph::graph -> ::petgraph
acl-cqc Apr 9, 2026
aadc6b2
better-backdoors
acl-cqc Apr 9, 2026
4137aff
syn_edge.rs module comment + remove compilation tests
acl-cqc Apr 9, 2026
7525ac4
sib_sub: ConvexChecker deprecation should name PortgraphCheckerWithNodes
acl-cqc Apr 9, 2026
e1b6fca
clippy hugr-persistent
acl-cqc Apr 9, 2026
db89b21
doc fix and doc workaround
acl-cqc Apr 9, 2026
956f087
better backdoor
acl-cqc Apr 9, 2026
9ad9d74
Remove node_map, expose node_to_pg / pg_to_node
acl-cqc Apr 27, 2026
20d2d95
refactor: inline make_boundary (only called once)
acl-cqc Apr 27, 2026
d14bf1b
test
acl-cqc Apr 27, 2026
706ea1c
views/tests.rs: add syn-edge test
acl-cqc Apr 28, 2026
f7150f1
fmt
acl-cqc Apr 28, 2026
29ed2fb
Update as_petgraph deprecation note
acl-cqc Apr 28, 2026
3d42940
also deprecate into_region_portgraph
acl-cqc Apr 29, 2026
8900ad8
Actually add syn edges
acl-cqc Apr 5, 2026
f90f9c1
Validation: don't look for order edge (and remove that test)
acl-cqc Apr 28, 2026
187755c
Builder: don't insert order edges for nonlocals
acl-cqc Mar 15, 2026
4f2b8bf
Update spec
acl-cqc Mar 20, 2026
63b308c
drop the assert that there are no syn edges to be dropped
acl-cqc Apr 27, 2026
9a79f46
"correct" test assertions i.e. changes in behaviour
acl-cqc Apr 29, 2026
24c5baf
Update python builder too
acl-cqc Apr 29, 2026
a173c2d
Remove region_portgraph, into_region_portgraph, as_petgraph, Petgraph…
acl-cqc Apr 29, 2026
52a9dd9
fmt
acl-cqc Apr 29, 2026
a210440
correct node_count -> capacity
acl-cqc May 5, 2026
16bbe5f
allow not expect deprecated works w/out mod hidden
acl-cqc May 5, 2026
ea9f210
Merge remote-tracking branch 'origin/main' into acl/syn_edge_prep
acl-cqc May 5, 2026
5d235f9
Merge remote-tracking branch 'origin/main' into acl/syn_edge_prep
acl-cqc May 5, 2026
199cc24
Merge branch 'acl/syn_edge_prep' into acl/syn_edges
acl-cqc May 5, 2026
b11ef50
Remove deprecated SiblingSubgraph stuff too
acl-cqc May 5, 2026
9df8c1d
rename hugr-persistent unused variables
acl-cqc May 5, 2026
64c3bef
Update docs re. deprecation (oops remove one missed from #3051)
acl-cqc May 5, 2026
b8a8108
snapshot-update
acl-cqc May 5, 2026
fcad20b
fix hugr-persistent, oops - add pub fn owned_scheduling_graph in hugr
acl-cqc May 5, 2026
5f7fd80
review comments, updating spec
acl-cqc May 6, 2026
09f6d3e
wordwrap, and driveby backquote Conditional
acl-cqc May 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 6 additions & 14 deletions hugr-core/src/builder/build_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::hugr::hugrmut::InsertionResult;
use crate::hugr::linking::{HugrLinking, NameLinkingPolicy, NodeLinkingDirective};
use crate::hugr::views::HugrView;
use crate::metadata::Metadata;
use crate::ops::{self, OpTag, OpTrait, OpType, Tag, TailLoop};
use crate::ops::{self, OpType, Tag, TailLoop};
use crate::utils::collect_array;
use crate::{Extension, IncomingPort, Node, OutgoingPort};

Expand Down Expand Up @@ -851,29 +851,21 @@ fn wire_up<T: Dataflow + ?Sized>(
}

let src_parent = src_parent.expect("Node has no parent");
let Some(src_sibling) = iter::successors(dst_parent, |&p| base.get_parent(p))
if !iter::successors(dst_parent, |&p| base.get_parent(p))
.tuple_windows()
.find_map(|(ancestor, ancestor_parent)| {
(ancestor_parent == src_parent ||
.any(|(_ancestor, ancestor_parent)| {
ancestor_parent == src_parent ||
// Dom edge - in CFGs
Some(ancestor_parent) == src_parent_parent)
.then_some(ancestor)
Some(ancestor_parent) == src_parent_parent
})
else {
{
return Err(BuilderWiringError::NoRelationIntergraph {
src,
src_offset: src_port.into(),
dst,
dst_offset: dst_port.into(),
});
};

if !OpTag::ControlFlowChild.is_superset(base.get_optype(src).tag())
&& !OpTag::ControlFlowChild.is_superset(base.get_optype(src_sibling).tag())
{
// Add a state order constraint unless one of the nodes is a CFG BasicBlock
base.add_other_edge(src, src_sibling);
}
} else if !typ.copyable() & base.linked_ports(src, src_port).next().is_some() {
// Don't copy linear edges.
return Err(BuilderWiringError::NoCopyLinear {
Expand Down
63 changes: 10 additions & 53 deletions hugr-core/src/hugr/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ use crate::ops::handle::NodeHandle;
/// Specifically, this trait provides access to the underlying portgraph
/// view.
pub trait HugrInternals {
/// The portgraph graph structure returned by [`HugrInternals::region_portgraph`].
/// The portgraph graph structure used internally by [`scheduling_graph`].
///
/// [`scheduling_graph`]: HugrView::scheduling_graph
type RegionPortgraph<'p>: LinkView<LinkEndpoint: Eq, NodeIndexBase = u32, PortIndexBase = u32, PortOffsetBase = u32>
+ Clone
+ 'p
Expand All @@ -31,27 +33,11 @@ pub trait HugrInternals {
type Node: Copy + Ord + std::fmt::Debug + std::fmt::Display + std::hash::Hash;

/// A mapping between HUGR nodes and portgraph nodes in the graph returned by
/// [`HugrInternals::region_portgraph`].
/// [`scheduling_graph`].
///
/// [`scheduling_graph`]: HugrView::scheduling_graph
type RegionPortgraphNodes: PortgraphNodeMap<Self::Node>;

/// Returns a flat portgraph view of a region in the HUGR, and a mapping between
/// HUGR nodes and portgraph nodes in the graph.
//
// NOTE: Ideally here we would just return `Self::RegionPortgraph<'_>`, but
// when doing so we are unable to restrict the type to implement petgraph's
// traits over references (e.g. `&MyGraph : IntoNodeIdentifiers`, which is
// needed if we want to use petgraph's algorithms on the region graph).
// This won't be solvable until we do the big petgraph refactor -.-
// In the meantime, just wrap the portgraph in a `FlatRegion` as needed.
#[deprecated(note = "Use scheduling_graph instead", since = "0.27.0")]
fn region_portgraph(
&self,
parent: Self::Node,
) -> (
portgraph::view::FlatRegion<'_, Self::RegionPortgraph<'_>>,
Self::RegionPortgraphNodes,
);

/// Returns a metadata entry associated with a node.
///
/// # Panics
Expand All @@ -60,8 +46,10 @@ pub trait HugrInternals {
fn node_metadata_map(&self, node: Self::Node) -> &NodeMetadataMap;
}

/// A map between hugr nodes and portgraph nodes in the graph returned by
/// [`HugrInternals::region_portgraph`].
/// A map between hugr nodes and portgraph nodes in a [HugrInternals::RegionPortgraph]
/// or [`scheduling_graph`].
///
/// [`scheduling_graph`]: HugrView::scheduling_graph
pub trait PortgraphNodeMap<N>: Clone + Sized + std::fmt::Debug {
/// Returns the portgraph index of a HUGR node in the associated region
/// graph.
Expand Down Expand Up @@ -120,20 +108,6 @@ impl HugrInternals for Hugr {

type RegionPortgraphNodes = DefaultPGNodeMap;

#[inline]
fn region_portgraph(
&self,
parent: Self::Node,
) -> (
portgraph::view::FlatRegion<'_, Self::RegionPortgraph<'_>>,
Self::RegionPortgraphNodes,
) {
let root = parent.into_portgraph();
let region =
portgraph::view::FlatRegion::new_without_root(&self.graph, &self.hierarchy, root);
(region, DefaultPGNodeMap)
}

#[inline]
fn node_metadata_map(&self, node: Self::Node) -> &NodeMetadataMap {
static EMPTY: OnceLock<NodeMetadataMap> = OnceLock::new();
Expand Down Expand Up @@ -393,23 +367,6 @@ impl HugrMutInternals for Hugr {
}
}

impl Hugr {
/// Consumes the HUGR and return a flat portgraph view of the region rooted
/// at `parent`.
#[inline]
#[deprecated(note = "Use scheduling_graph instead", since = "0.27.0")]
pub fn into_region_portgraph(
self,
parent: Node,
) -> portgraph::view::FlatRegion<'static, MultiPortGraph<u32, u32, u32>> {
let root = parent.into_portgraph();
let Self {
graph, hierarchy, ..
} = self;
portgraph::view::FlatRegion::new_without_root(graph, hierarchy, root)
}
}

#[cfg(test)]
mod test {
use crate::{
Expand Down
24 changes: 0 additions & 24 deletions hugr-core/src/hugr/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,19 +486,6 @@ impl<'a, H: HugrView> ValidationContext<'a, H> {
{
if ancestor_parent == from_parent {
// External edge.
if !is_static {
// Must have an order edge.
self.hugr
.node_connections(from, ancestor)
.find(|&[p, _]| from_optype.port_kind(p) == Some(EdgeKind::StateOrder))
.ok_or(InterGraphEdgeError::MissingOrderEdge {
from,
from_offset,
to,
to_offset,
to_ancestor: ancestor,
})?;
}
return Ok(());
} else if Some(ancestor_parent) == from_parent_parent && !is_static {
// Dominator edge
Expand Down Expand Up @@ -807,17 +794,6 @@ pub enum InterGraphEdgeError<N: HugrNode> {
to_offset: Port,
ancestor_parent_op: Box<OpType>,
},
/// The sibling ancestors of the external inter-graph edge endpoints must be have an order edge between them.
#[error(
"Missing state order between the external inter-graph source {from} and the ancestor of the target {to_ancestor}. In an external inter-graph edge from {from} ({from_offset}) to {to} ({to_offset})."
)]
MissingOrderEdge {
from: N,
from_offset: Port,
to: N,
to_offset: Port,
to_ancestor: N,
},
/// The ancestors of an inter-graph edge are not related.
#[error(
"The ancestors of an inter-graph edge are not related. In an inter-graph edge from {from} ({from_offset}) to {to} ({to_offset})."
Expand Down
39 changes: 0 additions & 39 deletions hugr-core/src/hugr/validate/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,45 +192,6 @@ fn df_children_restrictions() {
);
}

#[test]
fn test_ext_edge() {
let mut h = closed_dfg_root_hugr(Signature::new(vec![bool_t(), bool_t()], vec![bool_t()]));
let [input, output] = h.get_io(h.entrypoint()).unwrap();

// Nested DFG bool_t() -> bool_t()
let sub_dfg = h.add_node_with_parent(
h.entrypoint(),
ops::DFG {
signature: Signature::new_endo([bool_t()]),
},
);
// this Xor has its 2nd input unconnected
let sub_op = {
let sub_input = h.add_node_with_parent(sub_dfg, ops::Input::new(vec![bool_t()]));
let sub_output = h.add_node_with_parent(sub_dfg, ops::Output::new(vec![bool_t()]));
let sub_op = h.add_node_with_parent(sub_dfg, and_op());
h.connect(sub_input, 0, sub_op, 0);
h.connect(sub_op, 0, sub_output, 0);
sub_op
};

h.connect(input, 0, sub_dfg, 0);
h.connect(sub_dfg, 0, output, 0);

assert_matches!(h.validate(), Err(ValidationError::UnconnectedPort { .. }));

h.connect(input, 1, sub_op, 1);
assert_matches!(
h.validate(),
Err(ValidationError::InterGraphEdgeError(
InterGraphEdgeError::MissingOrderEdge { .. }
))
);
//Order edge. This will need metadata indicating its purpose.
h.add_other_edge(input, sub_dfg);
h.validate().unwrap();
}

#[test]
fn test_local_const() {
let mut h = closed_dfg_root_hugr(Signature::new_endo([bool_t()]));
Expand Down
Loading
Loading