diff --git a/.vscode/launch.json b/.vscode/launch.json
index ccd7bf5f..7bbe9a08 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1520,6 +1520,29 @@
}
]
},
+ {
+ "name": "(gdb) Holoinfer: tests",
+ "type": "cppdbg",
+ "request": "launch",
+ "program": "${command:cmake.buildDirectory}/gtests/HOLOINFER_TEST",
+ "args": [],
+ "stopAtEntry": false,
+ "cwd": "${command:cmake.buildDirectory}",
+ "externalConsole": false,
+ "MIMode": "gdb",
+ "setupCommands": [
+ {
+ "description": "Enable pretty-printing for gdb",
+ "text": "-enable-pretty-printing",
+ "ignoreFailures": true
+ },
+ {
+ "description": "Set Disassembly Flavor to Intel",
+ "text": "-gdb-set disassembly-flavor intel",
+ "ignoreFailures": true
+ }
+ ]
+ },
{
"name": "(gdb) Holoviz: functional tests",
"type": "cppdbg",
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 6174db62..91e12916 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -121,7 +121,10 @@
"ranges": "cpp",
"barrier": "cpp",
"latch": "cpp",
- "syncstream": "cpp"
+ "syncstream": "cpp",
+ "__functional_base_03": "cpp",
+ "annotated_ptr": "cpp",
+ "stream_ref": "cpp"
},
"git.alwaysSignOff": true,
"git.untrackedChanges": "separate",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 49f489b7..ad320d71 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,6 +32,7 @@ option(HOLOSCAN_DOWNLOAD_DATASETS "Download SDK Datasets" ON)
option(HOLOSCAN_BUILD_TESTS "Build Holoscan SDK Tests" ON)
option(HOLOSCAN_USE_CCACHE "Use ccache for building Holoscan SDK" OFF)
option(HOLOSCAN_INSTALL_EXAMPLE_SOURCE "Install the example source code" ON)
+option(HOLOSCAN_ENABLE_CLANG_TIDY "Enable use of clang-tidy" OFF)
# ##############################################################################
# # Prerequisite statements
@@ -254,6 +255,12 @@ install(DIRECTORY ${cli11_SOURCE_DIR}/include/CLI/
COMPONENT holoscan-core
)
+# Copy bundled spdlog headers
+install(DIRECTORY ${spdlog_SOURCE_DIR}/include/spdlog/
+ DESTINATION include/3rdparty/spdlog
+ COMPONENT holoscan-core
+)
+
# Copy version file
install(FILES ${${HOLOSCAN_PACKAGE_NAME}_BINARY_DIR}/include/holoscan/version_config.hpp
DESTINATION include/holoscan
@@ -268,6 +275,7 @@ install(DIRECTORY
${GXF_INCLUDE_DIR}/gxf/cuda
${GXF_INCLUDE_DIR}/gxf/logger
${GXF_INCLUDE_DIR}/gxf/multimedia
+ ${GXF_INCLUDE_DIR}/gxf/rmm
${GXF_INCLUDE_DIR}/gxf/serialization
${GXF_INCLUDE_DIR}/gxf/std
${GXF_INCLUDE_DIR}/gxf/ucx
@@ -438,6 +446,11 @@ if(HOLOSCAN_BUILD_TESTS)
add_test(NAME HOLOVIZ_UNIT_TEST COMMAND holoscan::viz::unittests)
endif()
+# If enabling clang-tidy
+if(HOLOSCAN_ENABLE_CLANG_TIDY)
+ set(CMAKE_CXX_CLANG_TIDY "clang-tidy;--checks=*,-llvmlibc-restrict-system-libc-headers,-fuchsia-default-arguments-calls,-llvmlibc-implementation-in-namespace,-readability-magic-numbers,-readability-identifier-length,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-altera-unroll-loops,-llvmlibc-callee-namespace,-google-build-using-namespace,-llvm-include-order,-bugprone-exception-escape,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-modernize-use-trailing-return-type,-altera-id-dependent-backward-branch,-fuchsia-default-arguments-declarations,-bugprone-easily-swappable-parameters,-clang-diagnostic-ignored-optimization-argument;--extra-arg=-std=c++17")
+endif()
+
if(HOLOSCAN_BUILD_PYTHON)
add_subdirectory(python)
endif()
diff --git a/CPPLINT.cfg b/CPPLINT.cfg
index 4bb37344..26abe35c 100644
--- a/CPPLINT.cfg
+++ b/CPPLINT.cfg
@@ -1,6 +1,7 @@
# mark cpp and cu files as header too so build/include_what_you_use will be applied
headers=cpp,cu,cuh,h,hpp
-filter=-build/header_guard,-readability/todo,-runtime/references,-build/c++11,-runtime/int,-build/include_subdir,-build/namespaces,-readability/casting
+# need -readability/nolint to ignore unrecognized NOLINT categories from clang-tidy
+filter=-build/header_guard,-readability/todo,-readability/nolint,-runtime/references,-build/c++11,-runtime/int,-build/include_subdir,-build/namespaces,-readability/casting
# CPPLINT.cfg file's 'exclude_files' option works only for file/folder names in the same directory as the .cfg file
# See https://github.com/google/styleguide/issues/220 for more details
exclude_files=\.cache|build|build-|install|data
diff --git a/DEVELOP.md b/DEVELOP.md
index b4eab4d0..cfaf1b63 100644
--- a/DEVELOP.md
+++ b/DEVELOP.md
@@ -81,15 +81,16 @@ To build the Holoscan SDK on a local environment, the following versions of dev
| Dependency | Min version | Needed by | Dockerfile stage |
|---|---|---|---|
-| CUDA | 12.2 | Core SDK | base |
+| CUDA | 12.6 | Core SDK | base |
| gRPC | 1.54.2 | Core SDK | grpc-builder |
-| UCX | 1.15.0 | Core SDK | ucx-builder |
-| GXF | 4.0 | Core SDK | gxf-downloader |
-| MOFED | 23.07 | ConnectX | mofed-installer |
-| TensorRT | 8.6.1 | Inference operator | base |
-| ONNX Runtime | 1.15.1 | Inference operator | onnxruntime-downloader |
-| LibTorch | 2.1.0 | Inference operator (torch plugin) | torch-downloader-[x86_64\|arm64] |
-| TorchVision | 0.16.0 | Inference operator (torch plugin) | torchvision-downloader-[x86_64\|arm64] |
+| UCX | 1.17.0 | Core SDK | base |
+| GXF | 4.1 | Core SDK | gxf-downloader |
+| MOFED | 24.07 | ConnectX | mofed-installer |
+| TensorRT | 10.3 | Inference operator | base |
+| NVPL | 24.03 | LibTorch | build |
+| ONNX Runtime | 1.18.1 | Inference operator | onnxruntime-downloader |
+| LibTorch | 2.5.0 | Inference operator (torch plugin) | torch-downloader-[x86_64\|arm64] |
+| TorchVision | 0.20.0 | Inference operator (torch plugin) | torchvision-downloader-[x86_64\|arm64] |
| Vulkan SDK | 1.3.216 | Holoviz operator | vulkansdk-builder |
| Vulkan loader and validation layers | 1.3.204 | Holoviz operator | dev |
| spirv-tools | 2022.1 | Holoviz operator | dev |
diff --git a/Dockerfile b/Dockerfile
index 64a597f3..a96dc1d1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -20,20 +20,19 @@
############################################################
# Dependencies ending in _YY.MM are built or extracted from
# the TensorRT or PyTorch NGC containers of that same version
-ARG ONNX_RUNTIME_VERSION=1.15.1_23.08
-ARG LIBTORCH_VERSION=2.1.0_23.08
-ARG TORCHVISION_VERSION=0.16.0_23.08
+ARG ONNX_RUNTIME_VERSION=1.18.1_38712740_24.08-cuda-12.6
+ARG LIBTORCH_VERSION=2.5.0_24.08
+ARG TORCHVISION_VERSION=0.20.0_24.08
ARG GRPC_VERSION=1.54.2
-ARG UCX_VERSION=1.15.0
-ARG GXF_VERSION=4.0_20240409_bc03d9d
-ARG MOFED_VERSION=23.10-2.1.3.1
+ARG GXF_VERSION=447_20241004_bf72709
+ARG MOFED_VERSION=24.07-0.6.1.0
############################################################
# Base image
############################################################
ARG GPU_TYPE=dgpu
-FROM nvcr.io/nvidia/tensorrt:23.08-py3 AS dgpu_base
-FROM nvcr.io/nvidia/tensorrt:23.12-py3-igpu AS igpu_base
+FROM nvcr.io/nvidia/tensorrt:24.08-py3 AS dgpu_base
+FROM nvcr.io/nvidia/tensorrt:24.08-py3-igpu AS igpu_base
FROM ${GPU_TYPE}_base AS base
ARG DEBIAN_FRONTEND=noninteractive
@@ -84,7 +83,7 @@ ARG ONNX_RUNTIME_VERSION
# note: built with CUDA and TensorRT providers
WORKDIR /opt/onnxruntime
RUN curl -S -L -# -o ort.tgz \
- https://edge.urm.nvidia.com/artifactory/sw-holoscan-thirdparty-generic-local/onnxruntime/onnxruntime-${ONNX_RUNTIME_VERSION}-cuda-12.2-$(uname -m).tar.gz
+ https://edge.urm.nvidia.com/artifactory/sw-holoscan-thirdparty-generic-local/onnxruntime/onnxruntime-${ONNX_RUNTIME_VERSION}-$(uname -m).tar.gz
RUN mkdir -p ${ONNX_RUNTIME_VERSION}
RUN tar -xf ort.tgz -C ${ONNX_RUNTIME_VERSION} --strip-components 2
@@ -96,15 +95,20 @@ ARG LIBTORCH_VERSION
ARG GPU_TYPE
# Download libtorch binaries from artifactory
-# note: extracted from nvcr.io/nvidia/pytorch:23.07-py3
+# note: extracted from nvcr.io/nvidia/pytorch:24.08-py3
WORKDIR /opt/libtorch/
RUN ARCH=$(uname -m) && if [ "$ARCH" = "aarch64" ]; then ARCH="${ARCH}-${GPU_TYPE}"; fi && \
curl -S -# -o libtorch.tgz -L \
https://edge.urm.nvidia.com/artifactory/sw-holoscan-thirdparty-generic-local/libtorch/libtorch-${LIBTORCH_VERSION}-${ARCH}.tar.gz
RUN mkdir -p ${LIBTORCH_VERSION}
RUN tar -xf libtorch.tgz -C ${LIBTORCH_VERSION} --strip-components 1
-# Remove kineto from config to remove warning, not needed by holoscan
+
+# Patch step to remove kineto from config to remove warning, not needed by holoscan
RUN find . -type f -name "*Config.cmake" -exec sed -i '/kineto/d' {} +
+# Patch step for CMake configuration warning
+COPY patches/libtorch.Caffe2.cmake.patch ${LIBTORCH_VERSION}/share/cmake/Caffe2/cuda.patch
+WORKDIR ${LIBTORCH_VERSION}
+RUN patch -p1 < share/cmake/Caffe2/cuda.patch
############################################################
# TorchVision
@@ -172,44 +176,21 @@ RUN UBUNTU_VERSION=$(cat /etc/lsb-release | grep DISTRIB_RELEASE | cut -d= -f2)
############################################################
# UCX
############################################################
-FROM mofed-installer AS ucx-builder
-ARG UCX_VERSION
-
-# Clone
-WORKDIR /opt/ucx/
-RUN git clone --depth 1 --branch v${UCX_VERSION} https://github.com/openucx/ucx.git src
-
-# Patch
-WORKDIR /opt/ucx/src
-RUN curl -L https://github.com/openucx/ucx/pull/9341.patch | git apply
+FROM build-tools AS ucx-patcher
-# Prerequisites to build
-RUN apt-get update \
- && apt-get install --no-install-recommends -y \
- libtool="2.4.6-*" \
- automake="1:1.16.5-*" \
- && rm -rf /var/lib/apt/lists/*
-
-# Build and install
-RUN ./autogen.sh
-WORKDIR /opt/ucx/build
-RUN ../src/contrib/configure-release-mt --with-cuda=/usr/local/cuda-12 \
- --prefix=/opt/ucx/${UCX_VERSION}
-RUN make -j $(( `nproc` > ${MAX_PROC} ? ${MAX_PROC} : `nproc` )) install
-
-# Apply patches for import and run
+# The base container provides custom builds of HPCX libraries without
+# the necessary rpath for non-containerized applications. We patch RPATH
+# for portability when we later repackage these libraries for distribution
+# outside of the container.
WORKDIR /opt/ucx/${UCX_VERSION}
-# patch cmake config
-RUN sed -i "s|set(prefix.*)|set(prefix \"$(pwd)\")|" lib/cmake/ucx/ucx-targets.cmake
-# patch rpath (relative to ORIGIN)
-RUN patchelf --set-rpath '$ORIGIN' lib/libuc*.so*
-RUN patchelf --set-rpath '$ORIGIN:$ORIGIN/..' lib/ucx/libuc*.so*
-RUN patchelf --set-rpath '$ORIGIN/../lib' bin/*
+RUN patchelf --set-rpath '$ORIGIN' /opt/hpcx/ucx/lib/libuc*.so* \
+ && patchelf --set-rpath '$ORIGIN:$ORIGIN/..' /opt/hpcx/ucx/lib/ucx/libuc*.so* \
+ && patchelf --set-rpath '$ORIGIN/../lib' /opt/hpcx/ucx/bin/*
############################################################
# GXF
############################################################
-FROM base AS gxf-builder
+FROM base AS gxf-downloader
ARG GXF_VERSION
WORKDIR /opt/nvidia/gxf
@@ -259,22 +240,21 @@ ENV GRPC=/opt/grpc/${GRPC_VERSION}
COPY --from=grpc-builder ${GRPC} ${GRPC}
ENV CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}:${GRPC}"
-# Copy UCX
-ARG UCX_VERSION
-ENV UCX=/opt/ucx/${UCX_VERSION}
-COPY --from=ucx-builder ${UCX} ${UCX}
-ENV PATH="${PATH}:${UCX}/bin"
-ENV CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}:${UCX}"
-# remove older version of UCX in hpcx install
-RUN rm -rf /opt/hpcx/ucx /usr/local/ucx
-RUN unset OPENUCX_VERSION
-# required for gxf_ucx.so to find ucx
-ENV LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${UCX}/lib"
+# Copy UCX and set other HPC-X runtime paths
+ENV HPCX=/opt/hpcx
+COPY --from=ucx-patcher ${HPCX}/ucx ${HPCX}/ucx
+ENV PATH="${PATH}:${HPCX}/ucx/bin:${HPCX}/ucc/bin:${HPCX}/ompi/bin"
+ENV CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}:${HPCX}/ucx"
+# Constrain HPCX's ld config to Holoscan/Torch explicit dependencies,
+# to prevent inadvertently picking up non-expected libraries
+RUN echo "${HPCX}/ucx/lib" > /etc/ld.so.conf.d/hpcx.conf \
+ && echo "${HPCX}/ucc/lib" >> /etc/ld.so.conf.d/hpcx.conf \
+ && echo "${HPCX}/ompi/lib" >> /etc/ld.so.conf.d/hpcx.conf
# Copy GXF
ARG GXF_VERSION
ENV GXF=/opt/nvidia/gxf/${GXF_VERSION}
-COPY --from=gxf-builder ${GXF} ${GXF}
+COPY --from=gxf-downloader ${GXF} ${GXF}
ENV CMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}:${GXF}"
# Setup Docker & NVIDIA Container Toolkit's apt repositories to enable DooD
@@ -289,6 +269,21 @@ RUN install -m 0755 -d /etc/apt/keyrings \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
+# Install NVIDIA Performance Libraries on arm64 dGPU platform
+# as a runtime requirement for the Holoinfer `libtorch` backend (2.5.0).
+ARG GPU_TYPE
+RUN if [[ $(uname -m) = "aarch64" && ${GPU_TYPE} = "dgpu" ]]; then \
+ curl -L https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/sbsa/cuda-keyring_1.1-1_all.deb -O \
+ && dpkg -i cuda-keyring_1.1-1_all.deb \
+ && apt-get update \
+ && apt-get install --no-install-recommends -y \
+ nvpl-blas=0.2.0.1-* \
+ nvpl-lapack=0.2.2.1-* \
+ && apt-get purge -y cuda-keyring \
+ && rm cuda-keyring_1.1-1_all.deb \
+ && rm -rf /var/lib/apt/lists/* \
+ ; fi
+
# APT INSTALLS
# valgrind - dynamic analysis
# clang-tidy - static analysis
diff --git a/NOTICE.txt b/NOTICE.txt
index ed6065c6..fc6ad65d 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -42,8 +42,8 @@ expected (https://github.com/TartanLlama/expected)
Licensed under CC0-1.0 (https://github.com/TartanLlama/expected/blob/v1.1.0/COPYING)
fmt (https://github.com/fmtlib/fmt)
-Copyright (c) 2012 - present, Victor Zverovich
-Licensed under MIT (https://github.com/fmtlib/fmt/blob/8.1.1/LICENSE.rst)
+Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
+Licensed under MIT (https://github.com/fmtlib/fmt/blob/10.1.1/LICENSE.rst)
GLFW (https://www.glfw.org/)
Copyright (c) 2002-2006 Marcus Geelnard
@@ -237,7 +237,7 @@ Licensed under Apache-2.0 (http://www.apache.org/licenses/LICENSE-2.0)
ONNX Runtime (https://github.com/microsoft/onnxruntime)
Copyright (c) Microsoft Corporation
-Licensed under MIT (https://github.com/microsoft/onnxruntime/blob/v1.15.1/LICENSE)
+Licensed under MIT (https://github.com/microsoft/onnxruntime/blob/v1.18.1/LICENSE)
openblas (https://packages.ubuntu.com/jammy/libopenblas0)
2011-2021 The OpenBLAS Project
@@ -275,12 +275,16 @@ RAPIDS rapids-cmake (https://github.com/rapidsai/rapids-cmake)
Copyright (c) 2020-2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
Licensed under Apache-2.0 (https://github.com/rapidsai/rapids-cmake/blob/branch-23.06/LICENSE)
+RMM (https://github.com/rapidsai/rmm)
+Copyright (c) 2018-2024, NVIDIA CORPORATION.
+Licensed under Apache 2.0 (https://github.com/rapidsai/rmm/blob/branch-24.04/LICENSE)
+
Google Fonts Roboto (https://github.com/googlefonts/roboto/releases/download/v2.138/roboto-android.zip)
Licensed under Apache-2.0 (https://github.com/googlefonts/roboto/blob/v2.138/LICENSE)
spdlog (https://github.com/gabime/spdlog)
Copyright (c) 2016 Gabi Melman.
-Licensed under MIT (https://github.com/gabime/spdlog/blob/v1.10.0/LICENSE)
+Licensed under MIT (https://github.com/gabime/spdlog/blob/v1.12.0/LICENSE)
spirv-tools (https://packages.ubuntu.com/jammy/spirv-tools)
2016-2017 Google Inc.
@@ -310,7 +314,7 @@ Copyright (C) 2016-2020 Advanced Micro Devices, Inc. All rights reserved.
Copyright (C) 2019 UChicago Argonne, LLC. All rights reserved.
Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
Copyright (C) 2016-2020 Stony Brook University. All rights reserved.
-Licensed under BSD-3-clause (https://github.com/openucx/ucx/blob/v1.15.0-rc2/LICENSE)
+Licensed under BSD-3-clause (https://github.com/openucx/ucx/blob/v1.17.0/LICENSE)
v4l-utils (https://packages.ubuntu.com/jammy/v4l-utils)
2006-2010 Mauro Carvalho Chehab
diff --git a/README.md b/README.md
index 085eeb8e..d094b6e5 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ The Holoscan User Guide includes:
- Requirements and setup steps;
- Detailed SDK documentation, including a developer introduction, examples, and API details.
-We also recommend visiting [NVIDIA HoloHub](https://nvidia-holoscan.github.io/holohub/) to view
+We also recommend visiting [NVIDIA HoloHub](https://github.com/nvidia-holoscan/holohub) to view
community projects and reusable components available for your Holoscan project.
## Obtaining the Holoscan SDK
@@ -54,7 +54,7 @@ and may include them in Holoscan SDK releases at our discretion. Please refer to
### Relation to NVIDIA Clara
-In previous releases, the prefix [`Clara`](https://developer.nvidia.com/industries/healthcare) was used to define Holoscan as a platform designed initially for [medical devices](https://www.nvidia.com/en-us/clara/developer-kits/). Starting with version 0.4.0, the Holoscan SDK is built to be domain-agnostic and can be used to build sensor AI applications in multiple domains. Domain specific content will be hosted on the [HoloHub](https://nvidia-holoscan.github.io/holohub) repository.
+In previous releases, the prefix [`Clara`](https://developer.nvidia.com/industries/healthcare) was used to define Holoscan as a platform designed initially for [medical devices](https://www.nvidia.com/en-us/clara/developer-kits/). Starting with version 0.4.0, the Holoscan SDK is built to be domain-agnostic and can be used to build sensor AI applications in multiple domains. Domain specific content will be hosted on the [HoloHub](https://github.com/nvidia-holoscan/holohub) repository.
### Repository structure
diff --git a/VERSION b/VERSION
index 437459cd..e70b4523 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.5.0
+2.6.0
diff --git a/cmake/deps/fmt_rapids.cmake b/cmake/deps/fmt_rapids.cmake
index f102de45..e3ca3635 100644
--- a/cmake/deps/fmt_rapids.cmake
+++ b/cmake/deps/fmt_rapids.cmake
@@ -1,4 +1,4 @@
-# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,13 +16,13 @@
# https://docs.rapids.ai/api/rapids-cmake/stable/command/rapids_cpm_find.html
include(${rapids-cmake-dir}/cpm/find.cmake)
-rapids_cpm_find(fmt 8.1.1
+rapids_cpm_find(fmt 10.1.1
GLOBAL_TARGETS fmt fmt-header-only
BUILD_EXPORT_SET ${HOLOSCAN_PACKAGE_NAME}-exports
CPM_ARGS
GITHUB_REPOSITORY fmtlib/fmt
- GIT_TAG 8.1.1
+ GIT_TAG 10.1.1
GIT_SHALLOW TRUE
OPTIONS
diff --git a/cmake/deps/gxf.cmake b/cmake/deps/gxf.cmake
index 33b9a7ca..de94264f 100644
--- a/cmake/deps/gxf.cmake
+++ b/cmake/deps/gxf.cmake
@@ -21,13 +21,14 @@ set(HOLOSCAN_GXF_COMPONENTS
gxe
logger
multimedia
+ rmm
sample # dependency of GXF::app
serialization
std
ucx
)
-find_package(GXF 4.0 CONFIG REQUIRED
+find_package(GXF 4.1 CONFIG REQUIRED
COMPONENTS ${HOLOSCAN_GXF_COMPONENTS}
)
message(STATUS "Found GXF: ${GXF_DIR}")
@@ -92,7 +93,7 @@ foreach(component ${HOLOSCAN_GXF_COMPONENTS})
)
# Patch `gxe` executable RUNPATH to find required GXF libraries in the self-contained HSDK installation.
- # GXF 4.0 libraries are entirely self-contained and do not require RPATH updates.
+ # GXF libraries are entirely self-contained and do not require RPATH updates.
find_program(PATCHELF_EXECUTABLE patchelf)
if(PATCHELF_EXECUTABLE)
execute_process(
diff --git a/cmake/deps/patches/rmm.patch b/cmake/deps/patches/rmm.patch
new file mode 100644
index 00000000..e51b3e14
--- /dev/null
+++ b/cmake/deps/patches/rmm.patch
@@ -0,0 +1,111 @@
+# SPDX-FileCopyrightText: Copyright (c) 2024 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.
+
+diff --git CMakeLists.txt CMakeLists.txt
+index 56454d4b..0a59296 100644
+--- CMakeLists.txt
++++ CMakeLists.txt
+@@ -12,7 +12,7 @@
+ # the License.
+ # =============================================================================
+
+-cmake_minimum_required(VERSION 3.26.4 FATAL_ERROR)
++cmake_minimum_required(VERSION 3.24.0 FATAL_ERROR)
+
+ include(rapids_config.cmake)
+
+@@ -131,6 +131,7 @@ endif()
+
+ # ##################################################################################################
+ # * install targets --------------------------------------------------------------------------------
++if(OFF) # disable exports in Holoscan SDK build
+
+ include(CPack)
+
+@@ -167,6 +168,7 @@ rapids_export(
+ NAMESPACE rmm::
+ DOCUMENTATION doc_string)
+
++endif()
+ # ##################################################################################################
+ # * make documentation -----------------------------------------------------------------------------
+
+diff --git include/rmm/cuda_stream_view.hpp include/rmm/cuda_stream_view.hpp
+index a34897d..231aae9 100644
+--- include/rmm/cuda_stream_view.hpp
++++ include/rmm/cuda_stream_view.hpp
+@@ -18,6 +18,7 @@
+
+ #include
+
++#define LIBCUDACXX_ENABLE_EXPERIMENTAL_MEMORY_RESOURCE
+ #include
+ #include
+
+diff --git include/rmm/logger.hpp include/rmm/logger.hpp
+index 6213221..edaf605 100644
+--- include/rmm/logger.hpp
++++ include/rmm/logger.hpp
+@@ -16,6 +16,7 @@
+
+ #pragma once
+
++#define FMT_HEADER_ONLY
+ #include
+ #include
+ #include
+
+diff --git include/rmm/mr/device/cuda_async_memory_resource.hpp include/rmm/mr/device/cuda_async_memory_resource.hpp
+index ac6b7207..702efae6 100644
+--- include/rmm/mr/device/cuda_async_memory_resource.hpp
++++ include/rmm/mr/device/cuda_async_memory_resource.hpp
+@@ -85,22 +85,22 @@ class cuda_async_memory_resource final : public device_memory_resource {
+ * resource should support interprocess communication (IPC). Default is
+ * `cudaMemHandleTypeNone` for no IPC support.
+ */
+- // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
+- template ,
+- thrust::optional>,
+- int> = 0>
+- [[deprecated("Use std::optional instead of thrust::optional.")]] //
+- explicit cuda_async_memory_resource(
+- Optional initial_pool_size,
+- Optional release_threshold = {},
+- thrust::optional export_handle_type = {})
+- : cuda_async_memory_resource(initial_pool_size.value_or(std::nullopt),
+- release_threshold.value_or(std::nullopt),
+- export_handle_type.value_or(std::nullopt))
++ // // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
++ // template ,
++ // thrust::optional>,
++ // int> = 0>
++ // [[deprecated("Use std::optional instead of thrust::optional.")]] //
++ // explicit cuda_async_memory_resource(
++ // Optional initial_pool_size,
++ // Optional release_threshold = {},
++ // thrust::optional export_handle_type = {})
++ // : cuda_async_memory_resource(initial_pool_size.value_or(std::nullopt),
++ // release_threshold.value_or(std::nullopt),
++ // export_handle_type.value_or(std::nullopt))
+
+- {
+- }
++ // {
++ // }
+
+ /**
+ * @brief Constructs a cuda_async_memory_resource with the optionally specified initial pool size
diff --git a/cmake/deps/pybind11.cmake b/cmake/deps/pybind11.cmake
index 4cebdcf5..3aa140e6 100644
--- a/cmake/deps/pybind11.cmake
+++ b/cmake/deps/pybind11.cmake
@@ -1,4 +1,4 @@
-# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,13 +17,13 @@
# https://docs.rapids.ai/api/rapids-cmake/stable/command/rapids_find_package.html#
include(${rapids-cmake-dir}/cpm/find.cmake)
-rapids_cpm_find(pybind11 2.11.1
+rapids_cpm_find(pybind11 2.13.6
GLOBAL_TARGETS pybind11
CPM_ARGS
GITHUB_REPOSITORY pybind/pybind11
- GIT_TAG v2.11.1
+ GIT_TAG v2.13.6
GIT_SHALLOW TRUE
EXCLUDE_FROM_ALL
)
diff --git a/cmake/deps/rmm.cmake b/cmake/deps/rmm.cmake
new file mode 100644
index 00000000..4fbde882
--- /dev/null
+++ b/cmake/deps/rmm.cmake
@@ -0,0 +1,40 @@
+# SPDX-FileCopyrightText: Copyright (c) 2022-2024 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.
+
+# https://docs.rapids.ai/api/rapids-cmake/stable/command/rapids_cpm_find.html
+include(${rapids-cmake-dir}/cpm/find.cmake)
+
+set(rmm_PATCH_FILEPATH "${CMAKE_SOURCE_DIR}/cmake/deps/patches/rmm.patch")
+
+rapids_cpm_find(rmm 24.04.00
+ GLOBAL_TARGETS rmm
+ BUILD_EXPORT_SET ${HOLOSCAN_PACKAGE_NAME}-exports
+ CPM_ARGS
+
+ GITHUB_REPOSITORY rapidsai/rmm
+ GIT_TAG v24.04.00
+ GIT_SHALLOW TRUE
+ PATCH_COMMAND git apply -p0 "${rmm_PATCH_FILEPATH}"
+
+ EXCLUDE_FROM_ALL
+)
+
+if(rmm_ADDED)
+ # Install the headers needed for development with the SDK
+ install(DIRECTORY ${rmm_SOURCE_DIR}/include/rmm
+ DESTINATION "include"
+ COMPONENT "holoscan-dependencies"
+ )
+endif()
diff --git a/cmake/deps/spdlog_rapids.cmake b/cmake/deps/spdlog_rapids.cmake
index 0fb2e5c2..74baaa7a 100644
--- a/cmake/deps/spdlog_rapids.cmake
+++ b/cmake/deps/spdlog_rapids.cmake
@@ -1,4 +1,4 @@
-# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,7 +19,7 @@ include(${rapids-cmake-dir}/cpm/find.cmake)
# Here we are using rapids_cpm_find() function instead of rapids_cpm_spdlog() function
# (https://docs.rapids.ai/api/rapids-cmake/stable/packages/rapids_cpm_spdlog.html), to
# override the default options.
-set(version 1.10.0)
+set(version 1.14.1)
rapids_cpm_find(spdlog ${version}
GLOBAL_TARGETS spdlog::spdlog spdlog::spdlog_header_only
diff --git a/cmake/deps/tensorrt.cmake b/cmake/deps/tensorrt.cmake
index b9f12e8e..1ce9cc25 100644
--- a/cmake/deps/tensorrt.cmake
+++ b/cmake/deps/tensorrt.cmake
@@ -1,4 +1,4 @@
-# SPDX-FileCopyrightText: Copyright (c) 2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,4 +13,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-find_package(TensorRT 8 MODULE REQUIRED)
+find_package(TensorRT 10 MODULE REQUIRED)
diff --git a/cmake/deps/ucx.cmake b/cmake/deps/ucx.cmake
index 20fa4f2f..af23ffc6 100644
--- a/cmake/deps/ucx.cmake
+++ b/cmake/deps/ucx.cmake
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-find_package(ucx 1.14.0 REQUIRED)
+find_package(ucx 1.17.0 REQUIRED)
install(
DIRECTORY ${UCX_LIBRARIES}
diff --git a/cmake/modules/FindONNXRuntime.cmake b/cmake/modules/FindONNXRuntime.cmake
index 1e0aee1d..9f8c10a7 100644
--- a/cmake/modules/FindONNXRuntime.cmake
+++ b/cmake/modules/FindONNXRuntime.cmake
@@ -1,4 +1,4 @@
-# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -29,10 +29,10 @@
# Find headers
find_path(ONNXRuntime_INCLUDE_DIR
- NAMES onnxruntime/core/session/onnxruntime_c_api.h
+ NAMES onnxruntime/onnxruntime_c_api.h
)
list(APPEND ONNXRuntime_INCLUDE_DIRS "${ONNXRuntime_INCLUDE_DIR}")
-list(APPEND ONNXRuntime_INCLUDE_DIRS "${ONNXRuntime_INCLUDE_DIR}/onnxruntime/core/session")
+list(APPEND ONNXRuntime_INCLUDE_DIRS "${ONNXRuntime_INCLUDE_DIR}/onnxruntime")
mark_as_advanced(ONNXRuntime_INCLUDE_DIR)
mark_as_advanced(ONNXRuntime_INCLUDE_DIRS)
diff --git a/cmake/modules/FindTensorRT.cmake b/cmake/modules/FindTensorRT.cmake
index 544a58f4..641d6a94 100644
--- a/cmake/modules/FindTensorRT.cmake
+++ b/cmake/modules/FindTensorRT.cmake
@@ -1,4 +1,4 @@
-# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -34,14 +34,14 @@ mark_as_advanced(TensorRT_INCLUDE_DIR)
# Find version
function(read_version name str)
- string(REGEX MATCH "${name} ([0-9]\\d*)" _ ${str})
+ string(REGEX MATCH "${name} ([0-9]+)" _ "${str}")
set(${name} ${CMAKE_MATCH_1} PARENT_SCOPE)
endfunction()
file(READ "${TensorRT_INCLUDE_DIR}/NvInferVersion.h" _TRT_VERSION_FILE)
-read_version(NV_TENSORRT_MAJOR ${_TRT_VERSION_FILE})
-read_version(NV_TENSORRT_MINOR ${_TRT_VERSION_FILE})
-read_version(NV_TENSORRT_PATCH ${_TRT_VERSION_FILE})
+read_version(NV_TENSORRT_MAJOR "${_TRT_VERSION_FILE}")
+read_version(NV_TENSORRT_MINOR "${_TRT_VERSION_FILE}")
+read_version(NV_TENSORRT_PATCH "${_TRT_VERSION_FILE}")
set(TensorRT_VERSION "${NV_TENSORRT_MAJOR}.${NV_TENSORRT_MINOR}.${NV_TENSORRT_PATCH}")
unset(_TRT_VERSION_FILE)
@@ -60,9 +60,7 @@ endmacro()
find_trt_library(nvinfer)
find_trt_library(nvinfer_plugin)
-find_trt_library(nvcaffe_parser)
find_trt_library(nvonnxparser)
-find_trt_library(nvparsers)
# Generate TensorRT_FOUND
include(FindPackageHandleStandardArgs)
diff --git a/cmake/modules/HoloscanCPack.cmake b/cmake/modules/HoloscanCPack.cmake
index 661e62b3..ca695054 100644
--- a/cmake/modules/HoloscanCPack.cmake
+++ b/cmake/modules/HoloscanCPack.cmake
@@ -65,17 +65,19 @@ set(CPACK_COMPONENTS_ALL
# - cuda-cudart-dev: needed for holoscan core and some operators
# Note: only cuda-cudart (non dev) needed at runtime
set(CPACK_DEBIAN_PACKAGE_DEPENDS
- "cuda-nvcc-12-2 | cuda-nvcc-12-9 | cuda-nvcc-12-8 | cuda-nvcc-12-7 | cuda-nvcc-12-6 | cuda-nvcc-12-5 | cuda-nvcc-12-4 | cuda-nvcc-12-3 | cuda-nvcc-12-1 | cuda-nvcc-12-0, \
- cuda-cudart-dev-12-2 | libcudart.so.12-dev"
+ "cuda-nvcc-12-6 | cuda-nvcc-12-9 | cuda-nvcc-12-8 | cuda-nvcc-12-7 | cuda-nvcc-12-5 | cuda-nvcc-12-4 | cuda-nvcc-12-3 | cuda-nvcc-12-2 |cuda-nvcc-12-1 | cuda-nvcc-12-0, \
+ cuda-cudart-dev-12-6 | libcudart.so.12-dev"
)
-# - libnvinfer-bin: meta package including required nvinfer libs, cublas, and cudnn.
+
+# Recommended packages for core runtime functionality:
+# - libnvinfer-bin: meta package including required nvinfer libs.
# Needed for all inference backends
-# Note: only libnvonnxparsers and libnvinfer-plugin needed at runtime
-# - libcublas: needed by all inference backends
+# Note: only libnvinfer, libnvonnxparsers, libnvinfer-plugin needed at runtime
+# - libcublas: needed by CuPy, libtorch, and OnnxRuntime
# Note: also a dependency of the libnvinfer packages
# - cuda-nvrtc: libtorch & CuPy dependency
# Note: also a dependency of cuda-nvcc
-# Note: should be able to use libnvrtc.so.12, but doesn't work
+# Note: should be able to use libnvrtc.so.12, but doesn't work as of Holoscan SDK 2.4
# - libcufft: needed by cupy and OnnxRuntime inference backend
# - libcurand: needed by libtorch and cupy
# - libcusolver: needed by cupy
@@ -83,22 +85,26 @@ set(CPACK_DEBIAN_PACKAGE_DEPENDS
# - libnpp-dev: needed for format_converter and bayer_demosaic operators
# Note: only libnpp (non dev) needed at runtime
# - libnvjitlink: needed by cupy
+# - nccl2: needed by cupy and Torch
# - libgomp1: needed by cupy
# - libvulkan1: needed for holoviz operator
# - libegl1: needed for holoviz operator in headless mode
# - libv4l-0: needed for v4l2 operator
# - python3-cloudpickle: needed for python distributed applications
# - python3-pip: needed for holoscan CLI (packager, runner)
+# - libnuma1: needed for holoscan::core on ARM64
set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "\
-libnvinfer-bin (>=8.6), libnvinfer-bin (<<9), \
-libcublas-12-2 | libcublas.so.12, \
-cuda-nvrtc-12-2 | cuda-nvrtc-12-9 | cuda-nvrtc-12-8 | cuda-nvrtc-12-7 | cuda-nvrtc-12-6 | cuda-nvrtc-12-5 | cuda-nvrtc-12-4 | cuda-nvrtc-12-3 | cuda-nvrtc-12-1 | cuda-nvrtc-12-0, \
-libcufft-12-2 | libcufft.so.11, \
-libcurand-12-2 | libcurand.so.10, \
-libcusolver-12-2 | libcusolver.so.11, \
-libcusparse-12-2 | libcusparse.so.12, \
-libnpp-dev-12-2 | libnpp.so.12-dev, \
-libnvjitlink-12-2 | libnvjitlink.so.12, \
+libnvinfer-bin (>=10.3), \
+libcublas-12-6 | libcublas.so.12, \
+cudnn9-cuda-12-6 | libcudnn.so.9, \
+cuda-nvrtc-12-6 | cuda-nvrtc-12-9 | cuda-nvrtc-12-8 | cuda-nvrtc-12-7 | cuda-nvrtc-12-5 | cuda-nvrtc-12-4 | cuda-nvrtc-12-3 | cuda-nvrtc-12-2 | cuda-nvrtc-12-1 | cuda-nvrtc-12-0, \
+libcufft-12-6 | libcufft.so.11, \
+libcurand-12-6 | libcurand.so.10, \
+libcusolver-12-6 | libcusolver.so.11, \
+libcusparse-12-6 | libcusparse.so.12, \
+libnpp-dev-12-6 | libnpp.so.12-dev, \
+libnvjitlink-12-6 | libnvjitlink.so.12, \
+libnccl2 | libnccl.so.2, \
libgomp1, \
libvulkan1, \
libegl1, \
@@ -106,9 +112,27 @@ libv4l-0, \
python3-cloudpickle, \
python3-pip"
)
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
+ set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "${CPACK_DEBIAN_PACKAGE_RECOMMENDS}, \
+libnuma1")
+endif()
+
+# Packages for optional features:
+# - libcupti: needed for Torch inference backend
+# - libnvToolsExt: needed for Torch inference backend
+# - libcudnn: needed for Torch and OnnxRuntime
+# - libcusparselt: needed for Torch inference backend
# - libpng, libjpeg, libopenblas: needed for Torch inference backend.
# - libjpeg needed by v4l2 for mjpeg support
-set(CPACK_DEBIAN_PACKAGE_SUGGESTS "libpng16-16, libjpeg-turbo8, libopenblas0")
+set(CPACK_DEBIAN_PACKAGE_SUGGESTS "\
+cuda-cupti-12-6 | libcupti.so.12, \
+cuda-nvtx-12-6 | libnvToolsExt.so.1, \
+libcudnn9-cuda-12 | libcudnn.so.9, \
+libcusparselt0 | libcusparselt.so.0, \
+libpng16-16, \
+libjpeg-turbo8, \
+libopenblas0"
+)
include(CPack)
diff --git a/cmake/modules/HoloscanDownloadData.cmake b/cmake/modules/HoloscanDownloadData.cmake
index 034a15bc..e77d9b51 100644
--- a/cmake/modules/HoloscanDownloadData.cmake
+++ b/cmake/modules/HoloscanDownloadData.cmake
@@ -1,4 +1,4 @@
-# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -72,7 +72,6 @@ function(holoscan_download_data dataname)
--download_dir ${DATA_DOWNLOAD_DIR}
--download_name ${dataname}
${extra_data_options}
- WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/scripts"
BYPRODUCTS ${DATA_BYPRODUCTS}
)
diff --git a/cmake/modules/SetupRapidsCMake.cmake b/cmake/modules/SetupRapidsCMake.cmake
index e0f51ece..549865d7 100644
--- a/cmake/modules/SetupRapidsCMake.cmake
+++ b/cmake/modules/SetupRapidsCMake.cmake
@@ -1,4 +1,4 @@
-# SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+# SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,7 +14,7 @@
# limitations under the License.
# https://github.com/rapidsai/rapids-cmake#installation
-file(DOWNLOAD https://raw.githubusercontent.com/rapidsai/rapids-cmake/branch-23.06/RAPIDS.cmake
+file(DOWNLOAD https://raw.githubusercontent.com/rapidsai/rapids-cmake/branch-24.04/RAPIDS.cmake
${CMAKE_BINARY_DIR}/RAPIDS.cmake
)
include(${CMAKE_BINARY_DIR}/RAPIDS.cmake)
diff --git a/cmake/modules/cpack/NOTICE.txt b/cmake/modules/cpack/NOTICE.txt
index 9acf490c..9b8e3906 100644
--- a/cmake/modules/cpack/NOTICE.txt
+++ b/cmake/modules/cpack/NOTICE.txt
@@ -26,8 +26,8 @@ expected (https://github.com/TartanLlama/expected)
Licensed under CC0-1.0 (https://github.com/TartanLlama/expected/blob/v1.1.0/COPYING)
fmt (https://github.com/fmtlib/fmt)
-Copyright (c) 2012 - present, Victor Zverovich
-Licensed under MIT (https://github.com/fmtlib/fmt/blob/8.1.1/LICENSE.rst)
+Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
+Licensed under MIT (https://github.com/fmtlib/fmt/blob/10.1.1/LICENSE.rst)
GLFW (https://www.glfw.org/)
Copyright (c) 2002-2006 Marcus Geelnard
@@ -144,12 +144,16 @@ python-on-whales (https://github.com/gabrieldemarmiesse/python-on-whales)
Copyright (c) 2020 Gabriel de Marmiesse de Lussan
Licensed under MIT (https://github.com/gabrieldemarmiesse/python-on-whales/raw/master/LICENSE)
+RMM (https://github.com/rapidsai/rmm)
+Copyright (c) 2018-2024, NVIDIA CORPORATION.
+Licensed under Apache 2.0 (https://github.com/rapidsai/rmm/blob/branch-24.04/LICENSE)
+
Google Fonts Roboto (https://github.com/googlefonts/roboto/releases/download/v2.138/roboto-android.zip)
Licensed under Apache-2.0 (https://github.com/googlefonts/roboto/blob/v2.138/LICENSE)
spdlog (https://github.com/gabime/spdlog)
Copyright (c) 2016 Gabi Melman.
-Licensed under MIT (https://github.com/gabime/spdlog/blob/v1.10.0/LICENSE)
+Licensed under MIT (https://github.com/gabime/spdlog/blob/v1.12.0/LICENSE)
UCX (https://openucx.org/)
Copyright (c) 2014-2015 UT-Battelle, LLC. All rights reserved.
@@ -163,7 +167,7 @@ Copyright (C) 2016-2020 Advanced Micro Devices, Inc. All rights reserved.
Copyright (C) 2019 UChicago Argonne, LLC. All rights reserved.
Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
Copyright (C) 2016-2020 Stony Brook University. All rights reserved.
-Licensed under BSD-3-clause (https://github.com/openucx/ucx/blob/v1.15.0-rc2/LICENSE)
+Licensed under BSD-3-clause (https://github.com/openucx/ucx/blob/v1.17.0/LICENSE)
yaml-cpp (https://github.com/jbeder/yaml-cpp)
Copyright (c) 2008-2015 Jesse Beder.
diff --git a/cmake/modules/wrap_operator_as_gxf_template/codelet.cpp.in b/cmake/modules/wrap_operator_as_gxf_template/codelet.cpp.in
index 65cab5b3..d0480d4d 100644
--- a/cmake/modules/wrap_operator_as_gxf_template/codelet.cpp.in
+++ b/cmake/modules/wrap_operator_as_gxf_template/codelet.cpp.in
@@ -20,8 +20,10 @@
namespace @CODELET_NAMESPACE@ {
+// NOLINTBEGIN(readability-redundant-member-init)
@CODELET_NAME@::@CODELET_NAME@() : holoscan::gxf::OperatorWrapper() {
op_ = std::make_shared<@OPERATOR_CLASS@>();
}
+// NOLINTEND(readability-redundant-member-init)
} // namespace @CODELET_NAMESPACE@
diff --git a/cmake/setup_dependencies.cmake b/cmake/setup_dependencies.cmake
index 4c47646b..cfd60ce4 100644
--- a/cmake/setup_dependencies.cmake
+++ b/cmake/setup_dependencies.cmake
@@ -44,6 +44,7 @@ superbuild_depend(grpc)
superbuild_depend(hwloc)
superbuild_depend(magic_enum)
superbuild_depend(spdlog_rapids)
+superbuild_depend(rmm) # fetches spdlog
superbuild_depend(tensorrt)
superbuild_depend(threads)
superbuild_depend(ucx)
diff --git a/docs/Dockerfile b/docs/Dockerfile
index fe19ed3f..d06afcfb 100644
--- a/docs/Dockerfile
+++ b/docs/Dockerfile
@@ -73,7 +73,7 @@ RUN python3 -m pip install --no-cache-dir \
################################################################
FROM $BASE_IMAGE AS docs-html
-# Copy over installed denpendencies from docs-base
+# Copy over installed dependencies from docs-base
COPY --from=docs-base /usr/bin/dot /usr/bin/dot
COPY --from=docs-base /usr/local/bin/doxygen /usr/local/bin/doxygen
COPY --from=docs-base /usr/local/lib/python3.10/dist-packages /usr/local/lib/python3.10/dist-packages
diff --git a/docs/api/holoscan_cpp_api.md b/docs/api/holoscan_cpp_api.md
index feaf1336..b5c4ba92 100644
--- a/docs/api/holoscan_cpp_api.md
+++ b/docs/api/holoscan_cpp_api.md
@@ -138,7 +138,11 @@
- {ref}`exhale_class_classholoscan_1_1AsynchronousCondition`
- {ref}`exhale_class_classholoscan_1_1BooleanCondition`
- {ref}`exhale_class_classholoscan_1_1CountCondition`
+- {ref}`exhale_class_classholoscan_1_1CudaBufferAvailableCondition`
+- {ref}`exhale_class_classholoscan_1_1CudaEventCondition`
+- {ref}`exhale_class_classholoscan_1_1CudaStreamCondition`
- {ref}`exhale_class_classholoscan_1_1DownstreamMessageAffordableCondition`
+- {ref}`exhale_class_classholoscan_1_1ExpiringMessageAvailableCondition`
- {ref}`exhale_class_classholoscan_1_1MessageAvailableCondition`
- {ref}`exhale_class_classholoscan_1_1PeriodicCondition`
@@ -147,6 +151,7 @@
- {ref}`exhale_class_classholoscan_1_1Allocator`
- {ref}`exhale_class_classholoscan_1_1BlockMemoryPool`
- {ref}`exhale_class_classholoscan_1_1Clock`
+- {ref}`exhale_class_classholoscan_1_1CudaAllocator`
- {ref}`exhale_class_classholoscan_1_1CudaStreamPool`
- {ref}`exhale_class_classholoscan_1_1DoubleBufferReceiver`
- {ref}`exhale_class_classholoscan_1_1DoubleBufferTransmitter`
@@ -154,9 +159,11 @@
- {ref}`exhale_class_classholoscan_1_1ManualClock`
- {ref}`exhale_class_classholoscan_1_1RealtimeClock`
- {ref}`exhale_class_classholoscan_1_1Receiver`
+- {ref}`exhale_class_classholoscan_1_1RMMAllocator`
- {ref}`exhale_class_classholoscan_1_1SerializationBuffer`
- {ref}`exhale_class_classholoscan_1_1StdComponentSerializer`
- {ref}`exhale_class_classholoscan_1_1StdEntitySerializer`
+- {ref}`exhale_class_classholoscan_1_1StreamOrderedAllocator`
- {ref}`exhale_class_classholoscan_1_1Transmitter`
- {ref}`exhale_class_classholoscan_1_1UcxComponentSerializer`
- {ref}`exhale_class_classholoscan_1_1UcxEntitySerializer`
diff --git a/docs/components/resources.md b/docs/components/resources.md
index 17ced065..5cc3efea 100644
--- a/docs/components/resources.md
+++ b/docs/components/resources.md
@@ -21,6 +21,21 @@ This is a memory pool which provides a user-specified number of equally sized bl
- The `num_blocks` parameter controls the total number of blocks that are allocated in the memory pool.
- The `dev_id` parameter is an optional parameter that can be used to specify the CUDA ID of the device on which the memory pool will be created.
+### RMMAllocator
+
+This allocator provides a pair of memory pools (one is a CUDA device memory pool and the other corresponds to pinned host memory). The underlying implementation is based on the [RAPIDS memory manager](https://github.com/rapidsai/rmm) (RMM) and uses a pair of `rmm::mr::pool_memory_resource` resource types (The device memory pool is a `rmm::mr::cuda_memory_resource` and the host pool is a `rmm::mr::pinned_memory_resource`) . Unlike `BlockMemoryPool`, this allocator can be used with operators like `VideoStreamReplayerOp` that require an allocator capable of allocating both host and device memory. Rather than fixed block sizes, it uses just an initial memory size to allocate and a maximum size that the pool can expand to.
+
+- The `device_memory_initial_size` parameter specifies the initial size of the device (GPU) memory pool. This is an optional parameter that defaults to 8 MB on aarch64 and 16 MB on x86_64. See note below on the format used to specify the value.
+- The `device_memory_max_size` parameter specifies the maximum size of the device (GPU) memory pool in MiB. This is an optional parameter that defaults to twice the value of `device_memory_initial_size`. See note below on the format used to specify the value.
+- The `host_memory_initial_size` parameter specifies the initial size of the device (GPU) memory pool in MiB. This is an optional parameter that defaults to 8 MB on aarch64 and 16 MB on x86_64. See note below on the format used to specify the value.
+- The `host_memory_max_size` parameter specifies the maximum size of the device (GPU) memory pool in MiB. This is an optional parameter that defaults to twice the value of `host_memory_initial_size`. See note below on the format used to specify the value.
+- The `dev_id` parameter is an optional parameter that can be used to specify the GPU device ID (as an integer) on which the memory pool will be created.
+
+:::{note}
+The values for the memory parameters, such as `device_memory_initial_size` must be specified in the form of a string containing a non-negative integer value followed by a suffix representing the units. Supported units are B, KB, MB, GB and TB where the values are powers of 1024 bytes
+(e.g. MB = 1024 * 1024 bytes). Examples of valid units are "512MB", "256 KB", "1 GB". If a floating point number is specified that decimal portion will be truncated (i.e. the value is rounded down to the nearest integer).
+:::
+
### CudaStreamPool
This allocator creates a pool of CUDA streams.
diff --git a/docs/examples/byom.md b/docs/examples/byom.md
index f198b4c8..14f7f335 100644
--- a/docs/examples/byom.md
+++ b/docs/examples/byom.md
@@ -172,7 +172,7 @@ Next, we look at the operators and their parameters defined in the application Y
```
- An instance of the `UnboundedAllocator` resource class is created (line `2`) and used by subsequent operators for
memory allocation. This allocator allocates memory dynamically on the host as needed. For applications where latency
-becomes an issue, there is the `BlockMemoryPool` allocator.
+becomes an issue, an allocator supporting a memory pool such as `BlockMemoryPool` or `RMMAllocator` could be used instead.
- The preprocessor operator (line `8`) takes care of converting the input video from the source video to a format that can be used by the AI model.
- The inference operator (line `12`) feeds the output from the preprocessor to the AI model to perform inference.
- The postprocessor operator (line `20`) postprocesses the output from the inference operator before passing it downstream to the visualizer.
@@ -381,7 +381,7 @@ In general, when deploying your own AI models, you will need to consider the ope
- **Output**: The postprocessed stream can be displayed or used by other downstream operators.
The Holoscan SDK comes with a number of [built-in operators](https://github.com/nvidia-holoscan/holoscan-sdk/tree/main/src/operators) that you can use to configure your own workflow.
-If needed, you can write your own custom operators or visit [Holohub](https://nvidia-holoscan.github.io/holohub/) for additional implementations and ideas for operators.
+If needed, you can write your own custom operators or visit [Holohub](https://github.com/nvidia-holoscan/holohub) for additional implementations and ideas for operators.
## Running the Application
diff --git a/docs/flow_tracking.md b/docs/flow_tracking.md
index 3fca40b4..b45e6bab 100644
--- a/docs/flow_tracking.md
+++ b/docs/flow_tracking.md
@@ -2,15 +2,12 @@
# Data Flow Tracking
:::{warning}
-Data Flow Tracking is currently not supported between multiple fragments in a [distributed application](./holoscan_create_distributed_app.md).
+Data Flow Tracking is currently only supported between multiple fragments in a [distributed application](./holoscan_create_distributed_app.md) in a single machine.
:::
-The Holoscan SDK provides the Data Flow Tracking APIs as a mechanism to profile your application and
-analyze the fine-grained timing properties and data flow between operators in the graph of a fragment.
+The Holoscan SDK provides the Data Flow Tracking APIs as a mechanism to profile your application and analyze the fine-grained timing properties and data flow between operators in the graph of a fragment.
-Currently, data flow tracking is only supported between the root operators and leaf operators of a
-graph and in simple cycles in a graph (support for tracking data flow between any pair of operators
-in a graph is planned for the future).
+Currently, data flow tracking is only supported between the root operators and leaf operators of a graph and in simple cycles in a graph (support for tracking data flow between any pair of operators in a graph is planned for the future).
- A *root operator* is an operator without any predecessor nodes.
- A *leaf operator* (also known as a *sink operator*) is an operator without any successor nodes.
@@ -32,10 +29,7 @@ The API also provides the ability to retrieve the number of messages sent from t
## Enabling Data Flow Tracking
-Before an application ({cpp:class}`C++ `/{py:class}`python `) is run with the `run()` method,
-data flow tracking can be enabled by calling the `track()` method in
-{cpp:func}`C++ ` and using the `Tracker` class in
-{py:class}`python `.
+Before an application ({cpp:class}`C++ `/{py:class}`python `) is run with the `run()` method, data flow tracking can be enabled. For single fragment applications, this can be done by calling the `track()` method in {cpp:func}`C++ ` and using the `Tracker` class in {py:class}`python `.
`````{tab-set}
````{tab-item} C++
@@ -64,10 +58,37 @@ with Tracker(app) as tracker:
````
`````
+## Enabling Data Flow Tracking for Distributed Applications
+
+For distributed (multi-fragment) applications, a separate tracker object is used for each Fragment so the API is slightly different than in the single fragment case.
+
+
+`````{tab-set}
+````{tab-item} C++
+```{code-block} cpp
+:emphasize-lines: 2
+:name: holoscan-enable-data-flow-tracking-cpp
+auto app = holoscan::make_application();
+auto trackers = app->track_distributed(); // Enable data flow tracking for a distributed app
+// Change tracker and application configurations
+...
+app->run();
+```
+Note that instead of a returning a single `DataFlowTracker*` like `track`, the `track_distributed` method returns a `std::unordered_map` where the keys are the names of the fragments.
+````
+````{tab-item} Python
+```{code-block} python
+with Tracker(app) as trackers:
+ app.run()
+```
+The `Tracker` context manager detects whether the app is distributed and returns a `dict[str, DataFlowTracker]` as `trackers` in the distributed case. For a single fragment application, the returned value is just a single `DataFlowTracker` object.
+````
+`````
+
## Retrieving Data Flow Tracking Results
After an application has been run, data flow tracking results can be accessed by
-various functions:
+various methods on the DataFlowTracker ({cpp:class}`C++ `/{py:class}`python `) class.
1. `print()` ({cpp:func}`C++ `/{py:func}`python `)
- Prints all data flow tracking results including end-to-end latencies and the number of
@@ -117,7 +138,7 @@ tracker.print();
from holoscan.core import Tracker
...
app = MyPingApp()
-with Tracker(app) as tracker:
+with Tracker(app) as trackers:
# Change tracker and application configurations
...
app.run()
@@ -126,9 +147,49 @@ with Tracker(app) as tracker:
````
`````
+If this was a distributed application, there would instead be a separate `DataFlowTracker` for each fragment. The overall flow tracking results for all fragments can be printed as in the following:
+
+`````{tab-set}
+````{tab-item} C++
+```{code-block} cpp
+:emphasize-lines: 6-10
+:name: holoscan-enable-data-flow-tracking-results-cpp
+auto app = holoscan::make_application();
+auto trackers = app->track_distributed(); // Enable data flow tracking for a distributed app
+// Change application configurations
+...
+app->run();
+// print the data flow tracking results
+for (const auto& [name, tracker] : trackers) {
+ std::cout << "Fragment: " << name << std::endl;
+ tracker->print();
+}
+```
+````
+````{tab-item} Python
+```{code-block} python
+:emphasize-lines: 6-9
+:name: holoscan-one-operator-workflow-python
+from holoscan.core import Tracker
+...
+app = MyPingApp()
+with Tracker(app) as trackers:
+ # Change tracker and application configurations
+ ...
+ app.run()
+ # print the data flow tracking results
+ for fragment_name, tracker in trackers.items():
+ print(f"Fragment: {fragment_name}")
+ tracker.print()
+```
+````
+`````
+
## Customizing Data Flow Tracking
-Data flow tracking can be customized using a few, optional configuration parameters. The `track()` method ({cpp:func}`C++ `/{py:class}`Tracker class in python `) can be configured to skip a few messages at the beginning of an application's execution as a *warm-up* period. It is also possible to discard a few messages at the end of an application's run as a *wrap-up* period. Additionally, outlier end-to-end latencies can be ignored by setting a latency threshold value which is the minimum latency below which the observed latencies are ignored.
+Data flow tracking can be customized using a few, optional configuration parameters. The `track()` method ({cpp:func}`C++ `//{py:func}`Python `) (or `track_distributed` method ({cpp:func}`C++ `/{py:func}`Python `)` for distributed apps) can be configured to skip a few messages at the beginning of an application's execution as a *warm-up* period. It is also possible to discard a few messages at the end of an application's run as a *wrap-up* period. Additionally, outlier end-to-end latencies can be ignored by setting a latency threshold value (in ms) which is the minimum latency below which the observed latencies are ignored.
+
+For Python, it is recommended to use the {py:class}`Tracker` context manager class instead of the `track` or `track_distributed` methods. This class will autodetect if the application is a single fragment or distributed app, using the appropriate method for each.
:::{tip}
For effective benchmarking, it is common practice to include warm-up and cool-down periods by skipping the initial and final messages.
@@ -147,8 +208,8 @@ Fragment::track(uint64_t num_start_messages_to_skip = kDefaultNumStartMessagesTo
```{code-block} python
:caption: Optional parameters to `Tracker`
Tracker(num_start_messages_to_skip=num_start_messages_to_skip,
- num_last_messages_to_discard=num_last_messages_to_discard,
- latency_threshold=latency_threshold)
+ num_last_messages_to_discard=num_last_messages_to_discard,
+ latency_threshold=latency_threshold)
```
````
`````
@@ -182,7 +243,7 @@ app->run();
````
````{tab-item} Python
```{code-block} python
-:emphasize-lines: 2
+:emphasize-lines: 4
:name: holoscan-flow-tracking-logging-python
from holoscan.core import Tracker
...
diff --git a/docs/getting_started.md b/docs/getting_started.md
index f423a909..48b01b61 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -23,12 +23,12 @@ The Holoscan SDK does not only provide a framework to build and run applications
The list of existing operators is available [here](./holoscan_operators_extensions.md), which points to the C++ or Python API documentation for more details. Specific documentation is available for the [visualization](./visualization.md) (codename: HoloViz) and [inference](./inference.md) (codename: HoloInfer) operators.
-Additionally, [HoloHub](https://nvidia-holoscan.github.io/holohub) is a central repository for users and developers to share reusable operators and sample applications with the Holoscan community, extending the capabilities of the SDK:
+Additionally, [HoloHub](https://github.com/nvidia-holoscan/holohub) is a central repository for users and developers to share reusable operators and sample applications with the Holoscan community, extending the capabilities of the SDK:
- Just like the SDK operators, the HoloHub operators can be used in your own Holoscan applications.
- The HoloHub sample applications can be used as reference implementations to complete the examples available in the SDK.
-Take a glance at [HoloHub](https://nvidia-holoscan.github.io/holohub) to find components you might want to leverage in your application, improve upon existing work, or contribute your own additions to the Holoscan platform.
+Take a glance at [HoloHub](https://github.com/nvidia-holoscan/holohub) to find components you might want to leverage in your application, improve upon existing work, or contribute your own additions to the Holoscan platform.
## 5. Write and run your own application
diff --git a/docs/holoscan_create_distributed_app.md b/docs/holoscan_create_distributed_app.md
index bd1f82b1..dbcfcf4c 100644
--- a/docs/holoscan_create_distributed_app.md
+++ b/docs/holoscan_create_distributed_app.md
@@ -251,6 +251,8 @@ You can set environment variables to modify the default actions of services and
- **HOLOSCAN_UCX_SERIALIZATION_BUFFER_SIZE** : can be used to override the default 7 kB serialization buffer size. This should typically not be needed as tensor types store only a small header in this buffer to avoid explicitly making a copy of their data. However, other data types do get directly copied to the serialization buffer and in some cases it may be necessary to increase it.
+- **HOLOSCAN_UCX_ASYNCHRONOUS** : If set to true, asynchronous transmit of UCX messages between fragments is enabled (this is the default). Setting this to False, forces synchronous transmission. Synchronous mode makes it easier to use an allocator like `BlockMemoryPool` as additional tensors would not be queued before the prior one was sent.
+
- **HOLOSCAN_UCX_DEVICE_ID** : The GPU ID of the device that will be used by UCX transmitter/receivers in distributed applications. If unspecified, it defaults to 0. A list of discrete GPUs available in a system can be obtained via `nvidia-smi -L`. GPU data sent between fragments of a distributed application must be on this device.
- **HOLOSCAN_UCX_PORTS** : This defines the preferred port numbers for the SDK when specific ports for UCX communication need to be predetermined, such as in a Kubernetes environment. If the distributed application requires three ports (UCX receivers) and the environment variable is unset, the SDK chooses three unused ports sequentially from the range 10000~32767. Specifying a value, for example, `HOLOSCAN_UCX_PORTS=10000`, results in the selection of ports 10000, 10001, and 10002. Multiple starting values can be comma-separated. The system increments from the last provided port if more ports are needed. Any unused specified ports are ignored.
diff --git a/docs/hsdk_faq.md b/docs/hsdk_faq.md
index c67a78e2..3009864b 100644
--- a/docs/hsdk_faq.md
+++ b/docs/hsdk_faq.md
@@ -32,13 +32,13 @@ A1: There are multiple ways to install the Holoscan SDK:
* For **dGPU** (x86_64, IGX Orin dGPU, Clara AGX dGPU, GH200)
```
-docker pull nvcr.io/nvidia/clara-holoscan/holoscan:v2.5.0-dgpu
+docker pull nvcr.io/nvidia/clara-holoscan/holoscan:v2.6.0-dgpu
```
* For **iGPU** (Jetson, IGX Orin iGPU, Clara AGX iGPU)
```
-docker pull nvcr.io/nvidia/clara-holoscan/holoscan:v2.5.0-igpu
+docker pull nvcr.io/nvidia/clara-holoscan/holoscan:v2.6.0-igpu
```
For more information, please refer to details and usage instructions on [**NGC**](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/clara-holoscan/containers/holoscan).
@@ -637,6 +637,9 @@ A36: Yes, for linear inference pipelines or applications with minimal computatio
A37: Increasing the number of worker threads can improve performance up to a point, but it also increases CPU usage.
+**Q38: Is there any memory pool (allocator) that supports both host and device memory?**
+
+Please use `RMMAllocator` for this purpose. It supports simultaneous memory pools for CUDA device memory and pinned host memory. A `BlockMemoryPool` can be used on either host or device memory, but cannot support both types at the same time. `UnboundedAllocator` also supports both host and device memory, but is not a memory pool (it allocates and frees new memory each time).
## Performance
@@ -1144,6 +1147,17 @@ A19:To resolve these errors, edit the `/etc/docker/daemon.json` file to include
You may need to consult your IT team and replace `IP-x` and `DNS-SERVER-x` with the provided values.
+**Q20:I am seeing the following error when trying to use the `RMMAllocator`**
+
+When running the application, if it fails to start with an error like the following being logged:
+
+```cpp
+[error] [rmm_allocator.cpp:74] Unexpected error while initializing RMM Allocator rmm_allocator: std::bad_alloc: out_of_memory: RMM failure at:bazel-out/k8-opt/bin/external/rmm/_virtual_includes/rmm/rmm/mr/device/pool_memory_resource.hpp:424: Maximum pool size exceeded
+```
+
+This indicates that the requested memory sizes on host and/or device exceed the available memory. Please make sure that your device supports the specified memory size. Also check that the specified the values for `device_memory_initial_size`, `device_memory_max_size`, `host_memory_initial_size` and `host_memory_max_size` were specified using the intended units (B, KB, MB, GB or TB).
+
+
## Miscellaneous
**Q1: Can I use DLA cores with the Holoscan SDK?**
diff --git a/docs/inference.md b/docs/inference.md
index 293bf9ca..557bf1bb 100644
--- a/docs/inference.md
+++ b/docs/inference.md
@@ -108,6 +108,10 @@ Required parameters and related features available with the Holoscan Inference M
"model_2_unique_identifier": "torch"
"model_3_unique_identifier": "torch"
```
+ - `trt_opt_profile`: This parameter is optional and is activated with TensorRT backend. This parameter is applicable on models with dynamic input shapes.
+ - Parameter is specified as a vector of 3 integers. First is the minimum batch size for the input, second is the optimum batch size and third value is the maximum batch size.
+ - Users can specify a batch profile for dynamic input. This profile is then used in engine creation. User must clear the cache to apply the updated optimization profile.
+ - Default value: {1,1,1}
- Other features: The table below illustrates other features and supported values in the current release.
diff --git a/docs/overview.md b/docs/overview.md
index 18d09283..6448dc6a 100644
--- a/docs/overview.md
+++ b/docs/overview.md
@@ -22,7 +22,7 @@ The Holoscan SDK provides a list of examples to illustrate specific capabilities
5. **Repository of Operators and Applications**
-[HoloHub](https://nvidia-holoscan.github.io/holohub) is a central repository for users and developers to share reusable operators and sample applications with the Holoscan community. Being open-source, these operators and applications can also be used as reference implementations to complete the built-in operators and examples available in the SDK.
+[HoloHub](https://github.com/nvidia-holoscan/holohub) is a central repository for users and developers to share reusable operators and sample applications with the Holoscan community. Being open-source, these operators and applications can also be used as reference implementations to complete the built-in operators and examples available in the SDK.
6. **Tooling to Package and Deploy Applications**
@@ -44,5 +44,5 @@ The Holoscan SDK documentation is composed of:
- [Release notes](https://github.com/nvidia-holoscan/holoscan-sdk/releases) on Github
:::{note}
-In previous releases, the prefix [`Clara`](https://developer.nvidia.com/industries/healthcare) was used to define Holoscan as a platform designed initially for [medical devices](https://www.nvidia.com/en-us/clara/developer-kits/). Starting with version 0.4.0, the Holoscan SDK is built to be domain-agnostic and can be used to build sensor AI applications in multiple domains. Domain specific content will be hosted on the [HoloHub](https://nvidia-holoscan.github.io/holohub) repository.
+In previous releases, the prefix [`Clara`](https://developer.nvidia.com/industries/healthcare) was used to define Holoscan as a platform designed initially for [medical devices](https://www.nvidia.com/en-us/clara/developer-kits/). Starting with version 0.4.0, the Holoscan SDK is built to be domain-agnostic and can be used to build sensor AI applications in multiple domains. Domain specific content will be hosted on the [HoloHub](https://github.com/nvidia-holoscan/holohub) repository.
:::
diff --git a/docs/sdk_installation.md b/docs/sdk_installation.md
index eccc1fa9..2dab76f9 100644
--- a/docs/sdk_installation.md
+++ b/docs/sdk_installation.md
@@ -19,10 +19,11 @@ Developer Kit | User Guide | OS | GPU Mode
------------- | ---------- | --- | ---
[NVIDIA IGX Orin][igx] | [Guide][igx-guide] | [IGX Software][igx-sw] 1.0 Production Release | iGPU **or*** dGPU
[NVIDIA Jetson AGX Orin and Orin Nano][jetson-orin] | [Guide][jetson-guide] | [JetPack][jp] 6.0 | iGPU
-[NVIDIA Clara AGX][clara-agx] _Only supporting the NGC container_ | [Guide][clara-guide] | [HoloPack][sdkm] 1.2 | iGPU **or*** dGPU
+[NVIDIA Clara AGX][clara-agx] _Only supporting the NGC container_ | [Guide][clara-guide] | [HoloPack][sdkm] 1.2 _[Upgrade to 535+ drivers required][cagx-upgrade]_ | dGPU
[clara-agx]: https://www.nvidia.com/en-gb/clara/intelligent-medical-instruments
[clara-guide]: https://github.com/nvidia-holoscan/holoscan-docs/blob/main/devkits/clara-agx/clara_agx_user_guide.md
+[cagx-upgrade]: https://github.com/nvidia-holoscan/holoscan-docs/blob/main/devkits/clara-agx/clara_agx_user_guide.md#update-nvidia-drivers
[sdkm]: https://developer.nvidia.com/drive/sdk-manager
[igx]: https://www.nvidia.com/en-us/edge-computing/products/igx/
[igx-guide]: https://developer.nvidia.com/igx-orin-developer-kit-user-guide
@@ -81,11 +82,11 @@ We provide multiple ways to install and run the Holoscan SDK:
````{tab-item} NGC Container
- **dGPU** (x86_64, IGX Orin dGPU, Clara AGX dGPU, GH200)
```bash
- docker pull nvcr.io/nvidia/clara-holoscan/holoscan:v2.5.0-dgpu
+ docker pull nvcr.io/nvidia/clara-holoscan/holoscan:v2.6.0-dgpu
```
- **iGPU** (Jetson, IGX Orin iGPU, Clara AGX iGPU)
```bash
- docker pull nvcr.io/nvidia/clara-holoscan/holoscan:v2.5.0-igpu
+ docker pull nvcr.io/nvidia/clara-holoscan/holoscan:v2.6.0-igpu
```
See details and usage instructions on [NGC][container].
````
@@ -198,7 +199,7 @@ For x86_64, ensure that the [CUDA Runtime is installed](https://developer.nvidia
| | NGC dev Container | Debian Package | Python Wheels |
|---|:---:|:---:|:---:|
| Runtime libraries | **Included** | **Included** | **Included** |
-| Python module | 3.10 | 3.10 | **3.8 to 3.11** |
+| Python module | 3.10 | 3.10 | **3.9 to 3.12** |
| C++ headers and CMake config | **Included** | **Included** | N/A |
| Examples (+ source) | **Included** | **Included** | [retrieve from GitHub][examples] |
| Sample datasets | **Included** | [retrieve from NGC][data] | [retrieve from NGC][data] |
@@ -225,14 +226,14 @@ For x86_64, ensure that the [CUDA Runtime is installed](https://developer.nvidia
[^1]: [CUDA 12](https://docs.nvidia.com/cuda/archive/12.1.1/cuda-installation-guide-linux/index.html) is required. Already installed on NVIDIA developer kits with IGX Software and JetPack.
[^2]: Debian installation on x86_64 requires the [latest cuda-keyring package](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/#network-repo-installation-for-ubuntu) to automatically install all dependencies.
[^3]: NPP 12 needed for the FormatConverter and BayerDemosaic operators. Already installed on NVIDIA developer kits with IGX Software and JetPack.
-[^4]: TensorRT 8.6.1+ and cuDNN needed for the Inference operator. Already installed on NVIDIA developer kits with IGX Software and JetPack.
+[^4]: TensorRT 10.3+ needed for the Inference operator. Already installed on NVIDIA developer kits with IGX Software and JetPack.
[^5]: Vulkan 1.3.204+ loader needed for the HoloViz operator (+ libegl1 for headless rendering). Already installed on NVIDIA developer kits with IGX Software and JetPack.
[^6]: V4L2 1.22+ needed for the V4L2 operator. Already installed on NVIDIA developer kits with IGX Software and JetPack. V4L2 also requires libjpeg.
-[^7]: Torch support requires LibTorch 2.1+, TorchVision 0.16+, OpenBLAS 0.3.20+, OpenMPI (aarch64 only), MKL 2021.1.1 (x86_64 only), libpng and libjpeg.
+[^7]: Torch support requires LibTorch 2.5+, TorchVision 0.20+, OpenBLAS 0.3.20+, OpenMPI v4.1.7a1+, UCC 1.4+, MKL 2021.1.1 (x86_64 only), NVIDIA Performance Libraries (aarch64 dGPU only), libpng, and libjpeg. Note that container builds use OpenMPI and UCC originating from the NVIDIA HPC-X package bundle.
[^8]: To install LibTorch and TorchVision, either build them from source, download our [pre-built packages](https://edge.urm.nvidia.com/artifactory/sw-holoscan-thirdparty-generic-local/), or copy them from the holoscan container (in `/opt`).
-[^9]: ONNXRuntime 1.15.1+ needed for the Inference operator. Note that ONNX models are also supported through the TensoRT backend of the Inference Operator.
+[^9]: ONNXRuntime 1.18.1+ needed for the Inference operator. Note that ONNX models are also supported through the TensorRT backend of the Inference Operator.
[^10]: To install ONNXRuntime, either build it from source, download our [pre-built package](https://edge.urm.nvidia.com/artifactory/sw-holoscan-thirdparty-generic-local/) with CUDA 12 and TensoRT execution provider support, or copy it from the holoscan container (in `/opt/onnxruntime`).
-[^11]: Tested with MOFED 23.10
+[^11]: Tested with MOFED 24.07
### Need more control over the SDK?
diff --git a/docs/set_up_gpudirect_rdma.md b/docs/set_up_gpudirect_rdma.md
index 75823635..367ff8fa 100644
--- a/docs/set_up_gpudirect_rdma.md
+++ b/docs/set_up_gpudirect_rdma.md
@@ -30,7 +30,7 @@ If not installed, or an older version is installed, you should install the appro
```bash
# You can choose different versions/OS or download directly from the
# Download Center in the webpage linked above
-MOFED_VERSION="23.10-2.1.3.1"
+MOFED_VERSION="24.07-0.6.1.0"
OS="ubuntu22.04"
MOFED_PACKAGE="MLNX_OFED_LINUX-${MOFED_VERSION}-${OS}-$(uname -m)"
wget --progress=dot:giga https://www.mellanox.com/downloads/ofed/MLNX_OFED-${MOFED_VERSION}/${MOFED_PACKAGE}.tgz
diff --git a/docs/use_igpu_with_dgpu.md b/docs/use_igpu_with_dgpu.md
index 67772584..de2c4a0e 100644
--- a/docs/use_igpu_with_dgpu.md
+++ b/docs/use_igpu_with_dgpu.md
@@ -11,11 +11,21 @@ We provide utilities to work around the second conflict:
`````{tab-set}
````{tab-item} IGX SW 1.0
-Refer to the [IGX user guide](https://docs.nvidia.com/igx-orin/user-guide/latest/igpu-dgpu.html) to learn how to leverage the iGPU in containers while the IGX developer kit is flashed in dGPU mode.
-To leverage both GPUs in Holoscan, you can create separate applications running concurrently per the IGX documentation above, where the iGPU application must run in the Holoscan iGPU container, and the dGPU application can run bare metal or in the Holoscan dGPU container.
+1. From an IGX developer kit flashed for dGPU, run the following command to enable iGPU container support:
-You can also create a single distributed application that leverages both the iGPU and dGPU by executing separate fragments on the iGPU and on the dGPU.
+ ```bash
+ sudo /opt/nvidia/l4t-igpu-container-on-dgpu-host-config/l4t-igpu-container-on-dgpu-host-config.sh configure
+ ```
+
+ Refer to the [IGX user guide][igx-igpu-dgpu] for details.
+
+2. To leverage both GPUs in Holoscan, you can either:
+
+ 1. create separate Holoscan applications running concurrently, where the iGPU application must run in the Holoscan iGPU container, and the dGPU application can run bare metal or in the Holoscan dGPU container. Refer to the [IGX user guide][igx-igpu-dgpu] for details on how to launch a Holoscan container using the iGPU.
+ 2. create a single distributed application that leverages both the iGPU and dGPU by executing separate fragments on the iGPU and on the dGPU.
+
+[igx-igpu-dgpu]: https://docs.nvidia.com/igx-orin/user-guide/latest/igpu-dgpu.html
The example below shows the ping distributed application between the iGPU and dGPU using Holoscan containers:
@@ -24,7 +34,7 @@ COMMON_DOCKER_FLAGS="--rm -i --init --net=host
--runtime=nvidia -e NVIDIA_DRIVER_CAPABILITIES=all
--cap-add CAP_SYS_PTRACE --ipc=host --ulimit memlock=-1 --ulimit stack=67108864
"
-HOLOSCAN_VERSION=2.2.0
+HOLOSCAN_VERSION=2.6.0
HOLOSCAN_IMG="nvcr.io/nvidia/clara-holoscan/holoscan:v$HOLOSCAN_VERSION"
HOLOSCAN_DGPU_IMG="$HOLOSCAN_IMG-dgpu"
HOLOSCAN_IGPU_IMG="$HOLOSCAN_IMG-igpu"
@@ -45,13 +55,13 @@ docker run \
docker run \
$COMMON_DOCKER_FLAGS \
-e NVIDIA_VISIBLE_DEVICES=nvidia.com/igpu=0 \
- $HOLOSCAN_IMG-igpu \
+ $HOLOSCAN_IGPU_IMG \
bash -c "./examples/ping_distributed/cpp/ping_distributed --gpu --worker"
```
````
````{tab-item} HoloPack 1.2+
-The [L4T Compute Assist](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/clara-holoscan/containers/l4t-compute-assist) is a container on NGC which isolates the iGPU stack in order to enable iGPU compute on the developer kits configured for dGPU. Other applications can run concurrently on the dGPU, natively or in another container.
+The [L4T Compute Assist](https://catalog.ngc.nvidia.com/orgs/nvidia/teams/clara-holoscan/containers/l4t-compute-assist) is a container on NGC which isolates the iGPU stack by containing the L4T BSP packages in order to enable iGPU compute on the developer kits configured for dGPU. Other applications can run concurrently on the dGPU, natively or in another container.
````
`````
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 41785517..e75207bc 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -12,42 +12,87 @@
# 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.
+cmake_minimum_required(VERSION 3.20)
+project(Holoscan-examples NONE)
+
+# If we build outside of the SDK main build we set the default value to true
+if(NOT DEFINED HOLOSCAN_BUILD_PYTHON)
+ set(HOLOSCAN_BUILD_PYTHON ON)
+endif()
+
+option(HOLOSCAN_CPP_EXAMPLES "Build C++ examples" ON)
+option(HOLOSCAN_PYTHON_EXAMPLES "Build Python examples" ${HOLOSCAN_BUILD_PYTHON})
+
+# Check if the data target exists otherwise define it
+if(NOT TARGET racerx_data)
+ # RacerX sample data
+ add_library(racerx_data INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/../data/racerx/racerx-small.mp4")
+
+ # Setup the installation rule
+ install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/racerx DESTINATION data COMPONENT holoscan-data)
+
+ # Download the datasets
+ list(APPEND CMAKE_PROGRAM_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../scripts)
+ include(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/HoloscanDownloadData.cmake)
+
+ set(RACERX_DATA_VERSION "20231009")
+ set(RACERX_DATA_MD5 "86cd7e5477bb9eaa0cfc0547912d77b2")
+
+ # Download the racerX sample data
+ holoscan_download_data(racerx
+ URL https://api.ngc.nvidia.com/v2/resources/nvidia/clara-holoscan/holoscan_racerx_video/versions/${RACERX_DATA_VERSION}/zip
+ URL_MD5 ${RACERX_DATA_MD5}
+ DOWNLOAD_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../data
+ BYPRODUCTS "${CMAKE_CURRENT_SOURCE_DIR}/../data/racerx/racerx-small.mp4"
+ )
+
+ # Add dependency to force the download
+ add_dependencies(racerx_data racerx_download)
+endif()
+
+# Enable testing
+include(CTest)
+
if(HOLOSCAN_BUILD_AJA)
add_subdirectory(aja_capture)
endif()
+
+# C++ only examples
+if(HOLOSCAN_CPP_EXAMPLES)
+ add_subdirectory(wrap_operator_as_gxf_extension)
+ add_subdirectory(ping_any)
+ add_subdirectory(ping_conditional)
+ add_subdirectory(ping_cycle)
+endif()
+
+# Python Only examples
+if(HOLOSCAN_PYTHON_EXAMPLES)
+ add_subdirectory(cupy_native)
+ add_subdirectory(numpy_native)
+ add_subdirectory(python_decorator)
+endif()
+
+# C++ and Python examples
add_subdirectory(bring_your_own_model)
add_subdirectory(cli_packager)
add_subdirectory(conditions)
-if(HOLOSCAN_BUILD_PYTHON)
- add_subdirectory(cupy_native)
-endif()
add_subdirectory(flow_tracker)
add_subdirectory(hello_world)
add_subdirectory(holoviz)
add_subdirectory(import_gxf_components)
add_subdirectory(multithread)
add_subdirectory(multi_branch_pipeline)
-if(HOLOSCAN_BUILD_PYTHON)
- add_subdirectory(numpy_native)
-endif()
-add_subdirectory(ping_any)
-add_subdirectory(ping_conditional)
-add_subdirectory(ping_cycle)
add_subdirectory(ping_simple)
add_subdirectory(ping_simple_run_async)
add_subdirectory(ping_custom_op)
add_subdirectory(ping_multi_port)
add_subdirectory(ping_distributed)
add_subdirectory(ping_vector)
-if(HOLOSCAN_BUILD_PYTHON)
- add_subdirectory(python_decorator)
-endif()
add_subdirectory(resources)
add_subdirectory(tensor_interop)
add_subdirectory(v4l2_camera)
add_subdirectory(video_replayer)
add_subdirectory(video_replayer_distributed)
-add_subdirectory(wrap_operator_as_gxf_extension)
if(HOLOSCAN_INSTALL_EXAMPLE_SOURCE)
# Generates the install CMakeLists.txt to compile all the cpp examples
diff --git a/examples/README.md b/examples/README.md
index ca235981..23d45ed9 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -1,7 +1,7 @@
# Holoscan SDK Examples
This directory contains examples to help users learn how to use the Holoscan SDK for development.
-See [HoloHub](https://nvidia-holoscan.github.io/holohub) to find additional reference applications.
+See [HoloHub](https://github.com/nvidia-holoscan/holohub) to find additional reference applications.
## Build instructions
diff --git a/examples/aja_capture/CMakeLists.txt b/examples/aja_capture/CMakeLists.txt
index be1771c0..85844c71 100644
--- a/examples/aja_capture/CMakeLists.txt
+++ b/examples/aja_capture/CMakeLists.txt
@@ -13,9 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-add_subdirectory(cpp)
+if(HOLOSCAN_CPP_EXAMPLES)
+ add_subdirectory(cpp)
+endif()
-if(HOLOSCAN_BUILD_PYTHON)
+if(HOLOSCAN_PYTHON_EXAMPLES)
add_subdirectory(python)
endif()
diff --git a/examples/aja_capture/README.md b/examples/aja_capture/README.md
index 3eaeb5b1..e508c7bb 100644
--- a/examples/aja_capture/README.md
+++ b/examples/aja_capture/README.md
@@ -49,7 +49,7 @@ Minimal example to demonstrate the use of the aja source operator to capture dev
```
## Settings
- To evaluate the AJA example using alternative resolutions, you may modify the aja_capture.yaml configuration file as needed. For instance, to test a resolution format of 1280 x 720 at 50 Hz, you can specify the following parameters in the aja section of the configuration :
+ To evaluate the AJA example using alternative resolutions, you may modify the aja_capture.yaml configuration file as needed. For instance, to test a resolution format of 1280 x 720 at 60 Hz, you can specify the following parameters in the aja section of the configuration :
```bash
aja:
diff --git a/examples/aja_capture/cpp/CMakeLists.txt b/examples/aja_capture/cpp/CMakeLists.txt
index 43fd05b4..19837196 100644
--- a/examples/aja_capture/cpp/CMakeLists.txt
+++ b/examples/aja_capture/cpp/CMakeLists.txt
@@ -74,7 +74,7 @@ if(HOLOSCAN_BUILD_TESTS AND TEST_AJA)
set(RECORDING_DIR ${CMAKE_CURRENT_BINARY_DIR}/recording_output)
set(SOURCE_VIDEO_BASENAME video_replayer_output)
- set(VALIDATION_FRAMES_DIR ${CMAKE_SOURCE_DIR}/tests/data/validation_frames/aja_capture/)
+ set(VALIDATION_FRAMES_DIR ${Holoscan-examples_SOURCE_DIR}/../tests/data/validation_frames/aja_capture/)
file(MAKE_DIRECTORY ${RECORDING_DIR})
@@ -87,7 +87,7 @@ if(HOLOSCAN_BUILD_TESTS AND TEST_AJA)
add_custom_command(OUTPUT aja_capture_test.cpp
PRE_LINK
COMMAND patch -u -o aja_capture_test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/aja_capture.cpp
- ${CMAKE_SOURCE_DIR}/tests/data/validation_frames/aja_capture/cpp_aja_capture.patch
+ ${Holoscan-examples_SOURCE_DIR}/../tests/data/validation_frames/aja_capture/cpp_aja_capture.patch
)
# Create the test executable
@@ -124,7 +124,7 @@ if(HOLOSCAN_BUILD_TESTS AND TEST_AJA)
# Add a test to check the validity of the frames
add_test(NAME EXAMPLE_CPP_AJA_CAPTURE_RENDER_TEST
- COMMAND python3 ${CMAKE_SOURCE_DIR}/scripts/video_validation.py
+ COMMAND python3 ${Holoscan-examples_SOURCE_DIR}/../scripts/video_validation.py
--source_video_dir ${RECORDING_DIR}
--source_video_basename ${SOURCE_VIDEO_BASENAME}
--output_dir ${RECORDING_DIR}
diff --git a/examples/aja_capture/python/CMakeLists.txt b/examples/aja_capture/python/CMakeLists.txt
index 4bb41493..bb39ba6a 100644
--- a/examples/aja_capture/python/CMakeLists.txt
+++ b/examples/aja_capture/python/CMakeLists.txt
@@ -43,7 +43,7 @@ if(HOLOSCAN_BUILD_TESTS AND TEST_AJA)
set(RECORDING_DIR ${CMAKE_CURRENT_BINARY_DIR}/recording_output)
set(SOURCE_VIDEO_BASENAME python_aja_capture_output)
- set(VALIDATION_FRAMES_DIR ${CMAKE_SOURCE_DIR}/tests/data/validation_frames/aja_capture/)
+ set(VALIDATION_FRAMES_DIR ${Holoscan-examples_SOURCE_DIR}/../tests/data/validation_frames/aja_capture/)
file(MAKE_DIRECTORY ${RECORDING_DIR})
@@ -57,7 +57,7 @@ if(HOLOSCAN_BUILD_TESTS AND TEST_AJA)
add_custom_command(OUTPUT aja_capture_test.py
PRE_LINK
COMMAND patch -u -o aja_capture_test.py ${CMAKE_CURRENT_SOURCE_DIR}/aja_capture.py
- ${CMAKE_SOURCE_DIR}/tests/data/validation_frames/aja_capture/python_aja_capture.patch
+ ${Holoscan-examples_SOURCE_DIR}/../tests/data/validation_frames/aja_capture/python_aja_capture.patch
)
add_custom_target(python_aja_capture_test ALL
@@ -76,7 +76,7 @@ if(HOLOSCAN_BUILD_TESTS AND TEST_AJA)
# Add a test to check the validity of the frames
add_test(NAME EXAMPLE_PYTHON_AJA_CAPTURE_RENDER_TEST
- COMMAND python3 ${CMAKE_SOURCE_DIR}/scripts/video_validation.py
+ COMMAND python3 ${Holoscan-examples_SOURCE_DIR}/../scripts/video_validation.py
--source_video_dir ${RECORDING_DIR}
--source_video_basename ${SOURCE_VIDEO_BASENAME}
--output_dir ${RECORDING_DIR}
diff --git a/examples/bring_your_own_model/CMakeLists.txt b/examples/bring_your_own_model/CMakeLists.txt
index c1b6d378..ed9358bc 100644
--- a/examples/bring_your_own_model/CMakeLists.txt
+++ b/examples/bring_your_own_model/CMakeLists.txt
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-if(HOLOSCAN_BUILD_PYTHON)
+if(HOLOSCAN_PYTHON_EXAMPLES)
add_subdirectory(python)
endif()
add_subdirectory(model)
diff --git a/examples/conditions/asynchronous/CMakeLists.txt b/examples/conditions/asynchronous/CMakeLists.txt
index 15697f79..c9769ebc 100644
--- a/examples/conditions/asynchronous/CMakeLists.txt
+++ b/examples/conditions/asynchronous/CMakeLists.txt
@@ -13,8 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-add_subdirectory(cpp)
-if(HOLOSCAN_BUILD_PYTHON)
+if(HOLOSCAN_CPP_EXAMPLES)
+ add_subdirectory(cpp)
+endif()
+
+if(HOLOSCAN_PYTHON_EXAMPLES)
add_subdirectory(python)
endif()
diff --git a/examples/conditions/asynchronous/cpp/ping_async.cpp b/examples/conditions/asynchronous/cpp/ping_async.cpp
index 0e9f1f65..a6ba0c4a 100644
--- a/examples/conditions/asynchronous/cpp/ping_async.cpp
+++ b/examples/conditions/asynchronous/cpp/ping_async.cpp
@@ -60,7 +60,7 @@ class App : public holoscan::Application {
bool async_transmit_ = false;
};
-int main(int argc, char** argv) {
+int main([[maybe_unused]] int argc, char** argv) {
auto app = holoscan::make_application();
// Get the configuration
@@ -69,12 +69,12 @@ int main(int argc, char** argv) {
app->config(config_path);
// set customizable application parameters via the YAML
- bool async_receive = app->from_config("async_receive").as();
- bool async_transmit = app->from_config("async_transmit").as();
+ auto async_receive = app->from_config("async_receive").as();
+ auto async_transmit = app->from_config("async_transmit").as();
app->set_async_receive(async_receive);
app->set_async_transmit(async_transmit);
- std::string scheduler = app->from_config("scheduler").as();
+ auto scheduler = app->from_config("scheduler").as();
holoscan::ArgList scheduler_args{holoscan::Arg("stop_on_deadlock", true),
holoscan::Arg("stop_on_deadlock_timeout", 500L)};
if (scheduler == "multi_thread") {
diff --git a/examples/conditions/expiring_message/CMakeLists.txt b/examples/conditions/expiring_message/CMakeLists.txt
index a3ac1334..0fa63c4d 100644
--- a/examples/conditions/expiring_message/CMakeLists.txt
+++ b/examples/conditions/expiring_message/CMakeLists.txt
@@ -13,8 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-add_subdirectory(cpp)
-if(HOLOSCAN_BUILD_PYTHON)
+if(HOLOSCAN_CPP_EXAMPLES)
+ add_subdirectory(cpp)
+endif()
+
+if(HOLOSCAN_PYTHON_EXAMPLES)
add_subdirectory(python)
endif()
diff --git a/examples/conditions/expiring_message/cpp/ping_expiring_message.cpp b/examples/conditions/expiring_message/cpp/ping_expiring_message.cpp
index e1ee40c6..1b585604 100644
--- a/examples/conditions/expiring_message/cpp/ping_expiring_message.cpp
+++ b/examples/conditions/expiring_message/cpp/ping_expiring_message.cpp
@@ -32,7 +32,8 @@ class PingTxOp : public Operator {
void setup(OperatorSpec& spec) override { spec.output>("out"); }
- void compute(InputContext&, OutputContext& op_output, ExecutionContext&) override {
+ void compute([[maybe_unused]] InputContext& op_input, OutputContext& op_output,
+ [[maybe_unused]] ExecutionContext& context) override {
auto value =
std::make_shared(fmt::format("ExpiringMessageAvailable ping: {}", index_));
++index_;
@@ -40,9 +41,9 @@ class PingTxOp : public Operator {
// retrieve the scheduler used for this application via it's fragment
auto scheduler = fragment_->scheduler();
// To get the clock we currently have to cast the scheduler to gxf::GXFScheduler.
- // TODO: Refactor C++ lib so the clock method is on Scheduler rather than GXFScheduler.
- // That would allow us to avoid this dynamic_pointer_cast, but might require adding
- // renaming Clock->GXFClock and then adding a new holoscan::Clock independent of GXF.
+ // TODO(unknown): Refactor C++ lib so the clock method is on Scheduler rather than
+ // GXFScheduler. That would allow us to avoid this dynamic_pointer_cast, but might require
+ // adding renaming Clock->GXFClock and then adding a new holoscan::Clock independent of GXF.
auto gxf_scheduler = std::dynamic_pointer_cast(scheduler);
auto clock = gxf_scheduler->clock();
auto timestamp = clock->timestamp();
@@ -72,19 +73,21 @@ class PingRxOp : public Operator {
.condition(ConditionType::kExpiringMessageAvailable, expiring_message_arglist);
}
- void compute(InputContext& op_input, OutputContext&, ExecutionContext&) override {
- auto in_value = op_input.receive>("in");
-
+ void compute(InputContext& op_input, [[maybe_unused]] OutputContext& op_output,
+ [[maybe_unused]] ExecutionContext& context) override {
HOLOSCAN_LOG_INFO("PingRxOp::compute() called");
- while (in_value) {
+ while (true) {
+ auto in_value = op_input.receive>("in");
+
+ if (!in_value) { break; }
+
auto message = in_value.value();
if (message) {
HOLOSCAN_LOG_INFO("Rx message received: {}", message->c_str());
} else {
HOLOSCAN_LOG_INFO("Rx message received: nullptr");
}
- in_value = op_input.receive>("in");
}
};
};
@@ -111,7 +114,7 @@ class App : public holoscan::Application {
}
};
-int main(int argc, char** argv) {
+int main([[maybe_unused]] int argc, char** argv) {
auto app = holoscan::make_application();
// Get the configuration
diff --git a/examples/conditions/periodic/CMakeLists.txt b/examples/conditions/periodic/CMakeLists.txt
index 952a4baf..4e4e14d7 100644
--- a/examples/conditions/periodic/CMakeLists.txt
+++ b/examples/conditions/periodic/CMakeLists.txt
@@ -13,8 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-add_subdirectory(cpp)
-if(HOLOSCAN_BUILD_PYTHON)
+if(HOLOSCAN_CPP_EXAMPLES)
+ add_subdirectory(cpp)
+endif()
+
+if(HOLOSCAN_PYTHON_EXAMPLES)
add_subdirectory(python)
endif()
diff --git a/examples/conditions/periodic/cpp/ping_periodic.cpp b/examples/conditions/periodic/cpp/ping_periodic.cpp
index 02e51002..81131e3e 100644
--- a/examples/conditions/periodic/cpp/ping_periodic.cpp
+++ b/examples/conditions/periodic/cpp/ping_periodic.cpp
@@ -30,7 +30,8 @@ class PingTxOp : public Operator {
void setup(OperatorSpec& spec) override { spec.output>("out"); }
- void compute(InputContext&, OutputContext& op_output, ExecutionContext&) override {
+ void compute([[maybe_unused]] InputContext& op_input, OutputContext& op_output,
+ [[maybe_unused]] ExecutionContext& context) override {
auto value = std::make_shared("Periodic ping...");
op_output.emit(value, "out");
};
@@ -44,7 +45,8 @@ class PingRxOp : public Operator {
void setup(OperatorSpec& spec) override { spec.input>("in"); }
- void compute(InputContext& op_input, OutputContext&, ExecutionContext&) override {
+ void compute(InputContext& op_input, [[maybe_unused]] OutputContext& op_output,
+ [[maybe_unused]] ExecutionContext& context) override {
auto in_value = op_input.receive>("in").value();
HOLOSCAN_LOG_INFO("Rx message received: {}", in_value->c_str());
@@ -77,7 +79,7 @@ class App : public holoscan::Application {
}
};
-int main(int argc, char** argv) {
+int main([[maybe_unused]] int argc, char** argv) {
auto app = holoscan::make_application();
// Get the configuration
diff --git a/examples/flow_tracker/CMakeLists.txt b/examples/flow_tracker/CMakeLists.txt
index 15697f79..c9769ebc 100644
--- a/examples/flow_tracker/CMakeLists.txt
+++ b/examples/flow_tracker/CMakeLists.txt
@@ -13,8 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-add_subdirectory(cpp)
-if(HOLOSCAN_BUILD_PYTHON)
+if(HOLOSCAN_CPP_EXAMPLES)
+ add_subdirectory(cpp)
+endif()
+
+if(HOLOSCAN_PYTHON_EXAMPLES)
add_subdirectory(python)
endif()
diff --git a/examples/flow_tracker/cpp/flow_tracker.cpp b/examples/flow_tracker/cpp/flow_tracker.cpp
index b3859479..b97dc0df 100644
--- a/examples/flow_tracker/cpp/flow_tracker.cpp
+++ b/examples/flow_tracker/cpp/flow_tracker.cpp
@@ -28,9 +28,21 @@ class ValueData {
}
~ValueData() { HOLOSCAN_LOG_TRACE("ValueData::~ValueData(): {}", data_); }
+ // Use default copy constructor
+ ValueData(const ValueData&) = default;
+
+ // Use default move constructor
+ ValueData(ValueData&&) noexcept = default;
+
+ // Use default copy assignment operator
+ ValueData& operator=(const ValueData&) = default;
+
+ // Use default move assignment operator
+ ValueData& operator=(ValueData&&) noexcept = default;
+
void data(int value) { data_ = value; }
- int data() const { return data_; }
+ [[nodiscard]] int data() const { return data_; }
private:
int data_;
@@ -46,10 +58,13 @@ class PingTxOp : public Operator {
void setup(OperatorSpec& spec) override { spec.output("out"); }
- void compute(InputContext&, OutputContext& op_output, ExecutionContext&) override {
+ void compute([[maybe_unused]] InputContext& op_input, OutputContext& op_output,
+ [[maybe_unused]] ExecutionContext& context) override {
auto value1 = ValueData(index_++);
op_output.emit(value1, "out");
};
+
+ private:
int index_ = 1;
};
@@ -65,7 +80,8 @@ class PingMxOp : public Operator {
spec.param(multiplier_, "multiplier", "Multiplier", "Multiply the input by this value", 2);
}
- void compute(InputContext& op_input, OutputContext& op_output, ExecutionContext&) override {
+ void compute(InputContext& op_input, OutputContext& op_output,
+ [[maybe_unused]] ExecutionContext& context) override {
auto value = op_input.receive("in").value();
HOLOSCAN_LOG_INFO("Middle message received (count: {})", count_++);
@@ -97,7 +113,8 @@ class PingRxOp : public Operator {
spec.input>("receivers", IOSpec::kAnySize);
}
- void compute(InputContext& op_input, OutputContext&, ExecutionContext&) override {
+ void compute(InputContext& op_input, [[maybe_unused]] OutputContext& op_output,
+ [[maybe_unused]] ExecutionContext& context) override {
auto value_vector = op_input.receive>("receivers").value();
HOLOSCAN_LOG_INFO("Rx message received (count: {}, size: {})", count_++, value_vector.size());
@@ -138,7 +155,7 @@ class MyPingApp : public holoscan::Application {
}
};
-int main(int argc, char** argv) {
+int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) {
auto app = holoscan::make_application();
// Skip 2 messages at the start and 3 messages at the end
auto& tracker = app->track(2, 3, 0);
diff --git a/examples/hello_world/CMakeLists.txt b/examples/hello_world/CMakeLists.txt
index 15697f79..c9769ebc 100644
--- a/examples/hello_world/CMakeLists.txt
+++ b/examples/hello_world/CMakeLists.txt
@@ -13,8 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-add_subdirectory(cpp)
-if(HOLOSCAN_BUILD_PYTHON)
+if(HOLOSCAN_CPP_EXAMPLES)
+ add_subdirectory(cpp)
+endif()
+
+if(HOLOSCAN_PYTHON_EXAMPLES)
add_subdirectory(python)
endif()
diff --git a/examples/hello_world/cpp/hello_world.cpp b/examples/hello_world/cpp/hello_world.cpp
index 38e943b9..8c7189c5 100644
--- a/examples/hello_world/cpp/hello_world.cpp
+++ b/examples/hello_world/cpp/hello_world.cpp
@@ -28,8 +28,8 @@ class HelloWorldOp : public Operator {
void setup(OperatorSpec& spec) override {}
- void compute(InputContext& op_input, OutputContext& op_output,
- ExecutionContext& context) override {
+ void compute([[maybe_unused]] InputContext& op_input, [[maybe_unused]] OutputContext& op_output,
+ [[maybe_unused]] ExecutionContext& context) override {
std::cout << std::endl;
std::cout << "Hello World!" << std::endl;
std::cout << std::endl;
@@ -51,7 +51,7 @@ class HelloWorldApp : public holoscan::Application {
}
};
-int main(int argc, char** argv) {
+int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) {
auto app = holoscan::make_application();
app->run();
diff --git a/examples/holoviz/CMakeLists.txt b/examples/holoviz/CMakeLists.txt
index 952a4baf..4e4e14d7 100644
--- a/examples/holoviz/CMakeLists.txt
+++ b/examples/holoviz/CMakeLists.txt
@@ -13,8 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-add_subdirectory(cpp)
-if(HOLOSCAN_BUILD_PYTHON)
+if(HOLOSCAN_CPP_EXAMPLES)
+ add_subdirectory(cpp)
+endif()
+
+if(HOLOSCAN_PYTHON_EXAMPLES)
add_subdirectory(python)
endif()
diff --git a/examples/holoviz/cpp/CMakeLists.txt b/examples/holoviz/cpp/CMakeLists.txt
index 6c555483..9b45a344 100644
--- a/examples/holoviz/cpp/CMakeLists.txt
+++ b/examples/holoviz/cpp/CMakeLists.txt
@@ -70,12 +70,12 @@ if(HOLOSCAN_BUILD_TESTS)
set(RECORDING_DIR ${CMAKE_CURRENT_BINARY_DIR}/recording_output)
set(SOURCE_VIDEO_BASENAME holoviz_geometry_output)
- set(VALIDATION_FRAMES_DIR ${CMAKE_SOURCE_DIR}/tests/data/validation_frames/holoviz_geometry/)
+ set(VALIDATION_FRAMES_DIR ${Holoscan-examples_SOURCE_DIR}/../tests/data/validation_frames/holoviz_geometry/)
file(MAKE_DIRECTORY ${RECORDING_DIR})
# Patch the current example to enable recording the rendering window
- set(_patch_file ${CMAKE_SOURCE_DIR}/tests/data/validation_frames/holoviz_geometry/cpp_holoviz_geometry.patch)
+ set(_patch_file ${Holoscan-examples_SOURCE_DIR}/../tests/data/validation_frames/holoviz_geometry/cpp_holoviz_geometry.patch)
add_custom_command(OUTPUT holoviz_geometry_test.cpp
PRE_LINK
COMMAND patch -u -o holoviz_geometry_test.cpp ${CMAKE_CURRENT_SOURCE_DIR}/holoviz_geometry.cpp
@@ -116,7 +116,7 @@ if(HOLOSCAN_BUILD_TESTS)
# Add a test to check the validity of the frames
add_test(NAME EXAMPLE_CPP_HOLOVIZ_GEOMETRY_RENDER_TEST
- COMMAND python3 ${CMAKE_SOURCE_DIR}/scripts/video_validation.py
+ COMMAND python3 ${Holoscan-examples_SOURCE_DIR}/../scripts/video_validation.py
--source_video_dir ${RECORDING_DIR}
--source_video_basename ${SOURCE_VIDEO_BASENAME}
--output_dir ${RECORDING_DIR}
diff --git a/examples/holoviz/cpp/holoviz_camera.cpp b/examples/holoviz/cpp/holoviz_camera.cpp
index 1c9d27f7..4b90238e 100644
--- a/examples/holoviz/cpp/holoviz_camera.cpp
+++ b/examples/holoviz/cpp/holoviz_camera.cpp
@@ -14,6 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+// NOLINTFILE(concurrency-mt-unsafe)
+
#include
#include
@@ -42,7 +44,8 @@ class CameraPoseRxOp : public Operator {
void start() override { start_time_ = std::chrono::steady_clock::now(); }
- void compute(InputContext& op_input, OutputContext&, ExecutionContext&) override {
+ void compute(InputContext& op_input, [[maybe_unused]] OutputContext& op_output,
+ [[maybe_unused]] ExecutionContext& context) override {
auto value = op_input.receive>("input").value();
// print once every second
@@ -106,7 +109,7 @@ class GeometrySourceOp : public Operator {
std::memcpy(tensor->pointer(), data.data(), N * C * sizeof(float));
}
- void compute(InputContext& op_input, OutputContext& op_output,
+ void compute([[maybe_unused]] InputContext& op_input, OutputContext& op_output,
ExecutionContext& context) override {
auto entity = gxf::Entity::New(&context);
auto specs = std::vector();
@@ -115,57 +118,57 @@ class GeometrySourceOp : public Operator {
// Each triangle is defined by a set of 3 (x, y, z) coordinate pairs.
add_data<6, 3>(entity,
"back",
- {{{-1.f, -1.f, -1.f},
- {1.f, -1.f, -1.f},
- {1.f, 1.f, -1.f},
- {1.f, 1.f, -1.f},
- {-1.f, 1.f, -1.f},
- {-1.f, -1.f, -1.f}}},
+ {{{-1.F, -1.F, -1.F},
+ {1.F, -1.F, -1.F},
+ {1.F, 1.F, -1.F},
+ {1.F, 1.F, -1.F},
+ {-1.F, 1.F, -1.F},
+ {-1.F, -1.F, -1.F}}},
context);
add_data<6, 3>(entity,
"front",
- {{{-1.f, -1.f, 1.f},
- {1.f, -1.f, 1.f},
- {1.f, 1.f, 1.f},
- {1.f, 1.f, 1.f},
- {-1.f, 1.f, 1.f},
- {-1.f, -1.f, 1.f}}},
+ {{{-1.F, -1.F, 1.F},
+ {1.F, -1.F, 1.F},
+ {1.F, 1.F, 1.F},
+ {1.F, 1.F, 1.F},
+ {-1.F, 1.F, 1.F},
+ {-1.F, -1.F, 1.F}}},
context);
add_data<6, 3>(entity,
"right",
- {{{1.f, -1.f, -1.f},
- {1.f, -1.f, 1.f},
- {1.f, 1.f, 1.f},
- {1.f, 1.f, 1.f},
- {1.f, 1.f, -1.f},
- {1.f, -1.f, -1.f}}},
+ {{{1.F, -1.F, -1.F},
+ {1.F, -1.F, 1.F},
+ {1.F, 1.F, 1.F},
+ {1.F, 1.F, 1.F},
+ {1.F, 1.F, -1.F},
+ {1.F, -1.F, -1.F}}},
context);
add_data<6, 3>(entity,
"left",
- {{{-1.f, -1.f, -1.f},
- {-1.f, -1.f, 1.f},
- {-1.f, 1.f, 1.f},
- {-1.f, 1.f, 1.f},
- {-1.f, 1.f, -1.f},
- {-1.f, -1.f, -1.f}}},
+ {{{-1.F, -1.F, -1.F},
+ {-1.F, -1.F, 1.F},
+ {-1.F, 1.F, 1.F},
+ {-1.F, 1.F, 1.F},
+ {-1.F, 1.F, -1.F},
+ {-1.F, -1.F, -1.F}}},
context);
add_data<6, 3>(entity,
"top",
- {{{-1.f, 1.f, -1.f},
- {-1.f, 1.f, 1.f},
- {1.f, 1.f, 1.f},
- {1.f, 1.f, 1.f},
- {1.f, 1.f, -1.f},
- {-1.f, 1.f, -1.f}}},
+ {{{-1.F, 1.F, -1.F},
+ {-1.F, 1.F, 1.F},
+ {1.F, 1.F, 1.F},
+ {1.F, 1.F, 1.F},
+ {1.F, 1.F, -1.F},
+ {-1.F, 1.F, -1.F}}},
context);
add_data<6, 3>(entity,
"bottom",
- {{{-1.f, -1.f, -1.f},
- {-1.f, -1.f, 1.f},
- {1.f, -1.f, 1.f},
- {1.f, -1.f, 1.f},
- {1.f, -1.f, -1.f},
- {-1.f, -1.f, -1.f}}},
+ {{{-1.F, -1.F, -1.F},
+ {-1.F, -1.F, 1.F},
+ {1.F, -1.F, 1.F},
+ {1.F, -1.F, 1.F},
+ {1.F, -1.F, -1.F},
+ {-1.F, -1.F, -1.F}}},
context);
// emit the tensors
@@ -173,10 +176,17 @@ class GeometrySourceOp : public Operator {
// every second, switch camera
if (std::chrono::steady_clock::now() - start_time_ > std::chrono::seconds(1)) {
+ // NOLINTBEGIN(cert-msc30-c,cert-msc50-cpp,concurrency-mt-unsafe)
+ // NOLINTBEGIN(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
const int camera = std::rand() % sizeof(cameras_) / sizeof(cameras_[0]);
+ // NOLINTEND(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
+ // NOLINTEND(cert-msc30-c,cert-msc50-cpp,concurrency-mt-unsafe)
+
+ // NOLINTBEGIN(cppcoreguidelines-pro-bounds-constant-array-index)
camera_eye_ = cameras_[camera][0];
camera_look_at_ = cameras_[camera][1];
camera_up_ = cameras_[camera][2];
+ // NOLINTEND(cppcoreguidelines-pro-bounds-constant-array-index)
op_output.emit(camera_eye_, "camera_eye_output");
op_output.emit(camera_look_at_, "camera_look_at_output");
@@ -195,13 +205,16 @@ class GeometrySourceOp : public Operator {
std::chrono::steady_clock::time_point start_time_;
+ // NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
+
// define some cameras we switch between
static constexpr std::array cameras_[4][3]{
- {{0.f, 0.f, 5.f}, {1.f, 1.f, 0.f}, {0.f, 1.f, 0.f}},
- {{1.f, 1.f, -3.f}, {0.f, 0.f, 0.f}, {0.f, 1.f, 0.f}},
- {{3.f, -4.f, 0.f}, {0.f, 1.f, 1.f}, {1.f, 0.f, 0.f}},
- {{-2.f, 0.f, -3.f}, {-1.f, 0.f, -1.f}, {0.f, 0.f, 1.f}}};
+ {{0.F, 0.F, 5.F}, {1.F, 1.F, 0.F}, {0.F, 1.F, 0.F}},
+ {{1.F, 1.F, -3.F}, {0.F, 0.F, 0.F}, {0.F, 1.F, 0.F}},
+ {{3.F, -4.F, 0.F}, {0.F, 1.F, 1.F}, {1.F, 0.F, 0.F}},
+ {{-2.F, 0.F, -3.F}, {-1.F, 0.F, -1.F}, {0.F, 0.F, 1.F}}};
+ // NOLINTEND(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
std::array camera_eye_ = cameras_[0][0];
std::array camera_look_at_ = cameras_[0][1];
std::array camera_up_ = cameras_[0][2];
@@ -250,17 +263,21 @@ class HolovizCameraApp : public holoscan::Application {
// Parameters defining the triangle primitives
const std::array spec_names{"back", "front", "left", "right", "top", "bottom"};
- for (int index = 0; index < spec_names.size(); ++index) {
+ unsigned int index = 0;
+ for (const auto* spec_name : spec_names) {
auto& spec = input_spec.emplace_back(
- ops::HolovizOp::InputSpec(spec_names[index], ops::HolovizOp::InputType::TRIANGLES_3D));
- spec.color_ = {
- float((index + 1) & 1), float(((index + 1) / 2) & 1), float(((index + 1) / 4) & 1), 1.0f};
+ ops::HolovizOp::InputSpec(spec_name, ops::HolovizOp::InputType::TRIANGLES_3D));
+ spec.color_ = {static_cast((index + 1) & 1U),
+ static_cast(((index + 1) / 2) & 1U),
+ static_cast(((index + 1) / 4) & 1U),
+ 1.0F};
+ index++;
}
auto visualizer = make_operator(
"holoviz",
- Arg("width", 1024u),
- Arg("height", 1024u),
+ Arg("width", 1024U),
+ Arg("height", 1024U),
Arg("tensors", input_spec),
Arg("enable_camera_pose_output", true),
Arg("camera_pose_output_type", std::string("extrinsics_model")),
@@ -285,16 +302,21 @@ class HolovizCameraApp : public holoscan::Application {
int main(int argc, char** argv) {
// Parse args
- struct option long_options[] = {
- {"help", no_argument, 0, 'h'}, {"count", required_argument, 0, 'c'}, {0, 0, 0, 0}};
+ // NOLINTBEGIN(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
+ struct option long_options[] = {{"help", no_argument, nullptr, 'h'},
+ {"count", required_argument, nullptr, 'c'},
+ {nullptr, 0, nullptr, 0}};
+ // NOLINTEND(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
uint64_t count = -1;
while (true) {
int option_index = 0;
- const int c = getopt_long(argc, argv, "hc:", long_options, &option_index);
+ // NOLINTBEGIN(concurrency-mt-unsafe)
+ const int c = getopt_long(argc, argv, "hc:", static_cast