Skip to content
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

Merged
merged 29 commits into from
May 16, 2024

Conversation

mark-koch
Copy link
Collaborator

@mark-koch mark-koch commented May 2, 2024

This PR makes Guppy depend on the Hugr 0.4 release candidate 0.4.0-alpha.1. Closes #198

Most 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

Comment on lines -95 to +98
[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)
]
Copy link
Collaborator Author

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

Comment on lines -326 to +345
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))
Copy link
Collaborator Author

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

Comment on lines -142 to -146
if self.ty.parametrized:
raise InternalGuppyError(
"Can't yet generate higher-order versions of custom functions. This "
"requires generic function *definitions*"
)
Copy link
Collaborator Author

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")
Copy link
Collaborator Author

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

Copy link
Contributor

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"....! :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Exactly!

Copy link
Contributor

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!

Copy link
Contributor

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!

@@ -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")
Copy link
Collaborator Author

@mark-koch mark-koch May 2, 2024

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

Copy link
Collaborator Author

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...

@mark-koch mark-koch marked this pull request as ready for review May 3, 2024 08:21
@mark-koch mark-koch requested a review from acl-cqc May 7, 2024 09:49
Copy link
Contributor

@acl-cqc acl-cqc left a 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/builtin.py Show resolved Hide resolved
@@ -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
Copy link
Contributor

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!)

Copy link
Collaborator Author

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

Copy link
Contributor

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)

Copy link
Collaborator Author

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

guppylang/tys/ty.py Outdated Show resolved Hide resolved
guppylang/tys/ty.py Outdated Show resolved Hide resolved
scripts/generate_schema.py Outdated Show resolved Hide resolved
guppylang/hugr_builder/hugr.py Outdated Show resolved Hide resolved
</FONT>
</TD>
</TR>
<TR><TD><FONT POINT-SIZE="{fontsize}" FACE="{fontface}"
Copy link
Contributor

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

Copy link
Collaborator Author

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

guppylang/prelude/builtins.py Show resolved Hide resolved
guppylang/tys/ty.py Show resolved Hide resolved
tests/error/iter_errors/end_missing.py Show resolved Hide resolved
@codecov-commenter
Copy link

codecov-commenter commented May 9, 2024

Codecov Report

Attention: Patch coverage is 96.78899% with 7 lines in your changes are missing coverage. Please review.

Project coverage is 90.56%. Comparing base (f7adb85) to head (7ff1734).

Files Patch % Lines
guppylang/compiler/expr_compiler.py 88.00% 3 Missing ⚠️
guppylang/definition/custom.py 83.33% 1 Missing ⚠️
guppylang/hugr_builder/hugr.py 98.38% 1 Missing ⚠️
guppylang/hugr_builder/visualise.py 0.00% 1 Missing ⚠️
guppylang/tys/ty.py 95.83% 1 Missing ⚠️
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.
📢 Have feedback on the report? Share it here.

@mark-koch mark-koch requested a review from acl-cqc May 9, 2024 11:24
input_nodes.append(n)
elif isinstance(n.op, ops.Output):
elif isinstance(n.op.root, ops.Output):
Copy link
Contributor

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
Copy link
Contributor

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.

Copy link
Collaborator Author

@mark-koch mark-koch May 16, 2024

Choose a reason for hiding this comment

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

Copy link
Contributor

@acl-cqc acl-cqc left a 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 ;-)

@mark-koch mark-koch merged commit bd7e67a into main May 16, 2024
4 checks passed
@mark-koch mark-koch deleted the chore/hugr-upgrade branch May 16, 2024 08:39
@mark-koch mark-koch mentioned this pull request May 17, 2024
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.

Upgrade to Hugr v0.4
3 participants