diff --git a/qiskit/primitives/base_sampler.py b/qiskit/primitives/base_sampler.py index 6cd957996029..1cb8da2a39dc 100644 --- a/qiskit/primitives/base_sampler.py +++ b/qiskit/primitives/base_sampler.py @@ -105,6 +105,7 @@ from qiskit.utils.deprecation import deprecate_arguments, deprecate_function from .sampler_result import SamplerResult +from .utils import final_measurement_mapping class BaseSampler(ABC): @@ -383,6 +384,23 @@ def run( f"The number of values ({len(parameter_value)}) does not match " f"the number of parameters ({circuit.num_parameters}) for the {i}-th circuit." ) + + for i, circuit in enumerate(circuits): + if circuit.num_clbits == 0: + raise QiskitError( + f"The {i}-th circuit does not have any classical bit. " + "Sampler requires classical bits, plus measurements " + "on the desired qubits." + ) + + mapping = final_measurement_mapping(circuit) + if set(range(circuit.num_clbits)) != set(mapping.values()): + raise QiskitError( + f"Some classical bits of the {i}-th circuit are not used for measurements." + f" the number of classical bits ({circuit.num_clbits})," + f" the used classical bits ({set(mapping.values())})." + ) + run_opts = copy(self.run_options) run_opts.update_options(**run_options) diff --git a/qiskit/primitives/sampler.py b/qiskit/primitives/sampler.py index 40d35a0778f2..b071e6d01d90 100644 --- a/qiskit/primitives/sampler.py +++ b/qiskit/primitives/sampler.py @@ -158,12 +158,6 @@ def _run( def _preprocess_circuit(circuit: QuantumCircuit): circuit = init_circuit(circuit) q_c_mapping = final_measurement_mapping(circuit) - if set(range(circuit.num_clbits)) != set(q_c_mapping.values()): - raise QiskitError( - "some classical bits are not used for measurements." - f" the number of classical bits {circuit.num_clbits}," - f" the used classical bits {set(q_c_mapping.values())}." - ) c_q_mapping = sorted((c, q) for q, c in q_c_mapping.items()) qargs = [q for _, q in c_q_mapping] circuit = circuit.remove_final_measurements(inplace=False) diff --git a/releasenotes/notes/add-sampler-error-check-38426fb186db44d4.yaml b/releasenotes/notes/add-sampler-error-check-38426fb186db44d4.yaml new file mode 100644 index 000000000000..b83989c0a640 --- /dev/null +++ b/releasenotes/notes/add-sampler-error-check-38426fb186db44d4.yaml @@ -0,0 +1,7 @@ +--- +upgrade: + - | + Added some error checks to :meth:`~qiskit.primitives.BaseSampler.run`. + It raises an error if there is no classical bit or some classical bits + are not used for measurements. + diff --git a/test/python/primitives/test_sampler.py b/test/python/primitives/test_sampler.py index 461d23bbd657..1e23a876f010 100644 --- a/test/python/primitives/test_sampler.py +++ b/test/python/primitives/test_sampler.py @@ -572,19 +572,33 @@ def test_run_2qubit(self): np.testing.assert_allclose(values, [0, 0, 0, 1]) def test_run_errors(self): - """Test for errors""" + """Test for errors with run method""" qc1 = QuantumCircuit(1) qc1.measure_all() qc2 = RealAmplitudes(num_qubits=1, reps=1) qc2.measure_all() + qc3 = QuantumCircuit(1) + qc4 = QuantumCircuit(1, 1) sampler = Sampler() - with self.assertRaises(QiskitError): - sampler.run([qc1], [[1e2]]).result() - with self.assertRaises(QiskitError): - sampler.run([qc2], [[]]).result() - with self.assertRaises(QiskitError): - sampler.run([qc2], [[1e2]]).result() + with self.subTest("set parameter values to a non-parameterized circuit"): + with self.assertRaises(QiskitError): + _ = sampler.run([qc1], [[1e2]]) + with self.subTest("missing all parameter values for a parameterized circuit"): + with self.assertRaises(QiskitError): + _ = sampler.run([qc2], [[]]) + with self.subTest("missing some parameter values for a parameterized circuit"): + with self.assertRaises(QiskitError): + _ = sampler.run([qc2], [[1e2]]) + with self.subTest("too many parameter values for a parameterized circuit"): + with self.assertRaises(QiskitError): + _ = sampler.run([qc2], [[1e2]] * 100) + with self.subTest("no classical bits"): + with self.assertRaises(QiskitError): + _ = sampler.run([qc3], [[]]) + with self.subTest("no measurement"): + with self.assertRaises(QiskitError): + _ = sampler.run([qc4], [[]]) def test_run_empty_parameter(self): """Test for empty parameter"""