-
Notifications
You must be signed in to change notification settings - Fork 7
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
feat!: Allow "Row Variables" declared as List<Type> #804
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #804 +/- ##
==========================================
+ Coverage 86.59% 86.72% +0.12%
==========================================
Files 83 88 +5
Lines 17582 18467 +885
Branches 17582 18074 +492
==========================================
+ Hits 15226 16015 +789
- Misses 1536 1612 +76
- Partials 820 840 +20
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Thinking about this, it might not be too bad (i.e. to make |
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 agree that the "proper way" is worth a quick try (time bounded!). The macro does help us but the annoying part will likely be that most uses of rows treat it like a slice of types (iterating, getting etc.). I'm imagining moving the current TypeRow
impls to a new ConcreteTypeRow
struct and then adding a panicking as_concrete()
to a TypeRow enum. Maybe there is something less onerous?
@acl-cqc What is the status of this? Did you get to try the |
Yes, or at least, partly, in branch |
I admit that I am not convinced of the value of this feature. Taking the value on faith, may I suggest a generalisation: EDIT: on further investigation the current implementaton already works as I describe! |
The value of the feature is to allow us to make operations like UnpackTuple, MakeTuple, etc., as library operations in the prelude, rather than the current LeafOp enum of ops which (without this PR) cannot be expressed in the extension system... |
I disagree. There is only aesthetic value in making these ops library operations. I instead understand the value to be to allow operations with variadic inputs/outputs to be defined. The cost of not allowing these to be defined is that one is forced, by their absence, to instead work with tuples. The requisite UnpackTuple operations introduce barriers to parallelism. |
hugr/src/types.rs
Outdated
/// New use (occurrence) of the row variable with specified index. | ||
/// `bound` must match that with which the variable was declared | ||
/// (i.e. as a [TypeParam::List]` of a `[TypeParam::Type]` of that bound). | ||
/// For use in [OpDef], not [FuncDefn], type schemes only. |
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.
This is the critical distinction, which is neither explained nor probably made, as clear(ly) as it needs to be. (So far, in this PR!)
88cd17e
to
b918bee
Compare
|
Oh, and fixed a failing proptest using a new |
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.
LGTM. I am unsure about debug_assert
/assert
. debug_assert
doesn't impose a performance cost.
pub fn any_non_row_var() -> BoxedStrategy<Self> { | ||
any::<Self>() | ||
.prop_filter("Cannot be a Row Variable", |t| !t.is_row_var()) | ||
.boxed() |
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.
This is fine, but for your notes: this is not the best way to do this. Filtering is to be avoided, because if too many values are filtered out tests will fail. One should instead generate the values that you want. Use filtering only when this is impractical.
To "generate values that you want", change the Arbitrary
impl for Type
. Change Parameters
to struct ArbitraryTypeParamerters(RecursionDepth,bool)
and in arbitrary_with
only include the RowVariable
strategy when this is new bool is true
. You will likely need to use Union
to achieve this, I think there is an example in the codebase.
hugr/src/types/signature.rs
Outdated
let idx = port.index(); | ||
if idx > 0 { | ||
// Check we have not skipped over / indexed past any row variables | ||
assert!(!row.iter().take(idx - 1).any(Type::is_row_var)); |
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 worry this is too expensive for an assert
. I would prefer to disallow any row variables, even after the index i.e. removing the take
.
check_type_arg(&row_arg, &row_param).unwrap(); | ||
|
||
// Now say a row variable referring to *that* row was used | ||
// to instantiate an outer "row parameter" (list of type). |
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.
Yes I think so, but not necessary in this PR. create an issue.
I edited the title to mark a breaking change. Can your review the commit message, in particular remove references to commits that will be squashed. |
…xtension_with_eval_parallel
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.
Great! just one nit.
@@ -193,6 +193,17 @@ impl FunctionType { | |||
} | |||
|
|||
impl FunctionType { | |||
/// If this FunctionType contains any row variables, return one. | |||
pub fn find_rowvar(&self) -> Option<(usize, TypeBound)> { |
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.
not sure this should be pub?
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 was going to have has_rowvars(&self) -> bool
and thought that definitely should be pub
. Then I realized that when it returned true
I'd have to scan through to find one to raise the error I wanted, so why not do that in the same go. I think having some kind of are-there-any-rowvars is a good method to have, I agree this is a slightly non-obvious form for it but it's no worse than the bool
one no?
Could return a list of vars, or Vec<(Direction, usize, (usize, TypeBound)>
(i.e. where each one was found) or something like that I guess?
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 the return type it's that I don't think this will have any users, so preferring not to pollute the namespace + docs. If you disagree, no problem.
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 think we should have a query method, yes. When we split FunTypeVarArgs and SignatureType it belongs only on the former (as necessarily false/None for Signature).
## 🤖 New release * `hugr`: 0.4.0 -> 0.5.0 * `hugr-cli`: 0.1.0 * `hugr-core`: 0.1.0 * `hugr-passes`: 0.1.0 <details><summary><i><b>Changelog</b></i></summary><p> ## `hugr` <blockquote> ## 0.5.0 (2024-05-29) ### Bug Fixes - Missing re-exports in `hugr::hugr` ([#1127](#1127)) - Set initial version of hugr-core to 0.1.0 ([#1129](#1129)) ### Features - [**breaking**] Remove `PartialEq` impl for `ConstF64` ([#1079](#1079)) - [**breaking**] Allow "Row Variables" declared as List<Type> ([#804](#804)) - Hugr binary cli tool ([#1096](#1096)) - [**breaking**] Move passes from `algorithms` into a separate crate ([#1100](#1100)) - [**breaking**] Disallow nonlocal value edges into FuncDefn's ([#1061](#1061)) - [**breaking**] Move cli in to hugr-cli sub-crate ([#1107](#1107)) - Add verbosity, return `Hugr` from `run`. ([#1116](#1116)) - Unseal and make public the traits `HugrInternals` and `HugrMutInternals` ([#1122](#1122)) ### Refactor - [**breaking**] No Ports in TypeRow ([#1087](#1087)) - Add a `hugr-core` crate ([#1108](#1108)) </blockquote> ## `hugr-core` <blockquote> ## 0.1.0 (2024-05-29) ### Bug Fixes - Set initial version of hugr-core to 0.1.0 ([#1129](#1129)) ### Features - [**breaking**] Move cli in to hugr-cli sub-crate ([#1107](#1107)) - Make internals of int ops and the "int" CustomType more public. ([#1114](#1114)) - Unseal and make public the traits `HugrInternals` and `HugrMutInternals` ([#1122](#1122)) ### Refactor - Add a `hugr-core` crate ([#1108](#1108)) </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/MarcoIeni/release-plz/). --------- Co-authored-by: Agustin Borgna <[email protected]>
🤖 I have created a release *beep* *boop* --- ## [0.3.0](hugr-py-v0.2.1...hugr-py-v0.3.0) (2024-07-03) ### ⚠ BREAKING CHANGES * * `add_child_op`(`_with_parent`), etc., gone; use `add_child_node`(`_with_parent`) with an (impl Into-)OpType. * `get_nodetype` gone - use `get_optype`. * `NodeType` gone - use `OpType` directly. * Various (Into<)Option<ExtensionSet> params removed from builder methods especially {cfg_,dfg_}builder. * `input_extensions` removed from serialization schema. * the Signature class is gone, but it's not clear how or why you might have been using it... * TailLoop node and associated builder functions now require specifying an ExtensionSet; extension/validate.rs deleted; some changes to Hugrs validated/rejected when the `extension_inference` feature flag is turned on * Type::validate takes extra bool (allow_rowvars); renamed {FunctionType, PolyFuncType}::(validate=>validate_var_len). ### Features * Allow "Row Variables" declared as List<Type> ([#804](#804)) ([3ea4834](3ea4834)) * **hugr-py:** add builders for Conditional and TailLoop ([#1210](#1210)) ([43569a4](43569a4)) * **hugr-py:** add CallIndirect, LoadFunction, Lift, Alias ([#1218](#1218)) ([db09193](db09193)), closes [#1213](#1213) * **hugr-py:** add values and constants ([#1203](#1203)) ([f7ea178](f7ea178)), closes [#1202](#1202) * **hugr-py:** automatically add state order edges for inter-graph edges ([#1165](#1165)) ([5da06e1](5da06e1)) * **hugr-py:** builder for function definition/declaration and call ([#1212](#1212)) ([af062ea](af062ea)) * **hugr-py:** builder ops separate from serialised ops ([#1140](#1140)) ([342eda3](342eda3)) * **hugr-py:** CFG builder ([#1192](#1192)) ([c5ea47f](c5ea47f)), closes [#1188](#1188) * **hugr-py:** define type hierarchy separate from serialized ([#1176](#1176)) ([10f4c42](10f4c42)) * **hugr-py:** only require input type annotations when building ([#1199](#1199)) ([2bb079f](2bb079f)) * **hugr-py:** python hugr builder ([#1098](#1098)) ([23408b5](23408b5)) * **hugr-py:** store children in node weight ([#1160](#1160)) ([1cdaeed](1cdaeed)), closes [#1159](#1159) * **hugr-py:** ToNode interface to treat builders as nodes ([#1193](#1193)) ([1da33e6](1da33e6)) * Validate Extensions using hierarchy, ignore input_extensions, RIP inference ([#1142](#1142)) ([8bec8e9](8bec8e9)) ### Bug Fixes * Add some validation for const nodes ([#1222](#1222)) ([c05edd3](c05edd3)) * **hugr-py:** more ruff lints + fix some typos ([#1246](#1246)) ([f158384](f158384)) * **py:** get rid of pydantic config deprecation warnings ([#1084](#1084)) ([52fcb9d](52fcb9d)) ### Documentation * **hugr-py:** add docs link to README ([#1259](#1259)) ([d2a9148](d2a9148)) * **hugr-py:** build and publish docs ([#1253](#1253)) ([902fc14](902fc14)) * **hugr-py:** docstrings for builder ([#1231](#1231)) ([3e4ac18](3e4ac18)) ### Code Refactoring * Remove "Signature" from hugr-py ([#1186](#1186)) ([65718f7](65718f7)) * Remove NodeType and input_extensions ([#1183](#1183)) ([ea5213d](ea5213d)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). --------- Co-authored-by: hugrbot <[email protected]> Co-authored-by: Seyon Sivarajah <[email protected]>
closes #787
BREAKING CHANGE: Type::validate takes extra bool (allow_rowvars); renamed {FunctionType, PolyFuncType}::(validate=>validate_var_len).