Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ CMake options (full table in `docs/getting-started.md`):
- `DAQIRI_ENABLE_S3` — enable AWS SDK-backed asynchronous raw packet writes to S3 (off by default).
- `DAQIRI_PREFER_SYSTEM_YAML_CPP` — prefer system `yaml-cpp` over the vendored `third_party/yaml-cpp` submodule (off by default; keep off when a conda/miniforge env is on `PATH`).

Package versions use CalVer (`YYYY.MM.PATCH`) from the top-level `VERSION` file. CMake reads that value into `project(daqiri VERSION ...)`, generates `daqiri/version.h`, feeds pkg-config/CMake package metadata, and exposes the same value in Python. `DAQIRI_ABI_VERSION` is separate and currently `0`; do not tie ABI policy to the CalVer year.

CUDA architectures default to `80;90` (A100, H100), with `121` (GB10) added when configuring with CUDA Toolkit 13.0 or newer. Override `CMAKE_CUDA_ARCHITECTURES` when targeting other GPUs.

**Socket / ibverbs relationship**: the socket engine is always built and provides UDP/TCP directly; its RoCE path delegates to the `ibverbs` engine (internally the `rdma` engine — `src/engines/rdma/`, target `daqiri_rdma`, define `DAQIRI_ENGINE_RDMA`; `ibverbs` is only the user-facing name). `src/CMakeLists.txt` builds the ibverbs/rdma engine only when `ibverbs` is in `DAQIRI_ENGINE`, and the socket engine links it conditionally — so `socket` RoCE is available only when `ibverbs` was built, while plain UDP/TCP always works.
Expand Down Expand Up @@ -68,6 +70,8 @@ clang-format -style=file -i -fallback-style=none <files>

**Single C++/CUDA shared library** (`libdaqiri.so`) exposing a C++ API through `#include <daqiri/daqiri.h>`. The public surface is intentionally flat free-function helpers (`get_rx_burst`, `get_packet_ptr`, `set_udp_header`, …) that all operate on opaque DAQIRI-owned buffers. Applications never touch engine types directly.

`include/daqiri/daqiri.h` also includes the generated `daqiri/version.h`, exposing `DAQIRI_VERSION`, CalVer component macros, `DAQIRI_ABI_VERSION`, and inline helpers such as `daqiri::version_string()` and `daqiri::abi_version()`.

### Engine abstraction
`src/engine.h` defines `daqiri::Engine` — an (almost) ABC with ~50 virtual methods covering init, RX/TX burst dequeue/enqueue, header-fill helpers, buffer free, and RDMA connection setup. Engines live in `src/engines/<name>/` (`dpdk/`, `rdma/`, `socket/`, `ibverbs/`). `DAQIRI_ENGINE` selects the optional `dpdk` and `ibverbs` engines at CMake configure time; the `socket` engine is always built. The user-facing value `ibverbs` builds **two** internal engines that both use libibverbs: `rdma` (`src/engines/rdma/`, `DAQIRI_ENGINE_RDMA`, RoCE/InfiniBand for socket `roce://`) and `ibverbs` (`src/engines/ibverbs/`, `DAQIRI_ENGINE_IBVERBS`, the pure-DevX MPRQ raw-Ethernet engine). Each engine produces its own static library (`daqiri_dpdk`, `daqiri_rdma`, `daqiri_socket`, `daqiri_ibverbs`) linked into `daqiri_common`, and each adds a `DAQIRI_ENGINE_<NAME>=1` compile definition.

