Skip to content

Fix LogicalCircuit-pytket/Quantinuum compatibility (RESOLVED - REQUIRES PEER REVIEW)#19

Open
conorfitzmaurice wants to merge 5 commits into
GT-Quantum-Computing-Association:compat-qtmfrom
conorfitzmaurice:compat-qtm
Open

Fix LogicalCircuit-pytket/Quantinuum compatibility (RESOLVED - REQUIRES PEER REVIEW)#19
conorfitzmaurice wants to merge 5 commits into
GT-Quantum-Computing-Association:compat-qtmfrom
conorfitzmaurice:compat-qtm

Conversation

@conorfitzmaurice
Copy link
Copy Markdown

@conorfitzmaurice conorfitzmaurice commented Feb 1, 2026

  • Added LogicalQ/Converters/pytket_compat.py with monkey-patch for Binary/Unary conditions
  • Added correct transpilation pipeline (UnBox -> DecomposeIfElseOps -> FlattenIfElseOps -> Decompose)
  • Updated Execution.py to use to_pytket() for QuantinuumBackend
  • Verified 1.0 fidelity, 80% scratch-bit reduction, works on AerSimulator as far as I know (still needs to be tested on Quantinuum emulator*)
    (AerSimulator verifies that it replicates the results in LogicalCircuit_Demo.ipynb)
    *(Do so by linking your pytket session 1. through cloud (more robust for later testing) with QIR or OpenQASM 2.0 using the respective API, or 2. locally (preferred for fast testing) with pytket built-in packages using pip install pytket-quantinuum)
    Update 2/02: Works on Quantinuum local conversions.

The existing Execution.py in compat-qtm had a broken _transpile function for QuantinuumBackend.

def _transpile(circuits, backend=None, coupling_map=None, optimization_level=0, **kwargs):
    pm = PassManager([DecomposeIfElseOpsTask(), Decompose()])
    circuits_decomposed = pm.run(circuits)
    tket_circuits_decomposed = [qiskit_to_tk(circuit_decomposed) for circuit_decomposed in circuits_decomposed]
    return backend.get_compiled_circuits(tket_circuits_decomposed, optimisation_level=optimization_level, **kwargs)

This produces errors like:

RuntimeError: Conditions can only be single bits or whole registers
RuntimeError: Nested conditional not supported

This demo fixes it by:

  1. Adding pytket_compat.py - provides monkey-patch and correct transpilation
  2. Modifying Execution.py - uses the new module for future Quantinuum conversion

Problem 1: Missing UnBoxTask():

  • LogicalQ code wraps operations in "box" gates. These must be unboxed before conversion, but the previous code doesn't include UnBoxTask().

Problem 2: Missing FlattenIfElseOpsTask():

  • QEC cycles create nested IfElseOp blocks (conditionals inside conditionals). The FlattenIfElseOps pass exists in the codebase but wasn't being used. Without, pytket throws "Nested conditional not supported".

Problem 3: qiskit_to_tk() can't handle Binary/Unary expressions:

  • After FlattenIfElseOps runs, it creates boolean expressions like:
    expr.Binary(expr.Binary.Op.BIT_AND, condition1, condition2, types.Bool())
    The pytket-qiskit converter doesn't recognize these expression types. It only handles simple (Clbit, value) tuples. This is a known limitation. As Rasmit explained, pytket qiskit_to_tk doesn't allow binary conditions - he has a patched pytket at https://github.com/RasmitDevkota/pytket/tree/main.

Problem 4: Missing DecomposeClassicalExp() for Quantinuum:

  • Even after successful conversion, Quantinuum backends require classical expressions to be decomposed into primitive operations.

Also, fidelity verification compares statevectors before and after conversion to prove correctness (you can run this yourself). During development, this required a workaround: pytket sorts quantum registers alphabetically during conversion, while qiskit preserves insertion order. This caused statevector indices to be permuted, giving false fidelity of 1/256 instead of 1.0. The fix tracks original qubit ordering and applies inverse permutation before comparison.
Lastly, previous QEC decoding generated complex boolean expressions that require many scratch bits. The fix includes a boolean algebra simplifier that reduces scratch-bit usage by 80% (10 -> 2 bits in typical cases) using rules like x & x -> x, x | 0 -> x, ~~x -> x.
Please someone test this on Quantinuum hardware (especially if you have credentials), thanks.

This pull request must be satisfied before merging #3.

@conorfitzmaurice conorfitzmaurice changed the title Fix pytket/Quantinuum compatibility Fix LogicalQ-pytket/Quantinuum compatibility Feb 1, 2026
@conorfitzmaurice conorfitzmaurice changed the title Fix LogicalQ-pytket/Quantinuum compatibility Fix LogicalCircuit-pytket/Quantinuum compatibility Feb 1, 2026
@conorfitzmaurice
Copy link
Copy Markdown
Author

Demo works on Quantinuum H1-1LE (someone please verify this).

@conorfitzmaurice conorfitzmaurice changed the title Fix LogicalCircuit-pytket/Quantinuum compatibility Fix LogicalCircuit-pytket/Quantinuum compatibility (RESOLVED - REQUIRES PEER REVIEW) Feb 3, 2026
@conorfitzmaurice conorfitzmaurice marked this pull request as draft February 3, 2026 03:46
@conorfitzmaurice conorfitzmaurice marked this pull request as ready for review February 3, 2026 03:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant