diff --git a/CHANGELOG.md b/CHANGELOG.md index fd2cac4e8..defdad043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ This project adheres to [Semantic Versioning], with the exception that minor rel ## [Unreleased] +### Changed + +- ♻️ Extract singleton pattern into reusable template base class for QDMI devices and driver ([#1444]) ([**@ystade**], [**@burgholzer**]) +- 🚚 Reorganize QDMI code structure by moving devices into dedicated subdirectories and separating driver and common utilities ([#1444]) ([**@ystade**]) + ## [3.4.0] - 2026-01-08 ### Added @@ -295,6 +300,7 @@ _📚 Refer to the [GitHub Release Notes](https://github.com/munich-quantum-tool +[#1444]: https://github.com/munich-quantum-toolkit/core/pull/1444 [#1415]: https://github.com/munich-quantum-toolkit/core/pull/1415 [#1414]: https://github.com/munich-quantum-toolkit/core/pull/1414 [#1413]: https://github.com/munich-quantum-toolkit/core/pull/1413 diff --git a/bindings/fomac/fomac.cpp b/bindings/fomac/fomac.cpp index 2475f5957..502ce3923 100644 --- a/bindings/fomac/fomac.cpp +++ b/bindings/fomac/fomac.cpp @@ -10,7 +10,7 @@ #include "fomac/FoMaC.hpp" -#include "qdmi/Driver.hpp" +#include "qdmi/driver/Driver.hpp" #include #include diff --git a/bindings/na/register_fomac.cpp b/bindings/na/register_fomac.cpp index e5e459dad..48ca699ca 100644 --- a/bindings/na/register_fomac.cpp +++ b/bindings/na/register_fomac.cpp @@ -10,7 +10,7 @@ #include "fomac/FoMaC.hpp" #include "na/fomac/Device.hpp" -#include "qdmi/na/Generator.hpp" +#include "qdmi/devices/na/Generator.hpp" #include #include diff --git a/include/mqt-core/fomac/FoMaC.hpp b/include/mqt-core/fomac/FoMaC.hpp index bd674167f..2e171cc6b 100644 --- a/include/mqt-core/fomac/FoMaC.hpp +++ b/include/mqt-core/fomac/FoMaC.hpp @@ -10,7 +10,7 @@ #pragma once -#include "qdmi/Common.hpp" +#include "qdmi/common/Common.hpp" #include #include diff --git a/include/mqt-core/na/fomac/Device.hpp b/include/mqt-core/na/fomac/Device.hpp index 77c784af6..e361c21a2 100644 --- a/include/mqt-core/na/fomac/Device.hpp +++ b/include/mqt-core/na/fomac/Device.hpp @@ -11,7 +11,7 @@ #pragma once #include "fomac/FoMaC.hpp" -#include "qdmi/na/Generator.hpp" +#include "qdmi/devices/na/Generator.hpp" // NOLINTNEXTLINE(misc-include-cleaner) #include diff --git a/include/mqt-core/qdmi/Common.hpp b/include/mqt-core/qdmi/common/Common.hpp similarity index 92% rename from include/mqt-core/qdmi/Common.hpp rename to include/mqt-core/qdmi/common/Common.hpp index a75172b23..b521ef32f 100644 --- a/include/mqt-core/qdmi/Common.hpp +++ b/include/mqt-core/qdmi/common/Common.hpp @@ -19,9 +19,40 @@ #include namespace qdmi { +template class Singleton { +protected: + /// @brief Protected constructor to enforce the singleton pattern. + Singleton() = default; + +public: + // Delete move constructor and move assignment operator because of the + // following reason: + // + // - Users access the singleton via get() which returns a reference + // - Moving would invalidate the singleton's state + // - Users never own the singleton instance + Singleton(Singleton&&) = delete; + Singleton& operator=(Singleton&&) = delete; + // Delete copy constructor and assignment operator to enforce singleton. + Singleton(const Singleton&) = delete; + Singleton& operator=(const Singleton&) = delete; + + /// @brief Virtual destructor for the Singleton base class. + virtual ~Singleton() = default; + + /// @returns the singleton instance of the derived class. + [[nodiscard]] static auto get() -> Concrete& { + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) + static auto* instance = new Concrete(); + // The instance is intentionally leaked to avoid static deinitialization + // issues (cf. static (de)initialization order fiasco) + return *instance; + } +}; + /** * @brief Function used to mark unreachable code - * @details Uses compiler specific extensions if possible. Even if no extension + * @details Uses compiler-specific extensions if possible. Even if no extension * is used, undefined behavior is still raised by an empty function body and the * noreturn attribute. */ diff --git a/include/mqt-core/qdmi/dd/Device.hpp b/include/mqt-core/qdmi/devices/dd/Device.hpp similarity index 94% rename from include/mqt-core/qdmi/dd/Device.hpp rename to include/mqt-core/qdmi/devices/dd/Device.hpp index 1b327eda7..d6e4350f1 100644 --- a/include/mqt-core/qdmi/dd/Device.hpp +++ b/include/mqt-core/qdmi/devices/dd/Device.hpp @@ -17,6 +17,7 @@ #include "dd/DDDefinitions.hpp" #include "dd/Package.hpp" #include "mqt_ddsim_qdmi/device.h" +#include "qdmi/common/Common.hpp" #include #include @@ -31,7 +32,9 @@ #include namespace qdmi::dd { -class Device final { +class Device final : public Singleton { + friend class Singleton; + /// Provides access to the device name. std::string name_; @@ -64,19 +67,6 @@ class Device final { Device(); public: - // Default move constructor and move assignment operator. - 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; - - /// @returns the singleton instance of the Device class. - [[nodiscard]] static auto get() -> Device&; - /** * @brief Allocates a new device session. * @see MQT_DDSIM_QDMI_device_session_alloc diff --git a/include/mqt-core/qdmi/na/Device.hpp b/include/mqt-core/qdmi/devices/na/Device.hpp similarity index 96% rename from include/mqt-core/qdmi/na/Device.hpp rename to include/mqt-core/qdmi/devices/na/Device.hpp index a75acb3e2..5a8b90c44 100644 --- a/include/mqt-core/qdmi/na/Device.hpp +++ b/include/mqt-core/qdmi/devices/na/Device.hpp @@ -15,6 +15,7 @@ */ #include "mqt_na_qdmi/device.h" +#include "qdmi/common/Common.hpp" #include #include @@ -27,7 +28,9 @@ #include namespace qdmi::na { -class Device final { +class Device final : public Singleton { + friend class Singleton; + /// @brief Provides access to the device name. std::string name_; @@ -69,19 +72,6 @@ class Device final { Device(); public: - // Default move constructor and move assignment operator. - Device(Device&&) = default; - Device& operator=(Device&&) = default; - // 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; - - /// @returns the singleton instance of the Device class. - [[nodiscard]] static auto get() -> Device&; - /** * @brief Allocates a new device session. * @see MQT_NA_QDMI_device_session_alloc diff --git a/include/mqt-core/qdmi/na/Generator.hpp b/include/mqt-core/qdmi/devices/na/Generator.hpp similarity index 100% rename from include/mqt-core/qdmi/na/Generator.hpp rename to include/mqt-core/qdmi/devices/na/Generator.hpp diff --git a/include/mqt-core/qdmi/sc/Device.hpp b/include/mqt-core/qdmi/devices/sc/Device.hpp similarity index 95% rename from include/mqt-core/qdmi/sc/Device.hpp rename to include/mqt-core/qdmi/devices/sc/Device.hpp index 31d4985cc..7a8f205fb 100644 --- a/include/mqt-core/qdmi/sc/Device.hpp +++ b/include/mqt-core/qdmi/devices/sc/Device.hpp @@ -15,6 +15,7 @@ */ #include "mqt_sc_qdmi/device.h" +#include "qdmi/common/Common.hpp" #include #include @@ -26,7 +27,9 @@ #include namespace qdmi::sc { -class Device final { +class Device final : public Singleton { + friend class Singleton; + /// @brief Provides access to the device name. std::string name_; @@ -51,19 +54,6 @@ class Device final { Device(); public: - // Delete move constructor and move assignment operator. - 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(); - - /// @returns the singleton instance of the Device class. - [[nodiscard]] static auto get() -> Device&; - /** * @brief Allocates a new device session. * @see MQT_SC_QDMI_device_session_alloc diff --git a/include/mqt-core/qdmi/sc/Generator.hpp b/include/mqt-core/qdmi/devices/sc/Generator.hpp similarity index 100% rename from include/mqt-core/qdmi/sc/Generator.hpp rename to include/mqt-core/qdmi/devices/sc/Generator.hpp diff --git a/include/mqt-core/qdmi/Driver.hpp b/include/mqt-core/qdmi/driver/Driver.hpp similarity index 96% rename from include/mqt-core/qdmi/Driver.hpp rename to include/mqt-core/qdmi/driver/Driver.hpp index 6ee08f3b2..0b3abe2d7 100644 --- a/include/mqt-core/qdmi/Driver.hpp +++ b/include/mqt-core/qdmi/driver/Driver.hpp @@ -10,6 +10,8 @@ #pragma once +#include "qdmi/common/Common.hpp" + #include #include #include @@ -18,7 +20,6 @@ #include #include #include -#include #include namespace qdmi { @@ -393,7 +394,9 @@ namespace qdmi { * sessions. It is responsible for loading the libraries, allocating sessions, * and providing access to the devices. */ -class Driver final { +class Driver final : public Singleton { + friend class Singleton; + /// @brief Private constructor to enforce the singleton pattern. Driver(); @@ -410,21 +413,6 @@ class Driver final { sessions_; public: - // Delete copy constructors and assignment operators to prevent copying the - // singleton instance. - Driver(const Driver&) = delete; - Driver& operator=(const Driver&) = delete; - Driver(Driver&&) = default; - Driver& operator=(Driver&&) = default; - - /// @brief Returns the singleton instance. - static auto get() -> Driver& { - static Driver instance; - return instance; - } - - /// @brief Destructor for the Driver class. - ~Driver(); /** * @brief Loads a dynamic device library and adds it to the driver. * diff --git a/src/fomac/FoMaC.cpp b/src/fomac/FoMaC.cpp index cd496eea3..ed31c931a 100644 --- a/src/fomac/FoMaC.cpp +++ b/src/fomac/FoMaC.cpp @@ -10,7 +10,7 @@ #include "fomac/FoMaC.hpp" -#include "qdmi/Common.hpp" +#include "qdmi/common/Common.hpp" #include #include diff --git a/src/na/fomac/Device.cpp b/src/na/fomac/Device.cpp index 1da6b8005..43895a88d 100644 --- a/src/na/fomac/Device.cpp +++ b/src/na/fomac/Device.cpp @@ -12,7 +12,7 @@ #include "fomac/FoMaC.hpp" #include "ir/Definitions.hpp" -#include "qdmi/na/Generator.hpp" +#include "qdmi/devices/na/Generator.hpp" #include #include diff --git a/src/qdmi/CMakeLists.txt b/src/qdmi/CMakeLists.txt index 18e84c219..6beb81f7a 100644 --- a/src/qdmi/CMakeLists.txt +++ b/src/qdmi/CMakeLists.txt @@ -6,56 +6,9 @@ # # Licensed under the MIT License -set(TARGET_NAME ${MQT_CORE_TARGET_NAME}-qdmi-common) - -if(NOT TARGET ${TARGET_NAME}) - # Add common library - add_mqt_core_library(${TARGET_NAME} ALIAS_NAME QDMICommon) - - # Add sources to target - target_sources(${TARGET_NAME} PRIVATE Common.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/Common.hpp) - - # Add link libraries - target_link_libraries( - ${TARGET_NAME} - PUBLIC qdmi::qdmi - PRIVATE qdmi::qdmi_project_warnings) - - # add to list of MQT core targets - list(APPEND MQT_CORE_TARGETS ${TARGET_NAME}) -endif() - -add_subdirectory(dd) -add_subdirectory(sc) -add_subdirectory(na) - -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 MQT::CoreQDMICommon - PRIVATE MQT::CoreQDMINaDevice MQT::CoreQDMIScDevice MQT::CoreQDMI_DDSIM_Device - qdmi::qdmi_project_warnings spdlog::spdlog ${CMAKE_DL_LIBS}) - - # add to list of MQT core targets - list(APPEND MQT_CORE_TARGETS ${TARGET_NAME}) -endif() +add_subdirectory(common) +add_subdirectory(devices) +add_subdirectory(driver) set(MQT_CORE_TARGETS ${MQT_CORE_TARGETS} diff --git a/src/qdmi/common/CMakeLists.txt b/src/qdmi/common/CMakeLists.txt new file mode 100644 index 000000000..cc8518339 --- /dev/null +++ b/src/qdmi/common/CMakeLists.txt @@ -0,0 +1,34 @@ +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +set(TARGET_NAME ${MQT_CORE_TARGET_NAME}-qdmi-common) + +if(NOT TARGET ${TARGET_NAME}) + # Add common library + add_mqt_core_library(${TARGET_NAME} ALIAS_NAME QDMICommon) + + # Add sources to target + target_sources(${TARGET_NAME} PRIVATE Common.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/common/Common.hpp) + + # Add link libraries + target_link_libraries( + ${TARGET_NAME} + PUBLIC qdmi::qdmi + PRIVATE qdmi::qdmi_project_warnings) + + # add to list of MQT core targets + list(APPEND MQT_CORE_TARGETS ${TARGET_NAME}) +endif() + +set(MQT_CORE_TARGETS + ${MQT_CORE_TARGETS} + PARENT_SCOPE) diff --git a/src/qdmi/Common.cpp b/src/qdmi/common/Common.cpp similarity index 97% rename from src/qdmi/Common.cpp rename to src/qdmi/common/Common.cpp index f998d3842..01cd7acc8 100644 --- a/src/qdmi/Common.cpp +++ b/src/qdmi/common/Common.cpp @@ -12,7 +12,7 @@ /// @brief Common definitions and utilities for working with QDMI in C++. /// @note This file will be upstreamed to the QDMI core library in the future. -#include "qdmi/Common.hpp" +#include "qdmi/common/Common.hpp" #include #include diff --git a/src/qdmi/devices/CMakeLists.txt b/src/qdmi/devices/CMakeLists.txt new file mode 100644 index 000000000..8977e7892 --- /dev/null +++ b/src/qdmi/devices/CMakeLists.txt @@ -0,0 +1,15 @@ +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +add_subdirectory(dd) +add_subdirectory(sc) +add_subdirectory(na) + +set(MQT_CORE_TARGETS + ${MQT_CORE_TARGETS} + PARENT_SCOPE) diff --git a/src/qdmi/dd/CMakeLists.txt b/src/qdmi/devices/dd/CMakeLists.txt similarity index 90% rename from src/qdmi/dd/CMakeLists.txt rename to src/qdmi/devices/dd/CMakeLists.txt index b6d1b0a45..374547713 100644 --- a/src/qdmi/dd/CMakeLists.txt +++ b/src/qdmi/devices/dd/CMakeLists.txt @@ -34,7 +34,7 @@ if(NOT TARGET ${TARGET_NAME}) ${MQT_CORE_INCLUDE_BUILD_DIR} ${CMAKE_CURRENT_BINARY_DIR}/include FILES - ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/dd/Device.hpp + ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/devices/dd/Device.hpp ${QDMI_HDRS}) # Add link libraries @@ -48,9 +48,7 @@ if(NOT TARGET ${TARGET_NAME}) set_target_properties(${TARGET_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) # Add to list of MQT Core targets - set(MQT_CORE_TARGETS - ${MQT_CORE_TARGETS} ${TARGET_NAME} - PARENT_SCOPE) + list(APPEND MQT_CORE_TARGETS ${TARGET_NAME}) # Make QDMI version available target_compile_definitions(${TARGET_NAME} PRIVATE QDMI_VERSION="${QDMI_VERSION}") @@ -59,3 +57,7 @@ if(NOT TARGET ${TARGET_NAME}) # in the tests add_library(qdmi::mqt_ddsim_device ALIAS ${TARGET_NAME}) endif() + +set(MQT_CORE_TARGETS + ${MQT_CORE_TARGETS} + PARENT_SCOPE) diff --git a/src/qdmi/dd/Device.cpp b/src/qdmi/devices/dd/Device.cpp similarity index 98% rename from src/qdmi/dd/Device.cpp rename to src/qdmi/devices/dd/Device.cpp index 7d41b1c0e..784c0c1f4 100644 --- a/src/qdmi/dd/Device.cpp +++ b/src/qdmi/devices/dd/Device.cpp @@ -12,7 +12,7 @@ * @brief The MQT QDMI device implementation for its DD-based simulator. */ -#include "qdmi/dd/Device.hpp" +#include "qdmi/devices/dd/Device.hpp" #include "circuit_optimizer/CircuitOptimizer.hpp" #include "dd/DDDefinitions.hpp" @@ -22,7 +22,7 @@ #include "ir/QuantumComputation.hpp" #include "mqt_ddsim_qdmi/device.h" #include "qasm3/Importer.hpp" -#include "qdmi/Common.hpp" +#include "qdmi/common/Common.hpp" #include #include @@ -149,13 +149,6 @@ namespace qdmi::dd { Device::Device() : name_("MQT Core DDSIM QDMI Device"), qubitsNum_(std::numeric_limits<::dd::Qubit>::max()) {} -auto Device::get() -> Device& { - // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) - static auto* instance = new Device(); - // The instance is intentionally leaked to avoid static deinitialization - // issues (cf. static (de)initialization order fiasco) - return *instance; -} auto Device::sessionAlloc(MQT_DDSIM_QDMI_Device_Session* session) -> QDMI_STATUS { if (session == nullptr) { diff --git a/src/qdmi/na/App.cpp b/src/qdmi/devices/na/App.cpp similarity index 99% rename from src/qdmi/na/App.cpp rename to src/qdmi/devices/na/App.cpp index 73f2e3cba..e6e7b524b 100644 --- a/src/qdmi/na/App.cpp +++ b/src/qdmi/devices/na/App.cpp @@ -8,7 +8,7 @@ * Licensed under the MIT License */ -#include "qdmi/na/Generator.hpp" +#include "qdmi/devices/na/Generator.hpp" #include #include diff --git a/src/qdmi/na/CMakeLists.txt b/src/qdmi/devices/na/CMakeLists.txt similarity index 95% rename from src/qdmi/na/CMakeLists.txt rename to src/qdmi/devices/na/CMakeLists.txt index 8af84570a..ce744459b 100644 --- a/src/qdmi/na/CMakeLists.txt +++ b/src/qdmi/devices/na/CMakeLists.txt @@ -19,8 +19,9 @@ if(NOT TARGET ${TARGET_NAME}) target_sources(${TARGET_NAME} PRIVATE Generator.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/na/Generator.hpp) + target_sources( + ${TARGET_NAME} PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_CORE_INCLUDE_BUILD_DIR} FILES + ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/devices/na/Generator.hpp) # Link nlohmann_json and spdlog target_link_libraries( @@ -116,7 +117,7 @@ if(NOT TARGET ${TARGET_NAME}) ${CMAKE_CURRENT_BINARY_DIR}/include FILES ${DEVICE_HDR} - ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/na/Device.hpp + ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/devices/na/Device.hpp ${QDMI_HDRS}) # add link libraries @@ -160,7 +161,7 @@ if(NOT TARGET ${TARGET_NAME}) ${CMAKE_CURRENT_BINARY_DIR}/include FILES ${DEVICE_HDR} - ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/na/Device.hpp + ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/devices/na/Device.hpp ${QDMI_HDRS}) # add link libraries target_link_libraries( diff --git a/src/qdmi/na/Device.cpp b/src/qdmi/devices/na/Device.cpp similarity index 98% rename from src/qdmi/na/Device.cpp rename to src/qdmi/devices/na/Device.cpp index 695028a6b..4fd5fd302 100644 --- a/src/qdmi/na/Device.cpp +++ b/src/qdmi/devices/na/Device.cpp @@ -12,10 +12,10 @@ * @brief The MQT QDMI device implementation for neutral atom devices. */ -#include "qdmi/na/Device.hpp" +#include "qdmi/devices/na/Device.hpp" #include "mqt_na_qdmi/device.h" -#include "qdmi/Common.hpp" +#include "qdmi/common/Common.hpp" #include "qdmi/na/DeviceMemberInitializers.hpp" #include @@ -44,13 +44,6 @@ Device::Device() { INITIALIZE_SITES(sites_); INITIALIZE_OPERATIONS(operations_); } -auto Device::get() -> Device& { - // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) - static auto* instance = new Device(); - // The instance is intentionally leaked to avoid static deinitialization - // issues (cf. static (de)initialization order fiasco) - return *instance; -} auto Device::sessionAlloc(MQT_NA_QDMI_Device_Session* session) -> int { if (session == nullptr) { return QDMI_ERROR_INVALIDARGUMENT; diff --git a/src/qdmi/na/DynDevice.cpp b/src/qdmi/devices/na/DynDevice.cpp similarity index 100% rename from src/qdmi/na/DynDevice.cpp rename to src/qdmi/devices/na/DynDevice.cpp diff --git a/src/qdmi/na/Generator.cpp b/src/qdmi/devices/na/Generator.cpp similarity index 99% rename from src/qdmi/na/Generator.cpp rename to src/qdmi/devices/na/Generator.cpp index 1bc805044..7b96e3d11 100644 --- a/src/qdmi/na/Generator.cpp +++ b/src/qdmi/devices/na/Generator.cpp @@ -12,7 +12,7 @@ * @brief The MQT QDMI device generator for neutral atom devices. */ -#include "qdmi/na/Generator.hpp" +#include "qdmi/devices/na/Generator.hpp" #include #include diff --git a/src/qdmi/sc/App.cpp b/src/qdmi/devices/sc/App.cpp similarity index 99% rename from src/qdmi/sc/App.cpp rename to src/qdmi/devices/sc/App.cpp index 5ea23fe61..6fb0783a2 100644 --- a/src/qdmi/sc/App.cpp +++ b/src/qdmi/devices/sc/App.cpp @@ -8,7 +8,7 @@ * Licensed under the MIT License */ -#include "qdmi/sc/Generator.hpp" +#include "qdmi/devices/sc/Generator.hpp" #include #include diff --git a/src/qdmi/sc/CMakeLists.txt b/src/qdmi/devices/sc/CMakeLists.txt similarity index 95% rename from src/qdmi/sc/CMakeLists.txt rename to src/qdmi/devices/sc/CMakeLists.txt index f685a4a92..91ce4588c 100644 --- a/src/qdmi/sc/CMakeLists.txt +++ b/src/qdmi/devices/sc/CMakeLists.txt @@ -19,8 +19,9 @@ if(NOT TARGET ${TARGET_NAME}) target_sources(${TARGET_NAME} PRIVATE Generator.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/sc/Generator.hpp) + target_sources( + ${TARGET_NAME} PUBLIC FILE_SET HEADERS BASE_DIRS ${MQT_CORE_INCLUDE_BUILD_DIR} FILES + ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/devices/sc/Generator.hpp) # Link nlohmann_json and spdlog target_link_libraries( @@ -113,7 +114,7 @@ if(NOT TARGET ${TARGET_NAME}) ${CMAKE_CURRENT_BINARY_DIR}/include FILES ${DEVICE_HDR} - ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/sc/Device.hpp + ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/devices/sc/Device.hpp ${QDMI_HDRS}) # add link libraries @@ -157,7 +158,7 @@ if(NOT TARGET ${TARGET_NAME}) ${CMAKE_CURRENT_BINARY_DIR}/include FILES ${DEVICE_HDR} - ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/sc/Device.hpp + ${MQT_CORE_INCLUDE_BUILD_DIR}/qdmi/devices/sc/Device.hpp ${QDMI_HDRS}) # add link libraries target_link_libraries( diff --git a/src/qdmi/sc/Device.cpp b/src/qdmi/devices/sc/Device.cpp similarity index 97% rename from src/qdmi/sc/Device.cpp rename to src/qdmi/devices/sc/Device.cpp index 241fc1d6c..f5c9448c9 100644 --- a/src/qdmi/sc/Device.cpp +++ b/src/qdmi/devices/sc/Device.cpp @@ -12,10 +12,10 @@ * @brief The MQT QDMI device implementation for superconducting devices. */ -#include "qdmi/sc/Device.hpp" +#include "qdmi/devices/sc/Device.hpp" #include "mqt_sc_qdmi/device.h" -#include "qdmi/Common.hpp" +#include "qdmi/common/Common.hpp" #include "qdmi/sc/DeviceMemberInitializers.hpp" #include @@ -43,17 +43,6 @@ Device::Device() { INITIALIZE_COUPLINGMAP(couplingMap_); INITIALIZE_OPERATIONS(operations_); } -Device::~Device() { - // Explicitly clear sessions before destruction to avoid spurious segfaults - sessions_.clear(); -} -auto Device::get() -> Device& { - // NOLINTNEXTLINE(cppcoreguidelines-owning-memory) - static auto* instance = new Device(); - // The instance is intentionally leaked to avoid static deinitialization - // issues (cf. static (de)initialization order fiasco) - return *instance; -} auto Device::sessionAlloc(MQT_SC_QDMI_Device_Session* session) -> int { if (session == nullptr) { return QDMI_ERROR_INVALIDARGUMENT; diff --git a/src/qdmi/sc/DynDevice.cpp b/src/qdmi/devices/sc/DynDevice.cpp similarity index 100% rename from src/qdmi/sc/DynDevice.cpp rename to src/qdmi/devices/sc/DynDevice.cpp diff --git a/src/qdmi/sc/Generator.cpp b/src/qdmi/devices/sc/Generator.cpp similarity index 99% rename from src/qdmi/sc/Generator.cpp rename to src/qdmi/devices/sc/Generator.cpp index 3a7bf3faf..71585e80a 100644 --- a/src/qdmi/sc/Generator.cpp +++ b/src/qdmi/devices/sc/Generator.cpp @@ -12,7 +12,7 @@ * @brief The MQT QDMI device generator for superconducting devices. */ -#include "qdmi/sc/Generator.hpp" +#include "qdmi/devices/sc/Generator.hpp" #include #include diff --git a/src/qdmi/driver/CMakeLists.txt b/src/qdmi/driver/CMakeLists.txt new file mode 100644 index 000000000..b80b26e7b --- /dev/null +++ b/src/qdmi/driver/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +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/Driver.hpp) + + # Add link libraries + target_link_libraries( + ${TARGET_NAME} + PUBLIC qdmi::qdmi MQT::CoreQDMICommon + PRIVATE MQT::CoreQDMINaDevice MQT::CoreQDMIScDevice MQT::CoreQDMI_DDSIM_Device + qdmi::qdmi_project_warnings spdlog::spdlog ${CMAKE_DL_LIBS}) + + # add to list of MQT core targets + list(APPEND MQT_CORE_TARGETS ${TARGET_NAME}) +endif() + +set(MQT_CORE_TARGETS + ${MQT_CORE_TARGETS} + PARENT_SCOPE) diff --git a/src/qdmi/Driver.cpp b/src/qdmi/driver/Driver.cpp similarity index 99% rename from src/qdmi/Driver.cpp rename to src/qdmi/driver/Driver.cpp index c746583c2..8bb0a8588 100644 --- a/src/qdmi/Driver.cpp +++ b/src/qdmi/driver/Driver.cpp @@ -8,12 +8,12 @@ * Licensed under the MIT License */ -#include "qdmi/Driver.hpp" +#include "qdmi/driver/Driver.hpp" #include "mqt_ddsim_qdmi/device.h" #include "mqt_na_qdmi/device.h" #include "mqt_sc_qdmi/device.h" -#include "qdmi/Common.hpp" +#include "qdmi/common/Common.hpp" #include #include @@ -394,11 +394,6 @@ Driver::Driver() { std::make_unique())); } -Driver::~Driver() { - sessions_.clear(); - devices_.clear(); -} - auto Driver::addDynamicDeviceLibrary(const std::string& libName, const std::string& prefix, const DeviceSessionConfig& config) diff --git a/test/fomac/test_fomac.cpp b/test/fomac/test_fomac.cpp index 3427dd0ed..52f61375a 100644 --- a/test/fomac/test_fomac.cpp +++ b/test/fomac/test_fomac.cpp @@ -9,7 +9,7 @@ */ #include "fomac/FoMaC.hpp" -#include "qdmi/Common.hpp" +#include "qdmi/common/Common.hpp" #include #include diff --git a/test/na/CMakeLists.txt b/test/na/CMakeLists.txt index 0ecf81be2..fa743e93b 100644 --- a/test/na/CMakeLists.txt +++ b/test/na/CMakeLists.txt @@ -12,5 +12,4 @@ if(TARGET MQT::CoreNA) target_link_libraries(mqt-core-na-test PRIVATE MQT::CoreQASM) endif() -add_subdirectory(device) add_subdirectory(fomac) diff --git a/test/qdmi/CMakeLists.txt b/test/qdmi/CMakeLists.txt index 65a59d24c..595fc88d1 100644 --- a/test/qdmi/CMakeLists.txt +++ b/test/qdmi/CMakeLists.txt @@ -6,17 +6,5 @@ # # Licensed under the MIT License -add_subdirectory(dd) -add_subdirectory(sc) - -set(TARGET_NAME mqt-core-qdmi-driver-test) - -if(TARGET MQT::CoreQDMIDriver) - package_add_test(${TARGET_NAME} MQT::CoreQDMIDriver test_driver.cpp) - add_dependencies(${TARGET_NAME} MQT::CoreQDMINaDeviceDyn MQT::CoreQDMIScDeviceDyn) - target_compile_definitions( - ${TARGET_NAME} - PRIVATE - "DYN_DEV_LIBS=std::array{ std::pair{\"$\", \"MQT_NA_DYN\"}, std::pair{\"$\", \"MQT_SC_DYN\"} }" - ) -endif() +add_subdirectory(devices) +add_subdirectory(driver) diff --git a/test/qdmi/devices/CMakeLists.txt b/test/qdmi/devices/CMakeLists.txt new file mode 100644 index 000000000..99cb9c88e --- /dev/null +++ b/test/qdmi/devices/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +add_subdirectory(dd) +add_subdirectory(na) +add_subdirectory(sc) diff --git a/test/qdmi/dd/CMakeLists.txt b/test/qdmi/devices/dd/CMakeLists.txt similarity index 100% rename from test/qdmi/dd/CMakeLists.txt rename to test/qdmi/devices/dd/CMakeLists.txt diff --git a/test/qdmi/dd/concurrency_test.cpp b/test/qdmi/devices/dd/concurrency_test.cpp similarity index 100% rename from test/qdmi/dd/concurrency_test.cpp rename to test/qdmi/devices/dd/concurrency_test.cpp diff --git a/test/qdmi/dd/device_properties_test.cpp b/test/qdmi/devices/dd/device_properties_test.cpp similarity index 100% rename from test/qdmi/dd/device_properties_test.cpp rename to test/qdmi/devices/dd/device_properties_test.cpp diff --git a/test/qdmi/dd/device_status_test.cpp b/test/qdmi/devices/dd/device_status_test.cpp similarity index 100% rename from test/qdmi/dd/device_status_test.cpp rename to test/qdmi/devices/dd/device_status_test.cpp diff --git a/test/qdmi/dd/error_handling_test.cpp b/test/qdmi/devices/dd/error_handling_test.cpp similarity index 100% rename from test/qdmi/dd/error_handling_test.cpp rename to test/qdmi/devices/dd/error_handling_test.cpp diff --git a/test/qdmi/dd/helpers/circuits.hpp b/test/qdmi/devices/dd/helpers/circuits.hpp similarity index 100% rename from test/qdmi/dd/helpers/circuits.hpp rename to test/qdmi/devices/dd/helpers/circuits.hpp diff --git a/test/qdmi/dd/helpers/test_utils.cpp b/test/qdmi/devices/dd/helpers/test_utils.cpp similarity index 100% rename from test/qdmi/dd/helpers/test_utils.cpp rename to test/qdmi/devices/dd/helpers/test_utils.cpp diff --git a/test/qdmi/dd/helpers/test_utils.hpp b/test/qdmi/devices/dd/helpers/test_utils.hpp similarity index 100% rename from test/qdmi/dd/helpers/test_utils.hpp rename to test/qdmi/devices/dd/helpers/test_utils.hpp diff --git a/test/qdmi/dd/job_lifecycle_test.cpp b/test/qdmi/devices/dd/job_lifecycle_test.cpp similarity index 100% rename from test/qdmi/dd/job_lifecycle_test.cpp rename to test/qdmi/devices/dd/job_lifecycle_test.cpp diff --git a/test/qdmi/dd/job_parameters_test.cpp b/test/qdmi/devices/dd/job_parameters_test.cpp similarity index 100% rename from test/qdmi/dd/job_parameters_test.cpp rename to test/qdmi/devices/dd/job_parameters_test.cpp diff --git a/test/qdmi/dd/results_probabilities_test.cpp b/test/qdmi/devices/dd/results_probabilities_test.cpp similarity index 100% rename from test/qdmi/dd/results_probabilities_test.cpp rename to test/qdmi/devices/dd/results_probabilities_test.cpp diff --git a/test/qdmi/dd/results_sampling_test.cpp b/test/qdmi/devices/dd/results_sampling_test.cpp similarity index 100% rename from test/qdmi/dd/results_sampling_test.cpp rename to test/qdmi/devices/dd/results_sampling_test.cpp diff --git a/test/qdmi/dd/results_statevector_test.cpp b/test/qdmi/devices/dd/results_statevector_test.cpp similarity index 100% rename from test/qdmi/dd/results_statevector_test.cpp rename to test/qdmi/devices/dd/results_statevector_test.cpp diff --git a/test/qdmi/dd/session_lifecycle_test.cpp b/test/qdmi/devices/dd/session_lifecycle_test.cpp similarity index 100% rename from test/qdmi/dd/session_lifecycle_test.cpp rename to test/qdmi/devices/dd/session_lifecycle_test.cpp diff --git a/test/na/device/CMakeLists.txt b/test/qdmi/devices/na/CMakeLists.txt similarity index 100% rename from test/na/device/CMakeLists.txt rename to test/qdmi/devices/na/CMakeLists.txt diff --git a/test/na/device/test_app.cpp b/test/qdmi/devices/na/test_app.cpp similarity index 100% rename from test/na/device/test_app.cpp rename to test/qdmi/devices/na/test_app.cpp diff --git a/test/na/device/test_device.cpp b/test/qdmi/devices/na/test_device.cpp similarity index 99% rename from test/na/device/test_device.cpp rename to test/qdmi/devices/na/test_device.cpp index 0a6aa5c2a..0fcf69dce 100644 --- a/test/na/device/test_device.cpp +++ b/test/qdmi/devices/na/test_device.cpp @@ -9,7 +9,7 @@ */ #include "mqt_na_qdmi/device.h" -#include "qdmi/na/Generator.hpp" +#include "qdmi/devices/na/Generator.hpp" #include #include diff --git a/test/na/device/test_generator.cpp b/test/qdmi/devices/na/test_generator.cpp similarity index 98% rename from test/na/device/test_generator.cpp rename to test/qdmi/devices/na/test_generator.cpp index 3353a155d..28ead2ece 100644 --- a/test/na/device/test_generator.cpp +++ b/test/qdmi/devices/na/test_generator.cpp @@ -8,7 +8,7 @@ * Licensed under the MIT License */ -#include "qdmi/na/Generator.hpp" +#include "qdmi/devices/na/Generator.hpp" #include #include diff --git a/test/qdmi/sc/CMakeLists.txt b/test/qdmi/devices/sc/CMakeLists.txt similarity index 100% rename from test/qdmi/sc/CMakeLists.txt rename to test/qdmi/devices/sc/CMakeLists.txt diff --git a/test/qdmi/sc/test_app.cpp b/test/qdmi/devices/sc/test_app.cpp similarity index 100% rename from test/qdmi/sc/test_app.cpp rename to test/qdmi/devices/sc/test_app.cpp diff --git a/test/qdmi/sc/test_device.cpp b/test/qdmi/devices/sc/test_device.cpp similarity index 100% rename from test/qdmi/sc/test_device.cpp rename to test/qdmi/devices/sc/test_device.cpp diff --git a/test/qdmi/sc/test_generator.cpp b/test/qdmi/devices/sc/test_generator.cpp similarity index 97% rename from test/qdmi/sc/test_generator.cpp rename to test/qdmi/devices/sc/test_generator.cpp index ea3b55642..fe2031371 100644 --- a/test/qdmi/sc/test_generator.cpp +++ b/test/qdmi/devices/sc/test_generator.cpp @@ -8,7 +8,7 @@ * Licensed under the MIT License */ -#include "qdmi/sc/Generator.hpp" +#include "qdmi/devices/sc/Generator.hpp" #include #include diff --git a/test/qdmi/driver/CMakeLists.txt b/test/qdmi/driver/CMakeLists.txt new file mode 100644 index 000000000..e13d1cb00 --- /dev/null +++ b/test/qdmi/driver/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (c) 2023 - 2026 Chair for Design Automation, TUM +# Copyright (c) 2025 - 2026 Munich Quantum Software Company GmbH +# All rights reserved. +# +# SPDX-License-Identifier: MIT +# +# Licensed under the MIT License + +set(TARGET_NAME mqt-core-qdmi-driver-test) + +if(TARGET MQT::CoreQDMIDriver) + package_add_test(${TARGET_NAME} MQT::CoreQDMIDriver test_driver.cpp) + add_dependencies(${TARGET_NAME} MQT::CoreQDMINaDeviceDyn MQT::CoreQDMIScDeviceDyn) + target_compile_definitions( + ${TARGET_NAME} + PRIVATE + "DYN_DEV_LIBS=std::array{ std::pair{\"$\", \"MQT_NA_DYN\"}, std::pair{\"$\", \"MQT_SC_DYN\"} }" + ) +endif() diff --git a/test/qdmi/test_driver.cpp b/test/qdmi/driver/test_driver.cpp similarity index 99% rename from test/qdmi/test_driver.cpp rename to test/qdmi/driver/test_driver.cpp index fd12c1781..e95ce57e9 100644 --- a/test/qdmi/test_driver.cpp +++ b/test/qdmi/driver/test_driver.cpp @@ -8,7 +8,7 @@ * Licensed under the MIT License */ -#include "qdmi/Driver.hpp" +#include "qdmi/driver/Driver.hpp" #include #include