Expand Down Expand Up @@ -124,7 +128,7 @@ The web docs live in `docs/` and are built with [MkDocs Material](https://squidf

**Keeping docs in sync with code:** before committing changes, scan for the recurring drift hotspots:
- **Stream-type list** (`src/engines/*/`) — README Engines table, `docs/getting-started.md`, `docs/concepts.md` (Stream Types section + Support and testing admonition), `docs/api-reference/configuration.md`
- **CMake options / `DAQIRI_ENGINE` default** (`src/CMakeLists.txt:137`) — README Quick Start, `docs/getting-started.md`, this file's Build & run section
- **CMake options / `DAQIRI_ENGINE` default** (`src/CMakeLists.txt`) — README Quick Start, `docs/getting-started.md`, this file's Build & run section
- **Benchmark binary or YAML names** (`examples/`) — the benchmark table above, `docs/benchmarks/raw_benchmarking.md`, the "Choosing an example config" decision tree in `docs/tutorials/configuration-walkthrough.md` (every YAML must have a leaf; CI's `scripts/check_doc_refs.py` enforces coverage), and per-platform performance docs (`docs/benchmarks/performance-*.md`)
- **Public API include** (`#include <daqiri/daqiri.h>`; source files under `include/daqiri/`) — `docs/api-reference/index.md`, `docs/api-reference/cpp.md`, `docs/api-reference/python.md`; if the change adds or renames a user-facing concept, also `docs/concepts.md`
- **Python bindings** (`python/daqiri_common_pybind.cpp`) — `docs/api-reference/python.md` (function reference tables, enums/classes tables, GIL Behavior section)
Expand Down
28 changes: 26 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,30 @@ if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(DAQIRI_USING_DEFAULT_CUDA_ARCHITECTURES ON)
endif()

project(daqiri VERSION 0.1.0 LANGUAGES C CXX CUDA)
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" DAQIRI_PROJECT_VERSION)
string(STRIP "${DAQIRI_PROJECT_VERSION}" DAQIRI_PROJECT_VERSION)
if(NOT DAQIRI_PROJECT_VERSION MATCHES "^([0-9][0-9][0-9][0-9])\\.([1-9]|1[0-2])\\.(0|[1-9][0-9]*)$")
message(FATAL_ERROR "VERSION must use CalVer format YYYY.MM.PATCH, for example 2026.7.0")
endif()

project(daqiri VERSION ${DAQIRI_PROJECT_VERSION} LANGUAGES C CXX CUDA)

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
find_package(CUDAToolkit REQUIRED)

set(DAQIRI_ABI_VERSION "0" CACHE STRING "DAQIRI shared library ABI version")
if(NOT DAQIRI_ABI_VERSION MATCHES "^(0|[1-9][0-9]*)$")
message(FATAL_ERROR "DAQIRI_ABI_VERSION must be a non-negative integer")
endif()

set(DAQIRI_GENERATED_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated/include")
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/daqiri_version.h.in
${DAQIRI_GENERATED_INCLUDE_DIR}/daqiri/version.h
@ONLY
)

if(DAQIRI_USING_DEFAULT_CUDA_ARCHITECTURES AND
CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0)
list(APPEND CMAKE_CUDA_ARCHITECTURES 121)
Expand Down Expand Up @@ -68,7 +86,7 @@ configure_package_config_file(
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/daqiriConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
COMPATIBILITY AnyNewerVersion
)

if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
Expand Down Expand Up @@ -150,3 +168,9 @@ install(
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
COMPONENT daqiri-cpp
)

install(
FILES ${DAQIRI_GENERATED_INCLUDE_DIR}/daqiri/version.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/daqiri
COMPONENT daqiri-cpp
)
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2026.7.0
34 changes: 34 additions & 0 deletions cmake/daqiri_version.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES.
* All rights reserved. SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#define DAQIRI_VERSION "@PROJECT_VERSION@"
#define DAQIRI_VERSION_YEAR @PROJECT_VERSION_MAJOR@
#define DAQIRI_VERSION_MONTH @PROJECT_VERSION_MINOR@
#define DAQIRI_VERSION_PATCH @PROJECT_VERSION_PATCH@
#define DAQIRI_ABI_VERSION @DAQIRI_ABI_VERSION@

namespace daqiri {

inline constexpr const char* version_string() noexcept { return DAQIRI_VERSION; }
inline constexpr int version_year() noexcept { return DAQIRI_VERSION_YEAR; }
inline constexpr int version_month() noexcept { return DAQIRI_VERSION_MONTH; }
inline constexpr int version_patch() noexcept { return DAQIRI_VERSION_PATCH; }
inline constexpr int abi_version() noexcept { return DAQIRI_ABI_VERSION; }

} // namespace daqiri
21 changes: 21 additions & 0 deletions docs/api-reference/cpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ For the terminology used here (*burst*, *segment*, *flow*, *queue*, *memory
region*, *zero-copy ownership*, *RX reorder*), keep the
[Concepts](../concepts.md) page open in a second tab.

## Version Metadata

DAQIRI package versions use CalVer in `YYYY.MM.PATCH` form. The public
`daqiri/daqiri.h` header includes `daqiri/version.h`, which exposes compile-time
macros and inline C++ helpers:

```cpp
#include <daqiri/daqiri.h>

static_assert(DAQIRI_VERSION_YEAR >= 2026);
const char *package_version = daqiri::version_string();
int abi = daqiri::abi_version();
```

`DAQIRI_ABI_VERSION` / `daqiri::abi_version()` is the shared-library ABI version
and is intentionally separate from the CalVer package version. The YAML
`common.version` field remains the configuration schema version.

## Initialization

```cpp
Expand Down Expand Up @@ -588,6 +606,9 @@ workflow sections above show the common call order and ownership rules.

| Function | Purpose |
| --- | --- |
| `version_string()` | Return the DAQIRI package version as `YYYY.MM.PATCH`. |
| `version_year()` / `version_month()` / `version_patch()` | Return the CalVer components. |
| `abi_version()` | Return the DAQIRI shared-library ABI version. |
| `daqiri_init(NetworkConfig &config)` | Initialize DAQIRI from an already-populated config object. |
| `daqiri_init(const std::string &yaml_string_or_path)` | Initialize from a YAML string or YAML file path. |
| `daqiri_init_from_yaml_string(const std::string &yaml_string)` | Initialize from YAML content. |
Expand Down
19 changes: 19 additions & 0 deletions docs/api-reference/python.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ import daqiri
The `daqiri` package re-exports the compiled `_daqiri` pybind11 module, so
application code uses one import.

DAQIRI package versions use CalVer in `YYYY.MM.PATCH` form. The Python package
exposes `daqiri.__version__`, `daqiri.__version_info__`, and
`daqiri.__abi_version__`; the ABI version is intentionally separate from the
CalVer package version. The YAML `common.version` field remains the
configuration schema version.

```python
import daqiri

print(daqiri.__version__)
print(daqiri.version_string(), daqiri.abi_version())
```

PyYAML is required at runtime when calling `daqiri_init()` with a Python `dict`
or a config-like object that provides `as_dict()`.

Expand Down Expand Up @@ -492,6 +505,9 @@ The workflow sections above show the common call order and ownership rules.

| Function | Purpose |
| --- | --- |
| `version_string()` | Return the DAQIRI package version as `YYYY.MM.PATCH`. |
| `version_year()` / `version_month()` / `version_patch()` | Return the CalVer components. |
| `abi_version()` | Return the DAQIRI shared-library ABI version. |
| `engine_type_from_string(str)` / `engine_type_to_string(type)` | Convert engine types. |
| `stream_type_from_string(str)` / `stream_type_to_string(type)` | Convert stream types. |
| `reorder_data_type_from_string(str)` / `reorder_data_type_to_string(type)` | Convert reorder data types. |
Expand Down Expand Up @@ -605,6 +621,9 @@ encapsulation/push rules are configured in YAML under `tx.flows`.
| `MAX_NUM_TX_QUEUES` | Maximum configured TX queues. |
| `MAX_INTERFACES` | Maximum configured interfaces. |
| `MAX_NUM_SEGS` | Maximum packet segments per burst. |
| `DAQIRI_VERSION` | DAQIRI package version as `YYYY.MM.PATCH`. |
| `DAQIRI_VERSION_YEAR` / `DAQIRI_VERSION_MONTH` / `DAQIRI_VERSION_PATCH` | CalVer components. |
| `DAQIRI_ABI_VERSION` | DAQIRI shared-library ABI version. |
| `DAQIRI_BURST_FLAG_REORDERED` | Burst flag indicating a reordered aggregate. |
| `DAQIRI_BURST_FLAG_REORDER_TIMEOUT` | Burst flag indicating a reorder timeout aggregate. |
| `MEM_ACCESS_LOCAL` | Local memory access flag. |
Expand Down
13 changes: 13 additions & 0 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,18 @@ find_package(daqiri REQUIRED)
target_link_libraries(my_app PRIVATE daqiri::daqiri)
```

DAQIRI uses CalVer package versions in `YYYY.MM.PATCH` form. Consumers that need
a minimum DAQIRI release can request it from CMake:

```cmake
find_package(daqiri 2026.7.0 REQUIRED)
```

Pkg-config consumers can use the installed `daqiri.pc` file:

```bash
c++ my_app.cpp -o my_app $(pkg-config --cflags --libs daqiri)
pkg-config --modversion daqiri
```

Both methods use the same public C++ include:
Expand All @@ -188,6 +196,11 @@ Both methods use the same public C++ include:
#include <daqiri/daqiri.h>
```

`daqiri/version.h` is included by `daqiri/daqiri.h` and provides
`DAQIRI_VERSION`, `daqiri::version_string()`, and related CalVer helpers.
DAQIRI's shared-library ABI version is tracked separately through
`DAQIRI_ABI_VERSION` / `daqiri::abi_version()`.

### CMake Options

| Option | Default | Description |
Expand Down
1 change: 1 addition & 0 deletions include/daqiri/daqiri.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@
#pragma once

#include <daqiri/common.h>
#include <daqiri/version.h>
14 changes: 14 additions & 0 deletions python/daqiri_common_pybind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,15 @@ PYBIND11_MODULE(_daqiri, m) {
m.attr("DAQIRI_BURST_FLAG_REORDERED") = DAQIRI_BURST_FLAG_REORDERED;
m.attr("DAQIRI_BURST_FLAG_REORDER_TIMEOUT") =
DAQIRI_BURST_FLAG_REORDER_TIMEOUT;
m.attr("__version__") = version_string();
m.attr("__version_info__") =
py::make_tuple(version_year(), version_month(), version_patch());
m.attr("__abi_version__") = abi_version();
m.attr("DAQIRI_VERSION") = DAQIRI_VERSION;
m.attr("DAQIRI_VERSION_YEAR") = DAQIRI_VERSION_YEAR;
m.attr("DAQIRI_VERSION_MONTH") = DAQIRI_VERSION_MONTH;
m.attr("DAQIRI_VERSION_PATCH") = DAQIRI_VERSION_PATCH;
m.attr("DAQIRI_ABI_VERSION") = DAQIRI_ABI_VERSION;
m.attr("MEM_ACCESS_LOCAL") =
py::int_(static_cast<uint32_t>(MEM_ACCESS_LOCAL));
m.attr("MEM_ACCESS_RDMA_WRITE") =
Expand Down Expand Up @@ -952,6 +961,11 @@ PYBIND11_MODULE(_daqiri, m) {

m.def("get_engine_type", static_cast<EngineType (*)()>(&get_engine_type),
"Get the current engine type");
m.def("version_string", &version_string, "Get the DAQIRI package version");
m.def("version_year", &version_year, "Get the DAQIRI CalVer year");
m.def("version_month", &version_month, "Get the DAQIRI CalVer month");
m.def("version_patch", &version_patch, "Get the DAQIRI CalVer patch number");
m.def("abi_version", &abi_version, "Get the DAQIRI shared library ABI version");
m.def("engine_type_from_string", &engine_type_from_string, "str"_a,
"Convert a string to an engine type");
m.def("engine_type_to_string", &engine_type_to_string, "type"_a,
Expand Down
5 changes: 5 additions & 0 deletions python/pybind11/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from . import _daqiri as _daqiri_module
from ._daqiri import * # noqa: F401,F403

__version__ = _daqiri_module.__version__
__version_info__ = _daqiri_module.__version_info__
__abi_version__ = _daqiri_module.__abi_version__
6 changes: 6 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ endif()
target_include_directories(daqiri_common
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
$<BUILD_INTERFACE:${DAQIRI_GENERATED_INCLUDE_DIR}>
$<BUILD_INTERFACE:${DAQIRI_SPDLOG_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE
Expand Down Expand Up @@ -232,6 +233,8 @@ set_target_properties(daqiri_common PROPERTIES
CUDA_RESOLVE_DEVICE_SYMBOLS ON
OUTPUT_NAME "daqiri"
EXPORT_NAME "daqiri"
VERSION "${CMAKE_PROJECT_VERSION}"
SOVERSION "${DAQIRI_ABI_VERSION}"
INSTALL_RPATH "$ORIGIN"
)
install(
Expand Down Expand Up @@ -323,6 +326,7 @@ foreach(ENGINE IN LISTS DAQIRI_ENGINE_INTERNAL_LIST)
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/..
${CMAKE_CURRENT_SOURCE_DIR}/../include
${DAQIRI_GENERATED_INCLUDE_DIR}
${DAQIRI_SPDLOG_INCLUDE_DIR}
)
target_link_libraries(${ENGINE_TARGET} PRIVATE CUDA::cudart ${DAQIRI_YAML_TARGET})
Expand All @@ -335,6 +339,8 @@ foreach(ENGINE IN LISTS DAQIRI_ENGINE_INTERNAL_LIST)
set_target_properties(${ENGINE_TARGET} PROPERTIES
OUTPUT_NAME "daqiri_${ENGINE_LOWER}"
EXPORT_NAME "${ENGINE_LOWER}"
VERSION "${CMAKE_PROJECT_VERSION}"
SOVERSION "${DAQIRI_ABI_VERSION}"
INSTALL_RPATH "$ORIGIN"
)
install(TARGETS ${ENGINE_TARGET}
Expand Down
4 changes: 3 additions & 1 deletion src/metrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#include "metrics.h"

#include <daqiri/version.h>

#include <array>
#include <atomic>
#include <mutex>
Expand Down Expand Up @@ -190,7 +192,7 @@ class Registry {
if (initialized_) { return; }

auto provider = otel::metrics::Provider::GetMeterProvider();
auto meter = provider->GetMeter("daqiri", "0.1.0");
auto meter = provider->GetMeter("daqiri", version_string());
rx_packets_ = meter->CreateInt64ObservableCounter(
"daqiri.rx.packets", "Packets received by DAQIRI", "{packet}");
tx_packets_ = meter->CreateInt64ObservableCounter(
Expand Down
Loading