From ffbf31a6cd71d1720e860645f07097240a6b1fc2 Mon Sep 17 00:00:00 2001 From: Callum Macpherson <93673602+CalMacCQ@users.noreply.github.com> Date: Fri, 8 Nov 2024 10:58:13 +0000 Subject: [PATCH] fix: Warn user about implicit qubit permutations in `tk_to_qiskit` (#412) * fix: warn user if Circuit contains IQP * add test * add changelog entry * remove unused import * organise imports for ruff * fix a typo * improve `_has_implicit_permutation` function Co-authored-by: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> * fix typo --------- Co-authored-by: Alec Edgington <54802828+cqc-alec@users.noreply.github.com> --- docs/changelog.md | 1 + pytket/extensions/qiskit/qiskit_convert.py | 14 ++++++++++++++ tests/qiskit_convert_test.py | 7 +++++++ 3 files changed, 22 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 0e06e304..3ea66662 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -7,6 +7,7 @@ ## Unreleased - Fix handling of non-default registers when selecting bits in results. +- The {py:func}`tk_to_qiskit` converter gives a warning if the input {py:class}`~pytket.circuit.Circuit` contains [implicit qubit permutations](https://docs.quantinuum.com/tket/user-guide/manual/manual_circuit.html#implicit-qubit-permutations). ## 0.58.0 (October 2024) diff --git a/pytket/extensions/qiskit/qiskit_convert.py b/pytket/extensions/qiskit/qiskit_convert.py index 49dcb584..51924e17 100644 --- a/pytket/extensions/qiskit/qiskit_convert.py +++ b/pytket/extensions/qiskit/qiskit_convert.py @@ -15,6 +15,7 @@ """Methods to allow conversion between Qiskit and pytket circuit classes """ +import warnings from collections import defaultdict from collections.abc import Iterable from inspect import signature @@ -855,6 +856,10 @@ def append_tk_command_to_qiskit( supported_gate_rebase = AutoRebase(_protected_tket_gates) +def _has_implicit_permutation(circ: Circuit) -> bool: + return any(q0 != q1 for q0, q1 in circ.implicit_qubit_permutation().items()) + + def tk_to_qiskit( tkcirc: Circuit, replace_implicit_swaps: bool = False ) -> QuantumCircuit: @@ -873,6 +878,15 @@ def tk_to_qiskit( tkc = tkcirc.copy() # Make a local copy of tkcirc if replace_implicit_swaps: tkc.replace_implicit_wire_swaps() + + if _has_implicit_permutation(tkcirc) and not replace_implicit_swaps: + warnings.warn( + "The pytket Circuit contains implicit qubit permutations" + + " which aren't handled by default." + + " Consider using the replace_implicit_swaps flag in tk_to_qiskit or" + + " replacing them using Circuit.replace_implicit_swaps()." + ) + qcirc = QuantumCircuit(name=tkc.name) qreg_sizes: dict[str, int] = {} for qb in tkc.qubits: diff --git a/tests/qiskit_convert_test.py b/tests/qiskit_convert_test.py index cdde50d3..631f8ee0 100644 --- a/tests/qiskit_convert_test.py +++ b/tests/qiskit_convert_test.py @@ -1172,3 +1172,10 @@ def test_nonregister_bits() -> None: c.rename_units({Bit(0): Bit(1)}) with pytest.raises(NotImplementedError): tk_to_qiskit(c) + + +def test_implicit_swap_warning() -> None: + c = Circuit(2).H(0).SWAP(0, 1) + c.replace_SWAPs() + with pytest.warns(UserWarning, match="The pytket Circuit contains implicit qubit"): + tk_to_qiskit(c)