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

Primitives support the dynamic circuits with control flow #9231

Merged

Conversation

ikkoham
Copy link
Contributor

@ikkoham ikkoham commented Dec 2, 2022

Summary

Primitives support the dynamic circuits with control flow.
If backend supports it, users can run the circuits using BackendSampler
and BackendEstimator.

Details and comments

@ikkoham ikkoham added Changelog: New Feature Include in the "Added" section of the changelog mod: primitives Related to the Primitives module labels Dec 2, 2022
@ikkoham ikkoham added this to the 0.23.0 milestone Dec 2, 2022
@ikkoham ikkoham requested review from a team and t-imamichi as code owners December 2, 2022 11:01
@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:

@coveralls
Copy link

coveralls commented Dec 2, 2022

Pull Request Test Coverage Report for Build 3950150312

  • 9 of 9 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.003%) to 84.871%

Totals Coverage Status
Change from base Build 3950148285: -0.003%
Covered Lines: 66042
Relevant Lines: 77815

💛 - Coveralls

Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

The change looks fine to me, thanks. I had a couple of questions about scope and testing, but they should hopefully be straightforwards.

Comment on lines 5 to 6
If backend supports it, users can run the circuits using :class:`~BackendSampler`
and :class:`~BackendEstimator`.
Copy link
Member

Choose a reason for hiding this comment

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

Does this change apply to only the BackendSampler and BackendEstimator, or is this a general improvement that affects all BaseSampler and BaseEstimator subclasses?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right. When I wrote this document, I thought that if a backend did not support control flow, primitives also did not support, but I was wrong.

Comment on lines 787 to 799
def test_circuit_key_controlflow(self):
"""Test for a circuit with control flow."""
qc = QuantumCircuit(2, 1)

with qc.for_loop(range(5)):
qc.h(0)
qc.cx(0, 1)
qc.measure(0, 0)
qc.break_loop().c_if(0, True)

self.assertIsInstance(hash(_circuit_key(qc)), int)
self.assertIsInstance(json.dumps(_circuit_key(qc)), str)

Copy link
Member

Choose a reason for hiding this comment

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

Aer supports control flow - would it be possible to try executing a simple Sampler and Estimator run on a BackendX backed by AerSimulator (with the appropriate @unittest.skipUnless(optionals.HAS_AER)).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I'll try it.

Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

I reworded the release note a little, but other than that I'm largely fine. The Aer test looks good, thanks.

I'm a bit concerned by some of the testing of _circuit_key, especially in that it seems to be implying it's being accessed over an API boundary by downstream packages. That particular issue hasn't come from this PR, but it may warrant following up on.

qc.break_loop().c_if(0, True)

self.assertIsInstance(hash(_circuit_key(qc)), int)
self.assertIsInstance(json.dumps(_circuit_key(qc)), str)
Copy link
Member

Choose a reason for hiding this comment

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

This json line doesn't look like it belongs in Terra - JSON serialisation of the internal object _circuit_key shouldn't be something Terra needs, and no package downstream of us should be relying on a private function having any particular behaviour.

Using a dummy primitive whose _run method (or whatever) just makes assertions / leaks the received circuit back to the caller somehow could be a cleaner way of making a public-API test.

from qiskit.circuit.random import random_circuit
from qiskit.primitives.base.base_primitive import BasePrimitive
from qiskit.primitives.utils import _circuit_key
Copy link
Member

Choose a reason for hiding this comment

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

I'm not a big fan of these tests of internal features, because generally they make it harder for the internal implementation to evolve without changing the tests. Ideally we should only be testing the outward public behaviour, and not the particulars of how that's achieved. If the tests are too tightly coupled, then any change to the internal implementation has to change the tests, and that makes it much easier for bugs and regressions to sneak in; we have to verify that the new tests are equivalent, and cover the same ground.

That said, this is a single function, and if you think it's much better to test this way, I won't block this PR on it.

I'd potentially attempt to rewrite the tests by using a custom subclass of the primitives for testing that has its _run (or whatever it's called) method defined to make assertions about the normalised circuits it gets back from the base class's handling. That's testing public parts of the subclassing API, rather than this internal detail of how that's done.

edit: I also see now that these tests are just moved from one file to another, rather than actually written new. I'm still not a fan, but it does move this change out-of-scope of this PR.

@ikkoham
Copy link
Contributor Author

ikkoham commented Jan 17, 2023

Yes, it is true. I think this should have been changed to a public function rather than a private function. (At first it was fine to keep it private, but the use of it has increased.)

@ikkoham
Copy link
Contributor Author

ikkoham commented Jan 17, 2023

I made _circuit_key public since this function has been already used from external (i.e. qiskit/algorithms/gradients).

@jakelishman
Copy link
Member

jakelishman commented Jan 17, 2023

I'm not a fan of making _circuit_key public, because of the concerns I've expressed (before on Slack, and on other primitives issues) about the management of circuits internally to enable the primitives' API and circuit_key's part in that, but that's not my call to make.

If you're going to do that, though, I'd much rather it was in a separate PR, which would now need to be targetted to Terra 0.24, rather than 0.23 whose release candidate is due on Thursday.

@jakelishman
Copy link
Member

@ikkoham: by the way, we tagged this as a release blocker for 0.23rc1, because I think it's something you need very strongly? Let us know if it's not the case and we can downgrade it.

@ikkoham ikkoham force-pushed the primitives/circuit-key-supports-controlflow branch from a02605e to b7e3ebc Compare January 18, 2023 00:08
@ikkoham
Copy link
Contributor Author

ikkoham commented Jan 18, 2023

This PR is needed in 0.23. I understand that private testing is not good, so I will create a separate PR and make it public with deprecation in 0.24.

Copy link
Member

@jakelishman jakelishman left a comment

Choose a reason for hiding this comment

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

I'm still not convinced by why the _circuit_key should be tested as JSON-serialisable with the default serialiser, but given that private function seems to be used elsewhere in the stack, I'm guessing it's something that needs to become part of its contract if/when it becomes public.

At any rate, the actual bulk of this PR I'm fine with, and my testing concerns are more about the risk of increased maintenance effort, which is relatively minor and not in my domain anyway.

@mergify mergify bot merged commit b4e10d5 into Qiskit:main Jan 18, 2023
@ikkoham ikkoham deleted the primitives/circuit-key-supports-controlflow branch January 19, 2023 00:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changelog: New Feature Include in the "Added" section of the changelog mod: primitives Related to the Primitives module priority: high
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants