From d68076b8d4b9f49c08e1202b8a2f3acb1299308a Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Tue, 14 Nov 2023 17:06:03 -0500 Subject: [PATCH] Add new transpiler exception class for too many qubits (#11241) * Add new transpiler exception class for too many qubits This commit adds a new exception class for when the transpiler is given a circuit too many qubits for a given backend. Previously the generic TranspilerError was raised for this, but it made it difficult for downstream users to catch as it wasn't easy to differentiate this error condition from other TranspilerError exceptions. There isn't any backwards compatibility issues with this because the new CircuitToWideForTarget class is a subclass of TranspilerError so any of the previous catches for TranspilerError will still catch this. * Fix typo in class name * Make test check more specific exception type * Replace :class: with :exc: in release note --- qiskit/compiler/transpiler.py | 4 ++-- qiskit/transpiler/__init__.py | 10 +++++++++- qiskit/transpiler/exceptions.py | 4 ++++ .../notes/new-exception-too-wide-3231c1df15952445.yaml | 9 +++++++++ test/python/compiler/test_transpiler.py | 4 ++-- 5 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/new-exception-too-wide-3231c1df15952445.yaml diff --git a/qiskit/compiler/transpiler.py b/qiskit/compiler/transpiler.py index 22dfd35be3c2..a2b3971b5944 100644 --- a/qiskit/compiler/transpiler.py +++ b/qiskit/compiler/transpiler.py @@ -28,7 +28,7 @@ from qiskit.pulse import Schedule, InstructionScheduleMap from qiskit.transpiler import Layout, CouplingMap, PropertySet from qiskit.transpiler.basepasses import BasePass -from qiskit.transpiler.exceptions import TranspilerError +from qiskit.transpiler.exceptions import TranspilerError, CircuitTooWideForTarget from qiskit.transpiler.instruction_durations import InstructionDurations, InstructionDurationsType from qiskit.transpiler.passes.synthesis.high_level_synthesis import HLSConfig from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager @@ -455,7 +455,7 @@ def _check_circuits_coupling_map(circuits, cmap, backend): # If coupling_map is not None or num_qubits == 1 num_qubits = len(circuit.qubits) if max_qubits is not None and (num_qubits > max_qubits): - raise TranspilerError( + raise CircuitTooWideForTarget( f"Number of qubits ({num_qubits}) in {circuit.name} " f"is greater than maximum ({max_qubits}) in the coupling_map" ) diff --git a/qiskit/transpiler/__init__.py b/qiskit/transpiler/__init__.py index 9abab3aa56a2..13ae12e09097 100644 --- a/qiskit/transpiler/__init__.py +++ b/qiskit/transpiler/__init__.py @@ -1251,6 +1251,8 @@ .. autoexception:: TranspilerAccessError .. autoexception:: CouplingError .. autoexception:: LayoutError +.. autoexception:: CircuitTooWideForTarget + """ # For backward compatibility @@ -1263,7 +1265,13 @@ from .passmanager import PassManager, StagedPassManager from .passmanager_config import PassManagerConfig from .propertyset import PropertySet # pylint: disable=no-name-in-module -from .exceptions import TranspilerError, TranspilerAccessError, CouplingError, LayoutError +from .exceptions import ( + TranspilerError, + TranspilerAccessError, + CouplingError, + LayoutError, + CircuitTooWideForTarget, +) from .fencedobjs import FencedDAGCircuit, FencedPropertySet from .basepasses import AnalysisPass, TransformationPass from .coupling import CouplingMap diff --git a/qiskit/transpiler/exceptions.py b/qiskit/transpiler/exceptions.py index ef79603bfed2..5c23cb2b3914 100644 --- a/qiskit/transpiler/exceptions.py +++ b/qiskit/transpiler/exceptions.py @@ -49,3 +49,7 @@ def __init__(self, *msg): def __str__(self): """Return the message.""" return repr(self.msg) + + +class CircuitTooWideForTarget(TranspilerError): + """Error raised if the circuit is too wide for the target.""" diff --git a/releasenotes/notes/new-exception-too-wide-3231c1df15952445.yaml b/releasenotes/notes/new-exception-too-wide-3231c1df15952445.yaml new file mode 100644 index 000000000000..d3bfa72c071e --- /dev/null +++ b/releasenotes/notes/new-exception-too-wide-3231c1df15952445.yaml @@ -0,0 +1,9 @@ +--- +features: + - | + Added a new exception class :exc:`.CircuitToWideForTarget` which + subclasses :exc:`.TranspilerError`. It's used in places where a + :exc:`.TranspilerError` was previously raised when the error was that + the number of circuit qubits was larger than the target backend's qubits. + The new class enables more differentiating between this error condition and + other :exc:`.TranspilerError`\s. diff --git a/test/python/compiler/test_transpiler.py b/test/python/compiler/test_transpiler.py index 9a54bdc7da0b..98db50a28b08 100644 --- a/test/python/compiler/test_transpiler.py +++ b/test/python/compiler/test_transpiler.py @@ -87,7 +87,7 @@ from qiskit.test import QiskitTestCase, slow_test from qiskit.tools import parallel from qiskit.transpiler import CouplingMap, Layout, PassManager, TransformationPass -from qiskit.transpiler.exceptions import TranspilerError +from qiskit.transpiler.exceptions import TranspilerError, CircuitTooWideForTarget from qiskit.transpiler.passes import BarrierBeforeFinalMeasurements, GateDirection, VF2PostLayout from qiskit.transpiler.passmanager_config import PassManagerConfig from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager, level_0_pass_manager @@ -987,7 +987,7 @@ def test_check_circuit_width(self): qc = QuantumCircuit(15, 15) - with self.assertRaises(TranspilerError): + with self.assertRaises(CircuitTooWideForTarget): transpile(qc, coupling_map=cmap) @data(0, 1, 2, 3)