-
Notifications
You must be signed in to change notification settings - Fork 13
feat: ReplaceTypes: recurse on replacements, much deprecation #2442
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
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #2442 +/- ##
==========================================
+ Coverage 83.41% 83.46% +0.04%
==========================================
Files 262 264 +2
Lines 51176 51684 +508
Branches 46737 47149 +412
==========================================
+ Hits 42689 43137 +448
- Misses 6109 6171 +62
+ Partials 2378 2376 -2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
58a05b1 to
1c9857f
Compare
| for region_root in regions { | ||
| for n in hugr.descendants(*region_root).collect::<Vec<_>>() { | ||
| changed |= self.change_node(hugr, n)?; | ||
| if n != hugr.entrypoint() && changed { |
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.
Note this is clearly wrong - it means linearization applies to the first node that changes and all nodes coming after that (!)
|
|
||
| impl ReplacementOptions { | ||
| /// Specifies that all operations within the replacement should have their | ||
| fn recursive() -> Self { |
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 didn't feel any need to make this public because I'm hoping to drop the whole struct...
| /// May be specified by | ||
| /// [ReplaceTypes::replace_op_with], [ReplaceTypes::replace_parametrized_op_with], | ||
| /// [ReplaceTypes::replace_type_opts] or [ReplaceTypes::replace_parametrized_type_opts]. | ||
| /// Otherwise (the default), replacements are inserted as given (without further processing). |
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.
Of course this is only relevant to the deprecated methods...so I could deprecate this struct. That's pretty messy though as there are a lot of uses ATM (supporting the interface where clients can specify one)...it'll easier to clean up the ReplaceTypes struct and remove all the references to this when the deprecated methods are removed, and THEN we can deprecate this struct (which will be unused)
mark-koch
left a comment
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.
Nice! Very happy with allowing copy_discard_op now 👍
| let [TypeArg::Runtime(ty)] = args else { | ||
| panic!("Expected just one type") | ||
| }; | ||
| Ok(Some(rt.get_linearizer().copy_discard_op(ty, 0)?)) |
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.
Nice!
hugr-passes/src/replace_types.rs
Outdated
| } else if !linearize_unchanged_ops { | ||
| continue; | ||
| } | ||
| if n != root { |
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.
Can you also assume here that root is the first descendant and just skip it via assert_eq!(descs.next(), Some(root)); (similar to change_node below)?
| self.linearize_outputs(hugr, n)?; | ||
| } | ||
| } | ||
| changed |= self.change_subtree(hugr, *region_root, false)?; |
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.
Why is linearize_unchanged_ops always false here?
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.
It's not...rather, I'm assuming we should not add anything outside the root. (If the root has value outports that we've changed, then we've broken anyway...unless they were unconnected, yes, in which case we might want a discard. I think that's still "outside the region", though. A sensible choice of region would be, say, a FuncDefn.)
I'll comment to that effect.
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.
Oh, sorry, I completely misunderstand....you mean the last parameter!
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.
Answer: because there are no ReplacementOptions in scope here; we only have ReplacementOptions for the RHS of a replacement. (We could add set_replacement_options on the whole pass, or have a run_with_options, or something, but I'm not adding that at this point.)
|
Test coverage looks poor because we no longer cover the deprecated methods, tests have been updated to use the new ones. |
closes #2668 (by a combination of the two routes, minus the extension).
There are two(/3) goals here:
copy_discard_op(ty, 0), as demonstrated in the test.Note that the first is a breaking behaviour change (potentially very breaking, i.e. infinite loop), so to keep this PR non-breaking, I add new methods
set_replace(_parametrized,)_(op,type)that process the RHS recursively. To satisfy the second goal, the op-replacing callback is passed the ReplaceTypes (hence rolling two breaking signature changes into one PR).. The naming of the new methods is a little odd, largely because the first choicereplace_blahis already taken, and we keep those methods (with non-recursive behaviour) but deprecated.(If later we really want to keep non-recursive replacement, we can add that later, but there are enough methods right now!)
Note for consts, there's no real equivalent to "recursive" replacement, because there is no way for the ReplaceTypes to look inside CustomConsts like lists, they are opaque. Instead, recursion must be done manually on the elements, as per e.g.
array_const:hugr/hugr-passes/src/replace_types/handlers.rs
Line 75 in fcd1026