Skip to content

✨ Add MQT Core compilation and QIR export - #1027

Draft
simon1hofmann wants to merge 4 commits into
mainfrom
feat/mqt-core-compiler
Draft

✨ Add MQT Core compilation and QIR export#1027
simon1hofmann wants to merge 4 commits into
mainfrom
feat/mqt-core-compiler

Conversation

@simon1hofmann

@simon1hofmann simon1hofmann commented Sep 12, 2026

Copy link
Copy Markdown
Collaborator

🤖 AI text below 🤖

Description

MQT Bench currently sends all compilation requests through Qiskit. This adds an optional MQT Core compiler selected with compiler="mqt" in Python or --compiler mqt in the CLI. Qiskit remains the default compiler, and both paths return QuantumCircuit objects.

The change adds Core compilation at the independent, native-gate, and mapped levels, QIR export as LLVM text or bitcode, compiler provenance in exports, mirror support, an optional dependency extra, and a dedicated CI test session. The CLI also defaults to optimization level 2 when that option is omitted.

Usage

From a checkout of this PR:

python -m pip install -e ".[mqt]"
from mqt.bench import BenchmarkLevel, get_benchmark
from mqt.bench.targets import get_device, get_target_for_gateset

independent = get_benchmark(
    "ghz", BenchmarkLevel.INDEP, 3, compiler="mqt"
)

native = get_benchmark(
    "ghz",
    BenchmarkLevel.NATIVEGATES,
    3,
    target=get_target_for_gateset("ibm_falcon", 3),
    compiler="mqt",
)

mapped = get_benchmark(
    "ghz",
    BenchmarkLevel.MAPPED,
    3,
    target=get_device("iqm_crystal_5"),
    compiler="mqt",
    generate_mirror_circuit=True,
)

The level-specific functions get_benchmark_indep, get_benchmark_native_gates, and get_benchmark_mapped accept the same compiler option. The algorithm level does not compile.

mqt-bench --compiler mqt --algorithm ghz --num-qubits 3 \
  --level mapped --target iqm_crystal_5 --save

The Core CLI filename contains _mqt_ and omits Qiskit's optimization level. QASM headers and QPY metadata record the compiler version. Qiskit recompilation updates an existing compiler record.

Level Core behavior
INDEP Decompose multi-controlled operations and run the default target-independent optimization pipeline.
NATIVEGATES Compile to the target gate set using all-to-all connectivity and the input circuit width; ignore physical gate placements.
MAPPED Compile to the device width, connectivity, and ordered native-gate placements.

QIR and LLVM output

The same mqt extra enables QIR export for circuits generated with either compiler. QIR uses LLVM IR; the output choices are:

Output format Encoding CLI behavior
qir or llvm LLVM text (.ll) Print to stdout, or write a file with --save.
qir-bitcode LLVM bitcode (.bc) Always write a file and print its path.
mqt-bench --compiler mqt --algorithm ghz --num-qubits 3 \
  --level indep --output-format qir

mqt-bench --compiler mqt --algorithm ghz_dynamic --num-qubits 3 \
  --level indep --output-format qir-bitcode --qir-profile adaptive
from pathlib import Path
from mqt.bench.output import OutputFormat, write_circuit

write_circuit(independent, Path("ghz.ll"), BenchmarkLevel.INDEP, OutputFormat.QIR)
write_circuit(
    independent, Path("ghz.bc"), BenchmarkLevel.INDEP, OutputFormat.QIR_BITCODE,
    qir_profile="base",
)

save_circuit also accepts qir_profile. The default is base; use adaptive for measurement feedback and supported classical control flow. LLVM text records the Bench header and Core exporter version using ; comments. Bitcode contains Core's QIR metadata without the Bench header.

