You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This issue is part of unitaryHACK 2026; note that you have to be registered to complete this issue. Learn more about the PR review process here.
A message from unitaryHACK about AI Slop: "While we allow LLMs as collaborative tools, fully AI-generated PRs are prohibited. Maintainers have the right to reject any contribution that appears to be automated or lacks human oversight."
Learn more about unitaryHACK rules and opportunities here and about the usage of AI, in particular, here!
Description
The MQT Core QDMI DD device (include/mqt-core/qdmi/devices/dd/Device.hpp, src/qdmi/devices/dd/Device.cpp) is a Decision-Diagram-based quantum simulator exposed via the Quantum Device Management Interface (QDMI) standard.
Currently, the device supports only OpenQASM 2 and OpenQASM 3 as input program formats (QDMI_PROGRAM_FORMAT_QASM2, QDMI_PROGRAM_FORMAT_QASM3). The QDMI standard also defines four Quantum Intermediate Representation (QIR) formats:
Format constant
Description
QDMI_PROGRAM_FORMAT_QIRBASESTRING
QIR Base Profile as LLVM IR text (.ll)
QDMI_PROGRAM_FORMAT_QIRBASEMODULE
QIR Base Profile as LLVM bitcode binary (.bc)
QDMI_PROGRAM_FORMAT_QIRADAPTIVESTRING
QIR Adaptive Profile as LLVM IR text (.ll)
QDMI_PROGRAM_FORMAT_QIRADAPTIVEMODULE
QIR Adaptive Profile as LLVM bitcode binary (.bc)
All four currently return QDMI_ERROR_NOTSUPPORTED (see test/qdmi/devices/dd/job_parameters_test.cpp, ProgramFormatSupport test).
The goal of this issue is to implement support for at minimumQDMI_PROGRAM_FORMAT_QIRBASESTRING and QDMI_PROGRAM_FORMAT_QIRBASEMODULE, so that a QIR program can be submitted to and executed by the DD device just like an OpenQASM program.
MQT Core already includes a fully working QIR execution stack:
QIR Runtime (src/qir/runtime/, include/mqt-core/qir/runtime/) — a DD-based implementation of QIR's __quantum__qis__* and __quantum__rt__* C API.
QIR Runner (src/qir/runner/Runner.cpp) — a standalone CLI tool using LLVM OrcJIT to JIT-compile and execute .ll/.bc files against the runtime.
This issue is about integrating that execution stack into the QDMI device's submit() / getResults() pipeline.
Background Reading
Before diving into implementation, make sure you understand the existing code:
Familiarise yourself with the QDMI DD device — go through include/mqt-core/qdmi/devices/dd/Device.hpp and src/qdmi/devices/dd/Device.cpp. Pay close attention to MQT_DDSIM_QDMI_Device_Job_impl_d::setParameter(), submit(), and getResults() — these are the three entry points you will be extending.
Study the existing QIR runner — skim through src/qir/runner/Runner.cpp. Understand how it uses llvm::parseIRFile, llvm::orc::LLJIT, and llvm::sys::DynamicLibrary::AddSymbol to JIT-compile a module and resolve QIR intrinsic symbols to the runtime. Note that it reads from a file path; for the device, the program arrives as an in-memory string or byte buffer, respectively.
Study the QIR Runtime — go through include/mqt-core/qir/runtime/Runtime.hpp and src/qir/runtime/Runtime.cpp. Understand the qir::Runtime singleton: how it manages qubit state (qState, dd), how measurement results are stored in rRegister, and what Runtime::reset() does. Also look at include/mqt-core/qir/runtime/QIR.h for the full list of C-level QIR intrinsics.
Run the existing tests — build and run test/qdmi/devices/dd/job_parameters_test.cpp and test/qdmi/devices/dd/results_sampling_test.cpp to confirm the baseline. Try running the QIR runner binary on test/qir/BellPairStatic.ll to see the existing execution path in action. For more information on how to run the test suite, see the developer documentation. For how to build and use the QIR runner the corresponding page in the documentation.
In-memory module parsing — The runner uses llvm::parseIRFile(path, ...) which reads from disk. For the QDMI device, the QIR program arrives as a std::string (LLVM IR text for QIRBASESTRING) or raw bytes (bitcode for QIRBASEMODULE). LLVM provides llvm::parseIR(llvm::MemoryBufferRef, ...) for parsing from a buffer — verify this works for both text and bitcode and decide how to handle the two format variants.
Result collection from JIT-executed QIR — After main() returns, measurement results reside in qir::Runtime's private rRegister (std::unordered_map<Result*, ResultStruct>). There is currently no public accessor. Add a public getResults() / getMeasurementBitstring() accessor to qir::Runtime.
Sampling (multiple shots) — For numShots_ > 0, the QIR program must be re-executed numShots_ times and results aggregated.
CMake / LLVM dependency gating — Linking MQT::CoreQIRRuntime and LLVM OrcJIT libs into mqt-core-qdmi-ddsim-device significantly increases the build footprint. Add a CMake option (e.g. BUILD_MQT_CORE_QDMI_WITH_QIR) so that QIR format support is opt-in.
Accept QIR formats in setParameter() — In src/qdmi/devices/dd/Device.cpp, extend MQT_DDSIM_QDMI_Device_Job_impl_d::setParameter() to allow QDMI_PROGRAM_FORMAT_QIRBASESTRING and QDMI_PROGRAM_FORMAT_QIRBASEMODULE (remove the QDMI_ERROR_NOTSUPPORTED guard for those two). For QIRBASEMODULE, the program parameter carries raw bytes rather than a null-terminated string — handle program_ storage accordingly (the current size - 1 substring logic assumes a C string; bitcode is binary).
Implement QIR execution in submit() — In submit(), add a branch alongside the existing OpenQASM path.
Testing
Update job_parameters_test.cpp — Move QDMI_PROGRAM_FORMAT_QIRBASESTRING and QDMI_PROGRAM_FORMAT_QIRBASEMODULE from the "Unsupported" list to the "Supported" list in the ProgramFormatSupport test.
Add QIR sampling tests — Add new test cases in test/qdmi/devices/dd/ (mirroring results_sampling_test.cpp) that submit a simple QIR Base Profile program (e.g. a Bell pair from test/qir/BellPairStatic.ll) as QIRBASESTRING, run with N shots, and assert the resulting histogram has the correct support ("00" and "11" states only) and sums to N. Repeat for QIRBASEMODULE using a pre-compiled .bc file.
Guard tests with CMake option — Ensure the new tests are only compiled and run when that option is enabled.
Note
This issue is part of unitaryHACK 2026; note that you have to be registered to complete this issue. Learn more about the PR review process here.
A message from unitaryHACK about AI Slop: "While we allow LLMs as collaborative tools, fully AI-generated PRs are prohibited. Maintainers have the right to reject any contribution that appears to be automated or lacks human oversight."
Learn more about unitaryHACK rules and opportunities here and about the usage of AI, in particular, here!
Description
The MQT Core QDMI DD device (
include/mqt-core/qdmi/devices/dd/Device.hpp,src/qdmi/devices/dd/Device.cpp) is a Decision-Diagram-based quantum simulator exposed via the Quantum Device Management Interface (QDMI) standard.Currently, the device supports only OpenQASM 2 and OpenQASM 3 as input program formats (
QDMI_PROGRAM_FORMAT_QASM2,QDMI_PROGRAM_FORMAT_QASM3). The QDMI standard also defines four Quantum Intermediate Representation (QIR) formats:QDMI_PROGRAM_FORMAT_QIRBASESTRING.ll)QDMI_PROGRAM_FORMAT_QIRBASEMODULE.bc)QDMI_PROGRAM_FORMAT_QIRADAPTIVESTRING.ll)QDMI_PROGRAM_FORMAT_QIRADAPTIVEMODULE.bc)All four currently return
QDMI_ERROR_NOTSUPPORTED(seetest/qdmi/devices/dd/job_parameters_test.cpp,ProgramFormatSupporttest).The goal of this issue is to implement support for at minimum
QDMI_PROGRAM_FORMAT_QIRBASESTRINGandQDMI_PROGRAM_FORMAT_QIRBASEMODULE, so that a QIR program can be submitted to and executed by the DD device just like an OpenQASM program.MQT Core already includes a fully working QIR execution stack:
src/qir/runtime/,include/mqt-core/qir/runtime/) — a DD-based implementation of QIR's__quantum__qis__*and__quantum__rt__*C API.src/qir/runner/Runner.cpp) — a standalone CLI tool using LLVM OrcJIT to JIT-compile and execute.ll/.bcfiles against the runtime.This issue is about integrating that execution stack into the QDMI device's
submit()/getResults()pipeline.Background Reading
Before diving into implementation, make sure you understand the existing code:
Familiarise yourself with the QDMI DD device — go through
include/mqt-core/qdmi/devices/dd/Device.hppandsrc/qdmi/devices/dd/Device.cpp. Pay close attention toMQT_DDSIM_QDMI_Device_Job_impl_d::setParameter(),submit(), andgetResults()— these are the three entry points you will be extending.Study the existing QIR runner — skim through
src/qir/runner/Runner.cpp. Understand how it usesllvm::parseIRFile,llvm::orc::LLJIT, andllvm::sys::DynamicLibrary::AddSymbolto JIT-compile a module and resolve QIR intrinsic symbols to the runtime. Note that it reads from a file path; for the device, the program arrives as an in-memory string or byte buffer, respectively.Study the QIR Runtime — go through
include/mqt-core/qir/runtime/Runtime.hppandsrc/qir/runtime/Runtime.cpp. Understand theqir::Runtimesingleton: how it manages qubit state (qState,dd), how measurement results are stored inrRegister, and whatRuntime::reset()does. Also look atinclude/mqt-core/qir/runtime/QIR.hfor the full list of C-level QIR intrinsics.Run the existing tests — build and run
test/qdmi/devices/dd/job_parameters_test.cppandtest/qdmi/devices/dd/results_sampling_test.cppto confirm the baseline. Try running the QIR runner binary ontest/qir/BellPairStatic.llto see the existing execution path in action. For more information on how to run the test suite, see the developer documentation. For how to build and use the QIR runner the corresponding page in the documentation.Read the QIR Base Profile spec (optional but helpful) — https://github.com/qir-alliance/qir-spec/blob/main/specification/profiles/Base_Profile.md
Tasks
In-memory module parsing — The runner uses
llvm::parseIRFile(path, ...)which reads from disk. For the QDMI device, the QIR program arrives as astd::string(LLVM IR text forQIRBASESTRING) or raw bytes (bitcode forQIRBASEMODULE). LLVM providesllvm::parseIR(llvm::MemoryBufferRef, ...)for parsing from a buffer — verify this works for both text and bitcode and decide how to handle the two format variants.Result collection from JIT-executed QIR — After
main()returns, measurement results reside inqir::Runtime's privaterRegister(std::unordered_map<Result*, ResultStruct>). There is currently no public accessor. Add a publicgetResults()/getMeasurementBitstring()accessor toqir::Runtime.Sampling (multiple shots) — For
numShots_ > 0, the QIR program must be re-executednumShots_times and results aggregated.CMake / LLVM dependency gating — Linking
MQT::CoreQIRRuntimeand LLVM OrcJIT libs intomqt-core-qdmi-ddsim-devicesignificantly increases the build footprint. Add a CMake option (e.g.BUILD_MQT_CORE_QDMI_WITH_QIR) so that QIR format support is opt-in.Accept QIR formats in
setParameter()— Insrc/qdmi/devices/dd/Device.cpp, extendMQT_DDSIM_QDMI_Device_Job_impl_d::setParameter()to allowQDMI_PROGRAM_FORMAT_QIRBASESTRINGandQDMI_PROGRAM_FORMAT_QIRBASEMODULE(remove theQDMI_ERROR_NOTSUPPORTEDguard for those two). ForQIRBASEMODULE, the program parameter carries raw bytes rather than a null-terminated string — handleprogram_storage accordingly (the currentsize - 1substring logic assumes a C string; bitcode is binary).Implement QIR execution in
submit()— Insubmit(), add a branch alongside the existing OpenQASM path.Testing
Update
job_parameters_test.cpp— MoveQDMI_PROGRAM_FORMAT_QIRBASESTRINGandQDMI_PROGRAM_FORMAT_QIRBASEMODULEfrom the "Unsupported" list to the "Supported" list in theProgramFormatSupporttest.Add QIR sampling tests — Add new test cases in
test/qdmi/devices/dd/(mirroringresults_sampling_test.cpp) that submit a simple QIR Base Profile program (e.g. a Bell pair fromtest/qir/BellPairStatic.ll) asQIRBASESTRING, run withNshots, and assert the resulting histogram has the correct support ("00"and"11"states only) and sums toN. Repeat forQIRBASEMODULEusing a pre-compiled.bcfile.Guard tests with CMake option — Ensure the new tests are only compiled and run when that option is enabled.