Skip to content

Fix GPU divide-by-zero for zero-extent samples in Flip and color conversion - #6506

Open
jantonguirao wants to merge 7 commits into
NVIDIA:mainfrom
jantonguirao:fix/dali-6504-zero-extent-divzero
Open

jantonguirao wants to merge 7 commits into
NVIDIA:mainfrom
jantonguirao:fix/dali-6504-zero-extent-divzero

Conversation

@jantonguirao

@jantonguirao jantonguirao commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Category:

Bug fix (non-breaking change which fixes an issue)

Description:

Fixes #6504. InvertTransforms/CopyTransforms and adjustMatrices compute their CUDA launch
grid by dividing by a batch-derived count. When the batch is empty, that count is zero, causing
a host-side division by zero before any kernel is even launched. The fix returns early from each
of these launchers when there is no work to do.

RunColorSpaceConversionKernel and FlipImpl have the same class of bug for zero-extent
samples within an otherwise non-empty batch, but that part is already fixed in #6505 — this PR
is scoped to the two remaining call sites to avoid duplicating that fix.

Additional information:

Affected modules and functionalities:

  • dali/operators/image/remap/warp_affine_params.cu: InvertTransforms/CopyTransforms now
    return early when count == 0.
  • dali/operators/image/remap/cvcuda/matrix_adjust.cu: adjustMatrices now returns early when
    the batch size is 0.

Key points relevant for the review:

Both fixed sites follow the same shape: a host-side <<<grid, block>>> launch configuration
computed by dividing by a count that can be zero. The fix is a minimal early-return guard in
each shared launcher, not a behavioral change for any non-zero case.

Tests:

  • Existing tests apply
  • New tests added
    • Python tests
    • GTests
    • Benchmark
    • Other
  • N/A

warp_affine_params.cu was compile-verified. matrix_adjust.cu (CV-CUDA) could not be
build-verified in this environment and was reviewed only; it follows the same one-line pattern.

Checklist

Documentation

  • N/A

DALI team only

Requirements

  • N/A

REQ IDs: N/A

JIRA TASK: N/A

Copilot AI lite review requested due to automatic review settings September 23, 2026 10:55
@copy-pr-bot

copy-pr-bot Bot commented Sep 23, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

No unresolved blocking issues were identified.

Review effort: Lite
Findings: None

What changed in this PR

Fixes GPU divide-by-zero failures for zero-extent samples by adding early returns before CUDA launch configuration.

Changes:

  • Guards Flip, color conversion, transform, and matrix launchers against zero work.
  • Adds regression tests for zero-extent Flip and color conversion cases.
File Description
dali/​operators/​image/​remap/​warp_affine_params.cu Skips empty transform launches.
dali/​operators/​image/​remap/​cvcuda/​matrix_adjust.cu Skips empty matrix launches.
dali/​kernels/​imgproc/​flip_gpu.cuh Skips zero-extent Flip launches.
dali/​kernels/​imgproc/​flip_gpu_test.cu Tests mixed zero-extent samples.
dali/​kernels/​imgproc/​color_manipulation/​color_space_conversion_kernel.cuh Skips zero-pixel conversions.
dali/​kernels/​imgproc/​color_manipulation/​color_space_conversion_kernel_test.cu Tests zero-pixel conversion handling.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@greptile-apps

greptile-apps Bot commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Adds divide-by-zero guards and test coverage to GPU image transform code.

The PR appears safe to merge; no outstanding previous finding or actionable new issue was established.

Summary

The PR adds zero-work guards to the GPU transform and matrix-adjust launchers, plus regression tests and the build and symbol-export changes needed to run them.

  • The non-empty companion tests compare results against hand-computed values.
  • Since the previous review, the transform test has switched from manual CUDA allocation and cleanup to owning DALI allocations.

Reviews (7) · Last reviewed commit: "Use mm::alloc_raw_unique instead of raw ..."

@jantonguirao

Copy link
Copy Markdown
Collaborator Author

