Skip to content

✨ Add native RCCX (relative-phase Toffoli) gate support#1886

Open
simon1hofmann wants to merge 61 commits into
mainfrom
feat/qco-rccx-op
Open

✨ Add native RCCX (relative-phase Toffoli) gate support#1886
simon1hofmann wants to merge 61 commits into
mainfrom
feat/qco-rccx-op

Conversation

@simon1hofmann

@simon1hofmann simon1hofmann commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Description

Adds native RCCX (relative-phase Toffoli) support across MQT Core.

Gate convention (Qiskit / OpenQASM): rccx(q0, q1, q2)q0 and q1 are the inner controls, q2 is the target. Controlled variants follow the usual pattern: crccx(c, q0, q1, q2) and mcrccx({c…}, q0, q1, q2).

RCCX is self-inverse and differs from CCX by relative phases on the computational basis.

IR & Python

  • New OpType::RCCX with rccx / crccx / mcrccx on QuantumComputation
  • Python bindings and regenerated stubs
  • StandardOperation::invert() treats RCCX as self-inverse
  • OpenQASM 3 import/export and I/O round-trip tests

MLIR (QC / QCO / QIR)

  • RCCXOp in QC, QCO, and QIR dialects with closed-form 8×8 unitary
  • Program builders: rccx, crccx, mcrccx
  • Translation and conversion coverage (QC ↔ QCO ↔ QIR ↔ Jeff)
  • QASM3 and QuantumComputation translation tests
  • Compiler pipeline and round-trip tests
  • Measurement fixtures added to RCCX program tests (aligned with DCX and similar gates)

Decision diagrams (DD)

  • getRccxDD builds the gate via canonical elementary decomposition
  • Outer controls merged for crccx / mcrccx; single-qubit steps on the target only
  • RCCX listed as self-inverse in DD inverse handling
  • Package and functionality tests

ZX functionality construction

  • addRccx — bare RCCX via addZSpider / addCnot
  • addCrccx — single outer control via addCphase, addMcphase, addMcx
  • addMcrccx — multi-control via addMcrz / addMcrx / addMcz / addMcphase / addMcx (delegates to addCrccx for one control)
  • parseOp dispatches by control count, consistent with other gates

Canonical decomposition (matches decompose-multi-controlled-gates / emitRCCXSequence):
H(t) → T(t) → CX(c1,t) → Tdg(t) → CX(c0,t) → T(t) → CX(c1,t) → Tdg(t) → H(t)

Qiskit plugin & QDMI

  • Qiskit ↔ MQT conversion for rccx / crccx / mcrccx
  • Backend and mock-backend tests
  • RCCX listed in QDMI DDSIM device gate set

AI Assistance

Used Composer 2.5 via Cursor for parts of this change. I reviewed the full
diff and take responsibility for everything in this PR.

Checklist

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes, or removals.
  • I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

If PR contains AI-assisted content:

  • I have disclosed the use of AI tools in the PR description as per our AI Usage Guidelines.
  • AI-assisted commits include an Assisted-by: [Model Name] via [Tool Name] footer.
  • I confirm that I have personally reviewed and understood all AI-generated content, and accept full responsibility for it.

Comment thread include/mqt-core/ir/operations/OpType.inc
Comment thread include/mqt-core/qasm3/StdGates.hpp
@simon1hofmann

Copy link
Copy Markdown
Contributor Author

