✨ Integrate QDMI Devices#1687
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
arch optionarch Option
arch Option…-quantum-toolkit/core into feat/arch-option-and-qdmi
…-quantum-toolkit/core into feat/arch-option-and-qdmi
|
@burgholzer (cc: @ystade) This pull request now implements a very basic QDMI V1 integration into our compiler collection. Before continuing, I want to discuss the following issues. Optionally enable QDMIAs of now, the current implementation tightly couples the Extract Nested ClassesIn order to augment the FoMaC device classes, I think it would be nice to extract them outside the Trailing Return Types (Nitpick, sorry!)I am really not that sure if the FoMaC classes benefit from the benefits of trailing return types. The // fomac/FoMaC.cpp
auto getParametersNum(const std::vector<Site>& sites = {},
const std::vector<double>& params = {}) const -> size_t;
// qdmi/sc/Device.hpp
auto sessionFree(MQT_SC_QDMI_Device_Session session) -> void;I've taken the liberty to implement some of the above FoMaC changes this morning (+ some improvements using modern C++ concepts) in Any comments appreciated! Many thanks 🙏 |
Hm. I'd argue that if we view QDMI as the primary way to add architecture information to
We have an open tracking issue going in that direction #1358. See also #1363 (comment)
Feel free to get rid of them. I am personally not the biggest fan of these either way.
Thanks, I'll take a look! 👍🏼
|
I was kind of thinking about IBM Benchpress. Not sure if we could still use QDMI here that easily.
Oh. Great! I'll have a look at these and try to incorporate them in the refactoring.
I've also opened #1849 to ease the comparison to the old implementation. |
I was hoping that we could take the input from benchpress and wrap it in QDMI at runtime.
Take those with a grain of salt though. It's been a while that they have been written and some circumstances might have changed since then. Still good to have a look though. |
|
A little late, but since I was tagged, I also wanted to comment: Trailing return typesI guess I am responsible for them. I love them because when you read FoMaC ConceptI guess everything has already been said here. I can just repeat here that in the future we want to directly build on QDMI and want to get rid of FoMaC or rather replace that by a C++ abstraction of QDMI. |
|
I think this one is ready to discuss.
--qdmi-list-devices // List all available QDMI devices.
--qdmi-device=iqm-radiance // Specify the device used for hardware-specific passes.
--qdmi-config=./qdmi.json // Specify session config, additional devices and their respective configs.
CLI Examplematthias:~$ cat ~/Downloads/qdmi.json
{
"devices": [
{
"libName": "/Users/matthias/Documents/projects/core/build/src/qdmi/devices/sc/libmqt-core-qdmi-sc-device.dylib",
"prefix": "MQT_SC",
"deviceConfig": {
"baseUrl": "...",
"token": "...",
"authFile": "...",
"authUrl": "...",
"username": "...",
"password": "...",
"custom1": "...",
"custom2": "...",
"custom3": "...",
"custom4": "...",
"custom5": "..."
}
}
]
}
matthias:~$ mqt-cc --qdmi-list-devices --qdmi-config ~/Downloads/qdmi.json
[2026-07-09 14:03:58.473] [info] [Driver.cpp:193] Device session parameter BASE URL not supported by device (skipped)
[2026-07-09 14:03:58.474] [info] [Driver.cpp:193] Device session parameter TOKEN not supported by device (skipped)
[2026-07-09 14:03:58.474] [info] [Driver.cpp:193] Device session parameter AUTH FILE not supported by device (skipped)
[2026-07-09 14:03:58.474] [info] [Driver.cpp:193] Device session parameter AUTH URL not supported by device (skipped)
[2026-07-09 14:03:58.474] [info] [Driver.cpp:193] Device session parameter USERNAME not supported by device (skipped)
[2026-07-09 14:03:58.474] [info] [Driver.cpp:193] Device session parameter PASSWORD not supported by device (skipped)
[2026-07-09 14:03:58.474] [info] [Driver.cpp:193] Device session parameter CUSTOM1 not supported by device (skipped)
[2026-07-09 14:03:58.474] [info] [Driver.cpp:193] Device session parameter CUSTOM2 not supported by device (skipped)
[2026-07-09 14:03:58.474] [info] [Driver.cpp:193] Device session parameter CUSTOM3 not supported by device (skipped)
[2026-07-09 14:03:58.474] [info] [Driver.cpp:193] Device session parameter CUSTOM4 not supported by device (skipped)
[2026-07-09 14:03:58.474] [info] [Driver.cpp:193] Device session parameter CUSTOM5 not supported by device (skipped)
Available QDMI devices:
MQT NA Default QDMI Device // Statically loaded.
MQT SC Default QDMI Device // Statically loaded.
MQT Core DDSIM QDMI Device // Statically loaded.
MQT SC Default QDMI Device // Dynamically loaded.Footnotes
|
…-quantum-toolkit/core into feat/arch-option-and-qdmi
|
I have not yet had the chance to look through everything in detail here yet, but I have one general high-level observation already: A lot of the QDMI-related functionality is built "outside" of QDMI here (building on top of FoMaC; relying on @MatthiasReumann does that make sense? Can you work with that? |
I'll try to summarize my thoughts on this. Let me know, if the following is valid.
Generally understood.
I wonder: Is there any valid reason to link devices statically in the Because isn't the purpose of the
Understood. Currently, what really confuses me - and I just realized - is that the Footnotes
|
IIRC we no longer statically link the QDMI devices that come with MQT Core. I would argue that the following things should be possible:
I believe I get where your confusion is coming from. This is a consequence of the initial design of QDMI v1. QDMI v1 defines the device and the client interface. HW Providers implement the (prefixed) device interface; clients can use the (non-prefixed) client interface with all the devices they have access to. The driver mediates between both interfaces. We have a rather lengthy exposition of that topic here: Munich-Quantum-Software-Stack/QDMI#215 that was written almost a year ago. So far, no one dared to make the move and eliminate the client interface in MQT Core to combine the FoMaC and Driver libraries (also getting rid of the FoMaC name 😅) |
|
@burgholzer Okay, I think I got a plan. Step 0: Device Generation
Step 1: Driver Boot-up
Step 2: Driver Runtime
Essentially, the JSON config files will be the canonical way to load devices into I'll leave it at that for now for this pull request. Any objections? @ystade Any opinions? |
In principle, this plan sounds solid.
Overall, this is definitely the right direction. Happy to discuss further 🙂 |
…-quantum-toolkit/core into feat/arch-option-and-qdmi
|
@coderabbitai full review |
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 4
♻️ Duplicate comments (1)
mlir/include/mlir/Support/SuperconductingDevice.h (1)
45-46: 📐 Maintainability & Code Quality | 🟡 Minor | 💤 Low valueDocument
distanceBetweenbehavior for edge cases.The Doxygen comment doesn't specify what
distanceBetweenreturns whenu == vor when qubits are unreachable. Since the implementation returns0foru == vand throws a fatal error for unreachable qubits, documenting this explicitly helps prevent misuse (e.g., unsigned underflow if callers subtract 1 from the distance).📝 Suggested documentation update
- /// Return the length of the shortest path between two qubits. + /// Return the length of the shortest path between two qubits. + /// + /// \param u The source qubit index. + /// \param v The target qubit index. + /// \return The shortest-path distance. The distance from a qubit to itself is 0. + /// \note Throws a fatal error if \p u and \p v are unreachable. Callers + /// that subtract 1 for swap counts must guard against a 0 return value. [[nodiscard]] size_t distanceBetween(size_t u, size_t v) const;🤖 Prompt for 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. In `@mlir/include/mlir/Support/SuperconductingDevice.h` around lines 45 - 46, Update the Doxygen comment for SuperconductingDevice::distanceBetween to document that it returns 0 when u == v and triggers a fatal error when the qubits are unreachable, while retaining the existing shortest-path description.
🤖 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 `@mlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cpp`:
- Around line 1218-1227: Update createMappingPass to validate that the supplied
SuperconductingDevice has symmetric couplings before constructing MappingPass,
rejecting asymmetric coupling maps; alternatively normalize the map to an
undirected form first. Preserve the existing behavior for valid symmetric
devices and ensure invalid input cannot reach FGraph or the routing heuristic.
In `@mlir/lib/Support/CMakeLists.txt`:
- Around line 9-13: Replace the SUPPORT_CPP file(GLOB_RECURSE) collection with
an explicit list of the directory’s .cpp sources, then pass that list to
MLIRSupportMQT. If retaining globbing is necessary, add CONFIGURE_DEPENDS to
ensure source additions and removals trigger CMake reconfiguration.
In `@mlir/lib/Support/Qdmi.cpp`:
- Around line 63-78: Guard every nlohmann::json::contains call with an is_object
check: update getJsonStringIfExists for jsonObj, the root j checks around
session and devices, and the deviceJson check around libName. Apply these
changes at mlir/lib/Support/Qdmi.cpp lines 28-34, 63-78, and 80-84 respectively,
preserving the existing parsing behavior for valid JSON objects.
In `@mlir/lib/Support/SuperconductingDevice.cpp`:
- Around line 70-81: Replace the aborting mapping.at lookups in the siteCoupling
endpoint transformation with explicit checked lookups for both s0 and s1. If
either endpoint is absent from mapping, report a clear error through the
surrounding SuperconductingDevice validation path instead of crashing; otherwise
preserve insertion of the mapped index pair.
---
Duplicate comments:
In `@mlir/include/mlir/Support/SuperconductingDevice.h`:
- Around line 45-46: Update the Doxygen comment for
SuperconductingDevice::distanceBetween to document that it returns 0 when u == v
and triggers a fatal error when the qubits are unreachable, while retaining the
existing shortest-path description.
🪄 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: 649709e5-d37a-4bf9-b3e6-c81204bdbf1b
📒 Files selected for processing (16)
CHANGELOG.mdmlir/include/mlir/Compiler/CompilerPipeline.hmlir/include/mlir/Dialect/QCO/Transforms/Mapping/Mapping.hmlir/include/mlir/Support/Graph.hmlir/include/mlir/Support/Qdmi.hmlir/include/mlir/Support/SuperconductingDevice.hmlir/lib/Compiler/CompilerPipeline.cppmlir/lib/Dialect/QCO/Transforms/CMakeLists.txtmlir/lib/Dialect/QCO/Transforms/Mapping/Mapping.cppmlir/lib/Dialect/QCO/Utils/Graph.cppmlir/lib/Support/CMakeLists.txtmlir/lib/Support/Qdmi.cppmlir/lib/Support/SuperconductingDevice.cppmlir/tools/mqt-cc/mqt-cc.cppmlir/unittests/Dialect/QCO/Transforms/Mapping/test_mapping.cppsrc/fomac/FoMaC.cpp
| file(GLOB_RECURSE SUPPORT_CPP "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") | ||
|
|
||
| add_mlir_library( | ||
| MLIRSupportMQT | ||
| IRVerification.cpp | ||
| Passes.cpp | ||
| PrettyPrinting.cpp | ||
| ${SUPPORT_CPP} |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
Avoid using GLOB to collect source files.
Using file(GLOB_RECURSE) without CONFIGURE_DEPENDS is a well-known CMake anti-pattern. If a developer adds or removes a .cpp file in this directory, the build system will not automatically reconfigure, leading to confusing build failures. It is generally safer to explicitly list the source files.
If you prefer to keep the globbing, consider adding the CONFIGURE_DEPENDS flag (requires CMake 3.12+).
♻️ Proposed fix
-file(GLOB_RECURSE SUPPORT_CPP "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
+file(GLOB_RECURSE SUPPORT_CPP CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
add_mlir_library(
MLIRSupportMQT📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| file(GLOB_RECURSE SUPPORT_CPP "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") | |
| add_mlir_library( | |
| MLIRSupportMQT | |
| IRVerification.cpp | |
| Passes.cpp | |
| PrettyPrinting.cpp | |
| ${SUPPORT_CPP} | |
| file(GLOB_RECURSE SUPPORT_CPP CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") | |
| add_mlir_library( | |
| MLIRSupportMQT | |
| ${SUPPORT_CPP} |
🤖 Prompt for 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.
In `@mlir/lib/Support/CMakeLists.txt` around lines 9 - 13, Replace the SUPPORT_CPP
file(GLOB_RECURSE) collection with an explicit list of the directory’s .cpp
sources, then pass that list to MLIRSupportMQT. If retaining globbing is
necessary, add CONFIGURE_DEPENDS to ensure source additions and removals trigger
CMake reconfiguration.
There was a problem hiding this comment.
@burgholzer If this works as described, we might want to add this everywhere.
There was a problem hiding this comment.
@MatthiasReumann Sounds good — happy to help apply CONFIGURE_DEPENDS more broadly once burgholzer confirms this pattern works well here. Just flagging that CONFIGURE_DEPENDS (CMake ≥ 3.12) still only re-runs the glob at configure time triggered by a build, not automatically on every file save, so it won't fully eliminate the need to re-run CMake in all IDE/workflow setups — but it's a solid middle ground between fully explicit source lists and unguarded globbing. Let me know if you'd like me to scan for other file(GLOB / file(GLOB_RECURSE) usages across the repo so you can decide where else to apply it.
Description
This pull request integrates QDMI into the MLIR Compiler Collection (
mqt-cc).Overview
SuperconductingDeviceclass that acts as an adapter for QDMI.qdmi)QuantumCompilerConfig. The QDMI device is then used in the hardware-specific phase to construct theSuperconductingDevice. I assume superconducting devices only. Future work might implement a "dispatcher" to create the correct pass pipeline for the respective device's constraints.CLI Example
Resolves #1082.
Checklist
If PR contains AI-assisted content:
Assisted-by: [Model Name] via [Tool Name]footer.