Current limitations

  • Dependencies: The extra requires MQT Core >=4,<5 and Qiskit >=2.5,<2.6. Circuit generation and the public circuit representation still use Qiskit. Import preparation converts permutation gates to swaps with Qiskit's permutation utility and expands existing composite controlled-gate definitions before Core compilation.
  • Targets: The adapter supports the bundled IBM Falcon/Eagle/Heron, IQM, Quantinuum, and Clifford+T+rotations gate sets. IonQ and Rigetti custom native gates are unsupported. Core does not provide Qiskit's approximate Clifford+T synthesis. Fixed or restricted gate parameters and unsupported instructions or synthesis requests produce errors; there is no fallback to Qiskit transpilation.
  • Optimization settings: Leave opt_level at its default of 2. Core uses its own fixed pipeline; this is not an equivalence to Qiskit optimization level 2. Values 0, 1, and 3 are rejected for Core compilation.
  • Layout metadata: Mapped results use physical circuit wires and preserve classical measurement destinations. Core does not emit Qiskit TranspileLayout metadata.
  • Control flow and mirrors: Dynamic circuits and structured loops are limited to Core's supported translation and target capabilities; loops may be unrolled to satisfy the target. Mirrors require an invertible circuit after final measurements are removed. The compiled circuit is mirrored across a barrier and, when a target is supplied, compiled again with Core.
  • QIR export: All circuit parameters must be bound. Unsupported profiles or lowering requests raise an export error; failed lowering leaves an existing destination file intact. Export lowers the supplied circuit without another optimization or mapping pipeline, but QIR lowering may decompose gates and assign QIR resource identifiers. The output is not guaranteed to preserve a device-native gate set or physical qubit numbering. Execution requires a runtime that supports the emitted QIS calls, QIR version, and profile capabilities; LLVM text/bitcode is not a standalone executable.
  • Reproducibility: Mapping uses Core's default seed and a CPU-dependent number of layout trials. Mapped results can differ across machines.

Validation

Tested locally with Python 3.13, MQT Core 4.0.0, and Qiskit 2.5.2 on macOS:

  • Full suite with branch coverage: 345 passed.
  • uvx nox -s mqt: 78 passed in a separate environment, using the new CI session.
  • uvx nox -s lint: passed, including formatting, type checking, dependency-lock validation, and workflow checks.
  • CI now collects the optional Core session's coverage as coverage-mqt.xml, uploads it with the other Python reports, and waits for it before the combined Codecov upload. The XML report generation was also verified locally.
  • Additional catalog smoke check: 70 compilations passed across 35 benchmarks at the independent and IBM Falcon native-gate levels. Shor was excluded from this additional check.

Local coverage from the full suite with --cov=mqt.bench --cov-branch:

Module Statement coverage Branch coverage
MQT Core adapter 100% 100%
Circuit export 100% 100%
CLI 93.5% 88.9%
Entire package 98.0% 96.9%

The tests also cover controlled matrix gates, custom array-valued instruction definitions, unsupported opaque instructions, the import depth limit, nested physical-site validation, dependency import failures, and file/stream/CLI error handling. The QASM stream error handler is included in coverage rather than excluded.

Regression coverage includes unitary equivalence across six gate sets, directed routing and measurement order, parameter identity, classical feed-forward, mirrors without Qiskit transpilation, unsupported targets, optional-dependency errors, CLI exports, and the native-import abort caused by array-valued permutation parameters. QIR tests execute both LLVM text and bitcode through Core's DDSIM runtime, verify measurement ordering and Adaptive feedback, and cover CLI output, stream types, invalid profiles, unbound parameters, missing dependencies, and file preservation on lowering failure. These checks do not establish a performance or circuit-quality advantage over Qiskit.

Codex assisted with the implementation, tests, documentation, and this description. The QIR/LLVM additions need human review, and GitHub CI must run on the updated branch; this PR remains a draft.

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:

  • Any agent that created, edited, or submitted GitHub content was explicitly authorized for that scope, as required by our AI Usage Guidelines.
  • Every agent-authored or agent-edited public text body begins with the visible disclosure 🤖 *AI text below* 🤖 (titles are exempt).
  • I have disclosed AI assistance in the PR description.
  • I confirm that I have personally reviewed and understood all AI-generated content, and accept full responsibility for it.

Assisted-by: GPT-6 via Codex
Assisted-by: GPT-6 via Codex
@codecov

codecov Bot commented Sep 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Assisted-by: GPT-6 via Codex
@simon1hofmann simon1hofmann changed the title ✨ Add MQT Core as an optional compiler ✨ Add MQT Core compilation and QIR export Sep 12, 2026
Include the MQT Core coverage report in the combined CI upload.

Assisted-by: GPT-6 via Codex
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