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 BackendSamplerV2 #11928

Merged
merged 10 commits into from
Mar 15, 2024
Merged

Add BackendSamplerV2 #11928

merged 10 commits into from
Mar 15, 2024

Conversation

t-imamichi
Copy link
Member

@t-imamichi t-imamichi commented Mar 1, 2024

Summary

This PR adds BackendSamplerV2 as a BaseSamplerV2 implementation using a backend.
This requires BackendV2 object that supports memory option.

I made tests based on those for StatevectorSampler.

Notes

  • I intentionally specified only BackendV2 as backend option though it still supports BackendV1 because I think we need to support only the latest version of backends. If requested, I can add BackendV1.
    • I added BackendV1 as well as BackendV2 support.
  • I didn't add transpile feature because Runtime Primitives V2 do not support transpile during execution. Users need to transform input circuits into ISA format beforehand.

Details and comments

@t-imamichi t-imamichi requested review from a team as code owners March 1, 2024 09:52
@qiskit-bot
Copy link
Collaborator

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

  • @Qiskit/terra-core
  • @ajavadia
  • @ikkoham
  • @levbishop
  • @t-imamichi

@t-imamichi t-imamichi added mod: primitives Related to the Primitives module Changelog: New Feature Include in the "Added" section of the changelog labels Mar 1, 2024
@coveralls
Copy link

coveralls commented Mar 1, 2024

Pull Request Test Coverage Report for Build 8297352993

Details

  • 98 of 99 (98.99%) changed or added relevant lines in 2 files are covered.
  • 4 unchanged lines in 2 files lost coverage.
  • Overall coverage increased (+0.04%) to 89.316%

Changes Missing Coverage Covered Lines Changed/Added Lines %
qiskit/primitives/backend_sampler_v2.py 97 98 98.98%
Files with Coverage Reduction New Missed Lines %
crates/qasm2/src/expr.rs 1 93.81%
crates/qasm2/src/lex.rs 3 92.19%
Totals Coverage Status
Change from base Build 8297051089: 0.04%
Covered Lines: 59820
Relevant Lines: 66976

💛 - Coveralls

@1ucian0 1ucian0 added this to the 1.1.0 milestone Mar 1, 2024
Copy link
Contributor

@ikkoham ikkoham left a comment

Choose a reason for hiding this comment

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

Basically LGTM, but we need more reviews.

qiskit/primitives/backend_sampler_v2.py Outdated Show resolved Hide resolved

def _validate_pubs(self, pubs: list[SamplerPub]):
for i, pub in enumerate(pubs):
if len(pub.circuit.cregs) == 0:
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to check for measure instruction? Should we rather check measure instruction?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not sure whether we need more validations. This is basically same as the check of StatevectorSampler.

if any(len(pub.circuit.cregs) == 0 for pub in coerced_pubs):
warnings.warn(
"One of your circuits has no output classical registers and so the result "
"will be empty. Did you mean to add measurement instructions?",
UserWarning,
)

@1ucian0
Copy link
Member

1ucian0 commented Mar 4, 2024

I tested this in the following way:

with Aer:

from qiskit import QuantumCircuit, transpile
from qiskit_aer import Aer
from qiskit.primitives import BackendSamplerV2

qasm_simulator = Aer.get_backend('qasm_simulator')
qasm_simulator_sampler = BackendSamplerV2(backend=qasm_simulator)

circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()

jobs = qasm_simulator_sampler.run([transpile(circuit, qasm_simulator)])
jobs.result()[0].data.meas.get_counts()

with fake backend (V1 and V2):

from qiskit import QuantumCircuit, transpile
from qiskit_ibm_runtime.fake_provider import FakeAlmadenV2 
from qiskit.primitives import BackendSamplerV2

fake_almaden = FakeAlmadenV2()
fake_almaden_sampler = BackendSamplerV2(backend=fake_almaden)