What is still missing and up to debate:

  • DD package simulation (getRccxDD)
  • ZX functionality construction
  • QDMI DDSIM backend listing
  • StandardOperation::invert() for RCCX

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/mqt/core/plugins/qiskit/qiskit_to_mqt.py`:
- Around line 321-324: Update the rccx handling in the conversion function to
pass the already computed qubits list to StandardOperation instead of
recomputing the qubit_map comprehension. Preserve the existing OpType.rccx
operation and return behavior.

In `@test/ir/test_io.cpp`:
- Around line 80-86: Add the direct <string_view> standard header include to
test_io.cpp for the std::string_view parameters in expectRccxExport, removing
reliance on transitive includes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6b41173f-e440-43b8-88a9-0da83fe59c08

📥 Commits

Reviewing files that changed from the base of the PR and between f2b6a38 and c44cfad.

📒 Files selected for processing (25)
  • docs/qdmi/qdmi_backend.md
  • include/mqt-core/ir/QuantumComputation.hpp
  • include/mqt-core/ir/operations/OpType.hpp
  • include/mqt-core/ir/operations/StandardOperation.hpp
  • include/mqt-core/qasm3/StdGates.hpp
  • include/mqt-core/zx/FunctionalityConstruction.hpp
  • mlir/include/mlir/Dialect/QCO/IR/QCOOps.td
  • mlir/include/mlir/Dialect/QCO/QCOUtils.h
  • mlir/lib/Conversion/JeffToQCO/JeffToQCO.cpp
  • mlir/lib/Conversion/QCOToJeff/QCOToJeff.cpp
  • mlir/lib/Dialect/QCO/IR/Operations/StandardGates/RCCXOp.cpp
  • mlir/lib/Dialect/QIR/Builder/QIRProgramBuilder.cpp
  • mlir/unittests/Compiler/test_compiler_pipeline.cpp
  • mlir/unittests/Conversion/JeffRoundTrip/test_jeff_round_trip.cpp
  • mlir/unittests/Dialect/QCO/IR/test_qco_ir.cpp
  • mlir/unittests/programs/qco_programs.cpp
  • mlir/unittests/programs/qco_programs.h
  • python/mqt/core/ir/__init__.pyi
  • python/mqt/core/ir/operations.pyi
  • python/mqt/core/plugins/qiskit/mqt_to_qiskit.py
  • python/mqt/core/plugins/qiskit/qiskit_to_mqt.py
  • src/ir/operations/StandardOperation.cpp
  • src/qdmi/devices/dd/Device.cpp
  • test/ir/test_io.cpp
  • test/python/plugins/test_qiskit.py

Comment thread python/mqt/core/plugins/qiskit/qiskit_to_mqt.py
Comment thread test/ir/test_io.cpp
@simon1hofmann

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@simon1hofmann
simon1hofmann marked this pull request as ready for review July 15, 2026 17:16
@simon1hofmann
simon1hofmann requested a review from denialhaag July 15, 2026 17:17
@simon1hofmann

Copy link
Copy Markdown
Contributor Author

Did not anticipate that many changes to add another gate, @denialhaag would it be possible to get a review?

@burgholzer

Copy link
Copy Markdown
Member

Did not anticipate that many changes to add another gate

Hahah. Yeah, it's quite wild how far reaching adding a single native gate is 😅

@denialhaag denialhaag left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for going through all of this, @simon1hofmann! 🙂

This already looks good to me. I just have some minor nitpicks, which you can find below. Don't be surprised by the number of comments; 16 of them are the same comment.

Comment thread mlir/lib/Conversion/JeffToQCO/JeffToQCO.cpp Outdated
Comment thread mlir/lib/Conversion/QCOToJeff/QCOToJeff.cpp Outdated
Comment thread mlir/lib/Dialect/QC/Builder/QCProgramBuilder.cpp Outdated
Comment thread mlir/lib/Dialect/QC/Translation/TranslateQuantumComputationToQC.cpp Outdated
Comment thread mlir/lib/Dialect/QIR/Builder/QIRProgramBuilder.cpp Outdated
Comment thread mlir/unittests/Dialect/QIR/IR/test_qir_ir.cpp Outdated
Comment thread src/ir/QuantumComputation.cpp Outdated
Comment thread src/qasm3/Parser.cpp
Comment thread src/zx/FunctionalityConstruction.cpp Outdated
Comment thread src/zx/FunctionalityConstruction.cpp
@simon1hofmann

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@denialhaag denialhaag left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing my comments! This LGTM now! 🙂

We should also add a changelog entry for the non-MLIR changes. I'm also wondering if we want to backport this. If we do so, I would not update MQTOpt and MQTRef, though. 🤔

I'll leave the final say to @burgholzer! 😌

@denialhaag
denialhaag requested a review from burgholzer July 16, 2026 11:48
@simon1hofmann

simon1hofmann commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for addressing my comments! This LGTM now! 🙂

We should also add a changelog entry for the non-MLIR changes. I'm also wondering if we want to backport this. If we do so, I would not update MQTOpt and MQTRef, though. 🤔

I'll leave the final say to @burgholzer! 😌

Thanks a lot for the review @denialhaag 🙏
I pushed two more commits to further simplify and align the code (handling R3CX as a controlled RCCX was not correct).

@denialhaag

Copy link
Copy Markdown
Member

I pushed two more commits to further simplify and align the code (handling R3CX as a controlled RCCX was not correct).

Ahh, good catch! The commits look good to me! 👍

@mergify mergify Bot added the conflict label Jul 16, 2026
simon1hofmann and others added 2 commits July 16, 2026 14:24
Signed-off-by: simon1hofmann <119581649+simon1hofmann@users.noreply.github.com>
Comment thread CHANGELOG.md
@mergify mergify Bot removed the conflict label Jul 16, 2026
@mergify mergify Bot added the conflict label Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Anything related to C++ code conflict Core Anything related to the Core library and IR DD Anything related to the DD package enhancement Improvement of existing feature MLIR Anything related to MLIR QDMI Anything related to QDMI QIR Anything related to QIR ZX Anything related to the ZX package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants