Skip to content

Support zero-element graphs (e.g. SDPA with batch size 0) - #404

Draft
Anerudhan wants to merge 1 commit into
NVIDIA:developfrom
Anerudhan:support-zero-element-graphs
Draft

Support zero-element graphs (e.g. SDPA with batch size 0)#404
Anerudhan wants to merge 1 commit into
NVIDIA:developfrom
Anerudhan:support-zero-element-graphs

Conversation

@Anerudhan

Copy link
Copy Markdown
Collaborator

Fixes #101

Problem

Building a graph containing a tensor with a 0-sized dimension (e.g. SDPA with batch_size = 0, as hit by PyTorch's cuDNN SDPA backend in pytorch/pytorch#133780) fails at backend tensor creation with a generic CUDNN_STATUS_BAD_PARAM, because cuDNN backend tensor descriptors do not accept 0-sized dimensions.

Solution

Detect zero-element graphs during validate(), after shape inference has filled in all tensor dims. If the graph references at least one zero-element tensor and every non-virtual output tensor is zero-element, executing the graph could never write an output byte — so the whole graph is a well-defined no-op:

  • build_operation_graph(), create_execution_plans() / create_execution_plan(), check_support(), build_plans() / build_plan_at_index(), and build() all succeed while skipping backend lowering entirely.
  • get_workspace_size() reports 0.
  • execute() (all overloads), autotune(), and warmup() return success without launching work; variant-pack pointers are ignored (zero-element tensors may be null).
  • populate_cuda_graph() leaves the provided CUDA graph empty (valid and instantiable); update_cuda_graph() is a no-op.
  • New Graph::is_zero_element_graph() (C++) and pygraph.is_zero_element_graph() (Python) report whether the graph was flagged.

Graphs that mix zero-element tensors with non-zero-element outputs (e.g. matmul contracting over a 0-sized dimension, whose output would need zero-filling) are rejected at validate() with a clear GRAPH_NOT_SUPPORTED message instead of the late backend BAD_PARAM.

Guarded limitations (clear errors instead of misbehavior):

  • Plan serialization (serialize(std::vector<uint8_t>&)) errors out — there is no plan to serialize (previously this path would have indexed plans.execution_plans[-1]). JSON structure serialization is unaffected; a graph deserialized from JSON re-detects the no-op in its own validate().
  • Runtime shape overrides (override_uids/shapes/strides) on a no-op graph error out rather than silently skipping real work.

Testing

  • New Catch2 cases in test/cpp/validate.cpp ([zero_element]): pointwise no-op pipeline (fully deviceless, including execute with a null handle), SDPA with batch 0, and the mixed zero/non-zero rejection. Full tests binary passes: 290 assertions in 27 test cases (cuDNN 9.19.1).
  • New pytest test/python/test_zero_element_graph.py: SDPA batch 0 end-to-end via pygraph (mirrors the issue repro), pointwise zero-element, and mixed-graph rejection. Verified on GPU via the pygraph bindings.
  • docs/zero-element-graphs.md documents the behavior; linked from llms.txt.
  • pre-commit (clang-format, black) clean on changed files.

🤖 Generated with Claude Code

Graphs whose non-virtual output tensors are all zero-element (a dimension
of size 0) are now detected during validate() and treated as no-ops: all
build stages skip backend lowering, get_workspace_size() reports 0, and
execute() returns success without launching work. The cuDNN backend does
not accept 0-sized tensor dimensions, so previously such graphs failed at
tensor creation with a generic CUDNN_STATUS_BAD_PARAM.

Graphs that mix zero-element tensors with non-zero-element outputs (e.g. a
matmul contracting over a 0-sized dimension) are rejected at validate()
with a clear GRAPH_NOT_SUPPORTED message.

Adds Graph::is_zero_element_graph() (C++) and
pygraph.is_zero_element_graph() (Python), C++ and Python tests, and docs.

Fixes NVIDIA#101

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 25d677bc-48ef-4fef-b885-27b07d77ae3a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

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.

Support batch size 0

1 participant