Skip to content

Conversation

@aborgna-q
Copy link
Collaborator

@aborgna-q aborgna-q commented Apr 28, 2025

Moves some methods around in HugrInternals / HugrView that we'll require for #1926 and #2029. Notable changes:

  • Adds a hierarchy method to HugrInternals that replaces most calls to base_hugr.
  • HugrInternals::base_hugr is now deprecated. It's only used by Sibling/DescendantGraph, validate and a random use in DeadCodeElimPass.
  • Adds a HugrInternals::region_portgraph method that returns a FlatRegion portgraph wrapper, and a HugrView::descendants call. These lets us replace most uses of SiblingGraph and DescendantGraph.
  • Renamed HugrInternals::{get_pg_index,get_node} to to_portgraph_node and from_portgraph_node.

This requires some new changes in portgraph. I'll make a minor release and update it here before merging.

We should be able to remove base_hugr after #2029. The deprecation warning here is only temporary.

BREAKING CHANGE: Modified multiple core HugrView and HugrInternals trait methods. See #2126.

@aborgna-q aborgna-q requested a review from lmondada April 28, 2025 15:06
@aborgna-q aborgna-q requested a review from a team as a code owner April 28, 2025 15:06
@aborgna-q aborgna-q requested a review from ss2165 April 28, 2025 15:06
@codecov
Copy link

codecov bot commented Apr 28, 2025

Codecov Report

Attention: Patch coverage is 85.26863% with 85 lines in your changes missing coverage. Please review.

Project coverage is 83.37%. Comparing base (c15d8ac) to head (4624909).
Report is 1 commits behind head on release-rs-v0.16.0.

Files with missing lines Patch % Lines
hugr-core/src/hugr/views/sibling.rs 71.73% 25 Missing and 1 partial ⚠️
hugr-core/src/hugr/views/descendants.rs 67.27% 16 Missing and 2 partials ⚠️
hugr-core/src/hugr/views/impls.rs 55.00% 9 Missing ⚠️
hugr-llvm/src/emit/ops.rs 61.90% 1 Missing and 7 partials ⚠️
hugr-core/src/hugr/views.rs 94.35% 7 Missing ⚠️
hugr-core/src/hugr/hugrmut.rs 93.93% 2 Missing and 4 partials ⚠️
hugr-core/src/hugr/patch/replace.rs 70.00% 2 Missing and 1 partial ⚠️
hugr-core/src/hugr/patch.rs 0.00% 2 Missing ⚠️
hugr-passes/src/force_order.rs 92.30% 2 Missing ⚠️
hugr-core/src/export.rs 83.33% 1 Missing ⚠️
... and 3 more
Additional details and impacted files
@@                  Coverage Diff                   @@
##           release-rs-v0.16.0    #2126      +/-   ##
======================================================
- Coverage               83.43%   83.37%   -0.07%     
======================================================
  Files                     219      219              
  Lines                   42200    42281      +81     
  Branches                38302    38383      +81     
======================================================
+ Hits                    35211    35252      +41     
- Misses                   5173     5209      +36     
- Partials                 1816     1820       +4     
Flag Coverage Δ
python 85.73% <ø> (ø)
rust 83.13% <85.26%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@hugrbot
Copy link
Collaborator

hugrbot commented Apr 28, 2025

This PR contains breaking changes to the public Rust API.

cargo-semver-checks summary

--- failure trait_method_added: pub trait method added ---

Description:
A non-sealed public trait added a new method without a default implementation, which breaks downstream implementations of the trait
      ref: https://doc.rust-lang.org/cargo/reference/semver.html#trait-new-item-no-default
     impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.41.0/src/lints/trait_method_added.ron

Failed in:
trait method hugr_core::hugr::internal::HugrInternals::region_portgraph in file /home/runner/work/hugr/hugr/PR_BRANCH/hugr-core/src/hugr/internal.rs:36
trait method hugr_core::hugr::internal::HugrInternals::to_portgraph_node in file /home/runner/work/hugr/hugr/PR_BRANCH/hugr-core/src/hugr/internal.rs:46
trait method hugr_core::hugr::internal::HugrInternals::from_portgraph_node in file /home/runner/work/hugr/hugr/PR_BRANCH/hugr-core/src/hugr/internal.rs:50

--- failure trait_method_default_impl_removed: pub trait default method impl removed ---

Description:
A method's default impl in an unsealed trait has been removed, breaking trait implementations that relied on that default
      ref: https://doc.rust-lang.org/book/ch10-02-traits.html#default-implementations
     impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.41.0/src/lints/trait_method_default_impl_removed.ron

Failed in:
trait method hugr_core::hugr::internal::HugrInternals::hierarchy in file /home/runner/work/hugr/hugr/PR_BRANCH/hugr-core/src/hugr/internal.rs:43

--- failure trait_method_missing: pub trait method removed or renamed ---

Description:
A trait method is no longer callable, and may have been renamed or removed entirely.
      ref: https://doc.rust-lang.org/cargo/reference/semver.html#major-any-change-to-trait-item-signatures
     impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.41.0/src/lints/trait_method_missing.ron

