From 1c4061054135565e29a07c99c9e3777f68140014 Mon Sep 17 00:00:00 2001 From: Takashi Imamichi Date: Mon, 5 Sep 2022 15:21:03 +0900 Subject: [PATCH 1/5] add an error check for sampler --- qiskit/primitives/base_sampler.py | 7 +++++++ test/python/primitives/test_sampler.py | 9 ++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/qiskit/primitives/base_sampler.py b/qiskit/primitives/base_sampler.py index 2b2f14b0d32f..e07c92654ebc 100644 --- a/qiskit/primitives/base_sampler.py +++ b/qiskit/primitives/base_sampler.py @@ -359,6 +359,13 @@ def run( 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." + ) + return self._run(circuits, parameter_values, parameter_views, **run_options) @abstractmethod diff --git a/test/python/primitives/test_sampler.py b/test/python/primitives/test_sampler.py index b126f927de97..0a01f76fc2a4 100644 --- a/test/python/primitives/test_sampler.py +++ b/test/python/primitives/test_sampler.py @@ -577,14 +577,17 @@ def test_run_errors(self): qc1.measure_all() qc2 = RealAmplitudes(num_qubits=1, reps=1) qc2.measure_all() + qc3 = QuantumCircuit(1) sampler = Sampler() with self.assertRaises(QiskitError): - sampler.run([qc1], [[1e2]]).result() + sampler.run([qc1], [[1e2]]) with self.assertRaises(QiskitError): - sampler.run([qc2], [[]]).result() + sampler.run([qc2], [[]]) with self.assertRaises(QiskitError): - sampler.run([qc2], [[1e2]]).result() + sampler.run([qc2], [[1e2]]) + with self.assertRaises(QiskitError): + result = sampler.run([qc3], [[]]) def test_run_empty_parameter(self): """Test for empty parameter""" From bdc055ee6088a80de23dee0526724f1c57c30932 Mon Sep 17 00:00:00 2001 From: Takashi Imamichi Date: Mon, 5 Sep 2022 16:39:34 +0900 Subject: [PATCH 2/5] update --- qiskit/primitives/base_sampler.py | 9 ++++++ ...-sampler-error-check-38426fb186db44d4.yaml | 7 +++++ test/python/primitives/test_sampler.py | 29 +++++++++++++------ 3 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 releasenotes/notes/add-sampler-error-check-38426fb186db44d4.yaml diff --git a/qiskit/primitives/base_sampler.py b/qiskit/primitives/base_sampler.py index e07c92654ebc..ffc9962e9551 100644 --- a/qiskit/primitives/base_sampler.py +++ b/qiskit/primitives/base_sampler.py @@ -104,6 +104,7 @@ from qiskit.utils.deprecation import deprecate_arguments, deprecate_function from .sampler_result import SamplerResult +from .utils import final_measurement_mapping class BaseSampler(ABC): @@ -366,6 +367,14 @@ def run( "Sampler requires classical bits." ) + mapping = final_measurement_mapping(circuit) + if set(range(circuit.num_clbits)) != set(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(mapping.values())})." + ) + return self._run(circuits, parameter_values, parameter_views, **run_options) @abstractmethod 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 0a01f76fc2a4..19e05111877d 100644 --- a/test/python/primitives/test_sampler.py +++ b/test/python/primitives/test_sampler.py @@ -572,22 +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]]) - with self.assertRaises(QiskitError): - sampler.run([qc2], [[]]) - with self.assertRaises(QiskitError): - sampler.run([qc2], [[1e2]]) - with self.assertRaises(QiskitError): - result = sampler.run([qc3], [[]]) + 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""" From cc4aea8a58e568d311efce32eb48c31beacd9070 Mon Sep 17 00:00:00 2001 From: Takashi Imamichi <31178928+t-imamichi@users.noreply.github.com> Date: Mon, 5 Sep 2022 16:43:23 +0900 Subject: [PATCH 3/5] Update qiskit/primitives/base_sampler.py Co-authored-by: Julien Gacon --- qiskit/primitives/base_sampler.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qiskit/primitives/base_sampler.py b/qiskit/primitives/base_sampler.py index ffc9962e9551..297e4d028d0d 100644 --- a/qiskit/primitives/base_sampler.py +++ b/qiskit/primitives/base_sampler.py @@ -364,7 +364,8 @@ def run( if circuit.num_clbits == 0: raise QiskitError( f"The {i}-th circuit does not have any classical bit. " - "Sampler requires classical bits." + "Sampler requires classical bits, plus measurements " + "on the desired qubits." ) mapping = final_measurement_mapping(circuit) From f1181110e20fc59c97134895a8d7f0e178af141e Mon Sep 17 00:00:00 2001 From: Takashi Imamichi Date: Mon, 5 Sep 2022 18:01:51 +0900 Subject: [PATCH 4/5] remove a duplicate check --- qiskit/primitives/sampler.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/qiskit/primitives/sampler.py b/qiskit/primitives/sampler.py index f9c1c2910ecb..e516cabd568e 100644 --- a/qiskit/primitives/sampler.py +++ b/qiskit/primitives/sampler.py @@ -156,12 +156,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 = cast(QuantumCircuit, circuit.remove_final_measurements(inplace=False)) From 7ee370aa04be924ffabcde481b4e57a305c31f71 Mon Sep 17 00:00:00 2001 From: Takashi Imamichi Date: Mon, 5 Sep 2022 18:06:06 +0900 Subject: [PATCH 5/5] update an error messgage --- qiskit/primitives/base_sampler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/primitives/base_sampler.py b/qiskit/primitives/base_sampler.py index 297e4d028d0d..ceda7eaf64c8 100644 --- a/qiskit/primitives/base_sampler.py +++ b/qiskit/primitives/base_sampler.py @@ -371,7 +371,7 @@ def run( mapping = final_measurement_mapping(circuit) if set(range(circuit.num_clbits)) != set(mapping.values()): raise QiskitError( - "Some classical bits are not used for measurements." + 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())})." )