-
Notifications
You must be signed in to change notification settings - Fork 6
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
fix: Add some validation for const nodes #1222
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1222 +/- ##
==========================================
- Coverage 87.03% 86.99% -0.05%
==========================================
Files 100 100
Lines 18918 18975 +57
Branches 16935 16992 +57
==========================================
+ Hits 16466 16508 +42
- Misses 1676 1689 +13
- Partials 776 778 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
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 test for floats is too specific, I think that generalising the code will mean that the fix for bad CustomConst will need to come from tweaking error handling around CustomSerialised
.
@@ -210,6 +212,35 @@ impl<'a, 'b> ValidationContext<'a, 'b> { | |||
// Thirdly that the node has correct children | |||
self.validate_children(node, op_type)?; | |||
|
|||
// OpType-specific checks. | |||
// TODO Maybe we should delegate these checks to the OpTypes themselves. |
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.
Maybe, but I can see why you don't. ValidateOp
is not set up for op-specific logic. I think it's fine here for now, but I do think you should extract it into a function. i.e.
if let OpType::Const(c) = op_type {
match c.validate()
}
hugr-core/src/hugr/validate.rs
Outdated
match c.get_type().as_type_enum() { | ||
TypeEnum::Sum(SumType::Unit { size: _ }) => { | ||
if let Value::Sum { | ||
tag: _, | ||
values, | ||
sum_type: _, | ||
} = c.value() | ||
{ | ||
if !values.is_empty() { | ||
return Err(ValidationError::UnitSumWithValues {}); | ||
} | ||
} | ||
} | ||
TypeEnum::Extension(custom_type) => { | ||
if custom_type.name() == "float64" { | ||
if let Value::Extension { e } = c.value() { | ||
if e.value().type_id() != TypeId::of::<ConstF64>() { | ||
return Err(ValidationError::WrongExtensionValueType {}); | ||
} | ||
} | ||
} | ||
} | ||
_ => {} | ||
} |
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 this is too specific to the bugs. We need to check all sum values have the right type, and we need logic that will work for all CustomConst
s.
A start is: (the body of Value::validate
):
match c.get_type().as_type_enum() { | |
TypeEnum::Sum(SumType::Unit { size: _ }) => { | |
if let Value::Sum { | |
tag: _, | |
values, | |
sum_type: _, | |
} = c.value() | |
{ | |
if !values.is_empty() { | |
return Err(ValidationError::UnitSumWithValues {}); | |
} | |
} | |
} | |
TypeEnum::Extension(custom_type) => { | |
if custom_type.name() == "float64" { | |
if let Value::Extension { e } = c.value() { | |
if e.value().type_id() != TypeId::of::<ConstF64>() { | |
return Err(ValidationError::WrongExtensionValueType {}); | |
} | |
} | |
} | |
} | |
_ => {} | |
} | |
match self { | |
Self::Extension { e } => e.value().validate(), | |
Self::Sum { tag, typ, values } => typ.check_type(values), | |
Self::Function { .. } => Ok(()) // we don't check inside Function Vlaues | |
} |
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.
Thanks! So, just to clarify, is your suggestion to:
- create a new
validate()
method forValue
s, and call that (when appropriate) fromvalidate_node()
; - in
Value::validate()
, for the case ofExtension
values, delegate toCustomConst::validate()
; - add overloads for
CustomConst::validate()
for specific types such asConstF64
?
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. ConstF64
does need a validate, which it doesn't have, but that is a different issue: It can't check serialisation, because ConstF64
only holds a f64
, but it should check that it's not NAN
or infinite.
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 indeed, and adding a validate()
to ConstF64
wouldn't catch the issue here, which is that we haven't got a ConstF64
at all...
)) | ||
.unwrap(); | ||
assert!( | ||
hugr.update_validate(&PRELUDE_REGISTRY).is_err(), |
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.
Needs to include float extensions here and below I think?. Maybe it's fine because CustomConst
don't work through extensions.
@@ -214,6 +215,12 @@ impl<'a, 'b> ValidationContext<'a, 'b> { | |||
// Thirdly that the node has correct children | |||
self.validate_children(node, op_type)?; | |||
|
|||
// OpType-specific checks. | |||
// TODO Maybe we should delegate these checks to the OpTypes themselves. |
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.
Perhaps this TODO can be removed now?
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 it should remain, it does feel like this should call into a trait.
@@ -759,6 +766,9 @@ pub enum ValidationError { | |||
/// [Opaque]: crate::ops::CustomOp::Opaque | |||
#[error(transparent)] | |||
CustomOpError(#[from] CustomOpError), | |||
/// TODO |
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.
Add docstring?
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.
Awkward, will post a PR to fixup this
I got that far, just couldn't see where the check was, but I see it now, thanks! |
## 🤖 New release * `hugr`: 0.5.1 -> 0.6.0 * `hugr-core`: 0.2.0 -> 0.3.0 * `hugr-passes`: 0.2.0 -> 0.3.0 * `hugr-cli`: 0.1.1 -> 0.1.2 <details><summary><i><b>Changelog</b></i></summary><p> ## `hugr` <blockquote> ## 0.6.0 (2024-06-28) ### Bug Fixes - SimpleReplacement panic on multiports ([#1191](#1191)) - Add some validation for const nodes ([#1222](#1222)) - Cfg not validating entry/exit types ([#1229](#1229)) - `extract_hugr` not removing root node ports ([#1239](#1239)) ### Documentation - Fix documentation of `ValidationError::ConstTypeError` ([#1227](#1227)) ### Features - CircuitBuilder::add_constant ([#1168](#1168)) - [**breaking**] Make the rewrite errors more useful ([#1174](#1174)) - [**breaking**] Validate Extensions using hierarchy, ignore input_extensions, RIP inference ([#1142](#1142)) - [**breaking**] Infer extension deltas for Case, Cfg, Conditional, DataflowBlock, Dfg, TailLoop ([#1195](#1195)) - Helper functions for requesting inference, use with builder in tests ([#1219](#1219)) ### Refactor - [**breaking**] FunctionBuilder takes impl Into<PolyFuncType> ([#1220](#1220)) - [**breaking**] Remove NodeType and input_extensions ([#1183](#1183)) </blockquote> ## `hugr-core` <blockquote> ## 0.3.0 (2024-06-28) ### Bug Fixes - SimpleReplacement panic on multiports ([#1191](#1191)) - Add some validation for const nodes ([#1222](#1222)) - Cfg not validating entry/exit types ([#1229](#1229)) - `extract_hugr` not removing root node ports ([#1239](#1239)) ### Documentation - Fix documentation of `ValidationError::ConstTypeError` ([#1227](#1227)) ### Features - CircuitBuilder::add_constant ([#1168](#1168)) - [**breaking**] Make the rewrite errors more useful ([#1174](#1174)) - [**breaking**] Validate Extensions using hierarchy, ignore input_extensions, RIP inference ([#1142](#1142)) - [**breaking**] Infer extension deltas for Case, Cfg, Conditional, DataflowBlock, Dfg, TailLoop ([#1195](#1195)) - Helper functions for requesting inference, use with builder in tests ([#1219](#1219)) ### Refactor - [**breaking**] Remove NodeType and input_extensions ([#1183](#1183)) - [**breaking**] FunctionBuilder takes impl Into<PolyFuncType> ([#1220](#1220)) </blockquote> ## `hugr-passes` <blockquote> ## 0.3.0 (2024-06-28) ### Features - [**breaking**] Validate Extensions using hierarchy, ignore input_extensions, RIP inference ([#1142](#1142)) - Helper functions for requesting inference, use with builder in tests ([#1219](#1219)) </blockquote> ## `hugr-cli` <blockquote> ## 0.1.1 (2024-06-07) ### Features - Reexport `clap::Parser` and `clap_verbosity_flag::Level` from hugr_cli ([#1146](#1146)) ### Refactor - Move binary to hugr-cli ([#1134](#1134)) </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/MarcoIeni/release-plz/). --------- Co-authored-by: Douglas Wilson <douglas.wilson@quantinuum.com>
🤖 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 <agustin.borgna+hugrbot@quantinuum.com> Co-authored-by: Seyon Sivarajah <seyon.sivarajah@quantinuum.com>
Fixes #1185. We add a test for #1091, but the fix unclear now, see #1225.