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

Add builder interface for new switch statement #9919

Merged
merged 4 commits into from
Apr 17, 2023

Conversation

jakelishman
Copy link
Member

Summary

With the addition of switch, we now have a second control-flow construct that

  • is not a loop, so can have lazily constructed blocks because of contained break and continue statements
  • can have multiple blocks that need their resources unifying

For the first part, we largely just have to handle things separately to if, though the placeholder instructions are much simpler because the placeholder will never need mutating and replacing (c.f. the else block). For the second point, we move a bunch of the previously if-specific code into a shared location in order to reuse it.

Unlike the if case, the switch builder uses nested context managers for its cases, because this mirrors a common indentation pattern for switch statements (at least if you're not a Linux kernel developer).

We need new special logic to reject statements that are loose in the switch context but not a case context. We could have just ignored that, but it feels like an easy potential mistake to make, so much better to loudly fail than silently do the wrong thing.

Details and comments

As with most of the builder interface PRs, most of the diff is in new tests.

@jakelishman jakelishman requested a review from a team as a code owner April 6, 2023 02:07
@qiskit-bot
Copy link
Collaborator

Thank you for opening a new pull request.

Before your PR can be merged it will first need to pass continuous integration tests and be reviewed. Sometimes the review process can be slow, so please be patient.

While you're waiting, please feel free to review other open PRs. While only a subset of people are authorized to approve pull requests for merging, everyone is encouraged to review open pull requests. Doing reviews helps reduce the burden on the core team and helps make the project's code better for everyone.

One or more of the the following people are requested to review this:

  • @Qiskit/terra-core

@jakelishman jakelishman added this to the 0.24.0 milestone Apr 6, 2023
@coveralls
Copy link

coveralls commented Apr 6, 2023

Pull Request Test Coverage Report for Build 4704993141

  • 180 of 186 (96.77%) changed or added relevant lines in 5 files are covered.
  • 26 unchanged lines in 4 files lost coverage.
  • Overall coverage increased (+0.01%) to 85.796%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/circuit/controlflow/builder.py 6 7 85.71%
qiskit/circuit/controlflow/switch_case.py 94 95 98.95%
qiskit/circuit/controlflow/_builder_utils.py 57 59 96.61%
qiskit/circuit/quantumcircuit.py 12 14 85.71%
Files with Coverage Reduction New Missed Lines %
qiskit/circuit/tools/pi_check.py 1 91.23%
qiskit/pulse/library/waveform.py 3 91.67%
crates/qasm2/src/lex.rs 4 91.39%
crates/qasm2/src/parse.rs 18 96.65%
Totals Coverage Status
Change from base Build 4704167625: 0.01%
Covered Lines: 70473
Relevant Lines: 82140

💛 - Coveralls

With the addition of `switch`, we now have a second control-flow
construct that

- is not a loop, so can have lazily constructed blocks because of
  contained `break` and `continue` statements
- can have multiple blocks that need their resources unifying

For the first part, we largely just have to handle things separately to
`if`, though the placeholder instructions are much simpler because the
placeholder will never need mutating and replacing (c.f. the `else`
block).  For the second point, we move a bunch of the previously
if-specific code into a shared location in order to reuse it.

Unlike the `if` case, the `switch` builder uses nested context managers
for its cases, because this mirrors a common indentation pattern for
switch statements (at least if you're not a Linux kernel developer).

We need new special logic to reject statements that are loose in the
`switch` context but not a `case` context.  We _could_ have just ignored
that, but it feels like an easy potential mistake to make, so much
better to loudly fail than silently do the wrong thing.
jakelishman added a commit to jakelishman/qiskit-terra that referenced this pull request Apr 6, 2023
Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

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

Overall this LGTM, the code seems pretty straightforward and mirroring what is already done for the if/else builder. I had one inline comment on a method I think we should potentially rename. Besides that I think we're missing a few combinations of test cases. There weren't any tests with loops inside a case. Also, I didn't see any test cases mixing while loops and switch statements. I think just for completeness it might be good to validate it all works as expected (especially with break/continue) even though I don't expect anything to break using that because of the existing coverage.

Also I assume the release note for this is integrated into the PR at the top of the stack?

return _unify_circuit_registers(circuits)


def _unify_circuit_resources_rebuild( # pylint: disable=invalid-name # (it's too long?!)
Copy link
Member

Choose a reason for hiding this comment

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

Lol, it doesn't seem that long to me. Actually, it's not longer than: 6ae6634#diff-6bc399dbeb2cecdb0736e132814faa79639d77be265911ae26d3d9fe32eda3f5R130 which didn't raise an error for me. It might be something else in the regex? Either way this is kind of bogus

Copy link
Member Author

Choose a reason for hiding this comment

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

funnily enough, it's because our pylint settings allow longer method names (50 chars) than function names (31 chars)... (Well, that was true of the old .pylintrc form - not certain once we cut out all the duplication.)

qiskit/circuit/controlflow/switch_case.py Outdated Show resolved Hide resolved
@jakelishman
Copy link
Member Author

I wrote the initial release note in #9833, I think with the intention of revisiting it once we were 100% sure of the complete feature set that would make it in.

@jakelishman jakelishman requested a review from mtreinish April 14, 2023 21:57
Copy link
Member

@mtreinish mtreinish left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for adding the tests.

@mtreinish mtreinish added this pull request to the merge queue Apr 17, 2023
Merged via the queue into Qiskit:main with commit c34caa8 Apr 17, 2023
@jakelishman jakelishman deleted the switch/builder branch April 17, 2023 16:50
king-p3nguin pushed a commit to king-p3nguin/qiskit-terra that referenced this pull request May 22, 2023
* Add builder interface for new switch statement

With the addition of `switch`, we now have a second control-flow
construct that

- is not a loop, so can have lazily constructed blocks because of
  contained `break` and `continue` statements
- can have multiple blocks that need their resources unifying

For the first part, we largely just have to handle things separately to
`if`, though the placeholder instructions are much simpler because the
placeholder will never need mutating and replacing (c.f. the `else`
block).  For the second point, we move a bunch of the previously
if-specific code into a shared location in order to reuse it.

Unlike the `if` case, the `switch` builder uses nested context managers
for its cases, because this mirrors a common indentation pattern for
switch statements (at least if you're not a Linux kernel developer).

We need new special logic to reject statements that are loose in the
`switch` context but not a `case` context.  We _could_ have just ignored
that, but it feels like an easy potential mistake to make, so much
better to loudly fail than silently do the wrong thing.

* Rename inner placeholder_resources calculation

* Add missing tests of loops inside switches
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants