Add BackendEstimatorV2 interface#156
Conversation
Add EstimatorPub, BackendEstimatorV2, BackendEstimatorJob, and estimator result containers backed by the existing BackendV2 sampler execution path. The implementation extracts Pauli and identity terms from SparseObservable, builds estimator measurement circuits with qubit-wise compatible grouping, derives shots from precision, and post-processes BitArray samples into evs, stds, shots, and target_precision. Include the wrapper fixes needed by the estimator: SparseObservable exposes QkObs array lengths correctly and copies safely, QuantumCircuit supports const-safe copy/measurement inspection and source-circuit compose replay, and hamming_parity/popcount are inline functions for multi-file test builds.
|
I kept the default C++ unit tests: estimator containers, QkObs/Pauli extraction, measurement planning, and Pauli statistics. For end-to-end backend validation, would you prefer a CI test that compares this C++ estimator path against Qiskit Python/Aer on the same circuits and observables, or a separate validation script outside the default CI suite? Thanks |
|
As I mentioned in the issue #145 (comment) |
|
|
||
| for (uint_t qubit = 0; qubit < basis.axes.size(); qubit++) { | ||
| if (basis.axes[qubit] == PauliAxis::X) { | ||
| measured.h(qubit); |
There was a problem hiding this comment.
We can not add h gate here to the circuit, because the input circuit should be ISA circuit here.
I think we do not have to add measure and rotations here if we have backend.run() for estimator
| if (basis.axes[qubit] == PauliAxis::X) { | ||
| measured.h(qubit); | ||
| } else if (basis.axes[qubit] == PauliAxis::Y) { | ||
| measured.sdg(qubit); |
There was a problem hiding this comment.
here also we do not accept sdg gate
Closes #145
Summary
Add a
BackendEstimatorV2primitive that mirrors the existingBackendSamplerV2shape:EstimatorPubcarries an ISA circuit and observables,estimator.run()returns aBackendEstimatorJob, and the job result contains expectation values and standard errors.The estimator uses the same precision-to-shots rule and Pauli expectation/std-error post-processing model as Qiskit Python
BackendEstimatorV2for the supported real-coefficient PauliSparseObservablesubset.The implementation reuses the existing
BackendV2sampler path,QuantumCircuit,SparseObservable/QkObs,BitArray, and standard-library math to extract Pauli terms, build grouped measurement circuits, execute them, and returnevs/stdswithshotsandtarget_precision.The patch includes the wrapper fixes required by the estimator and deterministic unit tests for estimator containers, observable extraction, measurement planning, and Pauli statistics.
Details
EstimatorPub,BackendEstimatorV2,BackendEstimatorJob,EstimatorPubResult, andEstimatorResult.SparseObservableterms.shotsfromprecision; the default0.015625matches PythonBackendEstimatorV2's documented1 / sqrt(4096)default (source), and Python maps precision to shots withceil(1 / precision**2)(source).BitArraypost-processing forevs/stds.Execution flow
BackendEstimatorV2::run()validates eachEstimatorPub, resolvesprecisionto a shot count, extracts real-coefficient Pauli terms fromSparseObservable, and groups qubit-wise compatible Pauli terms intomeasurement circuits.
BackendV2::run()sampler interface.BackendEstimatorJob::result()reads the returnedBitArraysamples andpost-processes them into
evs,stds,shots, andtarget_precision.Scope notes
BackendV2::run()sampler interface.Existing wrapper fixes
SparseObservable
Fix
bit_terms()andboundaries()to use theQkObsC API array lengths, makeindices()and the copy constructor null-safe, and add deep-copyoperator=. Estimator term extraction depends on these arrays, andEstimatorPubassignment needs copiedQkObsownership rather than a shared raw handle.QuantumCircuit
Make
copy()const, add constget_measure_map(), and fixcompose(circ, ...)to read instruction kinds from the source circuit. Estimator validation is read-only, and measured circuits must replay the input circuit before adding basis rotations.utils.hpp
Replace the header-level
hamming_parity/popcountfunction pointer variables with C++11 inline functions. This keepsQiskit::popcount(x)call sites unchanged and avoids duplicate symbols when multiple test translation units include the header.Testing
AI disclosure: I used ChatGPT/Codex for drafting and review assistance. I reviewed and own the final design, implementation, tests, and PR wording. Local checks I ran are listed above.