Skip to content

✨ Neutral Atom QDMI Device #996

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 69 commits into
base: main
Choose a base branch
from
Draft

✨ Neutral Atom QDMI Device #996

wants to merge 69 commits into from

Conversation

ystade
Copy link
Collaborator

@ystade ystade commented Jun 13, 2025

Description

This PR adds a universal QDMI device implementation for neutral atom-based quantum computers. The device itself is specified in a JSON file whose structure is given by a protobuf definition. During compilation time, the JSON file is read and translated to C++ code similar to how TableGen works in the LLVM project.

Subsequent PRs will add a QDMI driver utilizing the new device and a FoMaC tailored to those neutral atom devices.

Checklist:

  • The pull request only contains commits that are focused and relevant to this change.
  • I have added appropriate tests that cover the new/changed functionality.
  • I have updated the documentation to reflect these changes.
  • I have added entries to the changelog for any noteworthy additions, changes, fixes or removals.
  • I have added migration instructions to the upgrade guide (if needed).
  • The changes follow the project's style guidelines and introduce no new warnings.
  • The changes are fully tested and pass the CI checks.
  • I have reviewed my own code changes.

@ystade
Copy link
Collaborator Author

ystade commented Jun 13, 2025

@burgholzer This PR is far from being ready, that's why it is labeled as Draft. However, it would be very helpful, if you could take a look at how the addition is structured and give feedback on this.

For context: The protobuf file in protocol/na/ is consumed by an executable defined in na/device/App.cpp. This executable parses the JSON in json/na/ and generates a C++ header files that is included in the na/device/Device.cpp file.

Copy link
Contributor

github-actions bot commented Jun 13, 2025

Cpp-Linter Report ⚠️

Some files did not pass the configured checks!

