Open pdhoolia opened 1 month ago
To address the deprecation of BaseSamplerV1
and ensure compatibility with both V1 and V2 samplers in the HamiltonianPhaseEstimation
class, we can follow these steps:
Modify the estimate_from_pe_circuit
method in phase_estimation.py
to handle both BaseSamplerV1
and BaseSamplerV2
results.
Update the class annotations to include both V1 and V2 sampler types.
Ensure backward compatibility by checking the type of sampler used and processing the results accordingly.
Here's how you can implement these changes:
Update estimate_from_pe_circuit
Method:
Modify the method to differentiate between BaseSamplerV1
and BaseSamplerV2
results:
def estimate_from_pe_circuit(self, pe_circuit):
phases_bitstrings = {}
if isinstance(self._sampler, BaseSampler):
# Handle V1 Sampler
phases = circuit_result.quasi_dists[0]
for key, phase in phases.items():
bitstring_key = self._get_reversed_bitstring(self._num_evaluation_qubits, key)
phases_bitstrings[bitstring_key] = phase
elif isinstance(self._sampler, BaseSamplerV2):
# Handle V2 Sampler
counts = circuit_result[0].data.meas.get_counts()
for key, count in counts.items():
bitstring_key = key[::-1] # Reverse the bitstring
phases_bitstrings[bitstring_key] = count / sum(counts.values()) # Normalize counts
else:
raise ValueError("Sampler does not belong to any known Sampler class")
phases = phases_bitstrings
return PhaseEstimationResult(
self._num_evaluation_qubits, circuit_result=circuit_result, phases=phases
)
Update Class Annotations:
Update the annotations in the class where the sampler is defined to accommodate both types:
from qiskit.primitives.base import BaseSampler, BaseSamplerV2
class HamiltonianPhaseEstimation:
def __init__(self, num_evaluation_qubits, sampler: BaseSampler | BaseSamplerV2 | None = None):
self._num_evaluation_qubits = num_evaluation_qubits
self._sampler = sampler
# Other initialization code
Ensure Compatibility:
Ensure that wherever the sampler is used, the code checks for its type and processes results accordingly. This approach ensures that when the V1 samplers are eventually removed, the codebase remains functional with V2 samplers.
Backward Compatibility: The changes ensure that the existing code using BaseSamplerV1
continues to work without modification while preparing for the transition to BaseSamplerV2
.
Future-proofing: By handling both sampler types, the code is resilient to the eventual removal of V1 samplers.
Performance: Ensure that the normalization of counts in the V2 case is efficient, especially if dealing with large datasets.
This approach maintains the functionality of HamiltonianPhaseEstimation
while accommodating the deprecation of V1 samplers, thus preventing potential errors when V1 classes are removed.
What is happening?
Since the release of the version Qiskit 1.2 the class
Sampler
is deprecated. With this choice we require that all implementations of theBaseSamplerV1
interface have been deprecated in favour of their V2 counterparts. The V2 alternative for theSampler
class isStatevectorSampler
.The class
HamiltonianPhaseEstimation
has not be modified to accommodate this modification and still uses theBaseSamplerV1
Sampler class. At the moment, the code is still working with the exception of printing a DeprecationWarning. However, once theSampler
class will be removed it will generate an error.At the moment
StatevectorSampler
CANNOT be used as sampler for theHamiltonianPhaseEstimation
. This is due to the implementation of the functionestimate_from_pe_circuit
in the moduleqiskit_algorithms/phase_estimators/phase_estimation.py.
How can we reproduce the issue?
Import required modules
Use the
Sampler
class to run theHamiltonianPhaseEstimation
tmp/ipykernel_1033530/360718787.py:1: DeprecationWarning: The class
qiskit.primitives.sampler.Sampler
is deprecated ...Use the
StatevectorSampler
leads to an error:--> 6 qpe_result = qpe.estimate(hamiltonian=SparsePauliOp('XZ'),
File ~/qiskit_algorithms/phase_estimators/hamiltonian_phase_estimation.py:173, in HamiltonianPhaseEstimation.estimate(self, hamiltonian, state_preparation, evolution, bound)
--> 173 phase_estimation_result = self._phase_estimation.estimate( 174 unitary=unitary, state_preparation=state_preparation)
File ~/qiskit_algorithms/phase_estimators/phase_estimation.py:230, in PhaseEstimation.estimate(self, unitary, state_preparation)
--> 230 return self.estimate_from_pe_circuit(pe_circuit)
File ~/qiskit_algorithms/phase_estimators/phase_estimation.py:199, in PhaseEstimation.estimate_from_pe_circuit(self, pe_circuit)
--> 199 phases = circuit_result.quasi_dists[0]
AttributeError: 'PrimitiveResult' object has no attribute 'quasi_dists'
The reason of the error arise because the
BaseSamplerV1
provides a result that is a quasi distribution, whileBaseSamplerV2
return a primitive unified blocs (PUB) results which is inconsistent with the actual implementation.What should happen?
The
estimate_from_pe_circuit
function inphase_estimation.py
should check which Sampler is passed on and allow back-compatibility, in case it is passed theBaseSamplerV1
, and also allow the usage of the suggestedBaseSamplerV2
Any suggestions?
I am happy to open a pull request to modify the code from the current implementation
To my suggested implementation:
Further modification is the annotation of the classes as
sampler: BaseSampler | BaseSamplerV2 | None = None
. I am open to discuss wheatear the check of the Sampler type is more appropriate in the initialization of thePhaseEstimation
object.