Failed in:
method root_type of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:50
method valid_node of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:62
method valid_non_root of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:70
method get_node_metadata of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:105
method node_count of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:116
method edge_count of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:119
method root_type of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:50
method valid_node of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:62
method valid_non_root of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:70
method get_node_metadata of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:105
method node_count of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:116
method edge_count of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:119
method root_type of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:50
method valid_node of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:62
method valid_non_root of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:70
method get_node_metadata of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:105
method node_count of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:116
method edge_count of trait HugrView, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/views.rs:119
method root_node of trait HugrInternals, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/internal.rs:44
method get_pg_index of trait HugrInternals, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/internal.rs:47
method get_node of trait HugrInternals, previously in file /home/runner/work/hugr/hugr/BASELINE_BRANCH/hugr-core/src/hugr/internal.rs:50

@aborgna-q
Copy link
Collaborator Author

Uh, the new Eq bound in

pub trait HugrInternals {
    /// The underlying portgraph view type.
    type Portgraph<'p>: LinkView<LinkEndpoint: Eq> + Clone + 'p
    where
        Self: 'p;

is an associated type bound, which was stabilized in rust 1.79...

The options here are to do CQCL/portgraph#204 and make a breaking release there, or to bump our MSRV...

Copy link
Contributor

@lmondada lmondada left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice cleanup indeed!

I have one concern, which regards the portgraph, region_portgraph and hierarchy methods. See comments below.

You might have thought about it already -- if not, happy to have a discussion and have a look at it myself.

Comment on lines 247 to 249
self.mu_out
.iter()
.try_for_each(|e| match self.replacement.valid_non_root(e.src) {
self.mu_out.iter().try_for_each(|e| {
match check_valid_non_root(&self.replacement, e.src) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heads up that these changes will probably conflict with #2070, which is about to be merged in. It should be easy to resolve though.

Comment on lines 32 to 43

/// Returns the portgraph [Hierarchy](portgraph::Hierarchy) of the graph
/// returned by [`HugrInternals::portgraph`].
#[inline]
fn hierarchy(&self) -> Cow<'_, portgraph::Hierarchy> {
Cow::Borrowed(&self.base_hugr().hierarchy)
/// Returns a flat portgraph view of a region in the HUGR.
///
/// This is a subgraph of [`HugrInternals::portgraph`], with a flat hierarchy.
fn region_portgraph(
&self,
parent: Self::Node,
) -> portgraph::view::FlatRegion<'_, Self::Portgraph<'_>> {
let pg = self.portgraph();
let root = self.to_portgraph_node(parent);
portgraph::view::FlatRegion::new_without_root(pg, self.hierarchy(), root)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The following comment is annoying, but unfortunately important for my usecase:

We are deprecating base_hugr---this is excellent for PersistentHugr, as I no longer need to create new Hugrs in memory.

However, if we still expose portgraph() and region_portgraph(), we won't get around the need for a new wrapper struct (call it PGView) to provide an implementation of LinkView for PersistentHugr. This is a problem as LinkEndpoint must implement Into<PortIndex>. In this case, it would require a conversion (HugrID, NodeID) -> u32, which leaves us with 16 bits each for HugrID and NodeID... I'm worried this isn't enough.

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same comment applies to hierarchy()... The problem with these methods is that they are "global", whereas the only accessor methods that are easy to implement on a PersistentHugr must be local to the neighbourhood of a node.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After removing some default impls, we now only use hierarchy() for

#1 is an issue I'll tackle in a different PR (it's also one of the last callers of base_hugr, so it needs some fixing), and the other one shouldn't be an issue.

Should I maybe just remove the method? (probs do the same as with base_hugr and deprecate it for now)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for the node index problem, it is annoying but the only solution I see is to make indices generic in portgraph (as is the case already in petgraph). That should be doable, but I'm not sure if it'll fit in this release :/

let region = self.hugr.region_portgraph(parent);
let entry_node = self.hugr.children(parent).next().unwrap();
dominators::simple_fast(&region.as_petgraph(), entry_node)
dominators::simple_fast(&region, entry_node.pg_index())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: rename pg_index -> to_portgraph_node for consistency?

@aborgna-q aborgna-q added this pull request to the merge queue Apr 29, 2025
Merged via the queue into release-rs-v0.16.0 with commit f0738b1 Apr 29, 2025
30 of 33 checks passed
@aborgna-q aborgna-q deleted the ab/deprecate-base-hugr branch April 29, 2025 14:37
aborgna-q added a commit that referenced this pull request May 7, 2025
Moves some methods around in `HugrInternals` / `HugrView` that we'll
require for #1926 and #2029. Notable changes:

- Adds a `hierarchy` method to `HugrInternals` that replaces most calls
to `base_hugr`.
- `HugrInternals::base_hugr` is now deprecated. It's only used by
`Sibling/DescendantGraph`, `validate` and a random use in
`DeadCodeElimPass`.
- Adds a `HugrInternals::region_portgraph` method that returns a
`FlatRegion` portgraph wrapper, and a `HugrView::descendants` call.
These lets us replace most uses of `SiblingGraph` and `DescendantGraph`.
- Renamed `HugrInternals::{get_pg_index,get_node}` to
`to_portgraph_node` and `from_portgraph_node`.

This requires some new changes in `portgraph`. I'll make a minor release
and update it here before merging.

We should be able to remove `base_hugr` after #2029. The deprecation
warning here is only temporary.

BREAKING CHANGE: Modified multiple core `HugrView` and `HugrInternals`
trait methods. See #2126.
This was referenced May 7, 2025
@hugrbot hugrbot mentioned this pull request May 14, 2025
This was referenced May 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(core): deprecate HugrView::node_count and replace with num_nodes

4 participants