-
Notifications
You must be signed in to change notification settings - Fork 29
fix: cast node.size to IntegerLiteral for qubit register size #258
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: cast node.size to IntegerLiteral for qubit register size #258
Conversation
|
@EuGig Thank you for your contribution! Could you please add details to the PR description on what you have tested, as well as a unit test showing that the issue is resolved by your change? |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## feature/integer-literal-cast #258 +/- ##
==============================================================
Coverage 100.00% 100.00%
==============================================================
Files 48 48
Lines 3712 3713 +1
Branches 889 891 +2
==============================================================
+ Hits 3712 3713 +1 ☔ View full report in Codecov by Sentry. |
|
Hi @rmshaffer! Tests added 👍 |
rmshaffer
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.
Thank you for this contribution! I think it would be good to expand the tests a little bit so that the behavior itself is validated, in addition to just seeing that no exception is thrown.
| try: | ||
| Interpreter().build_circuit(source=qasm) | ||
| except AttributeError as exc: | ||
| pytest.fail("Interpreter raised an AttributeError") |
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.
In addition to testing that no exception is thrown (which is good!), could you test that the behavior actually matches what you expect for each of these cases? Especially to see that the qubit register r1 is declared with the size you expect. An example of this is in test_measurement function in this file, where the qubit register is measured into a bit register of the appropriate size, and the measured_qubits property is then asserted to match your expectation.
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 example, the first one could be modified to be like this (since the bitstring "10" = 2 as an int):
bit[2] b;
qubit["10"] r1;
b = measure r1;
And then validate by doing something like:
circuit = Interpreter().build_circuit(qasm)
assert circuit.measured_qubits == expected
where expected is set to [0, 1] for this case.
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 have some other (slightly wacky) programs in a comment here; maybe these could be added as tests? (they just need testing that there's no uncaught exception - as the QASM itself is invalid according to the spec for most of them)
|
@EuGig to ensure that code formatting is correct, please run |
|
This is great, thanks @EuGig! I'm just looking what the spec says about casting here: https://openqasm.com/language/types.html#casting-specifics. I feel like the spec itself could do with some clearing up with regard to what constants are allowed for the 'size' when declaring a register - https://openqasm.com/language/types.html#classical-bits-and-registers does not mention it. Though https://openqasm.com/language/types.html#qubits mentions that indexing by constant values must be supported. I personally feel as though |
ffd586b to
b8abef9
Compare
rmshaffer
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.
Two very minor comments, and then I think this would be ready to merge. Thank you for your patience!
test/unit_tests/braket/default_simulator/openqasm/test_interpreter.py
Outdated
Show resolved
Hide resolved
test/unit_tests/braket/default_simulator/openqasm/test_interpreter.py
Outdated
Show resolved
Hide resolved
1342c83 to
f7def25
Compare
…ibute 'value'. Fixes bug [amazon-braket#240] by casting node.size into IntegerLiteral
rmshaffer
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.
Leaving a few additional comments, which you can address if you have time. Either way, we'll get this merged by the deadline of Wed 6/19 so that the unitaryHACK bounty can be assigned to you. Thank you for your persistence here!
| x.values[len(y.values) :] + [BooleanLiteral(False) for _ in range(len(y.values))] | ||
| if isinstance(y, ArrayLiteral) | ||
| else x.values[y.value :] + [BooleanLiteral(False) for _ in range(y.value)] |
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.
[minor] this inline logic is getting hard to read - could it be factored out into an internal helper function? perhaps casting.py would be a good place.
| [BooleanLiteral(False) for _ in range(len(y.values))] | ||
| + x.values[: len(x.values) - len(y.values)] | ||
| if isinstance(y, ArrayLiteral) | ||
| else [BooleanLiteral(False) for _ in range(y.value)] | ||
| + x.values[: len(x.values) - y.value] |
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.
[minor] this inline logic is getting hard to read - could it be factored out into an internal helper function? perhaps casting.py would be a good place.
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.
ArrayLiteral: {
# returns array
getattr(BinaryOperator, "&"): lambda x, y: ArrayLiteral(
[BooleanLiteral(xv.value and yv.value) for xv, yv in zip(x.values, y.values)]
),
Does this mean that these operators can be applied to array literals too now? It might be better to convert bitstrings to an int type asap where these operations can be handled by python. This would also avoid the possiblity of {0, 3, 6} & 1 (if indeed this does apply to all array literals and not just bitstring), which to me doesn't make much sense.
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.
Also on this theme, it seems as though this is treating bitstring literals in the same way as 0b integer literals ("Integer literals can be written in decimal without a prefix, or as a hex, octal, or binary number, as denoted by a leading 0x/0X, 0o, or 0b/0B prefix. "). I feel as though the 'spirit' of the spec is that the bit string is syntactic sugar for an array containing only 0s and 1s, rather than a number; but the writing does not specify this.
| """ | ||
| bit[1] b; | ||
| qubit[1] r1; | ||
| h r1["0" << "1"]; | ||
| b = measure r1; | ||
| """, |
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.
[minor] these tests which run gates don't validate that they are run correctly, and they also only test h r1[0] and not any other qubit indices. Could they be expanded a bit - for example, to test running gates on additional qubits beyond 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.
I believe this would be (a bit) better as 0 << X is always 0; using 1 << 1 gives 2:
"""
bit[3] b;
qubit[3] r1;
h r1["1" << "1"];
b = measure r1;
""",
I don't have a quantum background, but by me eye this should result in the probability state of r1[2] = 0.5 and the other qubits are default.
|
Thank you @rmshaffer! I'll continue working on the PR. |
Thank you @EuGig for your work on this so far! Because the unitaryHACK period is ending, I'm going to merge the PR in its current state into the branch I have opened PR #263 to merge that If you are able to continue to make some of the suggested changes, please open another PR from your fork which targets the |
Issue: #240
Description of changes:
Fixes bug [#240] by casting node.size into IntegerLiteral.
Building a circuit from a quasi string raises an
AttributeErrorexception in case the qubit register is specified as a string literal.Testing done:
A unit-test is added that checks that the
AttributeErroris not raised anymore.Merge Checklist
Put an
xin the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your pull request.General
Tests
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.