mirror of https://github.com/Qiskit/qiskit.git
Add better error messages for typical SamplerV2 and EstimatorV2 error cases (#12031)
* add an early error for a case * Update qiskit/primitives/containers/sampler_pub.py Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> * add better message for estimator pub * Update qiskit/primitives/containers/estimator_pub.py Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> * add an additional message --------- Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
This commit is contained in:
parent
c26e25cddb
commit
194cc8fb9a
|
@ -132,6 +132,15 @@ class EstimatorPub(ShapedMixin):
|
|||
validate=False, # Assume Pub is already validated
|
||||
)
|
||||
return pub
|
||||
|
||||
if isinstance(pub, QuantumCircuit):
|
||||
raise ValueError(
|
||||
f"An invalid Estimator pub-like was given ({type(pub)}). "
|
||||
"If you want to run a single pub, you need to wrap it with `[]` like "
|
||||
"`estimator.run([(circuit, observables, param_values)])` "
|
||||
"instead of `estimator.run((circuit, observables, param_values))`."
|
||||
)
|
||||
|
||||
if len(pub) not in [2, 3, 4]:
|
||||
raise ValueError(
|
||||
f"The length of pub must be 2, 3 or 4, but length {len(pub)} is given."
|
||||
|
@ -208,8 +217,6 @@ estimator, if ``precision=None`` the estimator will determine the target precisi
|
|||
An Estimator Pub can also be initialized in the following formats which
|
||||
will be converted to the full Pub tuple:
|
||||
|
||||
* ``circuit
|
||||
* ``(circuit,)``
|
||||
* ``(circuit, observables)``
|
||||
* ``(circuit, observalbes, parameter_values)``
|
||||
* ``(circuit, observables, parameter_values)``
|
||||
"""
|
||||
|
|
|
@ -18,10 +18,11 @@ Sampler Pub class
|
|||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Tuple, Union
|
||||
from numbers import Integral
|
||||
from typing import Tuple, Union
|
||||
|
||||
from qiskit import QuantumCircuit
|
||||
from qiskit.circuit import CircuitInstruction
|
||||
|
||||
from .bindings_array import BindingsArray, BindingsArrayLike
|
||||
from .shape import ShapedMixin
|
||||
|
@ -113,6 +114,14 @@ class SamplerPub(ShapedMixin):
|
|||
if isinstance(pub, QuantumCircuit):
|
||||
return cls(circuit=pub, shots=shots, validate=True)
|
||||
|
||||
if isinstance(pub, CircuitInstruction):
|
||||
raise ValueError(
|
||||
f"An invalid Sampler pub-like was given ({type(pub)}). "
|
||||
"If you want to run a single circuit, "
|
||||
"you need to wrap it with `[]` like `sampler.run([circuit])` "
|
||||
"instead of `sampler.run(circuit)`."
|
||||
)
|
||||
|
||||
if len(pub) not in [1, 2, 3]:
|
||||
raise ValueError(
|
||||
f"The length of pub must be 1, 2 or 3, but length {len(pub)} is given."
|
||||
|
@ -147,10 +156,17 @@ class SamplerPub(ShapedMixin):
|
|||
# Cross validate circuits and parameter values
|
||||
num_parameters = self.parameter_values.num_parameters
|
||||
if num_parameters != self.circuit.num_parameters:
|
||||
raise ValueError(
|
||||
message = (
|
||||
f"The number of values ({num_parameters}) does not match "
|
||||
f"the number of parameters ({self.circuit.num_parameters}) for the circuit."
|
||||
)
|
||||
if num_parameters == 0:
|
||||
message += (
|
||||
" Note that if you want to run a single pub, you need to wrap it with `[]` like "
|
||||
"`sampler.run([(circuit, param_values)])` instead of "
|
||||
"`sampler.run((circuit, param_values))`."
|
||||
)
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
SamplerPubLike = Union[
|
||||
|
@ -171,7 +187,7 @@ if ``shots=None`` the number of run shots is determined by the sampler.
|
|||
A Sampler Pub can also be initialized in the following formats which
|
||||
will be converted to the full Pub tuple:
|
||||
|
||||
* ``circuit
|
||||
* ``circuit``
|
||||
* ``(circuit,)``
|
||||
* ``(circuit, parameter_values)``
|
||||
"""
|
||||
|
|
|
@ -56,6 +56,7 @@ class TestBackendEstimator(QiskitTestCase):
|
|||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self._rng = np.random.default_rng(12)
|
||||
self.ansatz = RealAmplitudes(num_qubits=2, reps=2)
|
||||
self.observable = SparsePauliOp.from_list(
|
||||
[
|
||||
|
@ -222,7 +223,7 @@ class TestBackendEstimator(QiskitTestCase):
|
|||
qc = RealAmplitudes(num_qubits=2, reps=2)
|
||||
op = SparsePauliOp.from_list([("IZ", 1), ("XI", 2), ("ZY", -1)])
|
||||
k = 5
|
||||
params_array = np.random.rand(k, qc.num_parameters)
|
||||
params_array = self._rng.random((k, qc.num_parameters))
|
||||
params_list = params_array.tolist()
|
||||
params_list_array = list(params_array)
|
||||
estimator = BackendEstimator(backend=backend)
|
||||
|
@ -288,7 +289,7 @@ class TestBackendEstimator(QiskitTestCase):
|
|||
qc = RealAmplitudes(num_qubits=2, reps=2)
|
||||
op = SparsePauliOp.from_list([("IZ", 1), ("XI", 2), ("ZY", -1)])
|
||||
k = 5
|
||||
params_array = np.random.rand(k, qc.num_parameters)
|
||||
params_array = self._rng.random((k, qc.num_parameters))
|
||||
params_list = params_array.tolist()
|
||||
estimator = BackendEstimator(backend=backend)
|
||||
with patch.object(backend, "run") as run_mock:
|
||||
|
@ -304,7 +305,7 @@ class TestBackendEstimator(QiskitTestCase):
|
|||
qc = RealAmplitudes(num_qubits=2, reps=2)
|
||||
op = SparsePauliOp.from_list([("IZ", 1), ("XI", 2), ("ZY", -1)])
|
||||
k = 5
|
||||
params_array = np.random.rand(k, qc.num_parameters)
|
||||
params_array = self._rng.random((k, qc.num_parameters))
|
||||
params_list = params_array.tolist()
|
||||
estimator = BackendEstimator(backend=backend)
|
||||
estimator.set_options(seed_simulator=123)
|
||||
|
@ -321,7 +322,7 @@ class TestBackendEstimator(QiskitTestCase):
|
|||
qc = RealAmplitudes(num_qubits=2, reps=2)
|
||||
op = SparsePauliOp.from_list([("IZ", 1), ("XI", 2), ("ZY", -1)])
|
||||
k = 5
|
||||
params_array = np.random.rand(k, qc.num_parameters)
|
||||
params_array = self._rng.random((k, qc.num_parameters))
|
||||
params_list = params_array.tolist()
|
||||
params_list_array = list(params_array)
|
||||
estimator = BackendEstimator(backend=backend)
|
||||
|
|
|
@ -45,6 +45,7 @@ class TestBackendEstimatorV2(QiskitTestCase):
|
|||
self._precision = 5e-3
|
||||
self._rtol = 3e-1
|
||||
self._seed = 12
|
||||
self._rng = np.random.default_rng(self._seed)
|
||||
self._options = {"default_precision": self._precision, "seed_simulator": self._seed}
|
||||
self.ansatz = RealAmplitudes(num_qubits=2, reps=2)
|
||||
self.observable = SparsePauliOp.from_list(
|
||||
|
@ -316,6 +317,9 @@ class TestBackendEstimatorV2(QiskitTestCase):
|
|||
est.run([(qc, op, None, -1)]).result()
|
||||
with self.assertRaises(ValueError):
|
||||
est.run([(qc, op)], precision=-1).result()
|
||||
with self.subTest("missing []"):
|
||||
with self.assertRaisesRegex(ValueError, "An invalid Estimator pub-like was given"):
|
||||
_ = est.run((qc, op)).result()
|
||||
|
||||
@combine(backend=BACKENDS, abelian_grouping=[True, False])
|
||||
def test_run_numpy_params(self, backend, abelian_grouping):
|
||||
|
@ -326,7 +330,7 @@ class TestBackendEstimatorV2(QiskitTestCase):
|
|||
op = SparsePauliOp.from_list([("IZ", 1), ("XI", 2), ("ZY", -1)])
|
||||
op = op.apply_layout(qc.layout)
|
||||
k = 5
|
||||
params_array = np.random.rand(k, qc.num_parameters)
|
||||
params_array = self._rng.random((k, qc.num_parameters))
|
||||
params_list = params_array.tolist()
|
||||
params_list_array = list(params_array)
|
||||
statevector_estimator = StatevectorEstimator(seed=123)
|
||||
|
@ -380,8 +384,7 @@ class TestBackendEstimatorV2(QiskitTestCase):
|
|||
qc = pm.run(qc)
|
||||
op = [SparsePauliOp("IX"), SparsePauliOp("YI")]
|
||||
shape = (3, 2)
|
||||
rng = np.random.default_rng(seed)
|
||||
params_array = rng.random(shape + (qc.num_parameters,))
|
||||
params_array = self._rng.random(shape + (qc.num_parameters,))
|
||||
params_list = params_array.tolist()
|
||||
params_list_array = list(params_array)
|
||||
statevector_estimator = StatevectorEstimator(seed=seed)
|
||||
|
|
|
@ -259,7 +259,8 @@ class TestBackendSampler(QiskitTestCase):
|
|||
qc = RealAmplitudes(num_qubits=2, reps=2)
|
||||
qc.measure_all()
|
||||
k = 5
|
||||
params_array = np.random.rand(k, qc.num_parameters)
|
||||
rng = np.random.default_rng(12)
|
||||
params_array = rng.random((k, qc.num_parameters))
|
||||
params_list = params_array.tolist()
|
||||
params_list_array = list(params_array)
|
||||
sampler = BackendSampler(backend=backend)
|
||||
|
|
|
@ -351,6 +351,12 @@ class TestBackendSamplerV2(QiskitTestCase):
|
|||
with self.subTest("zero shots, pub"):
|
||||
with self.assertRaises(ValueError):
|
||||
_ = sampler.run([SamplerPub(qc1, shots=0)]).result()
|
||||
with self.subTest("missing []"):
|
||||
with self.assertRaisesRegex(ValueError, "An invalid Sampler pub-like was given"):
|
||||
_ = sampler.run(qc1).result()
|
||||
with self.subTest("missing [] for pqc"):
|
||||
with self.assertRaisesRegex(ValueError, "Note that if you want to run a single pub,"):
|
||||
_ = sampler.run((qc2, [0, 1])).result()
|
||||
|
||||
@combine(backend=BACKENDS)
|
||||
def test_run_empty_parameter(self, backend):
|
||||
|
|
|
@ -237,7 +237,8 @@ class TestEstimator(QiskitTestCase):
|
|||
qc = RealAmplitudes(num_qubits=2, reps=2)
|
||||
op = SparsePauliOp.from_list([("IZ", 1), ("XI", 2), ("ZY", -1)])
|
||||
k = 5
|
||||
params_array = np.random.rand(k, qc.num_parameters)
|
||||
rng = np.random.default_rng(12)
|
||||
params_array = rng.random((k, qc.num_parameters))
|
||||
params_list = params_array.tolist()
|
||||
params_list_array = list(params_array)
|
||||
estimator = Estimator()
|
||||
|
|
|
@ -324,7 +324,8 @@ class TestSampler(QiskitTestCase):
|
|||
qc = RealAmplitudes(num_qubits=2, reps=2)
|
||||
qc.measure_all()
|
||||
k = 5
|
||||
params_array = np.random.rand(k, qc.num_parameters)
|
||||
rng = np.random.default_rng(12)
|
||||
params_array = rng.random((k, qc.num_parameters))
|
||||
params_list = params_array.tolist()
|
||||
params_list_array = list(params_array)
|
||||
sampler = Sampler()
|
||||
|
|
|
@ -236,13 +236,17 @@ class TestStatevectorEstimator(QiskitTestCase):
|
|||
est.run([(qc, op)], precision=-1).result()
|
||||
with self.assertRaises(ValueError):
|
||||
est.run([(qc, 1j * op)], precision=0.1).result()
|
||||
with self.subTest("missing []"):
|
||||
with self.assertRaisesRegex(ValueError, "An invalid Estimator pub-like was given"):
|
||||
_ = est.run((qc, op)).result()
|
||||
|
||||
def test_run_numpy_params(self):
|
||||
"""Test for numpy array as parameter values"""
|
||||
qc = RealAmplitudes(num_qubits=2, reps=2)
|
||||
op = SparsePauliOp.from_list([("IZ", 1), ("XI", 2), ("ZY", -1)])
|
||||
k = 5
|
||||
params_array = np.random.rand(k, qc.num_parameters)
|
||||
rng = np.random.default_rng(12)
|
||||
params_array = rng.random((k, qc.num_parameters))
|
||||
params_list = params_array.tolist()
|
||||
params_list_array = list(params_array)
|
||||
estimator = StatevectorEstimator()
|
||||
|
|
|
@ -320,6 +320,12 @@ class TestStatevectorSampler(QiskitTestCase):
|
|||
with self.subTest("zero shots, pub"):
|
||||
with self.assertRaises(ValueError):
|
||||
_ = sampler.run([SamplerPub(qc1, shots=0)]).result()
|
||||
with self.subTest("missing []"):
|
||||
with self.assertRaisesRegex(ValueError, "An invalid Sampler pub-like was given"):
|
||||
_ = sampler.run(qc1).result()
|
||||
with self.subTest("missing [] for pqc"):
|
||||
with self.assertRaisesRegex(ValueError, "Note that if you want to run a single pub,"):
|
||||
_ = sampler.run((qc2, [0, 1])).result()
|
||||
|
||||
def test_run_empty_parameter(self):
|
||||
"""Test for empty parameter"""
|
||||
|
|
Loading…
Reference in New Issue