Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SetLayout to error with invalid int list input #11653

Merged
merged 3 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions qiskit/transpiler/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,7 @@
.. autoexception:: CouplingError
.. autoexception:: LayoutError
.. autoexception:: CircuitTooWideForTarget
.. autoexception:: InvalidLayoutError

"""

Expand All @@ -1266,6 +1267,7 @@
CouplingError,
LayoutError,
CircuitTooWideForTarget,
InvalidLayoutError,
)
from .basepasses import AnalysisPass, TransformationPass
from .coupling import CouplingMap
Expand Down
4 changes: 4 additions & 0 deletions qiskit/transpiler/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,7 @@ def __str__(self):

class CircuitTooWideForTarget(TranspilerError):
"""Error raised if the circuit is too wide for the target."""


class InvalidLayoutError(TranspilerError):
"""Error raised when a user provided layout is invalid."""
11 changes: 8 additions & 3 deletions qiskit/transpiler/passes/layout/set_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
# that they have been altered from the originals.

"""Set the ``layout`` property to the given layout."""
from qiskit.transpiler import Layout, TranspilerError
from qiskit.transpiler import Layout
from qiskit.transpiler.exceptions import InvalidLayoutError
from qiskit.transpiler.basepasses import AnalysisPass


Expand Down Expand Up @@ -47,17 +48,21 @@ def run(self, dag):
"""
if isinstance(self.layout, list):
if len(self.layout) != len(dag.qubits):
raise TranspilerError(
raise InvalidLayoutError(
"The length of the layout is different than the size of the "
f"circuit: {len(self.layout)} <> {len(dag.qubits)}"
)
if len(set(self.layout)) != len(self.layout):
raise InvalidLayoutError(
f"The provided layout {self.layout} contains duplicate qubits"
)
layout = Layout({phys: dag.qubits[i] for i, phys in enumerate(self.layout)})
elif isinstance(self.layout, Layout):
layout = self.layout.copy()
elif self.layout is None:
layout = None
else:
raise TranspilerError(
raise InvalidLayoutError(
f"SetLayout was intialized with the layout type: {type(self.layout)}"
)
self.property_set["layout"] = layout
Expand Down
13 changes: 13 additions & 0 deletions releasenotes/notes/add-invalid-layout-error-d0d64086748d4b54.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
features:
- |
Added a new exception class :class:`.InvalidLayoutError` that is a :class:`.TranspilerError`
subclass which is raised when a user provided layout is invalid (mismatched size, duplicate
qubits, etc).
fixes:
- |
Fixed an issue with the :class:`.SetLayout` transpiler pass where an invalid integer list input
that contained duplicate entries which would result in an invalid :class:`.Layout` being
generated and subsequent transpiler passes would fail with a cryptic error. This is now caught
when :meth:`.SetLayout.run` is called an :class:`.InvalidLayoutError` error will be raised
indicating there are duplicate entries in the integer list.
7 changes: 7 additions & 0 deletions test/python/transpiler/test_setlayout.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ def test_raise_when_layout_len_does_not_match(self):
with self.assertRaises(TranspilerError):
pass_manager.run(circuit)

def test_raise_if_int_list_layout_contains_duplicates(self):
"""Test the error is raised if the specified intlist contains duplicates"""
circuit = QuantumCircuit(4)
layout_pass = SetLayout([0, 1, 1, 2])
with self.assertRaises(TranspilerError):
layout_pass(circuit)


if __name__ == "__main__":
unittest.main()
Loading