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 89 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 72 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
3f7e2b5
Setup protobuf dep
ystade Jun 4, 2025
d6eaab9
Draft doc for NA QDMI device
ystade Jun 4, 2025
90a1ed8
🎨 Run pre-commit
ystade Jun 4, 2025
5b9e442
🐛 Fix license tool
ystade Jun 4, 2025
e08fde0
➕ Add QDMI to the party
ystade Jun 4, 2025
1d93600
➕ Add spdlog to the party
ystade Jun 4, 2025
2348278
✨ Implement device as singleton
ystade Jun 4, 2025
fbc3605
🎨 Improve error handling
ystade Jun 4, 2025
12eeb25
✅ Setup test infrastructure for qdmi device
ystade Jun 4, 2025
585e0a9
🐛 Fix device and tests
ystade Jun 4, 2025
d2d3c96
🐛 Try to fix some bugs related to QDMI version and protobuf
ystade Jun 4, 2025
c62f95a
🚧 Still fixing protobuf include
ystade Jun 4, 2025
b8bd40b
🐛 Finally fix build
ystade Jun 4, 2025
1792945
🎨 Write out JSON schema
ystade Jun 5, 2025
13a360d
🩹 Fix JSON schema write-out
ystade Jun 5, 2025
88a944c
📝 Add comment
ystade Jun 5, 2025
3c59017
🎨 Implement dummy job interface
ystade Jun 5, 2025
3eea7c7
✅ Fix tests
ystade Jun 5, 2025
b857905
🎨 Implement querying sites
ystade Jun 5, 2025
262b24a
✏️ Fix typo
ystade Jun 5, 2025
709c03b
♻️ Refactor structure and add documentation
ystade Jun 5, 2025
411ee8d
🎨 Implement operations and decoeherence times
ystade Jun 5, 2025
8dcdd3b
🎨 Expose operation properties
ystade Jun 5, 2025
04d9219
🎨 Restructure file
ystade Jun 5, 2025
c3635b7
🎨 Add shuttling operations
ystade Jun 5, 2025
c4a091e
🎨 Initialize units
ystade Jun 5, 2025
99a425b
🐛 Fix finalize
ystade Jun 5, 2025
8b63686
🐛 Fix test
ystade Jun 5, 2025
9e2650e
🎨 Imrpove naming of tests
ystade Jun 5, 2025
f4ca5a6
🍱 Add device.json
ystade Jun 5, 2025
6306815
🔥 Remove initialized
ystade Jun 6, 2025
18aadea
🎨 Use add mqt core library
ystade Jun 6, 2025
3b6917e
🚧 Start restructuring
ystade Jun 12, 2025
1d39c79
🎨 Update cmake config for gen
ystade Jun 13, 2025
c43a22f
✨ First version of generator
ystade Jun 13, 2025
91acdd5
🐛 Print proper version
ystade Jun 13, 2025
218cb3b
🎨 Resturcture, put everything in device
ystade Jun 13, 2025
802632e
🐛 Fix restructuring
ystade Jun 13, 2025
9f3ea65
🐛 Fix all remaining bugs
ystade Jun 13, 2025
a51992f
🔥 Remove outdated docs
ystade Jun 13, 2025
2c4db2e
⏪️ Revert target names
ystade Jun 13, 2025
747c251
🎨 Use unique ptr for sessions
ystade Jun 13, 2025
f9fa92f
✅ Incoporate number of qubits
ystade Jun 16, 2025
223343b
🎨 Improve documentation
ystade Jun 16, 2025
0e2250c
Potential fix for code scanning alert no. 602: For loop variable chan…
ystade Jun 18, 2025
92a5a72
🔥 Remove superfluous variable
ystade Jun 16, 2025
67b459b
🐛 Fix
ystade Jun 16, 2025
a63361e
🎨 Incorporate first changes from review
ystade Jun 20, 2025
50440bc
🎨 Adapt new proto def
ystade Jun 20, 2025
e5b6b25
📝 Add doc page
ystade Jun 20, 2025
db35039
🎨 Add comment in proto file
ystade Jun 20, 2025
27fd4c8
🎨 Update gen exec
ystade Jun 20, 2025
99ceec4
⬆️ Update QDMI
ystade Jun 20, 2025
1f19e7a
🎨 Remove doxygen left-over
ystade Jun 20, 2025
bb2c04f
🐛 Link spdlog header only
ystade Jun 25, 2025
19741bf
Revert "🐛 Link spdlog header only"
ystade Jun 25, 2025
8367dfa
🎨 Add missing header
ystade Jun 25, 2025
9b53d18
🎨 Configure protobuf
ystade Jun 25, 2025
833ae4e
🐛 Fix cmake config
ystade Jun 25, 2025
816af7e
✅ Increase test coverage
ystade Jun 25, 2025
2593953
🔧 Setup cmake structure for tests
ystade Jun 25, 2025
7353749
🎨 Cluster more tests into one target
ystade Jun 26, 2025
9c87cea
🎨 Fix incldues
ystade Jun 26, 2025
d773132
Add more try catch
ystade Jun 26, 2025
647bdb4
🎨 Fix includes
ystade Jun 26, 2025
f4e9512
🎨 Add module number to site props
ystade Jun 26, 2025
cb056e2
🧪 Add more tests for executable
ystade Jun 26, 2025
f1067fb
🐛 Fix generator
ystade Jun 26, 2025
30092b7
🐛 Try to fix MVSC build
ystade Jun 27, 2025
203f4a1
🔧 Small modification
ystade Jun 27, 2025
ebdc2b2
💚 Fix clang-tidy warning
ystade Jun 27, 2025
2b58953
💚 Remove GTEST_HAS_ABSL
ystade Jun 27, 2025
c16e971
🔥 Remove left-over
ystade Jun 27, 2025
2a4f341
🐛 Fix export target
ystade Jun 28, 2025
851caed
✅ Add more App.cpp tests
ystade Jun 28, 2025
a2db640
✅ More App tests
ystade Jun 28, 2025
3365330
✅ Imrpove testing of device
ystade Jun 28, 2025
2187999
✅ Add tests for generator
ystade Jun 28, 2025
6fa6a01
Merge remote-tracking branch 'origin/main' into qdmi-na-device
ystade Jun 28, 2025
92657e1
🐛 Fix test
ystade Jun 28, 2025
017608d
🎨 Add extent of lattices
ystade Jul 1, 2025
ff9ae40
🎨 Remove 'repeat' from lattice definition
ystade Jul 2, 2025
33c29da
🎨 Fix tests
ystade Jul 2, 2025
7411f92
Merge remote-tracking branch 'origin/main' into qdmi-na-device
ystade Jul 2, 2025
169eb91
💚 Work on CI warnings
ystade Jul 2, 2025
8613882
🔧 Comment ABSEIL inclusion
ystade Jul 2, 2025
d8e981e
🎨 Mark protobuf header as system header
ystade Jul 2, 2025
cbfb156
Revert "🔧 Comment ABSEIL inclusion"
ystade Jul 2, 2025
50af0ef
🔧 Fix config
ystade Jul 2, 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
3 changes: 2 additions & 1 deletion .license-tools-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
".mlir": "SLASH_STYLE",
".td": "SLASH_STYLE",
".yaml": "POUND_STYLE",
".toml": "POUND_STYLE"
".toml": "POUND_STYLE",
".proto": "SLASH_STYLE"
},
"exclude": [
"^\\.[^/]+",
Expand Down
59 changes: 59 additions & 0 deletions cmake/ExternalDependencies.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,23 @@ else()
list(APPEND FETCH_PACKAGES boost_mp)
endif()

# Abseil is required by GTest and Protobuf. To avoid version conflicts, we add this dependency
# centrally.
set(ABSL_VERSION
20250512.1
CACHE STRING "abseil-cpp version")
set(ABSL_URL https://github.com/abseil/abseil-cpp/archive/refs/tags/${ABSL_VERSION}.tar.gz)
# The install instruction for re2 cannot be disabled and they require the export targets from
# abseil.
set(ABSL_ENABLE_INSTALL
ON
CACHE BOOL "" FORCE)
set(ABSL_MSVC_STATIC_RUNTIME
OFF
CACHE BOOL "" FORCE)
FetchContent_Declare(abseil-cpp URL ${ABSL_URL} FIND_PACKAGE_ARGS ${ABSL_VERSION} CONFIG NAMES absl)
list(APPEND FETCH_PACKAGES abseil-cpp)

if(BUILD_MQT_CORE_TESTS)
set(gtest_force_shared_crt
ON
Expand All @@ -71,5 +88,47 @@ if(BUILD_MQT_CORE_TESTS)
list(APPEND FETCH_PACKAGES googletest)
endif()

set(Protobuf_VERSION
31.1
CACHE STRING "protobuf version")
set(Protobuf_URL
https://github.com/protocolbuffers/protobuf/releases/download/v${Protobuf_VERSION}/protobuf-${Protobuf_VERSION}.tar.gz
)
# the default of the following is ON, they are just here to make more explicit that they are
# required
set(protobuf_BUILD_PROTOBUF_BINARIES ON)
set(protobuf_BUILD_PROTOC_BINARIES ON)
set(protobuf_BUILD_LIBUPB ON)
# the default of the following is ON, but we do not need the tests
set(protobuf_BUILD_TESTS OFF)
set(protobuf_MSVC_STATIC_RUNTIME OFF)
FetchContent_Declare(protobuf URL ${Protobuf_URL} FIND_PACKAGE_ARGS ${Protobuf_VERSION} CONFIG
NAMES protobuf)
list(APPEND FETCH_PACKAGES protobuf)

# cmake-format: off
set(QDMI_VERSION 1.2.0
CACHE STRING "QDMI version")
set(QDMI_REV "9034e653a6e368579d99e352ecd8390e6e947bc6"
CACHE STRING "QDMI identifier (tag, branch or commit hash)")
set(QDMI_REPO_OWNER "Munich-Quantum-Software-Stack"
CACHE STRING "QDMI repository owner (change when using a fork)")
# cmake-format: on
FetchContent_Declare(
qdmi
GIT_REPOSITORY https://github.com/${QDMI_REPO_OWNER}/qdmi.git
GIT_TAG ${QDMI_REV}
FIND_PACKAGE_ARGS ${QDMI_VERSION})
list(APPEND FETCH_PACKAGES qdmi)

set(SPDLOG_VERSION
1.15.3
CACHE STRING "spdlog version")
set(SPDLOG_URL https://github.com/gabime/spdlog/archive/refs/tags/v${SPDLOG_VERSION}.tar.gz)
# Add position independent code for spdlog, this is required for python bindings on linux
set(SPDLOG_BUILD_PIC ON)
FetchContent_Declare(spdlog URL ${SPDLOG_URL} FIND_PACKAGE_ARGS ${SPDLOG_VERSION})
list(APPEND FETCH_PACKAGES spdlog)

# Make all declared dependencies available.
FetchContent_MakeAvailable(${FETCH_PACKAGES})
115 changes: 115 additions & 0 deletions docs/na_qdmi_device.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
file_format: mystnb
kernelspec:
name: python3
mystnb:
number_source_lines: true
---

# MQT Core Neutral Atom QDMI Device

## Objective

Compilation passes throughout MQT need information about the target device.
The Neutral Atom QDMI device provides a uniform way to provide the necessary information.
It defines a representation to easily provide static information in the form of a file.

<!-- todo: Explain how to use the device. -->

## Describing a Device

The basis of a device implementation is a specification in a JSON file.
These JSON files are defined on the basis of a protocol buffer schema that can be found in `proto/na/device.proto`.
During compilation, this JSON file is parsed and the corresponding C++ code is produced for the actual QDMI device implementation.
The C++ code is then compiled to a library that can be used by the QDMI driver.

### JSON Schema

An example instance of a device JSON file can be found in `json/na/device.json`.

#### Top-Level Fields

- **`name`** _(string)_: The name of the device.
- **`num_qubits`** _(integer)_: The total number of qubits in the device.
- **`traps`** _(array)_: A list of traps defining the qubit lattice structure.
- **`minAtomDistance`** _(number)_: The minimum distance between atoms in the lattice.
- **`globalSingleQubitOperations`** _(array)_: A list of global single-qubit operations supported by the device.
- **`globalMultiQubitOperations`** _(array)_: A list of global multi-qubit operations supported by the device.
- **`localSingleQubitOperations`** _(array)_: A list of local single-qubit operations supported by the device.
- **`localMultiQubitOperations`** _(array)_: A list of local multi-qubit operations supported by the device.
- **`shuttlingUnits`** _(array)_: A list of shuttling units for moving qubits.
- **`decoherenceTimes`** _(object)_: Decoherence times for the qubits.
- **`lengthUnit`** _(object)_: The unit of length used in the file.
- **`timeUnit`** _(object)_: The unit of time used in the file.

---

#### Detailed Field Descriptions

##### `traps` _(array of objects)_:

- **`latticeOrigin`** _(object)_: The origin of the lattice.
- **`x`** _(number)_: X-coordinate of the origin.
- **`y`** _(number)_: Y-coordinate of the origin.
- **`latticeVector1`** _(object)_: Defines one lattice vector.
- **`vector`** _(object)_: A vector in the lattice.
- **`x`** _(number)_: X-component of the vector.
- **`y`** _(number)_: Y-component of the vector.
- **`repeat`** _(integer)_: Number of repetitions of the vector.
- **`latticeVector2`** _(object)_: Defines the other lattice vector.
- **`vector`** _(object)_: A vector in the lattice.
- **`x`** _(number)_: X-component of the vector.
- **`y`** _(number)_: Y-component of the vector.
- **`repeat`** _(integer)_: Number of repetitions of the vector.
- **`sublatticeOffsets`** _(array of objects)_: Offsets for sublattices.
- **`x`** _(number)_: X-offset.
- **`y`** _(number)_: Y-offset.

##### `globalSingleQubitOperations` and `localSingleQubitOperations` _(array of objects)_:

- **`name`** _(string)_: The name of the operation.
- **`region`** _(object)_: The region where the operation is applied.
- **`origin`** _(object)_: The origin of the region.
- **`x`** _(number)_: X-coordinate of the origin.
- **`y`** _(number)_: Y-coordinate of the origin.
- **`size`** _(object)_: The size of the region.
- **`width`** _(number)_: Width of the region.
- **`height`** _(number)_: Height of the region.
- **`duration`** _(number)_: Duration of the operation.
- **`fidelity`** _(number)_: Fidelity of the operation.
- **`numParameters`** _(integer)_: Number of parameters for the operation.

##### `globalMultiQubitOperations` and `localMultiQubitOperations` _(array of objects)_:

- **`name`** _(string)_: The name of the operation.
- **`region`** _(object)_: The region where the operation is applied (same structure as above).
- **`interactionRadius`** _(number)_: Radius of interaction for the operation.
- **`blockingRadius`** _(number)_: Blocking radius for the operation.
- **`numQubits`** _(integer)_: Number of qubits involved in the operation.
- **`numParameters`** _(integer)_: Number of parameters for the operation.
- **`duration`** _(number)_: Duration of the operation.
- **`fidelity`** _(number)_: Fidelity of the operation.
- **`idlingFidelity`** _(number, optional)_: Fidelity when qubits are idle.

##### `shuttlingUnits` _(array of objects)_:

- **`name`** _(string)_: The name of the shuttling unit.
- **`region`** _(object)_: The region where the shuttling unit operates (same structure as above).
- **`numRows`** _(integer)_: Number of rows in the shuttling unit.
- **`numColumns`** _(integer)_: Number of columns in the shuttling unit.
- **`movingSpeed`** _(number)_: Speed of movement.
- **`loadDuration`** _(number)_: Duration to load a qubit.
- **`storeDuration`** _(number)_: Duration to store a qubit.
- **`loadFidelity`** _(number)_: Fidelity of loading a qubit.
- **`storeFidelity`** _(number)_: Fidelity of storing a qubit.
- **`numParameters`** _(integer)_: Number of parameters for the shuttling unit.

##### `decoherenceTimes` _(object)_:

- **`t1`** _(number)_: Relaxation time (T1) in the specified time unit.
- **`t2`** _(number)_: Dephasing time (T2) in the specified time unit.

##### `lengthUnit` and `timeUnit` _(objects)_:

- **`value`** _(number)_: The scaling factor for the unit.
- **`unit`** _(string)_: The unit of measurement (e.g., "um" for micrometers, "us" for microseconds).
73 changes: 73 additions & 0 deletions include/mqt-core/na/device/Generator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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

#include "na/device/device.pb.h"

#include <istream>
#include <ostream>
#include <string>

namespace na {
/**
* @brief Writes a JSON schema with default values for the device configuration
* to the specified output stream.
* @param os is the output stream to write the JSON schema to.
* @throws std::runtime_error if the JSON conversion fails.
*/
auto writeJSONSchema(std::ostream& os) -> void;

/**
* @brief Writes a JSON schema with default values for the device configuration
* to the specified path.
* @param path The path to write the JSON schema to.
* @throws std::runtime_error if the JSON conversion fails or the file cannot be
* opened.
*/
auto writeJSONSchema(const std::string& path) -> void;

/**
* @brief Parses the device configuration from an input stream.
* @param is is the input stream containing the JSON representation of the
* device configuration.
* @returns The parsed device configuration as a Protobuf message.
* @throws std::runtime_error if the JSON cannot be parsed.
*/
[[nodiscard]] auto readJSON(std::istream& is) -> Device;

/**
* @brief Parses the device configuration from a JSON file.
* @param path is the path to the JSON file containing the device configuration.
* @returns The parsed device configuration as a Protobuf message.
* @throws std::runtime_error if the JSON file does not exist, or the JSON file
* cannot be parsed.
*/
[[nodiscard]] auto readJSON(const std::string& path) -> Device;

/**
* @brief Writes a header file with the device configuration to the specified
* output stream.
* @param device is the protobuf representation of the device.
* @param os is the output stream to write the header file to.
* @throws std::runtime_error if the file cannot be opened or written to.
*/
auto writeHeader(const Device& device, std::ostream& os) -> void;

/**
* @brief Writes a header file with the device configuration to the specified
* path.
* @param device is the protobuf representation of the device.
* @param path is the path to write the header file to.
* @throws std::runtime_error if the file cannot be opened or written to.
*/
auto writeHeader(const Device& device, const std::string& path) -> void;

} // namespace na
Loading
Loading