Skip to content

Assertion failure and hang in compiler #2179

Description

@IlanIwumbwe

When running the circuit below, a certain combination of operations make it such that there's an assertion failure in the C++ core, while another leads to a hang in the C++ core. (I think this is the case because I cannot kill the process with Ctrl-C)

Run the circuit below

import math

from pytket import Bit, Circuit, Qubit
from pytket.architecture import Architecture
from pytket.circuit import CircBox, if_bit, if_not_bit
from pytket.extensions.qiskit.backends.aer import AerBackend
from pytket.passes import DecomposeBoxes, DecomposeMultiQubitsCX, DefaultMappingPass

sub_0 = Circuit()
sing_28 = Qubit("sing_28", 0)
sub_0.add_qubit(sing_28)
sing_41 = Qubit("sing_41", 0)
sub_0.add_qubit(sing_41)
reg_54 = sub_0.add_q_register("reg_54", 2)
reg_69 = sub_0.add_c_register("reg_69", 2)
sing_83 = Bit("sing_83", 0)
sub_0.add_bit(sing_83)
sing_96 = Bit("sing_96", 0)
sub_0.add_bit(sing_96)

sub_0.CRx(math.pi, reg_54[0], sing_41, condition=if_bit(reg_69[0]))
sub_0.add_clexpr_from_logicexp(sing_96 | sing_83, [reg_69[1]])
sub_0.H(reg_54[1], condition=if_not_bit(reg_69[1]))

sub_0 = CircBox(sub_0)

sub_1 = Circuit()
sing_907 = Qubit("sing_907", 0)
sub_1.add_qubit(sing_907)
sing_920 = Qubit("sing_920", 0)
sub_1.add_qubit(sing_920)
sing_933 = Qubit("sing_933", 0)
sub_1.add_qubit(sing_933)
reg_946 = sub_1.add_q_register("reg_946", 1)
reg_959 = sub_1.add_c_register("reg_959", 2)
sing_973 = Bit("sing_973", 0)
sub_1.add_bit(sing_973)
sing_986 = Bit("sing_986", 0)
sub_1.add_bit(sing_986)

sub_1.add_gate(
    sub_0,
    [sing_933, sing_920, sing_907, reg_946[0], reg_959[1], sing_973, sing_986, reg_959[0]],
    condition=if_not_bit(reg_959[0]),
)

sub_1 = CircBox(sub_1)

sub_2 = Circuit()
sing_1965 = Qubit("sing_1965", 0)
sub_2.add_qubit(sing_1965)
reg_1978 = sub_2.add_q_register("reg_1978", 3)
sing_1994 = Qubit("sing_1994", 0)
sub_2.add_qubit(sing_1994)
reg_2008 = sub_2.add_c_register("reg_2008", 3)
reg_2024 = sub_2.add_c_register("reg_2024", 1)
sing_2036 = Bit("sing_2036", 0)
sub_2.add_bit(sing_2036)

sub_2.add_gate(
    sub_1,
    [
        reg_1978[0],
        reg_1978[2],
        sing_1965,
        reg_1978[1],
        reg_2008[0],
        reg_2024[0],
        reg_2008[1],
        reg_2008[2],
    ],
    condition=if_not_bit(reg_2008[1]),
)
sub_2.measure_all()


def _make_line_topology(n_qubits: int):
    return [(i, i + 1) for i in range(n_qubits)]


def _route_circuit(circuit: Circuit) -> None:
    arch = Architecture(_make_line_topology(circuit.n_qubits))

    DecomposeMultiQubitsCX().apply(circuit)
    # DelayMeasures(allow_partial=True).apply(circuit)

    DefaultMappingPass(arch).apply(circuit)


circuit_copy = sub_2.copy()

# routing block
DecomposeBoxes().apply(circuit_copy)
_route_circuit(circuit_copy)
##########

backend = AerBackend()
circ_prime = backend.get_compiled_circuit(circuit_copy, optimisation_level=2)

That results in

[2026-05-23 14:20:45] [tket] [critical] Assertion '!"slice is empty"' (/root/.conan2/p/b/tket6d8167ff01a9a/b/src/Circuit/macro_circ_info.cpp : operator++ : 622) failed.  Aborting.
Aborted (core dumped)

whether or not the routing block is present.

  • Commenting out the H gate in sub_0 and removing the routing block makes the test case pass. But leaving the routing block makes it such that the process can no longer be killed. I guess this is because there's some infinite loop going on in the C++ core so it doesn't give control back to the python frontend.

  • Commenting out the CrX gate in sub_0 makes the test case pass whether or not the routing block is removed.

Info

tket version: 0.12.16
OS: Ubuntu 24.04
Python version: 3.12.3

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions