Skip to content

Add large-tensor convolution fuzzer#401

Open
msalasooNV wants to merge 6 commits into
NVIDIA:developfrom
msalasooNV:msalasoo/conv-large-tensor-fuzzer
Open

Add large-tensor convolution fuzzer#401
msalasooNV wants to merge 6 commits into
NVIDIA:developfrom
msalasooNV:msalasoo/conv-large-tensor-fuzzer

Conversation

@msalasooNV

@msalasooNV msalasooNV commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

Affected area

  • CI or test infrastructure

Summary

Adds test/python/test_conv_large_tensor_fuzzer.py, a seeded Python large-tensor
convolution fuzzer for FPROP, DGRAD, and WGRAD. The test generates configurations
with large tensors, offsets, and reductions, compares cuDNN execution against a
PyTorch float32 reference, and skips cases whose generated graph has no supported
engine configuration on the current architecture.

FPROP and WGRAD include C*R*S > 2^27 boundary coverage. DGRAD still exercises
large tensors and filters, but uses a conservative runtime-work estimate rather than
claiming the same reduction boundary.

The fuzzer includes configurable L0/L1 testcase counts, a conservative per-case
runtime-work cap to reject unusually expensive generated problems, exact configuration
JSON emission for failures, and data policies for very large reductions that keep
reference comparisons stable while still exercising large tensor shapes.
Integer-policy comparisons use fixed dtype-specific bounds, while dense-random
comparisons scale with each operation's effective reduction depth. Developer
diagnostics can restrict generation to one operation and optionally select one or more
public graph engine indices for that operation.

Why

Large tensor convolution shapes can expose backend and frontend issues that are not
covered by smaller deterministic tests. This adds reproducible fuzz coverage for those
cases without wiring a new CI job in this repo.

The generator rejects configs above a conservative runtime-work estimate, uses
deterministic seeds, emits copy-pasteable repro context, and treats unsupported
generated graphs as skips instead of hard failures. GPU allocation failures are reported
separately as insufficient-memory skips with configuration and lifecycle-phase context.

Related issues

None.

API and compatibility impact

None. This adds a Python test file only and does not change public frontend APIs
or compatibility behavior.

Testing

Full-sweep validation used:

CUDNN_FUZZ_NUM_TESTS_L0=64 \
CUDNN_FUZZ_NUM_TESTS_L1=576 \
CUDNN_FUZZ_WORK_BUDGET_FLOPS=1e14 \
python -m pytest test/python/test_conv_large_tensor_fuzzer.py \
  -o addopts= -m "L0 or L1" -n <workers> --tb=short --durations=20 -ra
Pytest workers SM90 result SM90 runtime SM100 result SM100 runtime Notes
4 618 passed, 22 skipped 1567.26s (0:26:07) 618 passed, 22 skipped 2772.69s (0:46:12) Expected downstream CI model; the local SM100 run was slower than the 25-30 minute target.
16 623 passed, 17 skipped 1289.71s (0:21:29) 621 passed, 19 skipped 1457.25s (0:24:17) Higher-parallelism comparison
1 618 passed, 22 skipped 1747.12s (0:29:07) 618 passed, 22 skipped 3335.29s (0:55:35) Serial sanity only, not the intended CI/runtime model.

The pass/skip counts can differ across pytest worker counts because the fuzzer
budgets tensor memory per worker at collection time. Different worker counts can
therefore accept different generated configs from the same top-level seeds, so
these rows are runtime validation for each worker mode rather than exact
testcase-for-testcase comparisons.

Developer configuration is exposed through these environment variables:

Variable Accepted value and behavior
CUDNN_FUZZ_NUM_TESTS_L0 Positive integer L0 testcase count; default 48.
CUDNN_FUZZ_NUM_TESTS_L1 Positive integer L1 testcase count; default 64.
CUDNN_FUZZ_WORK_BUDGET_FLOPS Positive numeric per-case estimated runtime-work cap; default 1e14.
CUDNN_FUZZ_ENGINE_OP Restrict generation to fprop, dgrad, or wgrad; aliases fp, dg, and wg are accepted. It can be used without an engine index.
CUDNN_FUZZ_GRAPH_ENGINE_INDICES Unique comma-separated public graph engine indices for the selected operation. Requires CUDNN_FUZZ_ENGINE_OP; each index is validated against the generated graph and one is selected deterministically per testcase.
CUDNN_FUZZ_REGEN_ON_UNSUPPORTED With an operation and engine indices, retry generated configs that do not support the selected engine. Accepted true values are 1, true, yes, and on; false values are 0, false, no, off, or empty. Other values fail during collection.
CUDNN_FUZZ_REGEN_ATTEMPTS Integer regeneration-attempt cap; default 50 and effective minimum 1.
CUDNN_FUZZ_REPRO_CONFIG Inline emitted configuration JSON for test_conv_large_tensor_repro. Takes precedence over CUDNN_FUZZ_REPRO_FILE.
CUDNN_FUZZ_REPRO_FILE Path to emitted configuration JSON for test_conv_large_tensor_repro.

Standard pytest controls remain available, including -m "L0 or L1",
-n <workers>, and -o addopts= -k test_conv_large_tensor_repro.

Focused repro validation:

  • Inline CUDNN_FUZZ_REPRO_CONFIG, file-based CUDNN_FUZZ_REPRO_FILE, and
    inline-over-file precedence passed on both architectures.
  • Malformed repro JSON produced a clear parser error.
  • Unmarked repro test is excluded from -m "L0 or L1" marker runs.
  • Representative integer-policy FPROP, DGRAD, and WGRAD repros passed on both
    architectures.

Focused engine-filter and argument validation:

  • Operation-only filtering with a non-default work cap passed on both
    architectures.
  • Public graph engine index 0 executed successfully for FPROP, DGRAD, and
    WGRAD on both architectures.
  • A comma-separated 0,1 FPROP engine list executed successfully on both
    architectures.
  • Missing operation selectors, duplicate or out-of-range indices, invalid
    operations/counts/work budgets/regeneration limits, regeneration without
    indices, and malformed JSON all produced the expected diagnostics.

Summary by CodeRabbit

  • Tests
    • Added large-tensor cuDNN convolution regression/fuzz coverage for 2D and 3D across forward, data-gradient, and weight-gradient.
    • Introduced configurable randomized test tiers with optional engine/op filtering, regeneration attempts, and work/memory budgets.
    • Added deterministic failure repro support with detailed shape/config context, computed tolerances, and policy metadata.
    • Unsupported graph/plan cases are skipped to keep signal high while real mismatches fail.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a configurable large-tensor cuDNN convolution fuzzer covering forward, data-gradient, and filter-gradient operations, with deterministic PyTorch references, engine filtering, workspace poisoning, repro payloads, regeneration, and L0/L1 pytest tiers.

Changes

Large-tensor convolution regression testing

Layer / File(s) Summary
Configuration and input generation
test/python/test_conv_large_tensor_fuzzer.py
Defines convolution configuration types, environment controls, data policies, tolerances, shape generation, deterministic tensor initialization, and workload filtering for large reduction products.
Reproducible failure payloads
test/python/test_conv_large_tensor_fuzzer.py
Serializes configurations, loads inline or file-based repros, records execution metadata, builds repro commands, and formats bounded failure context.
Reference and cuDNN execution
test/python/test_conv_large_tensor_fuzzer.py
Computes float32 PyTorch references, executes cuDNN graph operations with optional engine selection and workspace poisoning, compares outputs, and categorizes execution results.
Regeneration and tiered test entry points
test/python/test_conv_large_tensor_fuzzer.py
Retries unsupported generated configurations, skips unavailable cases, pre-generates L0/L1 parameters, and adds exact-repro plus randomized pytest tests.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Pytest
  participant Runner as _run_single_config
  participant Reference as PyTorch reference
  participant CuDNN as cudnn.pygraph
  participant GPU as CUDA tensors
  Pytest->>Runner: execute LargeTensorConfig
  Runner->>Reference: compute float32 convolution reference
  Runner->>GPU: transfer initialized inputs
  Runner->>CuDNN: build and execute convolution graph
  CuDNN->>GPU: write convolution result
  Runner->>Runner: compare result with reference
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a large-tensor convolution fuzzer.
Description check ✅ Passed The description covers the required sections well, including affected area, summary, why, related issues, compatibility, and testing.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/python/test_conv_large_tensor_fuzzer.py`:
- Around line 452-476: Update _tolerances to derive accum from
_effective_reduction_size(cfg) rather than always using cfg.c multiplied by
filter_spatial, while preserving the existing tolerance formulas and bounds.
Ensure the effective size is capped by the applicable sparse nonzero count, and
extend the related tests to validate tolerance policies for sparse FPROP, DGRAD,
and WGRAD cases.
- Around line 376-390: Update _estimate_work_flops so the DGRAD branch
calculates work from output_spatial, matching the convolution contribution count
used by FPROP/WGRAD, while retaining the existing batch, channel, filter, and
spatial factors needed for C*R*S coverage. Remove the input_spatial factor from
DGRAD to avoid overestimating valid cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d3a1713a-cb6c-4828-bdea-d66440134550

📥 Commits

Reviewing files that changed from the base of the PR and between 1085001 and 41d53c1.

📒 Files selected for processing (1)
  • test/python/test_conv_large_tensor_fuzzer.py

Comment thread test/python/test_conv_large_tensor_fuzzer.py Outdated
Comment thread test/python/test_conv_large_tensor_fuzzer.py
@msalasooNV
msalasooNV force-pushed the msalasoo/conv-large-tensor-fuzzer branch from f0a3001 to 0d489d8 Compare July 24, 2026 03:01

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/python/test_conv_large_tensor_fuzzer.py`:
- Around line 1419-1431: Mark the test_conv_large_tensor_repro test with an
appropriate L0–L4 pytest level marker, consistent with its fast-skip behavior
when repro configuration environment variables are unset, so it participates in
marker-filtered runs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d12ebe82-e3b3-4eed-95ef-20b7d23fb6b6

📥 Commits

Reviewing files that changed from the base of the PR and between f0a3001 and 0d489d8.

📒 Files selected for processing (1)
  • test/python/test_conv_large_tensor_fuzzer.py

Comment on lines +1419 to +1431
def test_conv_large_tensor_repro(cudnn_handle):
cfg = _load_repro_config()
if cfg is None:
pytest.skip(f"Set {_REPRO_CONFIG_ENV} or {_REPRO_FILE_ENV} to run an exact configuration")

ok, msg = _run_single_config(cfg, cudnn_handle)
if ok:
return
if msg.startswith("insufficient_memory"):
pytest.skip(f"Insufficient GPU memory: {msg}" f"{_format_repro_context(cfg, message=msg)}")
if msg.startswith("not_supported"):
pytest.skip(f"Graph not supported on this arch: {msg}")
pytest.fail(f"cuDNN execution error: {msg}" f"{_format_repro_context(cfg, message=msg)}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add an L0–L4 marker to test_conv_large_tensor_repro.

Unlike the L0/L1 entry points, this collected test carries no level marker, so it is excluded from marker-filtered runs (e.g. -m L0). Mark it with an appropriate level (it fast-skips when the repro env vars are unset).

Proposed fix
+@pytest.mark.L0
 def test_conv_large_tensor_repro(cudnn_handle):
     cfg = _load_repro_config()

As per coding guidelines: "Mark every new Python test with a level from L0 through L4".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_conv_large_tensor_repro(cudnn_handle):
cfg = _load_repro_config()
if cfg is None:
pytest.skip(f"Set {_REPRO_CONFIG_ENV} or {_REPRO_FILE_ENV} to run an exact configuration")
ok, msg = _run_single_config(cfg, cudnn_handle)
if ok:
return
if msg.startswith("insufficient_memory"):
pytest.skip(f"Insufficient GPU memory: {msg}" f"{_format_repro_context(cfg, message=msg)}")
if msg.startswith("not_supported"):
pytest.skip(f"Graph not supported on this arch: {msg}")
pytest.fail(f"cuDNN execution error: {msg}" f"{_format_repro_context(cfg, message=msg)}")
`@pytest.mark.L0`
def test_conv_large_tensor_repro(cudnn_handle):
cfg = _load_repro_config()
if cfg is None:
pytest.skip(f"Set {_REPRO_CONFIG_ENV} or {_REPRO_FILE_ENV} to run an exact configuration")
ok, msg = _run_single_config(cfg, cudnn_handle)
if ok:
return
if msg.startswith("insufficient_memory"):
pytest.skip(f"Insufficient GPU memory: {msg}" f"{_format_repro_context(cfg, message=msg)}")
if msg.startswith("not_supported"):
pytest.skip(f"Graph not supported on this arch: {msg}")
pytest.fail(f"cuDNN execution error: {msg}" f"{_format_repro_context(cfg, message=msg)}")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/python/test_conv_large_tensor_fuzzer.py` around lines 1419 - 1431, Mark
the test_conv_large_tensor_repro test with an appropriate L0–L4 pytest level
marker, consistent with its fast-skip behavior when repro configuration
environment variables are unset, so it participates in marker-filtered runs.

Source: Coding guidelines

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.

2 participants