circuit = QuantumCircuit(2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure_all()

jobs = fake_almaden_sampler.run([transpile(circuit, fake_almaden)])
print(jobs.result()[0].data.meas.get_counts())

It works as expected.

I was surprised with the following errors:

  • access databin items with subscripts seems like it is not working. That is print(jobs.result()[0].data['meas'].get_counts()) is failing with 'DataBin' object is not subscriptable. Probably unrelated with this PR.
  • When accidentally calling the primitive with a circuit instead of an array with a circuit jobs = fake_almaden_sampler.run(transpile(circuit, fake_almaden)), the error AttributeError: 'U2Gate' object has no attribute 'parameters' which seems suspicious as it is an access error. It might be because something deeper is wrong.
  • I was unable to seed the simulated running. The reference implementation supports sampler.run(qc, shots=shots, seed=42) but fake_almaden_sampler.run([transpile(circuit, fake_almaden)], seed=42) is not supported, it seems.

Copy link
Member

Choose a reason for hiding this comment

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

I find these tests hard to read. At the same time, they are based on test/python/primitives/test_backend_sampler.py, which I also find hard to read. So probably for a follow up.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe an example with Fake7QPulseV1 similar to #11928 (comment) ?

@t-imamichi
Copy link
Member Author

Thank you for your review, Luciano. I add some comments to your surprises.

  1. access databin items with subscripts are not implemented since the first PR Add V2 primitive container classes #11524. Do we need to add it in a separate PR, @ihincks?
  2. SamplerV2 accepts only an iterable of pubs or publikes.
    self, pubs: Iterable[SamplerPubLike], *, shots: int | None = None
    So, jobs = fake_almaden_sampler.run(transpile(circuit, fake_almaden)) is interpreted as individual instruction of the transpiled circuit as an input publike. It should be jobs = fake_almaden_sampler.run([transpile(circuit, fake_almaden)]) (put a circuit in a list).
  3. It does not support any run_options currently. I suppose a backend can set the seed in the constructor, i.e., BackendSamplerV2(backend=BackendSomething(seed=seed)). If it is preferable to accept run options in run method, I will add it.

@1ucian0 1ucian0 self-assigned this Mar 7, 2024
Copy link
Contributor

@ihincks ihincks left a comment

Choose a reason for hiding this comment

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

Thank you @t-imamichi I only have a few minor comments. Other than those, this implimentation LGTM.

qiskit/primitives/backend_sampler_v2.py Outdated Show resolved Hide resolved
qiskit/primitives/backend_sampler_v2.py Outdated Show resolved Hide resolved
qiskit/primitives/backend_sampler_v2.py Outdated Show resolved Hide resolved
t-imamichi and others added 3 commits March 12, 2024 22:35
Co-authored-by: Ian Hincks <ian.hincks@gmail.com>
Co-authored-by: Ikko Hamamura <ikkoham@users.noreply.github.com>
@t-imamichi
Copy link
Member Author

I added BackendV1 support and tests with Fake7QPulseV1.

@t-imamichi
Copy link
Member Author

I added options to set seed_simulator.

features:
- |
The implementation :class:`~.BackendSamplerV2` of :class:`~.BaseSamplerV2` was added.
This requires :class:`~.BackendV2` object that supports ``memory`` option to computes bitstrings.
Copy link
Member

Choose a reason for hiding this comment

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

Do you mind adding an example like #11928 (comment) ?

(pqc2, [0, 1, 2, 3, 4, 5, 6, 7], {0: 1898, 1: 6864, 2: 928, 3: 311})
) # case 6

def _assert_allclose(self, bitarray: BitArray, target: NDArray | BitArray, rtol=1e-1, atol=5e2):
Copy link
Member

Choose a reason for hiding this comment

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

with seeding, to you still need this _assert_allclose?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. It is necessary because unit tests use both an exact simulator and noise simulators.

Copy link
Member

@1ucian0 1ucian0 left a comment

Choose a reason for hiding this comment

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

Some non-blocking comments. It they can be addressed in this PR, great. Otherwise, in a follow up

@t-imamichi
Copy link
Member Author

I updated the code based on #11931 as follows.

  • updated the docstrings
  • moved default_shots to options
  • added a sample code

1ucian0
1ucian0 previously approved these changes Mar 15, 2024
Copy link
Member

@1ucian0 1ucian0 left a comment

Choose a reason for hiding this comment

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

Let's merge it! Thanks!

@1ucian0 1ucian0 added this pull request to the merge queue Mar 15, 2024
@1ucian0 1ucian0 removed this pull request from the merge queue due to a manual request Mar 15, 2024
@1ucian0 1ucian0 added this pull request to the merge queue Mar 15, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to a conflict with the base branch Mar 15, 2024
@t-imamichi
Copy link
Member Author

Fixed a conflict

@1ucian0 1ucian0 added this pull request to the merge queue Mar 15, 2024
Merged via the queue into Qiskit:main with commit 2369761 Mar 15, 2024
12 checks passed
@t-imamichi t-imamichi deleted the backend-sampler-v2 branch March 16, 2024 01:24
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants