Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
67e0402
✨ Implement SC device
ystade Nov 24, 2025
2812858
✅ Setup tests for SC device
ystade Nov 24, 2025
ab883c3
🐛 Fix tests
ystade Nov 24, 2025
f9097cd
Merge remote-tracking branch 'origin/main' into ystade/qdmi-sc-device
ystade Nov 24, 2025
8553ccb
🐛 Fix tests
ystade Nov 24, 2025
19e699b
📝 Add docstrings to `ystade/qdmi-sc-device` (#1329)
coderabbitai[bot] Nov 24, 2025
39d47cb
📝 Fix docstring in generator
ystade Nov 24, 2025
6620171
🎨 WOrk on rabbit's suggestions
ystade Nov 24, 2025
e30ea78
Merge branch 'main' into ystade/qdmi-sc-device
burgholzer Nov 24, 2025
332c3e1
🎨 Add missing free for sessions
ystade Nov 25, 2025
204ad85
🎨 Make memebr functions non static
ystade Nov 25, 2025
6e4500a
🎨 Work on more feedback
ystade Nov 25, 2025
9a9a734
🎨 Work on more commetns
ystade Nov 25, 2025
6c1b974
🎨 Apply more suggestions
ystade Nov 26, 2025
078679a
Merge remote-tracking branch 'origin/main' into ystade/qdmi-sc-device
ystade Nov 26, 2025
9aa2ba8
🎨 Adopt test suite
ystade Nov 26, 2025
72faea0
🎨 Accumulate a couple of improvements
ystade Nov 26, 2025
ac0c32d
⬆️👨‍💻 Update munich-quantum-toolkit/workflows action to v1.17.3 (#1335)
renovate[bot] Nov 27, 2025
d759783
⬆️👨‍💻 Pin munich-quantum-software/setup-mlir action to 2f40b6e (#1334)
renovate[bot] Nov 27, 2025
8a99129
🔧 Streamline DX (#1337)
denialhaag Nov 28, 2025
2e2d440
⬆️🪝 Update pre-commit hook astral-sh/ruff-pre-commit to v0.14.7 (#1339)
renovate[bot] Nov 29, 2025
2f2bb5a
⬆️🪝 Update pre-commit hook astral-sh/uv-pre-commit to v0.9.13 (#1340)
renovate[bot] Nov 29, 2025
080b813
⬆️🪝 Update pre-commit hook crate-ci/typos to v1.40.0 (#1341)
renovate[bot] Nov 29, 2025
aa441bc
⬆️🪝 Update pre-commit hook emzeat/mz-lictools to v2.9.0 (#1344)
renovate[bot] Nov 29, 2025
bde5874
⬆️🪝 Update pre-commit hook rbubley/mirrors-prettier to v3.7.2 (#1342)
renovate[bot] Nov 29, 2025
eac1c9e
⬆️🪝 Update pre-commit hook pre-commit/mirrors-mypy to v1.19.0 (#1343)
renovate[bot] Nov 30, 2025
8c638ca
✨ Add `WireIterator` (#1310)
MatthiasReumann Nov 30, 2025
8edd823
⬆️🪝 Update pre-commit hook rbubley/mirrors-prettier to v3.7.3 (#1345)
renovate[bot] Nov 30, 2025
302c199
🐛 Fix dynamic QDMI Device (#1336)
ystade Nov 30, 2025
a0b3ee3
⬆️🔒️ Lock file maintenance (#1346)
renovate[bot] Dec 1, 2025
6f768be
🎨 Apply changes from #1336 also in new SC device
ystade Dec 1, 2025
e6eb3e1
Merge remote-tracking branch 'origin/main' into ystade/qdmi-sc-device
ystade Dec 1, 2025
4e458a6
🐛 Fix driver tests
ystade Dec 1, 2025
a3bdab6
🎨 Some clean-up
ystade Dec 1, 2025
3cd5dba
✅ Skip failing tests
ystade Dec 1, 2025
0ac07d2
🎨 Add missing include
ystade Dec 1, 2025
ca6f8ba
🎨 Fix akward wrapping
ystade Dec 1, 2025
cdc1cd2
🎨 Apply some suggestions
ystade Dec 1, 2025
5049d82
💚 Fix linter warnings
ystade Dec 2, 2025
e9d2e62
💚 Remove unecessary includes
ystade Dec 3, 2025
0fe2fae
Merge remote-tracking branch 'origin/main' into ystade/qdmi-sc-device
ystade Dec 3, 2025
18bf0fe
🎨 Refactor device structure
ystade Dec 1, 2025
d3a6f13
🎨 Link dynamic device statically
ystade Dec 2, 2025
e03baf8
🎨 Make singleton instance hidde
ystade Dec 2, 2025
89fdf07
🎨 Next try
ystade Dec 2, 2025
fd9c562
🎨 Working solution
ystade Dec 2, 2025
e68f5e8
🎨 Improve
ystade Dec 2, 2025
9d88c5a
🎨 Make code around singleton cleaner, fix includes
ystade Dec 3, 2025
b4dfb5a
🎨 Fix windows build
ystade Dec 3, 2025
801a2ef
🎨 Add debug output in load twice test
ystade Dec 3, 2025
433f9c4
Revert "🎨 Add debug output in load twice test"
ystade Dec 3, 2025
8dccb47
✅ Clearer tests
ystade Dec 3, 2025
0f920cb
📝 Update changelog
ystade Dec 3, 2025
7393c68
Merge remote-tracking branch 'origin/main' into ystade/qdmi-sc-device…
ystade Dec 5, 2025
40405cb
🐛 Fix merge
ystade Dec 5, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This project adheres to [Semantic Versioning], with the exception that minor rel

### Changed

- 🎨 Extract the singleton handling of QDMI devices and make it thread-safe ([#1347]) ([**@ystade**])
- 👷 Stop testing on `ubuntu-22.04` and `ubuntu-22.04-arm` runners ([#1359]) ([**@denialhaag**], [**@burgholzer**])
- 👷 Stop testing with `clang-19` and start testing with `clang-21` ([#1359]) ([**@denialhaag**], [**@burgholzer**])
- 👷 Fix macOS tests with Homebrew Clang via new `munich-quantum-toolkit/workflows` version ([#1359]) ([**@denialhaag**], [**@burgholzer**])
Expand Down Expand Up @@ -271,6 +272,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool
<!-- PR links -->

[#1359]: https://github.com/munich-quantum-toolkit/core/pull/1359
[#1347]: https://github.com/munich-quantum-toolkit/core/pull/1347
[#1338]: https://github.com/munich-quantum-toolkit/core/pull/1338
[#1336]: https://github.com/munich-quantum-toolkit/core/pull/1336
[#1328]: https://github.com/munich-quantum-toolkit/core/pull/1328
Expand Down
2 changes: 1 addition & 1 deletion bindings/na/fomac/fomac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// clang-format off
#include "fomac/FoMaC.hpp"
#include "na/fomac/Device.hpp"
#include "na/device/Generator.hpp"
#include "qdmi/devices/na/Generator.hpp"

#include <pybind11/cast.h>
#include <pybind11/operators.h>
Expand Down
2 changes: 1 addition & 1 deletion include/mqt-core/na/fomac/Device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#pragma once

#include "fomac/FoMaC.hpp"
#include "na/device/Generator.hpp"
#include "qdmi/devices/na/Generator.hpp"

// NOLINTNEXTLINE(misc-include-cleaner)
#include <nlohmann/json.hpp>
Expand Down
97 changes: 97 additions & 0 deletions include/mqt-core/qdmi/devices/base/Device.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2023 - 2025 Chair for Design Automation, TUM
* Copyright (c) 2025 Munich Quantum Software Company GmbH
* All rights reserved.
*
* SPDX-License-Identifier: MIT
*
* Licensed under the MIT License
*/

#pragma once

/** @file
* @brief The generic MQT QDMI device implementation that specific devices
* inherit from.
*/

#include <cassert>
#include <memory>
#include <mutex>

// Define a macro for hidden visibility, which works on GCC and Clang.
#if defined(__GNUC__) || defined(__clang__)
#define MQT_HIDDEN __attribute__((visibility("hidden")))
#else
#define MQT_HIDDEN
#endif
Comment on lines +22 to +27
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider avoiding raw owning pointers for instance and mutex

You intentionally leak the mutex to sidestep static deinitialization order, and manage instance via a raw pointer:

MQT_HIDDEN inline static std::shared_ptr<ConcreteType>* instance = nullptr;
MQT_HIDDEN inline static std::mutex* mutex = new std::mutex;

This works, but it is non‑idiomatic and easy to misuse. A cleaner alternative is to rely on function‑local statics for initialization order and avoid manual new/delete:

static auto instanceStorage() -> std::shared_ptr<ConcreteType>& {
  static std::shared_ptr<ConcreteType> inst{};
  return inst;
}
static auto instanceMutex() -> std::mutex& {
  static std::mutex m;
  return m;
}

and then use instanceStorage() / instanceMutex() in initialize(), finalize(), and get(). That eliminates raw owning pointers and the intentional leak while still avoiding the static deinit‑order fiasco.

Not mandatory for correctness once get() is fixed, but it would simplify reasoning and static‑analysis tooling.

Also applies to: 32-35

🤖 Prompt for AI Agents
In include/mqt-core/qdmi/devices/base/Device.hpp around lines 22-27 (and
similarly 32-35), replace the raw owning pointers and intentional leak for
instance and mutex with function-local statics: create a function returning a
reference to a static std::shared_ptr<ConcreteType> (instanceStorage()) and
another returning a reference to a static std::mutex (instanceMutex()), then
update initialize(), finalize(), and get() to use those accessors instead of the
pointer variables; this removes manual new/delete, avoids the leak, and
preserves safe initialization order without changing external behavior.


namespace qdmi {
template <class ConcreteType> class SingletonDevice {
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
MQT_HIDDEN inline static std::shared_ptr<ConcreteType>* instance = nullptr;
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
MQT_HIDDEN inline static std::mutex* mutex = new std::mutex;

Comment on lines +32 to +35
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, find and read the Device.hpp file to see the full SingletonDevice implementation
find . -name "Device.hpp" -path "*/qdmi/devices/base/*" | head -5

Repository: munich-quantum-toolkit/core

Length of output: 118


🏁 Script executed:

# Read the full Device.hpp file to understand the complete SingletonDevice implementation
cat -n ./include/mqt-core/qdmi/devices/base/Device.hpp

Repository: munich-quantum-toolkit/core

Length of output: 3837


🏁 Script executed:

# Search for calls to SingletonDevice::get() to see if there are production callers
# and if they provide any guards or assumptions
rg "\.get\(\)" --type cpp -B 2 -A 2 | head -80

Repository: munich-quantum-toolkit/core

Length of output: 5521


🏁 Script executed:

# Search more specifically for SingletonDevice class usage and get() calls
# First find all files that use SingletonDevice
rg "SingletonDevice" --type cpp -l | head -20

Repository: munich-quantum-toolkit/core

Length of output: 248


🏁 Script executed:

# Check one concrete device implementation to see the pattern
cat -n ./include/mqt-core/qdmi/devices/dd/Device.hpp | head -50

Repository: munich-quantum-toolkit/core

Length of output: 1665


🏁 Script executed:

# Search for Device::get() or similar get() calls in QDMI device code
rg "Device::get|device.*get\(\)" include/mqt-core/qdmi/ src/qdmi/ --type cpp -B 2 -A 2

Repository: munich-quantum-toolkit/core

Length of output: 5176


🏁 Script executed:

# Check one of the Device.cpp implementation files to see the full context
cat -n ./src/qdmi/devices/dd/Device.cpp | head -100

Repository: munich-quantum-toolkit/core

Length of output: 4468


🏁 Script executed:

# Look at the specific get() calls and their exception handling
rg -A 10 "Device::get\(\)->" src/qdmi/devices/dd/Device.cpp | head -60

Repository: munich-quantum-toolkit/core

Length of output: 2340


🏁 Script executed:

# Let me check if there are any test files that verify get() behavior when device is not initialized
find . -path "*/test/*" -name "*device*test*.cpp" -o -path "*/test/*" -name "*Device*test*.cpp" | grep -i qdmi | head -5

Repository: munich-quantum-toolkit/core

Length of output: 166


🏁 Script executed:

# Check one test file to see initialization patterns
cat -n ./test/qdmi/devices/dd/device_status_test.cpp | head -80

Repository: munich-quantum-toolkit/core

Length of output: 3380


🏁 Script executed:

# Check the SessionGuard implementation to see if it calls initialize()
cat -n ./test/qdmi/dd/helpers/test_utils.hpp | head -100

Repository: munich-quantum-toolkit/core

Length of output: 140


🏁 Script executed:

# Find test_utils.hpp
find . -name "test_utils.hpp" -path "*/qdmi/*"

Repository: munich-quantum-toolkit/core

Length of output: 116


🏁 Script executed:

# Read test_utils.hpp to see SessionGuard implementation
cat -n ./test/qdmi/devices/dd/helpers/test_utils.hpp

Repository: munich-quantum-toolkit/core

Length of output: 2608


🏁 Script executed:

# Find the SessionGuard implementation
rg "SessionGuard::" test/qdmi/devices/dd/helpers/ -A 5

Repository: munich-quantum-toolkit/core

Length of output: 1020


Fix SingletonDevice::get() null pointer dereference and inconsistent error handling

The get() method has a critical undefined behavior bug: if instance is nullptr (before initialize() or after finalize()), the line assert(*instance != nullptr) dereferences a null pointer before the assertion fires. Additionally, production code in Device.cpp wraps some get() calls in try-catch blocks expecting std::runtime_error, but the implementation uses assert() which doesn't throw.

[[nodiscard]] static auto get() -> std::shared_ptr<ConcreteType> {
  const std::scoped_lock lock(*mutex);
  assert(*instance != nullptr &&
         "Device not initialized. Call `initialize()` first.");
  return *instance;
}

Should be changed to:

[[nodiscard]] static auto get() -> std::shared_ptr<ConcreteType> {
  const std::scoped_lock lock(*mutex);
  if (instance == nullptr || !*instance) {
    throw std::runtime_error(
        "Device not initialized. Call `initialize()` before `get()`.");
  }
  return *instance;
}

This matches the documented error handling pattern already expected by production code callers (lines 57-64, 71-85, 90-95 in Device.cpp which catch std::runtime_error), ensures all code paths are safe, and removes undefined behavior.

🤖 Prompt for AI Agents
In include/mqt-core/qdmi/devices/base/Device.hpp around lines 32 to 35, the
SingletonDevice::get() currently dereferences instance via assert(*instance !=
nullptr) causing undefined behavior if instance is null and uses assert instead
of throwing; change the implementation to lock the mutex, check if instance is
nullptr or *instance is null, and if so throw a std::runtime_error with the
message "Device not initialized. Call `initialize()` before `get()`.", otherwise
return *instance so callers expecting exceptions (not assertions) behave
correctly and no null pointer is dereferenced.

protected:
/// @brief Protected constructor to enforce the singleton pattern.
SingletonDevice() = default;
// Allow std::make_shared to access the protected constructor.
friend class std::shared_ptr<ConcreteType>;

public:
// Delete move constructor and move assignment operator.
SingletonDevice(SingletonDevice&&) = delete;
SingletonDevice& operator=(SingletonDevice&&) = delete;
// Delete copy constructor and assignment operator to enforce singleton.
SingletonDevice(const SingletonDevice&) = delete;
SingletonDevice& operator=(const SingletonDevice&) = delete;

/// @brief Destructor for the SingletonDevice class.
virtual ~SingletonDevice() = default;

/**
* @brief Initializes the singleton instance.
* @details Must be called before `get()`.
*/
static void initialize() {
const std::scoped_lock lock(*mutex);
if (instance == nullptr) {
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
instance = new std::shared_ptr<ConcreteType>(new ConcreteType);
}
}

/**
* @brief Destroys the singleton instance.
* @details After this call, `get()` must not be called until a new
* `initialize()` call. Any existing shared_ptr will keep the object alive
* until they go out of scope.
*/
static void finalize() {
const std::scoped_lock lock(*mutex);
if (instance != nullptr) {
// Reset the shared_ptr to release the managed object.
*instance = nullptr;
// Delete the shared_ptr object itself.
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
delete instance;
instance = nullptr;
}
// Do NOT delete the static mutex. The mutex is intentionally leaked to
// avoid static deinitialization issues (cf. static deinitialization order
// fiasco)
}

/**
* @brief Get the singleton instance of the device.
* @return A shared pointer to the device instance.
*/
[[nodiscard]] static auto get() -> std::shared_ptr<ConcreteType> {
const std::scoped_lock lock(*mutex);
assert(*instance != nullptr &&
"Device not initialized. Call `initialize()` first.");
return *instance;
}
};
} // namespace qdmi
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "dd/DDDefinitions.hpp"
#include "dd/Package.hpp"
#include "mqt_ddsim_qdmi/device.h"
#include "qdmi/devices/base/Device.hpp"

#include <atomic>
#include <cstddef>
Expand All @@ -31,7 +32,8 @@
#include <unordered_map>

namespace qdmi::dd {
class Device final {
class Device final : public SingletonDevice<Device> {
friend class SingletonDevice;
/// Provides access to the device name.
std::string name_;

Expand Down Expand Up @@ -63,9 +65,6 @@ class Device final {
/// @brief Private constructor to enforce the singleton pattern.
Device();

/// @brief The singleton instance.
static std::atomic<Device*> instance;

public:
// Default move constructor and move assignment operator.
Device(Device&&) = delete;
Expand All @@ -75,23 +74,7 @@ class Device final {
Device& operator=(const Device&) = delete;

/// @brief Destructor for the Device class.
~Device() = default;

/**
* @brief Initializes the singleton instance.
* @details Must be called before `get()`.
*/
static void initialize();

/**
* @brief Destroys the singleton instance.
* @details After this call, `get()` must not be called until a new
* `initialize()` call.
*/
static void finalize();

/// @returns the singleton instance of the Device class.
[[nodiscard]] static auto get() -> Device&;
~Device() override = default;

/**
* @brief Allocates a new device session.
Expand Down Expand Up @@ -264,7 +247,7 @@ struct MQT_DDSIM_QDMI_Device_Job_impl_d {
/// Constructor for the MQT_DDSIM_QDMI_Device_Job_impl_d.
explicit MQT_DDSIM_QDMI_Device_Job_impl_d(
MQT_DDSIM_QDMI_Device_Session_impl_d* session)
: session_(session), id_(qdmi::dd::Device::get().generateUniqueID()) {}
: session_(session), id_(qdmi::dd::Device::get()->generateUniqueID()) {}
/**
* @brief Frees the device job.
* @note This function just forwards to the session's @ref freeDeviceJob
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
*/

#include "mqt_na_qdmi/device.h"
#include "qdmi/devices/base/Device.hpp"

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <memory>
Expand All @@ -28,7 +28,8 @@
#include <vector>

namespace qdmi::na {
class Device final {
class Device final : public SingletonDevice<Device> {
friend class SingletonDevice;
/// @brief Provides access to the device name.
std::string name_;

Expand Down Expand Up @@ -69,35 +70,16 @@ class Device final {
/// @brief Private constructor to enforce the singleton pattern.
Device();

/// @brief The singleton instance.
static std::atomic<Device*> instance;

public:
// Default move constructor and move assignment operator.
Device(Device&&) = default;
Device& operator=(Device&&) = default;
Device(Device&&) = delete;
Device& operator=(Device&&) = delete;
// Delete copy constructor and assignment operator to enforce singleton.
Device(const Device&) = delete;
Device& operator=(const Device&) = delete;

/// @brief Destructor for the Device class.
~Device() = default;

/**
* @brief Initializes the singleton instance.
* @details Must be called before `get()`.
*/
static void initialize();

/**
* @brief Destroys the singleton instance.
* @details After this call, `get()` must not be called until a new
* `initialize()` call.
*/
static void finalize();

/// @returns the singleton instance of the Device class.
[[nodiscard]] static auto get() -> Device&;
~Device() override = default;

/**
* @brief Allocates a new device session.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,20 @@
*/

#include "mqt_sc_qdmi/device.h"
#include "qdmi/devices/base/Device.hpp"

#include <atomic>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
#include <variant>
#include <vector>

namespace qdmi::sc {
class Device final {
class Device final : public SingletonDevice<Device> {
friend class SingletonDevice;
/// @brief Provides access to the device name.
std::string name_;

Expand All @@ -52,9 +52,6 @@ class Device final {
/// @brief Private constructor to enforce the singleton pattern.
Device();

/// @brief The singleton instance.
static std::atomic<Device*> instance;

public:
// Delete move constructor and move assignment operator.
Device(Device&&) = delete;
Expand All @@ -64,23 +61,7 @@ class Device final {
Device& operator=(const Device&) = delete;

/// @brief Destructor for the Device class.
~Device();

/**
* @brief Initializes the singleton instance.
* @details Must be called before `get()`.
*/
static void initialize();

/**
* @brief Destroys the singleton instance.
* @details After this call, `get()` must not be called until a new
* `initialize()` call.
*/
static void finalize();

/// @returns the singleton instance of the Device class.
[[nodiscard]] static auto get() -> Device&;
~Device() override;

/**
* @brief Allocates a new device session.
Expand Down
1 change: 0 additions & 1 deletion src/na/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# Licensed under the MIT License

# add subdirectories
add_subdirectory(device)
add_subdirectory(fomac)

if(NOT TARGET ${MQT_CORE_TARGET_NAME}-na)
Expand Down
2 changes: 1 addition & 1 deletion src/na/fomac/Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

#include "fomac/FoMaC.hpp"
#include "ir/Definitions.hpp"
#include "na/device/Generator.hpp"
#include "qdmi/devices/na/Generator.hpp"

#include <algorithm>
#include <array>
Expand Down
33 changes: 6 additions & 27 deletions src/qdmi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,10 @@
#
# Licensed under the MIT License

add_subdirectory(dd)
add_subdirectory(sc)
add_subdirectory(devices)
add_subdirectory(driver)

set(TARGET_NAME ${MQT_CORE_TARGET_NAME}-qdmi-driver)

if(NOT TARGET ${TARGET_NAME})
# Add driver library
add_mqt_core_library(${TARGET_NAME} ALIAS_NAME QDMIDriver)

# Add sources to target
target_sources(${TARGET_NAME} PRIVATE Driver.cpp)

# Add headers using file sets
target_sources(${TARGET_NAME} PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_CORE_INCLUDE_BUILD_DIR}
FILES ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/Driver.hpp)

# Add link libraries
target_link_libraries(
${TARGET_NAME}
PUBLIC qdmi::qdmi
PRIVATE MQT::CoreQDMINaDevice MQT::CoreQDMIScDevice MQT::CoreQDMI_DDSIM_Device
qdmi::project_warnings)

# add to list of MQT core targets
set(MQT_CORE_TARGETS
${MQT_CORE_TARGETS} ${TARGET_NAME}
PARENT_SCOPE)
endif()
# add to list of MQT core targets
set(MQT_CORE_TARGETS
${MQT_CORE_TARGETS}
PARENT_SCOPE)
17 changes: 17 additions & 0 deletions src/qdmi/devices/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (c) 2023 - 2025 Chair for Design Automation, TUM
# Copyright (c) 2025 Munich Quantum Software Company GmbH
# All rights reserved.
#
# SPDX-License-Identifier: MIT
#
# Licensed under the MIT License

add_subdirectory(base)
add_subdirectory(na)
add_subdirectory(dd)
add_subdirectory(sc)

# add to list of MQT core targets
set(MQT_CORE_TARGETS
${MQT_CORE_TARGETS}
PARENT_SCOPE)
Loading
Loading