Skip to content

Commit

Permalink
Merge branch 'main' into backendv2
Browse files Browse the repository at this point in the history
  • Loading branch information
doichanj authored Oct 24, 2023
2 parents c6a5621 + 861ec5c commit b41631a
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 31 deletions.
51 changes: 47 additions & 4 deletions qiskit_aer/primitives/estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
Optimize1qGatesDecomposition,
SetLayout,
)
from qiskit.utils import deprecate_arg, deprecate_func

from .. import AerError, AerSimulator

Expand Down Expand Up @@ -75,6 +76,12 @@ class Estimator(BaseEstimator):
normal distribution approximation.
"""

@deprecate_arg(
"approximation",
since=0.13,
package_name="qiskit-aer",
additional_msg="approximation=True will be default in the future.",
)
def __init__(
self,
*,
Expand Down Expand Up @@ -107,7 +114,15 @@ def __init__(
self._transpile_options = Options()
if transpile_options is not None:
self._transpile_options.update_options(**transpile_options)
self.approximation = approximation
if not approximation:
warn(
"Option approximation=False is deprecated as of qiskit-aer 0.13. "
"It will be removed no earlier than 3 months after the release date. "
"Instead, use BackendEstmator from qiskit.primitives.",
DeprecationWarning,
stacklevel=3,
)
self._approximation = approximation
self._skip_transpilation = skip_transpilation
self._cache: dict[tuple[tuple[int], tuple[int], bool], tuple[dict, dict]] = {}
self._transpiled_circuits: dict[int, QuantumCircuit] = {}
Expand All @@ -116,6 +131,34 @@ def __init__(
self._observable_ids: dict[tuple, int] = {}
self._abelian_grouping = abelian_grouping

@property
@deprecate_func(
since=0.13,
package_name="qiskit-aer",
is_property=True,
)
def approximation(self):
"""The approximation property"""
return self._approximation

@approximation.setter
@deprecate_func(
since=0.13,
package_name="qiskit-aer",
is_property=True,
)
def approximation(self, approximation):
"""Setter for approximation"""
if not approximation:
warn(
"Option approximation=False is deprecated as of qiskit-aer 0.13. "
"It will be removed no earlier than 3 months after the release date. "
"Instead, use BackendEstmator from qiskit.primitives.",
DeprecationWarning,
stacklevel=3,
)
self._approximation = approximation

def _call(
self,
circuits: Sequence[int],
Expand All @@ -127,7 +170,7 @@ def _call(
if seed is not None:
run_options.setdefault("seed_simulator", seed)

if self.approximation:
if self._approximation:
return self._compute_with_approximation(
circuits, observables, parameter_values, run_options, seed
)
Expand Down Expand Up @@ -181,7 +224,7 @@ def _compute(self, circuits, observables, parameter_values, run_options):
)

# Key for cache
key = (tuple(circuits), tuple(observables), self.approximation)
key = (tuple(circuits), tuple(observables), self._approximation)

# Create expectation value experiments.
if key in self._cache: # Use a cache
Expand Down Expand Up @@ -379,7 +422,7 @@ def _compute_with_approximation(
self, circuits, observables, parameter_values, run_options, seed
):
# Key for cache
key = (tuple(circuits), tuple(observables), self.approximation)
key = (tuple(circuits), tuple(observables), self._approximation)
shots = run_options.pop("shots", None)

# Create expectation value experiments.
Expand Down
68 changes: 41 additions & 27 deletions test/terra/primitives/test_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,10 @@ def test_estimator(self, abelian_grouping):
with self.subTest("SparsePauliOp"):
observable = SparsePauliOp.from_list(lst)
ansatz = RealAmplitudes(num_qubits=2, reps=2)
est = Estimator(
backend_options={"method": "statevector"}, abelian_grouping=abelian_grouping
)
with self.assertWarns(DeprecationWarning):
est = Estimator(
backend_options={"method": "statevector"}, abelian_grouping=abelian_grouping
)
result = est.run(
ansatz, observable, parameter_values=[[0, 1, 1, 2, 3, 5]], seed=15
).result()
Expand All @@ -88,9 +89,10 @@ def test_estimator(self, abelian_grouping):
]
)
ansatz = RealAmplitudes(num_qubits=2, reps=2)
est = Estimator(
backend_options={"method": "statevector"}, abelian_grouping=abelian_grouping
)
with self.assertWarns(DeprecationWarning):
est = Estimator(
backend_options={"method": "statevector"}, abelian_grouping=abelian_grouping
)
result = est.run(ansatz, observable, parameter_values=[[0] * 6], seed=15).result()
self.assertIsInstance(result, EstimatorResult)
np.testing.assert_allclose(result.values, [-0.4], rtol=0.02)
Expand All @@ -107,15 +109,17 @@ def test_init_observable_from_operator(self, abelian_grouping):
[0.1809312, 0.0, 0.0, -1.06365335],
]
)
est = Estimator(abelian_grouping=abelian_grouping)
with self.assertWarns(DeprecationWarning):
est = Estimator(abelian_grouping=abelian_grouping)
result = est.run([circuit], [matrix], seed=15, shots=8192).result()
self.assertIsInstance(result, EstimatorResult)
np.testing.assert_allclose(result.values, [self.expval], rtol=0.02)

@data(True, False)
def test_evaluate(self, abelian_grouping):
"""test for evaluate"""
est = Estimator(abelian_grouping=abelian_grouping)
with self.assertWarns(DeprecationWarning):
est = Estimator(abelian_grouping=abelian_grouping)
result = est.run(
self.ansatz, self.observable, parameter_values=[[0, 1, 1, 2, 3, 5]], seed=15, shots=8192
).result()
Expand All @@ -125,7 +129,8 @@ def test_evaluate(self, abelian_grouping):
@data(True, False)
def test_evaluate_multi_params(self, abelian_grouping):
"""test for evaluate with multiple parameters"""
est = Estimator(abelian_grouping=abelian_grouping)
with self.assertWarns(DeprecationWarning):
est = Estimator(abelian_grouping=abelian_grouping)
result = est.run(
[self.ansatz] * 2,
[self.observable] * 2,
Expand All @@ -139,7 +144,8 @@ def test_evaluate_multi_params(self, abelian_grouping):
def test_evaluate_no_params(self, abelian_grouping):
"""test for evaluate without parameters"""
circuit = self.ansatz.assign_parameters([0, 1, 1, 2, 3, 5])
est = Estimator(abelian_grouping=abelian_grouping)
with self.assertWarns(DeprecationWarning):
est = Estimator(abelian_grouping=abelian_grouping)
result = est.run(circuit, self.observable, seed=15, shots=8192).result()
self.assertIsInstance(result, EstimatorResult)
np.testing.assert_allclose(result.values, [self.expval], rtol=0.02)
Expand All @@ -152,7 +158,8 @@ def test_run_with_multiple_observables_and_none_parameters(self, abelian_groupin
circuit.cx(0, 1)
circuit.cx(1, 2)
# Skip transpilation until solve qiskit-terra issue(10568)
est = Estimator(abelian_grouping=abelian_grouping, skip_transpilation=True)
with self.assertWarns(DeprecationWarning):
est = Estimator(abelian_grouping=abelian_grouping, skip_transpilation=True)
result = est.run(
[circuit] * 2, [SparsePauliOp("ZZZ"), SparsePauliOp("III")], seed=15
).result()
Expand All @@ -169,7 +176,8 @@ def test_1qubit(self, abelian_grouping):
op0 = SparsePauliOp.from_list([("I", 1)])
op1 = SparsePauliOp.from_list([("Z", 1)])

est = Estimator(abelian_grouping=abelian_grouping)
with self.assertWarns(DeprecationWarning):
est = Estimator(abelian_grouping=abelian_grouping)
with self.subTest("test circuit 0, observable 0"):
result = est.run(qc0, op0).result()
self.assertIsInstance(result, EstimatorResult)
Expand Down Expand Up @@ -201,7 +209,8 @@ def test_2qubits(self, abelian_grouping):
op1 = SparsePauliOp.from_list([("ZI", 1)])
op2 = SparsePauliOp.from_list([("IZ", 1)])

est = Estimator(abelian_grouping=abelian_grouping)
with self.assertWarns(DeprecationWarning):
est = Estimator(abelian_grouping=abelian_grouping)
with self.subTest("test circuit 0, observable 0"):
result = est.run(qc0, op0).result()
self.assertIsInstance(result, EstimatorResult)
Expand Down Expand Up @@ -238,7 +247,8 @@ def test_empty_parameter(self, abelian_grouping):
n = 2
qc = QuantumCircuit(n)
op = SparsePauliOp.from_list([("I" * n, 1)])
estimator = Estimator(abelian_grouping=abelian_grouping)
with self.assertWarns(DeprecationWarning):
estimator = Estimator(abelian_grouping=abelian_grouping)
with self.subTest("one circuit"):
result = estimator.run(qc, op, shots=1000).result()
np.testing.assert_allclose(result.values, [1])
Expand All @@ -258,7 +268,8 @@ def test_numpy_params(self, abelian_grouping):
params_array = np.random.rand(k, qc.num_parameters)
params_list = params_array.tolist()
params_list_array = list(params_array)
estimator = Estimator(abelian_grouping=abelian_grouping)
with self.assertWarns(DeprecationWarning):
estimator = Estimator(abelian_grouping=abelian_grouping)
target = estimator.run([qc] * k, [op] * k, params_list, seed=15).result()

with self.subTest("ndarrary"):
Expand All @@ -276,7 +287,8 @@ def test_with_shots_option_with_approximation(self, abelian_grouping):
"""test with shots option."""
# Note: abelian_gropuing is ignored when approximation is True as documented.
# The purpose of this test is to make sure the results remain the same.
est = Estimator(approximation=True, abelian_grouping=abelian_grouping)
with self.assertWarns(DeprecationWarning):
est = Estimator(approximation=True, abelian_grouping=abelian_grouping)
result = est.run(
self.ansatz, self.observable, parameter_values=[[0, 1, 1, 2, 3, 5]], shots=1024, seed=15
).result()
Expand All @@ -286,7 +298,8 @@ def test_with_shots_option_with_approximation(self, abelian_grouping):

def test_with_shots_option_without_approximation(self):
"""test with shots option."""
est = Estimator(approximation=False, abelian_grouping=False)
with self.assertWarns(DeprecationWarning):
est = Estimator(approximation=False, abelian_grouping=False)
result = est.run(
self.ansatz, self.observable, parameter_values=[[0, 1, 1, 2, 3, 5]], shots=1024, seed=15
).result()
Expand All @@ -296,15 +309,15 @@ def test_with_shots_option_without_approximation(self):

def test_warn_shots_none_without_approximation(self):
"""Test waning for shots=None without approximation."""
est = Estimator(approximation=False)
with self.assertWarns(RuntimeWarning):
result = est.run(
self.ansatz,
self.observable,
parameter_values=[[0, 1, 1, 2, 3, 5]],
shots=None,
seed=15,
).result()
with self.assertWarns(DeprecationWarning):
est = Estimator(approximation=False)
result = est.run(
self.ansatz,
self.observable,
parameter_values=[[0, 1, 1, 2, 3, 5]],
shots=None,
seed=15,
).result()
self.assertIsInstance(result, EstimatorResult)
np.testing.assert_allclose(result.values, [-1.313831587508902])
self.assertIsInstance(result.metadata[0]["variance"], float)
Expand All @@ -319,7 +332,8 @@ def test_result_order(self):
qc2.ry(np.pi / 2 * param, 0)
qc2.measure_all()

estimator = Estimator(approximation=True)
with self.assertWarns(DeprecationWarning):
estimator = Estimator(approximation=True)
job = estimator.run([qc1, qc2, qc1, qc1, qc2], ["Z"] * 5, [[], [1], [], [], [1]])
result = job.result()
np.testing.assert_allclose(result.values, [1, 0, 1, 1, 0], atol=1e-10)
Expand Down

0 comments on commit b41631a

Please sign in to comment.