cudaPackages.nvimgcodec, cudaPackages.dali, python3Packages.nvidia-dali: init at 0.9.0, 2.4.0, 2.4.0 (#577197)

This commit is contained in:
Connor Baker
2026-10-28 03:33:35 +00:00
committed by GitHub
8 changed files with 965 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
From 7fa7b7bedd46a6e346d2bf1504388e7dd00138ed Mon Sep 17 00:00:00 2001
From: Connor Baker <ConnorBaker01@gmail.com>
Date: Sun, 25 Oct 2026 18:12:47 -0700
Subject: [PATCH] fix: link cuSOLVER and cuBLAS only when FindHomography is
built
cvcuda_priv links CUDA::cusolver_static, CUDA::cublas_static and
CUDA::cublasLt_static unconditionally, but only OpFindHomography.cu
uses them. A build that selects a subset of the operators with
CV_CUDA_SRC_PATERN, as DALI does, still needs the static cuSOLVER and
cuBLAS libraries, and fails to configure where they aren't installed:
CMake Error at src/cvcuda/priv/CMakeLists.txt (target_link_libraries):
Target "cvcuda_priv" links to:
CUDA::cusolver_static
but the target was not found.
Link them only when OpFindHomography.cu is part of the build. A full
build links the same libraries in the same order as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---
src/cvcuda/priv/CMakeLists.txt | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/third_party/cvcuda/src/cvcuda/priv/CMakeLists.txt b/third_party/cvcuda/src/cvcuda/priv/CMakeLists.txt
index deac31c..7645497 100644
--- a/third_party/cvcuda/src/cvcuda/priv/CMakeLists.txt
+++ b/third_party/cvcuda/src/cvcuda/priv/CMakeLists.txt
@@ -95,6 +95,12 @@ add_library(cvcuda_priv STATIC
${CV_CUDA_PRIV_FILES}
)
+# Only FindHomography uses cuSOLVER and cuBLAS, and CV_CUDA_SRC_PATERN can leave it out
+set(CV_CUDA_PRIV_SOLVER_LIBS)
+if ("OpFindHomography.cu" IN_LIST CV_CUDA_PRIV_FILES)
+ set(CV_CUDA_PRIV_SOLVER_LIBS CUDA::cusolver_static CUDA::cublas_static CUDA::cublasLt_static)
+endif()
+
target_link_libraries(cvcuda_priv
PUBLIC
nvcv_types
@@ -103,8 +109,6 @@ target_link_libraries(cvcuda_priv
nvcv_util_sanitizer
cvcuda_legacy
CUDA::cudart_static
- CUDA::cusolver_static
- CUDA::cublas_static
- CUDA::cublasLt_static
+ ${CV_CUDA_PRIV_SOLVER_LIBS}
-lrt
)
--
2.43.0

View File

@@ -0,0 +1,79 @@
From 9c3b5760bfe021d0d6f974ad1559bcc13c7c463c Mon Sep 17 00:00:00 2001
From: Janusz Lisiecki <jlisiecki@nvidia.com>
Date: Mon, 19 Oct 2026 09:53:38 +0200
Subject: [PATCH 2/2] Batch staging copies for nvCOMP decompression
Signed-off-by: Janusz Lisiecki <jlisiecki@nvidia.com>
---
dali/operators/decoder/inflate/inflate_gpu.cc | 18 ++++++++----------
dali/test/python/operator_1/test_inflate.py | 3 ++-
2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/dali/operators/decoder/inflate/inflate_gpu.cc b/dali/operators/decoder/inflate/inflate_gpu.cc
index 658f3922..b54bc0fb 100644
--- a/dali/operators/decoder/inflate/inflate_gpu.cc
+++ b/dali/operators/decoder/inflate/inflate_gpu.cc
@@ -22,6 +22,7 @@
#include "dali/core/common.h"
#include "dali/core/static_switch.h"
#include "dali/core/tensor_shape.h"
+#include "dali/kernels/common/scatter_gather.h"
#include "dali/kernels/kernel_manager.h"
#include "dali/operators/decoder/inflate/inflate.h"
#include "dali/operators/decoder/inflate/inflate_gpu.h"
@@ -59,18 +60,20 @@ class InflateOpGpuLZ4Impl : public InflateOpImplBase<GPUBackend> {
// aligned input and output buffers, so stage only the chunks that need it.
constexpr size_t alignment = nvcompLZ4RequiredDecompressionAlignment;
const auto &in_chunk_sizes = params_.GetInChunkSizes();
- auto original_output_ptrs = inflated_ptrs_;
+ kernels::ScatterGatherGPU input_copies, output_copies;
for (size_t i = 0; i < total_chunks_num; i++) {
if (reinterpret_cast<uintptr_t>(input_ptrs_[i]) % alignment != 0) {
auto *aligned_input = scratchpad.AllocateGPU<uint8_t>(in_chunk_sizes[i], alignment);
- CUDA_CALL(cudaMemcpyAsync(aligned_input, input_ptrs_[i], in_chunk_sizes[i],
- cudaMemcpyDeviceToDevice, stream));
+ input_copies.AddCopy(aligned_input, input_ptrs_[i], in_chunk_sizes[i]);
input_ptrs_[i] = aligned_input;
}
if (reinterpret_cast<uintptr_t>(inflated_ptrs_[i]) % alignment != 0) {
- inflated_ptrs_[i] = scratchpad.AllocateGPU<uint8_t>(inflated_sizes_[i], alignment);
+ auto *aligned_output = scratchpad.AllocateGPU<uint8_t>(inflated_sizes_[i], alignment);
+ output_copies.AddCopy(inflated_ptrs_[i], aligned_output, inflated_sizes_[i]);
+ inflated_ptrs_[i] = aligned_output;
}
}
+ input_copies.Run(stream);
size_t *actual_out_sizes = scratchpad.AllocateGPU<size_t>(total_chunks_num);
auto [in_sizes, in, out_sizes, out] = scratchpad.ToContiguousGPU(
@@ -121,12 +124,7 @@ class InflateOpGpuLZ4Impl : public InflateOpImplBase<GPUBackend> {
// Here, we take care of the opposite case, when the allocations are bigger than really
// necessary and thus may contain some uninitialized memory.
FillTheTails(output.type(), total_chunks_num, out, actual_out_sizes, out_sizes, stream);
- for (size_t i = 0; i < total_chunks_num; i++) {
- if (inflated_ptrs_[i] != original_output_ptrs[i]) {
- CUDA_CALL(cudaMemcpyAsync(original_output_ptrs[i], inflated_ptrs_[i], inflated_sizes_[i],
- cudaMemcpyDeviceToDevice, stream));
- }
- }
+ output_copies.Run(stream);
}
protected:
diff --git a/dali/test/python/operator_1/test_inflate.py b/dali/test/python/operator_1/test_inflate.py
index 2cb176c0..a3e5f257 100644
--- a/dali/test/python/operator_1/test_inflate.py
+++ b/dali/test/python/operator_1/test_inflate.py
@@ -178,7 +178,8 @@ def test_checks_sufficient_output_buffer():
]
)
def test_unaligned_chunks(dtype, offset, oversized):
- sample = np.arange(15, dtype=dtype).reshape(3, 5)
+ # Enough unaligned ranges to exercise the batched copy kernel in both directions.
+ sample = np.arange(85, dtype=dtype).reshape(17, 5)
chunks = [sample_to_lz4(frame) for frame in sample]
sizes = np.array([len(chunk) for chunk in chunks], dtype=np.int32)
offsets = np.array(offset + np.cumsum([0] + list(sizes[:-1])), dtype=np.int32)
--
2.43.0

View File

@@ -0,0 +1,227 @@
From ad607fa44f20392718258fc2a6a28ecf1b79590b Mon Sep 17 00:00:00 2001
From: Janusz Lisiecki <jlisiecki@nvidia.com>
Date: Mon, 19 Oct 2026 09:41:08 +0200
Subject: [PATCH 1/2] Update nvCOMP to 6.0 for CUDA 12.9 and 13.4 builds
Signed-off-by: Janusz Lisiecki <jlisiecki@nvidia.com>
---
cmake/Dependencies.common.cmake | 2 +-
dali/core/dynlink_nvcomp.cc | 4 +--
dali/operators/decoder/inflate/inflate_gpu.cc | 29 +++++++++++++++--
dali/test/python/operator_1/test_inflate.py | 32 +++++++++++++++++++
docker/Dockerfile.cuda129.aarch64.deps | 2 +-
docker/Dockerfile.cuda129.x86_64.deps | 2 +-
docker/Dockerfile.cuda134.aarch64.deps | 2 +-
docker/Dockerfile.cuda134.x86_64.deps | 2 +-
internal_tools/stub_generator/nvcomp.json | 2 +-
9 files changed, 66 insertions(+), 11 deletions(-)
diff --git a/cmake/Dependencies.common.cmake b/cmake/Dependencies.common.cmake
index 80e073f9..78bfa6f7 100644
--- a/cmake/Dependencies.common.cmake
+++ b/cmake/Dependencies.common.cmake
@@ -167,7 +167,7 @@ if(BUILD_NVCOMP)
list(APPEND DALI_LIBS ${nvcomp_LIBS})
else()
message(STATUS "Found nvCOMP: ${nvcomp_INCLUDE_DIR}.")
- set(DALI_INSTALL_REQUIRES_NVCOMP "\'nvidia-libnvcomp-cu${CUDA_VERSION_MAJOR} == 5.3.0.16\',")
+ set(DALI_INSTALL_REQUIRES_NVCOMP "\'nvidia-libnvcomp-cu${CUDA_VERSION_MAJOR} == 6.0.0.12\',")
message(STATUS "Adding nvComp requirement as: ${DALI_INSTALL_REQUIRES_NVCOMP}")
endif()
endif()
diff --git a/dali/core/dynlink_nvcomp.cc b/dali/core/dynlink_nvcomp.cc
index ae9459d7..f64a1cfa 100644
--- a/dali/core/dynlink_nvcomp.cc
+++ b/dali/core/dynlink_nvcomp.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+// Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ namespace {
typedef void* NVCOMP;
static const char __nvCompfileLibName[] = "libnvcomp.so";
-static const char __nvCompfileLibName1[] = "libnvcomp.so.5";
+static const char __nvCompfileLibName1[] = "libnvcomp.so.6";
NVCOMP loadNvCompFileLibrary() {
NVCOMP ret = nullptr;
diff --git a/dali/operators/decoder/inflate/inflate_gpu.cc b/dali/operators/decoder/inflate/inflate_gpu.cc
index 2f0a929a..658f3922 100644
--- a/dali/operators/decoder/inflate/inflate_gpu.cc
+++ b/dali/operators/decoder/inflate/inflate_gpu.cc
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cstdint>
#include <memory>
#include <string>
#include <vector>
@@ -54,6 +55,22 @@ class InflateOpGpuLZ4Impl : public InflateOpImplBase<GPUBackend> {
auto stream = ws.stream();
kernels::DynamicScratchpad scratchpad(stream);
+ // Chunks can start at arbitrary byte offsets in DALI tensors. nvCOMP 6 requires
+ // aligned input and output buffers, so stage only the chunks that need it.
+ constexpr size_t alignment = nvcompLZ4RequiredDecompressionAlignment;
+ const auto &in_chunk_sizes = params_.GetInChunkSizes();
+ auto original_output_ptrs = inflated_ptrs_;
+ for (size_t i = 0; i < total_chunks_num; i++) {
+ if (reinterpret_cast<uintptr_t>(input_ptrs_[i]) % alignment != 0) {
+ auto *aligned_input = scratchpad.AllocateGPU<uint8_t>(in_chunk_sizes[i], alignment);
+ CUDA_CALL(cudaMemcpyAsync(aligned_input, input_ptrs_[i], in_chunk_sizes[i],
+ cudaMemcpyDeviceToDevice, stream));
+ input_ptrs_[i] = aligned_input;
+ }
+ if (reinterpret_cast<uintptr_t>(inflated_ptrs_[i]) % alignment != 0) {
+ inflated_ptrs_[i] = scratchpad.AllocateGPU<uint8_t>(inflated_sizes_[i], alignment);
+ }
+ }
size_t *actual_out_sizes = scratchpad.AllocateGPU<size_t>(total_chunks_num);
auto [in_sizes, in, out_sizes, out] = scratchpad.ToContiguousGPU(
@@ -86,14 +103,14 @@ class InflateOpGpuLZ4Impl : public InflateOpImplBase<GPUBackend> {
}
size_t tempSize;
- CUDA_CALL(nvcompBatchedLZ4DecompressGetTempSizeAsync(
+ CUDA_CALL(nvcompBatchedLZ4DecompressGetTempSize(
total_chunks_num,
params_.GetMaxOutChunkVol() * element_type_.size(),
{},
&tempSize,
- params_.GetMaxOutVol() * element_type_.size()));
+ params_.GetMaxOutVol() * element_type_.size(), stream));
- void *temp = scratchpad.AllocateGPU<uint8_t>(tempSize);
+ void *temp = scratchpad.AllocateGPU<uint8_t>(tempSize, alignment);
nvcompStatus_t *device_statuses = scratchpad.AllocateGPU<nvcompStatus_t>(total_chunks_num);
CUDA_CALL(nvcompBatchedLZ4DecompressAsync(in, in_sizes, out_sizes, actual_out_sizes,
total_chunks_num, temp, tempSize, out, {},
@@ -104,6 +121,12 @@ class InflateOpGpuLZ4Impl : public InflateOpImplBase<GPUBackend> {
// Here, we take care of the opposite case, when the allocations are bigger than really
// necessary and thus may contain some uninitialized memory.
FillTheTails(output.type(), total_chunks_num, out, actual_out_sizes, out_sizes, stream);
+ for (size_t i = 0; i < total_chunks_num; i++) {
+ if (inflated_ptrs_[i] != original_output_ptrs[i]) {
+ CUDA_CALL(cudaMemcpyAsync(original_output_ptrs[i], inflated_ptrs_[i], inflated_sizes_[i],
+ cudaMemcpyDeviceToDevice, stream));
+ }
+ }
}
protected:
diff --git a/dali/test/python/operator_1/test_inflate.py b/dali/test/python/operator_1/test_inflate.py
index fd34e694..2cb176c0 100644
--- a/dali/test/python/operator_1/test_inflate.py
+++ b/dali/test/python/operator_1/test_inflate.py
@@ -167,6 +167,38 @@ def test_checks_sufficient_output_buffer():
check_batch(inflated, [sample], batch_size=1)
+@has_operator("decoders.inflate")
+@restrict_platform(min_compute_cap=6.0)
+@params(
+ *[
+ (dtype, offset, oversized)
+ for dtype in [np.uint8, np.uint16]
+ for offset in range(4)
+ for oversized in [False, True]
+ ]
+)
+def test_unaligned_chunks(dtype, offset, oversized):
+ sample = np.arange(15, dtype=dtype).reshape(3, 5)
+ chunks = [sample_to_lz4(frame) for frame in sample]
+ sizes = np.array([len(chunk) for chunk in chunks], dtype=np.int32)
+ offsets = np.array(offset + np.cumsum([0] + list(sizes[:-1])), dtype=np.int32)
+ compressed = np.concatenate([np.zeros(offset, dtype=np.uint8), *chunks])
+
+ @pipeline_def(batch_size=1, num_threads=4, device_id=0)
+ def pipeline():
+ data = fn.external_source(source=lambda: compressed, batch=False)
+ return fn.decoders.inflate(
+ data.gpu(),
+ shape=[7 if oversized else 5],
+ dtype=np_type_to_dali(dtype),
+ chunk_offsets=offsets,
+ chunk_sizes=sizes,
+ )
+
+ (inflated,) = pipeline().run()
+ check_batch(inflated, [sample], batch_size=1, oversized_shape=oversized)
+
+
def _test_scalar_shape(dtype, shape, layout):
def sample_source(sample_info):
sample_size = np.prod(shape)
diff --git a/docker/Dockerfile.cuda129.aarch64.deps b/docker/Dockerfile.cuda129.aarch64.deps
index cf97e4cb..f3580637 100644
--- a/docker/Dockerfile.cuda129.aarch64.deps
+++ b/docker/Dockerfile.cuda129.aarch64.deps
@@ -12,7 +12,7 @@ RUN curl -LO https://developer.download.nvidia.com/compute/cuda/12.9.1/local_ins
rm -f cuda_*.run;
RUN CUFILE_VERSION=1.14.1.1-1 && \
- NVCOMP_VERSION=5.3.0.16 && \
+ NVCOMP_VERSION=6.0.0.12 && \
CUDA_VERSION_MAJOR=12 && \
CUDA_VERSION_MINOR=9 && \
apt-get update && \
diff --git a/docker/Dockerfile.cuda129.x86_64.deps b/docker/Dockerfile.cuda129.x86_64.deps
index 12e237d0..b962a838 100644
--- a/docker/Dockerfile.cuda129.x86_64.deps
+++ b/docker/Dockerfile.cuda129.x86_64.deps
@@ -12,7 +12,7 @@ RUN curl -LO https://developer.download.nvidia.com/compute/cuda/12.9.1/local_ins
rm -f cuda_*.run;
RUN CUFILE_VERSION=1.14.1.1-1 && \
- NVCOMP_VERSION=5.3.0.16 && \
+ NVCOMP_VERSION=6.0.0.12 && \
CUDA_VERSION_MAJOR=12 && \
CUDA_VERSION_MINOR=9 && \
apt-get update && \
diff --git a/docker/Dockerfile.cuda134.aarch64.deps b/docker/Dockerfile.cuda134.aarch64.deps
index 743bd52e..1548d3b8 100644
--- a/docker/Dockerfile.cuda134.aarch64.deps
+++ b/docker/Dockerfile.cuda134.aarch64.deps
@@ -7,7 +7,7 @@ RUN CUDA_SUBVERSION=13.4.2-1 && \
CUFILE_VERSION=1.19.1.55-1 && \
CUDA_VERSION_MAJOR=13 && \
CUDA_VERSION_MINOR=4 && \
- NVCOMP_VERSION=5.3.0.16 && \
+ NVCOMP_VERSION=6.0.0.12 && \
apt-get update && \
apt-get install wget software-properties-common -y && \
apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/sbsa/3bf863cc.pub && \
diff --git a/docker/Dockerfile.cuda134.x86_64.deps b/docker/Dockerfile.cuda134.x86_64.deps
index 2035d956..c61f1286 100644
--- a/docker/Dockerfile.cuda134.x86_64.deps
+++ b/docker/Dockerfile.cuda134.x86_64.deps
@@ -7,7 +7,7 @@ RUN CUDA_SUBVERSION=13.4.2-1 && \
CUFILE_VERSION=1.19.1.55-1 && \
CUDA_VERSION_MAJOR=13 && \
CUDA_VERSION_MINOR=4 && \
- NVCOMP_VERSION=5.3.0.16 && \
+ NVCOMP_VERSION=6.0.0.12 && \
apt-get update && \
apt-get install wget software-properties-common -y && \
apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/x86_64/3bf863cc.pub && \
diff --git a/internal_tools/stub_generator/nvcomp.json b/internal_tools/stub_generator/nvcomp.json
index 899e2ed5..656bc5fd 100644
--- a/internal_tools/stub_generator/nvcomp.json
+++ b/internal_tools/stub_generator/nvcomp.json
@@ -6,7 +6,7 @@
"calling_conv":"",
"not_found_error":"nvcompErrorNotSupported",
"functions": {
- "nvcompBatchedLZ4DecompressGetTempSizeAsync": {},
+ "nvcompBatchedLZ4DecompressGetTempSize": {},
"nvcompBatchedLZ4DecompressAsync": {},
"nvcompBatchedLZ4GetDecompressSizeAsync": {},
"nvcompGetStatusString": {
--
2.43.0

View File

@@ -0,0 +1,257 @@
{
autoAddDriverRunpath,
aws-sdk-cpp,
backendStdenv,
boost,
cfitsio,
cmake,
cuda_cudart,
cuda_nvcc,
cuda_nvml_dev,
cudaNamePrefix,
cutlass,
dlpack,
fetchFromGitHub,
fetchpatch2,
ffmpeg_8-headless,
flags,
gitUpdater,
lib,
libcufft,
libcufile,
libcurand,
libnpp,
libsndfile,
libtar,
lmdb,
ninja,
nvcomp,
nvimgcodec,
nvtx,
opencv4WithoutCuda,
pkg-config,
protobuf,
python3,
rapidjson,
# DALI only uses the S3 client.
aws-sdk-cpp-s3 ? aws-sdk-cpp.override { apis = [ "s3" ]; },
}:
let
inherit (lib) cmakeBool cmakeFeature getLib;
in
backendStdenv.mkDerivation (finalAttrs: {
__structuredAttrs = true;
strictDeps = true;
# NOTE: Depends on the CUDA package set, so use cudaNamePrefix.
name = "${cudaNamePrefix}-${finalAttrs.pname}-${finalAttrs.version}";
pname = "dali";
version = "2.4.0";
src = fetchFromGitHub {
owner = "NVIDIA";
repo = "DALI";
tag = "v${finalAttrs.version}";
# DALI builds CV-CUDA (a subset of its operators), FFTS (a fork) and the COCO API from the submodules.
fetchSubmodules = true;
# Fetch only those; the others are replaced by Nixpkgs packages or unused. Without a pathspec, `git submodule update
# --init` initializes (and so clones) only the submodules whose path matches a submodule.active pattern, and sets no
# submodule.<name>.active (which would outrank the patterns). The patterns are matched in every repository, nested
# ones included, so CV-CUDA's own submodules (under 3rdparty) and any submodule a later version adds at another path
# are left as empty directories. They are GIT_CONFIG_* entries, appended like nix-prefetch-git's own, because
# fetchgit's gitConfigFile would replace the user's config.gitConfigFile.
preFetch = ''
for path in third_party/{cocoapi,cvcuda,ffts}; do
i=''${GIT_CONFIG_COUNT:-0}
export GIT_CONFIG_COUNT=$((i + 1)) "GIT_CONFIG_KEY_$i=submodule.active" "GIT_CONFIG_VALUE_$i=$path"
done
'';
hash = "sha256-NTRJFhOe5CtjOuPFDZmNuAUV9zkRG8g0aE2/2QClfaU=";
};
patches = [
# Update nvCOMP to 6.0: DALI 2.4.0 loads libnvcomp.so.5 and uses the nvCOMP 5 LZ4 API, while Nixpkgs has nvCOMP 6.
# The two commits of https://github.com/NVIDIA/DALI/pull/6530, ad607fa44f20392718258fc2a6a28ecf1b79590b and
# 9c3b5760bfe021d0d6f974ad1559bcc13c7c463c, which apply to 2.4.0 as they are. The PR is open (a draft), so they are
# vendored with `git format-patch` (a rebase of the PR could let GitHub garbage-collect them).
./nvcomp-6.patch
./nvcomp-6-batch-staging-copies.patch
# Find the headers of the CUDA libraries DALI generates dlopen stubs from (the driver, cuFile, cuFFT, NPP and NVML)
# with find_path, instead of expecting them in CUDAToolkit_TARGET_DIR/include, which is cuda_nvcc's.
# From https://github.com/NVIDIA/DALI/pull/6550, merged after 2.4.0.
(fetchpatch2 {
name = "find-cuda-library-headers.patch";
url = "https://github.com/NVIDIA/DALI/commit/e6dd6294ecbb6aa242da5d7864208a466d22bac2.patch?full_index=1";
hash = "sha256-6rdej/M7LjHkXUHexRIUvYlSKq/aeQjdZXrdk3o4Mag=";
})
# Warn instead of failing when the old thread pool (which the mixed image decoder uses) can't pin its threads to the
# GPU's CPUs, as when NVML can't read the CPU topology from /sys, which the sandbox lacks
# (https://github.com/NVIDIA/DALI/issues/6551). From https://github.com/NVIDIA/DALI/pull/6552, which is open, so it
# is vendored, without its tests: `git format-patch -1 5e1262eed055a93fa9c4eea7b3bee8178ca3abd6 --
# dali/pipeline/util/thread_pool.cc`.
./warn-on-old-thread-pool-affinity-failures.patch
# DALI builds only some CV-CUDA operators (CV_CUDA_SRC_PATERN), not FindHomography, the only user of cuSOLVER and
# cuBLAS; link them only when FindHomography is built, instead of requiring their static libraries
# (https://github.com/CVCUDA/CV-CUDA/issues/302). CV-CUDA doesn't accept outside contributions, so the fix is
# vendored: `git format-patch -1 --src-prefix=a/third_party/cvcuda/ --dst-prefix=b/third_party/cvcuda/` of
# https://github.com/ConnorBaker/CV-CUDA/commit/7fa7b7bedd46a6e346d2bf1504388e7dd00138ed, the backport of
# https://github.com/ConnorBaker/CV-CUDA/commit/e9ecacfcedf41b9c4518696c268e2518c3133643 to ef50300b (DALI 2.4.0's
# third_party/cvcuda). The prefixes apply it to the submodule's checkout.
./cvcuda-link-solver-only-for-find-homography.patch
];
# Use the header-only Boost.Preprocessor, RapidJSON, CUTLASS and DLPack of Nixpkgs instead of the submodules.
postPatch =
# Replaces third_party/boost/preprocessor, third_party/rapidjson and third_party/cutlass. DALI uses none of the
# CUTLASS utilities (tools/util), which Nixpkgs' CUTLASS installs only with its tools.
''
substituteInPlace cmake/Dependencies.common.cmake \
--replace-fail \
"\''${PROJECT_SOURCE_DIR}/third_party/boost/preprocessor/include" \
"${lib.getDev boost}/include" \
--replace-fail \
"\''${PROJECT_SOURCE_DIR}/third_party/rapidjson/include" \
"${lib.getDev rapidjson}/include" \
--replace-fail \
"include_directories(SYSTEM third_party/cutlass/include)" \
"include_directories(SYSTEM ${lib.getInclude cutlass}/include)" \
--replace-fail \
"include_directories(SYSTEM third_party/cutlass/tools/util/include)" \
""
''
# Replaces third_party/dlpack.
+ ''
substituteInPlace dali/pipeline/data/dltensor.h dali/pipeline/data/dltensor_obj.h \
--replace-fail '"third_party/dlpack/include/dlpack/dlpack.h"' "<dlpack/dlpack.h>"
''
# Replaces third_party/boost/preprocessor as the source of the Boost.Preprocessor headers that the Python package
# ships with its own (for building plugins).
+ ''
substituteInPlace dali/CMakeLists.txt \
--replace-fail \
'cp -rL "''${PROJECT_SOURCE_DIR}/third_party/boost/preprocessor/include/." "''${PROJECT_BINARY_DIR}/''${DALI_INCLUDE_DIR}/"' \
'cp -rL --no-preserve=mode --parents boost/preprocessor boost/preprocessor.hpp "''${PROJECT_BINARY_DIR}/''${DALI_INCLUDE_DIR}/" WORKING_DIRECTORY "${lib.getDev boost}/include"'
'';
nativeBuildInputs = [
autoAddDriverRunpath
cmake
cuda_nvcc
ninja
pkg-config
protobuf
# Generates the stubs for the libraries loaded with dlopen (CUDA driver, nvCOMP, cuFile) from their headers with
# libclang.
(python3.pythonOnBuildForHost.withPackages (ps: [ ps.clang ]))
];
buildInputs = [
aws-sdk-cpp-s3
# Replaces the Boost.Preprocessor submodule (third_party/boost/preprocessor)
boost
cfitsio
cuda_cudart
(lib.getOutput "static" cuda_cudart)
cuda_nvml_dev
# Replaces the CUTLASS submodule (third_party/cutlass)
cutlass
# Replaces the DLPack submodule (third_party/dlpack)
dlpack
ffmpeg_8-headless
libcufft
libcufile
libcurand
libnpp
libsndfile
libtar
lmdb
nvcomp
nvimgcodec
nvtx
# DALI only uses OpenCV's CPU core and imgproc modules.
opencv4WithoutCuda
protobuf
# Replaces the RapidJSON submodule (third_party/rapidjson)
rapidjson
];
cmakeFlags = [
# Selects the CUDA_known_archs set and the dependency file (aarch64-linux is the Jetson cross-compilation setup).
(cmakeFeature "ARCH" backendStdenv.hostPlatform.parsed.cpu.name)
# DALI appends PTX for the last architecture.
(cmakeFeature "CUDA_TARGET_ARCHS" flags.cmakeCudaArchitecturesString)
(cmakeBool "BUILD_PYTHON" false)
(cmakeBool "BUILD_TEST" false)
(cmakeBool "BUILD_BENCHMARK" false)
(cmakeBool "FORMAT_PYTHON_STUB_FILES" false)
# Load the CUDA libraries (cuFFT, NPP) and nvCOMP with dlopen, like the wheels and conda-forge, instead of linking
# them statically. The CUDA driver is loaded with dlopen as well (LINK_DRIVER defaults to OFF).
(cmakeBool "WITH_DYNAMIC_CUDA_TOOLKIT" true)
# Off by default
(cmakeBool "BUILD_NVCOMP" true)
(cmakeBool "BUILD_CUFILE" true)
# nvImageCodec is loaded with dlopen by default; it can only be linked statically when DALI builds it itself (as an
# ExternalProject cloned from GitHub).
(cmakeFeature "NVIMGCODEC_DEFAULT_INSTALL_PATH" "${getLib nvimgcodec}")
# The other optional features (NVDEC, optical flow, NVML, CV-CUDA, the AWS SDK, cfitsio, libsndfile, libtar and
# LMDB) are on by default.
# Google Cloud Storage support needs google-cloud-cpp 3.0 or later, which Nixpkgs doesn't have; DALI would turn it
# off with a warning.
(cmakeBool "BUILD_GCS" false)
# Links CV-CUDA against stubs of glibc 2.17's libdl, librt and libpthread, which are Git LFS objects (missing from
# the source), to run on distributions with an older glibc.
(cmakeBool "ENABLE_COMPAT_OLD_GLIBC" false)
# Defaults to the static library
(cmakeBool "Protobuf_USE_STATIC_LIBS" false)
];
# CV-CUDA installs an /etc/ld.so.conf.d drop-in for its libraries, which DALI's libraries find through their runpath.
postInstall = ''
rm -r "$out/etc"
'';
# The libraries DALI loads with dlopen aren't in DT_NEEDED, so they must be added to the runpath after it is shrunk.
# The CUDA driver and its NVDEC, NVML and optical flow libraries come from autoAddDriverRunpath.
postFixup = ''
for lib in "$out"/lib/libdali*.so; do
patchelf --add-rpath "${
lib.makeLibraryPath [
libcufft
libcufile
libnpp
nvcomp
nvimgcodec
]
}" "$lib"
done
'';
passthru.updateScript = gitUpdater {
inherit (finalAttrs) pname version;
rev-prefix = "v";
# Skip the tags of the development branches (e.g. v2.4.0-dev)
ignoredVersions = "-dev$";
};
meta = {
description = "GPU-accelerated library for data loading and pre-processing for deep learning";
homepage = "https://github.com/NVIDIA/DALI";
changelog = "https://github.com/NVIDIA/DALI/releases/tag/${finalAttrs.src.tag}";
license = with lib.licenses; [
asl20
# Bundled third-party code (see Acknowledgements.txt)
bsd2
bsd3
mit
];
platforms = [
"aarch64-linux"
"x86_64-linux"
];
maintainers = with lib.maintainers; [ connorbaker ];
teams = [ lib.teams.cuda ];
};
})

View File

@@ -0,0 +1,47 @@
From 5e1262eed055a93fa9c4eea7b3bee8178ca3abd6 Mon Sep 17 00:00:00 2001
From: Janusz Lisiecki <jlisiecki@nvidia.com>
Date: Mon, 26 Oct 2026 08:36:47 +0100
Subject: [PATCH] Warn on CPU affinity failures in the old thread pool
Treat affinity setup as best effort, matching NewThreadPool. This lets
mixed image decoding continue when NVML cannot report CPU topology.
Add regression tests for affinity failure recovery and task exception
propagation.
Fixes #6551.
Signed-off-by: Janusz Lisiecki <jlisiecki@nvidia.com>
---
dali/pipeline/util/thread_pool.cc | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/dali/pipeline/util/thread_pool.cc b/dali/pipeline/util/thread_pool.cc
index 5c1bd84..e044cca 100644
--- a/dali/pipeline/util/thread_pool.cc
+++ b/dali/pipeline/util/thread_pool.cc
@@ -15,6 +15,7 @@
#include <chrono>
#include <cstdlib>
#include <limits>
+#include <typeinfo>
#include <utility>
#include "dali/pipeline/util/thread_pool.h"
#if NVML_ENABLED
@@ -153,8 +154,12 @@ void OldThreadPool::ThreadMain(int thread_id, int device_id, bool set_affinity,
nvml::SetCPUAffinity(core);
}
#endif
+ } catch (const std::exception &e) {
+ DALI_WARN("Couldn't set thread affinity in thread ", thread_id, " of thread pool \"",
+ name, "\". Exception ", typeid(e).name(), ": ", e.what());
} catch (...) {
- tl_errors_[thread_id].push(std::current_exception());
+ DALI_WARN("Couldn't set thread affinity in thread ", thread_id, " of thread pool \"",
+ name, "\". Unknown error.");
}
while (running_) {
--
2.43.0

View File

@@ -0,0 +1,125 @@
{
backendStdenv,
boost,
cmake,
cuda_cudart,
cuda_culibos ? null,
cuda_nvcc,
cudaAtLeast,
cudaNamePrefix,
fetchFromGitHub,
flags,
gitUpdater,
lib,
libjpeg_turbo,
libnvjpeg,
libnvjpeg_2k,
libnvtiff,
libtiff,
ninja,
nvtx,
opencv4WithoutCuda,
python3,
zlib,
zstd,
}:
backendStdenv.mkDerivation (finalAttrs: {
__structuredAttrs = true;
strictDeps = true;
# NOTE: Depends on the CUDA package set, so use cudaNamePrefix.
name = "${cudaNamePrefix}-${finalAttrs.pname}-${finalAttrs.version}";
pname = "nvimgcodec";
version = "0.9.0";
src = fetchFromGitHub {
owner = "NVIDIA";
repo = "nvImageCodec";
tag = "v${finalAttrs.version}";
hash = "sha256-25IlghY8r2ZyUSwptJrwFp+8WluLdZr6P3AgR5FY3xw=";
};
# Use the NVTX and Boost.Preprocessor headers of Nixpkgs instead of the submodules (external/NVTX and
# external/boost/preprocessor), which aren't fetched. The DLPack submodule (external/dlpack) is used only by the Python
# bindings, which aren't built.
postPatch = ''
substituteInPlace cmake/Dependencies.cmake \
--replace-fail \
"\''${PROJECT_SOURCE_DIR}/external/NVTX/c/include" \
"${lib.getInclude nvtx}/include" \
--replace-fail \
"\''${PROJECT_SOURCE_DIR}/external/boost/preprocessor/include" \
"${lib.getDev boost}/include"
'';
nativeBuildInputs = [
cmake
cuda_nvcc
ninja
# Generates the stubs for the CUDA driver API (loaded with dlopen) from cuda.h with libclang.
(python3.pythonOnBuildForHost.withPackages (ps: [ ps.clang ]))
];
buildInputs = [
# Replaces the Boost.Preprocessor submodule (external/boost/preprocessor)
boost
cuda_cudart
libjpeg_turbo
libnvjpeg
libnvjpeg_2k
libnvtiff
libtiff
# Replaces the NVTX submodule (external/NVTX)
nvtx
# The OpenCV extension only uses the CPU codecs (imgcodecs).
opencv4WithoutCuda
zlib
zstd
]
# The nvJPEG and nvTIFF extensions link CUDA::culibos, a separate redistributable since CUDA 13.
++ lib.optionals (cudaAtLeast "13.0") [ cuda_culibos ];
cmakeFlags = [
(lib.cmakeFeature "CUDA_TARGET_ARCHS" flags.cmakeCudaArchitecturesString)
# The directory of cuda.h, from which the stubs for the CUDA driver API are generated, is looked for only in the
# CUDA toolkit include directories (cuda_nvcc and cccl).
(lib.cmakeFeature "CUDA_MAIN_INCLUDE_DIR" "${lib.getOutput "include" cuda_cudart}/include")
(lib.cmakeBool "BUILD_SAMPLES" false)
(lib.cmakeBool "BUILD_TEST" false)
(lib.cmakeBool "BUILD_PYTHON" false)
# Link nvJPEG, nvJPEG2000 and nvTIFF instead of loading them with dlopen. The CUDA driver is still loaded with
# dlopen (WITH_DYNAMIC_CUDA), so the library can be loaded on machines without a GPU.
(lib.cmakeBool "WITH_DYNAMIC_NVJPEG" false)
(lib.cmakeBool "WITH_DYNAMIC_NVJPEG2K" false)
(lib.cmakeBool "WITH_DYNAMIC_NVTIFF" false)
(lib.cmakeBool "WITH_SHARED_CUDA_LIBS" true)
# Upstream defaults to lib64/libnvimgcodec/<CUDA major>; the extensions are looked up next to the library, in
# <libdir>/extensions.
(lib.cmakeFeature "NVIMGCODEC_INSTALL_LIBDIR" "lib")
(lib.cmakeFeature "NVIMGCODEC_INSTALL_BINDIR" "bin")
(lib.cmakeFeature "NVIMGCODEC_INSTALL_EXTENSIONS_DIR" "lib/extensions")
(lib.cmakeFeature "NVIMGCODEC_INSTALL_EXTENSION_LIBDIR" "lib/extensions")
# Would install /etc/ld.so.conf.d/nvimgcodec-<CUDA major>.conf
(lib.cmakeBool "NVIMGCODEC_INSTALL_LD_SO_CONF" false)
];
passthru.updateScript = gitUpdater {
inherit (finalAttrs) pname version;
rev-prefix = "v";
};
meta = {
description = "Library of GPU- and CPU-accelerated image codecs with a unified interface";
homepage = "https://github.com/NVIDIA/nvImageCodec";
changelog = "https://github.com/NVIDIA/nvImageCodec/releases/tag/${finalAttrs.src.tag}";
license = lib.licenses.asl20;
platforms = [
"aarch64-linux"
"x86_64-linux"
];
maintainers = with lib.maintainers; [ connorbaker ];
teams = [ lib.teams.cuda ];
};
})

View File

@@ -0,0 +1,171 @@
{
lib,
buildPythonPackage,
cudaPackages,
python,
# buildInputs
pybind11,
# build-system
setuptools,
# dependencies
astunparse,
gast,
libcst,
makefun,
numpy,
nvtx,
optree,
packaging,
six,
}:
let
inherit (cudaPackages) dali;
inherit (lib) cmakeBool cmakeFeature;
in
buildPythonPackage (finalAttrs: {
pname = "nvidia-dali";
inherit (dali) version src patches;
pyproject = true;
__structuredAttrs = true;
postPatch =
# Replaces the submodules of the header-only libraries with Nixpkgs', as for the C++ libraries.
dali.postPatch
# Name the distribution nvidia-dali instead of nvidia-dali-cuda<CUDA major>0, since Nixpkgs selects the CUDA version
# with cudaPackages, and drop the requirements on the nvImageCodec and nvCOMP wheels: DALI loads both with dlopen,
# and cudaPackages.dali has them in its runpath.
+ ''
substituteInPlace dali/python/setup.py.in \
--replace-fail \
"name='nvidia-dali@DALI_FLAVOR_MINUS@-cuda@CUDA_VERSION_SHORT_DIGIT_ONLY@'" \
"name='nvidia-dali'" \
--replace-fail "@DALI_INSTALL_REQUIRES_NVIMGCODEC@" "" \
--replace-fail "@DALI_INSTALL_REQUIRES_NVCOMP@" ""
'';
# The bindings are built with the configuration of the C++ libraries, which CMake checks again.
inherit (dali) nativeBuildInputs;
buildInputs = dali.buildInputs ++ [
dali
pybind11
];
build-system = [ setuptools ];
dependencies = [
astunparse
gast
libcst
makefun
numpy
nvtx
optree
packaging
six
];
# Build only the Python bindings (backend_impl and the python_function plugin), against the C++ libraries of
# cudaPackages.dali, like conda-forge does. The flags of the C++ libraries set BUILD_PYTHON=OFF; the later value wins.
cmakeFlags = dali.cmakeFlags ++ [
(cmakeBool "BUILD_PYTHON" true)
(cmakeBool "PREBUILD_DALI_LIBS" true)
(cmakeFeature "PYTHON_VERSIONS" python.pythonVersion)
(cmakeBool "USE_PREBUILD_PYBIND11" true)
];
# The Python package (with the headers for building plugins) is staged in dali/python of the build tree.
preBuild = ''
cmake --build . --target dali_python python_function_plugin copy_post_build_target install_headers
cd dali/python
'';
# nvidia.dali.sysconfig points plugin builds (-L, -ldali) at the package directory, where the wheels bundle the C++
# libraries.
postInstall = ''
ln -s ${lib.getLib dali}/lib/libdali*.so "$out/${python.sitePackages}/nvidia/dali/"
'';
pythonImportsCheck = [
"nvidia.dali"
# The experimental dynamic mode, the only user of nvtx
"nvidia.dali.experimental.dynamic"
];
passthru = {
# Decodes JPEGs on the GPU with nvImageCodec, resizes and median-blurs them (CV-CUDA), and inflates LZ4 data with
# nvCOMP, which DALI all loads with dlopen.
gpuCheck =
((cudaPackages.writeGpuTestPython.override { python3Packages = python.pkgs; })
{
name = "nvidia-dali-gpu-check";
libraries = ps: [
ps.lz4
ps.nvidia-dali
];
}
''
import lz4.block
import numpy as np
from nvidia.dali import fn, pipeline_def, types
images = "${finalAttrs.src}/docs/examples/data/images"
@pipeline_def(batch_size=4, num_threads=2, device_id=0)
def decode():
jpegs, _ = fn.readers.file(file_root=images)
decoded = fn.decoders.image(jpegs, device="mixed", output_type=types.RGB)
resized = fn.resize(decoded, resize_x=224, resize_y=224)
return fn.experimental.median_blur(resized, window_size=3), fn.decoders.image(jpegs, device="cpu")
pipe = decode()
gpu, cpu = pipe.run()
for sample in gpu.as_cpu():
assert np.array(sample).shape == (224, 224, 3), np.array(sample).shape
for sample in cpu:
assert np.array(sample).ndim == 3
print("decoded, resized and blurred", len(gpu), "images")
frames = np.arange(85, dtype=np.int32).reshape(17, 5)
chunks = [np.frombuffer(lz4.block.compress(f.tobytes(), store_size=False), np.uint8) for f in frames]
sizes = np.array([len(c) for c in chunks], dtype=np.int32)
# An odd offset, which nvCOMP 6 requires DALI to stage in aligned buffers
offsets = np.array(1 + np.cumsum([0, *sizes[:-1]]), dtype=np.int32)
compressed = np.concatenate([np.zeros(1, np.uint8), *chunks])
@pipeline_def(batch_size=1, num_threads=2, device_id=0)
def inflate():
data = fn.external_source(source=lambda: compressed, batch=False)
return fn.decoders.inflate(
data.gpu(), shape=[5], dtype=types.INT32, chunk_offsets=offsets, chunk_sizes=sizes
)
(inflated,) = inflate().run()
np.testing.assert_array_equal(np.array(inflated.as_cpu()[0]), frames)
print("inflated", len(chunks), "LZ4 chunks")
''
).gpuCheck;
# The version and source are cudaPackages.dali's: its update script, run on that attribute, updates both.
updateScript = dali.updateScript // {
attrPath = "cudaPackages.dali";
};
};
meta = {
description = "GPU-accelerated library for data loading and pre-processing for deep learning (Python API)";
homepage = "https://github.com/NVIDIA/DALI";
changelog = "https://github.com/NVIDIA/DALI/releases/tag/${finalAttrs.src.tag}";
inherit (dali.meta) license platforms;
maintainers = with lib.maintainers; [ connorbaker ];
teams = [ lib.teams.cuda ];
};
})

View File

@@ -12434,6 +12434,8 @@ self: super: with self; {
nvidia-cutlass-operators = callPackage ../development/python-modules/nvidia-cutlass-operators { };
nvidia-dali = callPackage ../development/python-modules/nvidia-dali { };
nvidia-dlprof-pytorch-nvtx =
callPackage ../development/python-modules/nvidia-dlprof-pytorch-nvtx
{ };