clang-tidy (v20.1.7) reports: 23 concern(s)
  • src/na/device/App.cpp:23:28: warning: [misc-include-cleaner]

    no header providing "std::string" is directly included

       16 | #include <vector>
       17 | 
       18 | namespace {
       19 | /**
       20 |  * Prints the usage information for the command line tool.
       21 |  * @param programName is the name of the program executable.
       22 |  */
       23 | auto printUsage(const std::string& programName) -> void {
          |                            ^
  • src/na/device/App.cpp:112:22: warning: [misc-include-cleaner]

    no header providing "uint8_t" is directly included

       14 | enum class Command : uint8_t {
          |                      ^
  • src/na/device/App.cpp:158:13: warning: [misc-include-cleaner]

    no header providing "std::pair" is directly included

       16 |     -> std::pair<Arguments, size_t> {
          |             ^
  • src/na/device/App.cpp:158:29: warning: [misc-include-cleaner]

    no header providing "size_t" is directly included

       14 |     -> std::pair<Arguments, size_t> {
          |                             ^
  • src/na/device/App.cpp:178:18: warning: [misc-include-cleaner]

    no header providing "std::invalid_argument" is directly included

       16 |       throw std::invalid_argument("Unknown argument: " + arg);
          |                  ^
  • src/na/device/App.cpp:275:5: warning: [bugprone-exception-escape]

    an exception may be thrown in function 'main' which should not throw exceptions

      275 | int main(int argc, char* argv[]) {
          |     ^
  • src/na/device/App.cpp:303:25: warning: [misc-include-cleaner]

    no header providing "std::exception" is directly included

       14 |     } catch (const std::exception& e) {
          |                         ^
  • src/na/device/App.cpp:317:14: warning: [misc-include-cleaner]

    no header providing "std::ignore" is directly included

       16 |         std::ignore = na::readJSON(validateArgs.jsonFile.value());
          |              ^
  • src/na/device/App.cpp:334:11: warning: [misc-include-cleaner]

    no header providing "na::Device" is directly included

       12 |       na::Device device;
          |           ^
  • src/na/device/Device.cpp:20:1: warning: [misc-include-cleaner]

    included header spdlog.h is not used directly

       20 | #include <spdlog/spdlog.h>
          | ^~~~~~~~~~~~~~~~~~~~~~~~~~
       21 | 
  • src/na/device/Device.cpp:24:28: warning: [misc-include-cleaner]

    no header providing "uint8_t" is directly included

       20 | #include <spdlog/spdlog.h>
       21 | 
       22 | namespace {
       23 | /// The status of the session.
       24 | enum class SessionStatus : uint8_t {
          |                            ^
  • src/na/device/Device.cpp:75:3: warning: [misc-include-cleaner]

    no header providing "int64_t" is directly included

       75 |   int64_t x; ///< X coordinate of the site in the lattice
          |   ^
  • src/na/device/Device.cpp:83:8: warning: [misc-include-cleaner]

    no header providing "std::string" is directly included

       21 |   std::string name;     ///< Name of the operation
          |        ^
  • src/na/device/Device.cpp:123:13: warning: [misc-include-cleaner]

    no header providing "std::vector" is directly included

       21 |     -> std::vector<std::unique_ptr<MQT_NA_QDMI_Site_impl_d>>& {
          |             ^
  • src/na/device/Device.cpp:123:25: warning: [misc-include-cleaner]

    no header providing "std::unique_ptr" is directly included

       20 |     -> std::vector<std::unique_ptr<MQT_NA_QDMI_Site_impl_d>>& {
          |                         ^
  • src/na/device/Device.cpp:163:13: warning: [misc-include-cleaner]

    no header providing "std::unordered_map" is directly included

       21 |     -> std::unordered_map<MQT_NA_QDMI_Device_Session,
          |             ^
  • src/na/device/Device.cpp:195:22: warning: [misc-include-cleaner]

    no header providing "strlen" is directly included

       20 |         if ((size) < strlen(prop_value) + 1) {                                 \
          |                      ^
  • src/na/device/Device.cpp:198:9: warning: [misc-include-cleaner]

    no header providing "strncpy" is directly included

      198 |         strncpy(static_cast<char*>(value), prop_value, size);                  \
          |         ^
  • src/na/device/Device.cpp:217:9: warning: [misc-include-cleaner]

    no header providing "memcpy" is directly included

      217 |         memcpy(static_cast<void*>(value),                                      \
          |         ^
  • src/na/device/Device.cpp:250:29: warning: [misc-include-cleaner]

    no header providing "std::make_unique" is directly included

      250 |   auto uniqueSession = std::make_unique<MQT_NA_QDMI_Device_Session_impl_d>();
          |                             ^
  • src/na/device/Device.cpp:252:53: warning: [misc-include-cleaner]

    no header providing "std::move" is directly included

       21 |                  .emplace(uniqueSession.get(), std::move(uniqueSession))
          |                                                     ^
  • src/na/device/Device.cpp:401:55: warning: [misc-include-cleaner]

    no header providing "uint64_t" is directly included

      401 |   ADD_SINGLE_VALUE_PROPERTY(QDMI_SITE_PROPERTY_INDEX, uint64_t, site->id, prop,
          |                                                       ^
  • src/na/device/Generator.cpp:117:20: warning: [clang-diagnostic-unused-function]

    unused function 'getLengthUnit'

      117 | [[nodiscard]] auto getLengthUnit(const Device& device) -> double {
          |                    ^~~~~~~~~~~~~

Have any feedback or feature suggestions? Share it here.

@ystade ystade mentioned this pull request Jun 20, 2025
8 tasks
@burgholzer burgholzer added feature New feature or request c++ Anything related to C++ code QDMI Anything related to QDMI labels Jun 20, 2025
@burgholzer burgholzer added this to the QDMI Support milestone Jun 20, 2025
@ystade
Copy link
Collaborator Author

ystade commented Jun 25, 2025

The new dependency of protobuf is still giving me a few headaches. Same as googletest it depends on abseil. However, when abseil is not installed, both fetch it but in different versions leading to two abseil libraries. Hence, the linker ignores the duplicate library and cannot find the abseil symbols at all during linking. This can either be fixed by installing abseil but in order not to enforce the installation of abseil to users of MQT Core, the other option is to fetch abseil centrally already in the MQT Core configuration.

When doing that, googletest can be instructed to use the available abseil by setting GTEST_HAS_ABSL ON. However, then googletest additionally requires re2. This then has also be added as a dependency in the MQT Core configuration.

Now, the ugly part comes: The cmake configuration of re2 does not allow to disable the generation of install targets. Simulteanously, the re2's install targets require the export targets from abseil, hence, ABSL_ENABLE_INSTALL is set to ON. In summary, this adds a lot of new install targets (that are btw not associated to any components). This then causes issues when building the Python wheel because before #1021 everything was installed into the wheel. After #1021 is merged this should be fixed for now.

However, when we want to ship the QDMI NA device at some point with the Python wheel, we need to be very careful what we include in the Python wheel. Because of #1021 together with the fact that the install targets of re2 do not belong to any component, those cannot be installed anymore in this setup. However, since we should not need to have protobuf itself in the wheel (the auto-generated QDMI NA device should suffice), we probably do not need to install protobuf including the abseil dependency. even if we need protobuf, this still might be possible, as protobuf does connect its install targets to components.

@ystade
Copy link
Collaborator Author

ystade commented Jun 25, 2025

In general, concerning abeil, re2 and perhaps protobuf and googletest we might want to consider to build the separately in the CI workflow, setup proper caching for them and install them such they can be found in MQT Core via find_package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Anything related to C++ code feature New feature or request QDMI Anything related to QDMI
Projects
No open projects
Status: No status
Development

Successfully merging this pull request may close these issues.

2 participants