-
Notifications
You must be signed in to change notification settings - Fork 3
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: Upgrade Hugr and start using the shared Pydantic model #201
Conversation
[v for v in row if not v.ty.linear or is_return_var(v.name)] | ||
[ | ||
v | ||
for v in sort_vars(row) | ||
if not v.ty.linear or is_return_var(v.name) | ||
] |
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 moved the call to sort_vars
from choose_vars_for_tuple_sum()
below to here as a drive-by since this is more consistent with the other sorting logic in this method
if any(value is None for value in vs): | ||
return None | ||
return val.Tuple(vs=vs) | ||
if doesnt_contain_none(vs): | ||
return ops.Value(ops.TupleValue(vs=vs)) |
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.
Mypy started complaining about this, so I added a doesnt_contain_none
type guard
if self.ty.parametrized: | ||
raise InternalGuppyError( | ||
"Can't yet generate higher-order versions of custom functions. This " | ||
"requires generic function *definitions*" | ||
) |
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.
A nice benefit of having the type args available here is that we can properly handle this case now!
@@ -259,6 +261,7 @@ def main() -> None: | |||
validate(module.compile()) | |||
|
|||
|
|||
@pytest.mark.skip("Not yet supported") |
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 worked before, but can no longer compile this since TypeApply
is gone. We can recover this test case by having smarter type arg inference in the future
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.
You mean backwards from the point of applying f
so that we can compile to f = foo[int] if b else bar[int]
, sort of thing? Yes, that's certainly possible, sounds pretty cool, might even be what we'd call "bidirectional type inference"....! :)
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.
Exactly!
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 wonder if there is some syntax we could add in a future PR to let you manually specify those type args and get this example going if type inference doesn't cope and you really, really, want to. But how often does one do this, I don't think it's a priority!
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 wonder if there is some syntax we could add in a future PR to let you manually specify those type args and get this example going if type inference doesn't cope and you really, really, want to. But how often does one do this, I don't think it's a priority!
tests/integration/test_py.py
Outdated
@@ -142,6 +142,7 @@ def foo(q1: qubit, q2: qubit, q3: qubit) -> tuple[qubit, qubit, qubit]: | |||
validate(module.compile()) | |||
|
|||
|
|||
@pytest.mark.skip("Requires Tket2 upgrade") |
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.
Pytket measurements in tket2 now returns a custom Bit
type instead of the prelude bool. This means, we need to load the Tket1 extension for validation, but the extension is still at Hugr v0.3
See #202
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.
Tket2 is on the Hugr 0.4 release candidate now, but it still doesn't work. We need to capture the LBit
type or write a conversion pass that turns TKET1 measurements into TKET2 measurements...
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.
Massive PR but generally looks good, thanks Mark :). A lot of small comments and questions and suggestions for future....
guppylang/tys/const.py
Outdated
@@ -36,7 +37,7 @@ class ConstValue(Const): | |||
|
|||
# Hugr encoding of the value | |||
# TODO: We might need a Guppy representation of this... | |||
value: val.Value | |||
value: ops.Const |
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 ops.Value
? (I admit there are a lot of TODOs around here so it might not really matter!)
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.
Yeah, the Pydantic model in the Hugr repo moved values into the ops
module
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.
Yeah. I was thinking this should be a Value, not the Const op-wrapper around one. Is this the thing that gets encoded as a TypeArg? Or used as a node in the Hugr? (If ops.Const
is correct you might want to update the comment two lines above)
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.
Ohh sorry I misunderstood. Yes, ops.Value
is better here
</FONT> | ||
</TD> | ||
</TR> | ||
<TR><TD><FONT POINT-SIZE="{fontsize}" FACE="{fontface}" |
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'd drop this reindenting-only change, unless there's some reason to keep it
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.
For some reason, the spacing in the visualisation started to look off. Chaning the indentation fixed it
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #201 +/- ##
==========================================
- Coverage 90.98% 90.56% -0.43%
==========================================
Files 47 43 -4
Lines 4971 4622 -349
==========================================
- Hits 4523 4186 -337
+ Misses 448 436 -12 ☔ View full report in Codecov by Sentry. |
guppylang/hugr_builder/hugr.py
Outdated
input_nodes.append(n) | ||
elif isinstance(n.op, ops.Output): | ||
elif isinstance(n.op.root, ops.Output): |
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.
Good fix there ;-). I wonder about match n.op.root
?
Hugr always uses a u64 for the value. The interpretation is: | ||
- as an unsigned integer, (value mod `2^N`); | ||
- as a signed integer, (value mod `2^(N-1) - 2^(N-1)*a`) | ||
where `N = 2^log_width` and `a` is the (N-1)th bit of `x` (counting from 0 = least |
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.
Quite detailed! I was going to suggest that it'd be easier just to say 'a' is the most significant bit
but I realize that there are bits beyond the N. It might still be easier just to start with "take the N least significant bits of the value. If the value is unsigned...."
Or even, "the interpretation is the twos-complement of the N least significant bits".
I mean, this is correct, so ok ;), but also quite hard to follow.
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 copied straight from the Hugr repo:
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.
Already APPROVEd but APPROVE again :-)
TBH the thing here that has the worst "code smell" to my mind is DummyOp. But we know that that's a workaround for a not-yet-existing Hugr feature, so we can expect something a bit, ugh. But certainly, any significant further effort on this PR might be better directed towards that ;-)
This PR makes Guppy depend on the Hugr 0.4 release candidate
0.4.0-alpha.1
. Closes #198Most of the edits are related to changes in the Pydantic model. However, we also had to get rid of
TypeApply
since this no longer exists in Hugr. Therefore, Guppy now rejects all programs that use polymorphic functions as values if the type arguments cannot be inferred