!build

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [69448342]: BUILD STARTED

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [69448342]: BUILD PASSED

@jantonguirao

Copy link
Copy Markdown
Collaborator Author

!build

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70400019]: BUILD STARTED

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70400019]: BUILD FAILED

@jantonguirao

Copy link
Copy Markdown
Collaborator Author

!build

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70414726]: BUILD STARTED

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70414726]: BUILD FAILED

@jantonguirao

Copy link
Copy Markdown
Collaborator Author

!build

Comment thread dali/operators/image/remap/cvcuda/matrix_adjust_test.cu
@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70432157]: BUILD STARTED

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70432157]: BUILD FAILED

…UDA affine remap

InvertTransforms/CopyTransforms and adjustMatrices compute their CUDA launch
grid by dividing by a batch-derived count. When the batch is empty, that
count is zero, causing a host-side division by zero before any kernel is
even launched. Return early from each launcher when there is no work to do.

RunColorSpaceConversionKernel and FlipImpl have the same class of bug for
zero-extent samples within an otherwise non-empty batch, but that part is
already fixed in NVIDIA#6505, so this is scoped to the two remaining call sites.

Fixes NVIDIA#6504
Cover the two remaining early-return guards in this PR:
- CopyTransformsGPU<ndims, invert> (warp_affine_params.cu) with count == 0
- adjustMatrices (matrix_adjust.cu) with a zero-batch nvcv::Tensor

Both used to divide by zero while computing the CUDA launch grid before
any kernel was launched.
matrix_adjust_test.cu includes nvcv/Tensor.hpp directly, but
dali_operator_test only links dali_operators PUBLIC, and dali_operators
links cvcuda PRIVATE, so the include directories never propagate to the
test target, breaking the build with BUILD_CVCUDA=ON.
dali_operators is built with -fvisibility=hidden, so the explicit
CopyTransformsGPU specializations were GLOBAL HIDDEN symbols, invisible
to dali_operator_test which links against dali_operators as a separate
binary. warp_affine_params_test.cu calls these directly, causing an
"undefined reference" link failure in CI. Mark the declaration
DLL_PUBLIC to export it.
The zero-count/zero-batch tests only assert that the launchers don't
crash, which a no-op or broken kernel would also satisfy. Add a
companion case to each that runs a non-empty batch through the same
launcher and checks the output against a hand-computed reference.
@jantonguirao
jantonguirao force-pushed the fix/dali-6504-zero-extent-divzero branch from 5d159c7 to 0d6c136 Compare September 29, 2026 14:39
@jantonguirao

Copy link
Copy Markdown
Collaborator Author

!build

Comment thread dali/operators/image/remap/warp_affine_params_test.cu Outdated
@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70468688]: BUILD STARTED

Same visibility issue as CopyTransformsGPU: dali_operators is built with
-fvisibility=hidden, so adjustMatrices and nvcvop::GetDataType(DALIDataType, int)
were hidden symbols, invisible to dali_operator_test. matrix_adjust_test.cu
calls both directly (the latter via the GetDataType<T>() template), causing
an "undefined reference" link failure in CI. Mark both declarations
DLL_PUBLIC to export them.

Verified via readelf that both go from GLOBAL HIDDEN to GLOBAL DEFAULT, and
that the resulting objects link cleanly against dali_operators/nvcv/cvcuda.
@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70468688]: BUILD FAILED

@jantonguirao

Copy link
Copy Markdown
Collaborator Author

!build

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70479418]: BUILD STARTED

Matches the repo's DALI memory API convention and releases the buffers
automatically if a CUDA call or assertion fails partway through.
@jantonguirao

Copy link
Copy Markdown
Collaborator Author

!build

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70488962]: BUILD STARTED

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70479418]: BUILD FAILED

@dali-automaton

Copy link
Copy Markdown
Collaborator

CI MESSAGE: [70488962]: BUILD PASSED

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GPU Flip and color conversion divide by zero for zero-extent samples

5 participants