QIR Support in the MQT¶
The Quantum Intermediate Representation (QIR) is a standardized intermediate representation for quantum programs based on the LLVM intermediate representation (LLVM IR).
The QIR Runtime in MQT Core¶
MQT Core provides a runtime for QIR that is based on its decision diagram-based quantum simulator. This allows for the execution of QIR programs using MQT Core’s high-performance simulation capabilities.
The runtime can be utilized in two ways:
As a standalone library that can be linked to any QIR program, resulting in a binary executable.
By using the
mqt-core-qir-runnercommand-line tool, which interprets QIR programs directly.
See [37] for more details.
Building the Runner¶
To build this tool, the CMake option BUILD_MQT_CORE_QIR_RUNNER has to be
enabled (which depends on BUILD_MQT_CORE_MLIR being set). From the root of the
repository, you can build the runner as follows:
cmake -S . -B build -DBUILD_MQT_CORE_QIR_RUNNER=ON -DBUILD_MQT_CORE_MLIR=ON
cmake --build build --target mqt-core-qir-runner
After building, the tool can be found in the build directory under
bin/mqt-core-qir-runner.
Executing a QIR Program¶
The mqt-core-qir-runner can be used to execute a QIR file (typically with a
.ll extension).
./build/bin/mqt-core-qir-runner bell.ll
The runner prints the program’s outputs to the console in one of the two
QIR Output Schemas (Labeled or Ordered): the two HEADER
records announce the schema, and each shot is wrapped in START and END
records with a METADATA\toutput_labeling_schema\t<schema> line inside.
The active schema is selected by the output_labeling_schema function attribute
on the entry-point function of the QIR program. The value ordered selects
Ordered; anything else, or a missing attribute, selects Labeled.
QIR Support in the DDSIM QDMI Device¶
The QDMI device accepts jobs in the following program formats: QASM2, QASM3, QIR
Base/Adaptive Profile Module (LLVM bitcode), and QIR Base/Adaptive Profile
String (LLVM assembly). These QIR formats are only supported when the
BUILD_MQT_CORE_QDMI_DDSIM_WITH_QIR CMake option is enabled. It is enabled by
default, but depends on BUILD_MQT_CORE_MLIR being set.
FoMaC C++ applications submit textual programs through the
Device::submitJob(const std::string&, ...) overload, which includes the
terminating null byte required by QDMI. Binary module payloads use the
Device::submitJob(std::span<const std::byte>, ...) overload instead. It
preserves embedded null bytes and submits exactly the span’s size without
appending a terminator. Job::getProgramBytes() retrieves such a payload
without interpreting its format or removing terminal null bytes; the existing
Job::getProgram() remains the textual, null-terminated accessor. It rejects
known binary and non-text formats based on their QDMI format identifier, even if
their payload happens to end in a null byte.
The Python API follows the same distinction: pass str to Device.submit_job
for a textual program and bytes for an exact binary payload.
Job.program_bytes always returns the unmodified payload, while Job.program
expects a null-terminated UTF-8 text payload and rejects known binary or
non-text formats.
The generic submission APIs intentionally reject QDMI calibration and batch-job formats. Calibration jobs do not carry a program, while batch jobs contain job handles rather than serialized program bytes. Their format identifiers remain available for capability discovery; they require dedicated typed APIs.