Skip to content

sdpa bwd: lead square A100 backward window graphs from a measured study - #2352

Merged
YangXu1990uiuc merged 1 commit into
NVIDIA:developfrom
0z5a:0z5a-sm80-bwd-square
Nov 8, 2026
Merged

YangXu1990uiuc merged 1 commit into
NVIDIA:developfrom
0z5a:0z5a-sm80-bwd-square

Conversation

@0z5a

@0z5a 0z5a commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Problem

sdpa_bwd_sm80 is a trail-only row, so on an A100 a dense backward under a left window runs on the backend. For square graphs that is the slow choice: on a fresh holdout the default ran at a geomean of 3.46x (bf16) and 2.79x (f16) over the faster of FROST and backend, and up to 35x.

Change

  • placement_table.py: 16 generated always entries for sdpa_bwd_sm80 on cc 8.0 only. They cover bf16 and f16, d64 and d128, dense bottom-right causal with a left window, MHA and GQA, with S on and off the 128-key tile. They come from gen.py study.json --margin 0.05 --emit on train, run from each dtype's study directory. Quotes are the only edit to the emitted lines.
  • bwd/heuristics.py: SQUARE_ONLY_LEAD_ROWS = {"sdpa_bwd_sm80"}. In _measured_lead, a row in that set lifts only when s_q == s_kv.
    • This is a hand rule under Rule S12, for a feature the class key excludes. class_key does not see squareness, and an earlier mixed square / non-square study on the A100 measured q < kv graphs in these same classes up to 1.45x slower on FROST (b12 40/8 d64, q 128, kv 8960, window 8000: 7.0 vs 4.8 ms). That study failed its gate and is diagnostic only; it is why this one measures square graphs alone.
    • I did not add squareness to class_key, because that would rekey every row's entries.
  • The new test checks that the square graphs of these classes lead, and that q < kv graphs of the same classes (for which lookup still answers True), padded graphs, graphs without a window and cc 8.6 keep trailing.

Measurement

  • Hardware and software: A100-SXM4-40GB, cuDNN 9.27.0, torch 2.14.1+cu130. Clocks were not locked, and no other GPU processes were running.
  • Tree: develop 6903d1a + this commit (python tree sha a74720f5c8d0c147 in both runs).
  • Train: 128 square cases per dtype, b 1-32, S 128-16250, windows 16-2048. Train regret at the default was 2.854 (bf16) and 2.921 (f16); with the fit, 1.000 and 1.001 (max 1.070, 2 of 128 f16 cases above 1.05).
  • Holdout: 128 square cases with other heads, batches, lengths and windows (b 1-24, S 128-16484, windows 24-8000), plus 32 q < kv cases in the same classes for routing. No case appears in the earlier mixed study. Grids and gate were frozen before anything was timed, and no entry changed after the holdout.
  • Timing: three repeats per square case, each with a fresh graph and tensors. Four legs are timed independently and interleaved: first backend plan, first FROST plan, first plan on this tree (auto), and first plan with the case's entry removed (default). Each leg keeps its median.

Regret is a leg's time over the faster of FROST and backend, geomean (max).

dtype cases default with the entries applied / default, geomean (min, max) beyond noise
bf16 64 3.462 (32.650) 1.001 (1.017) 0.289 (0.031, 0.973) 0
f16 64 2.794 (35.521) 1.001 (1.009) 0.358 (0.028, 0.975) 0
  • Every timed holdout case got faster. The slowest is 0.975x of the default (f16 b24 28/4 d128 S 128, window 8000: 0.418 vs 0.429 ms).
  • Largest time saved: 1671.9 → 51.2 ms, bf16 b12 48/6 d128 S 16484, window 96.
  • Noise: repeat spread has median 0.007, p90 0.011, max 0.026. The default and backend legs were the same plan on every case, and their ratio ranges from 0.996 to 1.036.
  • Routing: in every repeat, auto was the FROST row on all 128 square cases. All 32 q < kv cases match an entry (lookup is True) and ran the same plan as the default. There were no errors.

How the holdout was run

The first run trained, fitted and started the holdout, then hit its rental deadline after 167 of 416 holdout lines. Those lines were never scored. A second run on another A100-SXM4-40GB host ran the whole holdout from scratch on the same frozen case file, with the same fit. Its driver is the first one with the train loop replaced by checksums of the first run's generator output and a check that the applied tree reproduces the same python sha. The frozen-file check passed at its start. Both drivers, their diff and the unscored partial file are in the records.

Not measured

  • Cold cache, and other cc 8.0 parts (A100 PCIe, A30). The key is cc 8.0, so the entries apply to every cc 8.0 part, but only the A100-SXM4-40GB was timed.
  • q > kv graphs: the backend rejects them under a bottom-right mask, and the guard keeps them trailing anyway.
  • Padded and trimmed graphs keep trailing through _measured_lead, so they were not timed.

Testing

Records (machine-readable results, gate, frozen cases, train data, generator output and drivers): https://gist.github.com/0z5a/c19c233368d38573122414fa24bb5b3f

Add 16 generated placement_table entries for sdpa_bwd_sm80 on cc 8.0 and
lead them only when s_q == s_kv: class_key does not see squareness, and
the earlier mixed study measured FROST slower than the backend on q < kv.

Signed-off-by: 0z5a <[email protected]>
@coderabbitai

coderabbitai Bot commented Nov 8, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. 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

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
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

@0z5a

0z5a commented Nov 8, 2026

Copy link
Copy Markdown
Contributor Author

@cudnn-ci-bot run python/sdpa/frost

@0z5a

0z5a commented Nov 8, 2026

Copy link
Copy Markdown
Contributor Author

ready

@Anerudhan Anerudhan added area:global_attention cat-perf-bug Performance regressions or cases where behavior is correct but too slow. mod-frost orig-external Reported or requested by an external user, customer, or community contributor. labels Nov 8, 2026
@Anerudhan Anerudhan added this to the Frontend 1.33.0 milestone Nov 8, 2026

@Anerudhan Anerudhan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Codex bot review · model: gpt-6-astra

Reviewed 1ff667bdd352 against base 819bb56f9e69.

Thank you for your contribution! The square-only guard keeps the measured A100 backward window classes ahead of the backend while preserving non-square and unmeasured routes. No actionable defect found in this change. I checked the full diff and a clean isolated merge with current develop.

Validation: Four focused placement/heuristic suites: 600 passed, 2 skipped at the PR head; 601 passed, 2 skipped on the merge with develop 819bb56. An independent probe using real recommendation and plan assembly covered all 16 new classes, 336 base-equal controls, 32 non-square routing checks and 16 existing other-row controls. Backend plans, knobs and OPENSOURCE selection remain intact (checklist D03/D05). Audited the supplied records: all nine frozen hashes and the applied Python tree hash match; replaying the repository generator on training data alone reproduces both outputs byte for byte. The disjoint holdout contains 128 timed square cases with three repeats and 32 untimed non-square routing checks. Recomputed author auto/default geomeans are 0.289 for BF16 and 0.358 for FP16; every timed case is faster and routing matches the stated rule. Host plan construction only, seven interleaved samples: median propose time was 12.07 us on base and 13.66 us on head for one promoted class. This is setup cost, not GPU execution time. Determinism: the promoted default SM80 path uses unordered floating-point dQ atomics. Explicit deterministic requests remain outside these placement entries and retain their prior route; the existing ordered dQ option is unchanged. No native repeatability claim is made.

Limitations: No native A100 run here. The supplied timing driver uses random backward inputs without a numerical reference and cannot establish correctness. Its reported values are medians across three repetitions, each retaining best event-timing rounds, with unlocked clocks; cold-cache and other cc 8.0 parts remain unmeasured. The author's existing python/sdpa/frost request is awaiting acknowledgment. I am reusing it. Two fork Actions runs require maintainer approval; their holds remain in place.

Approved: no P0 or high-risk P1 found. Remaining findings stay with the owner; merge timing stays with the owner.

@YangXu1990uiuc
YangXu1990uiuc merged commit c56f681 into NVIDIA:develop Nov 8, 2026
6 of 7 checks passed
@YangXu1990uiuc

Copy link
Copy Markdown
Collaborator

Thank you for the contribution! Merged as c56f681 after verifying the approved full head and matching the final merge tree to the checked integration tree.

The existing python/sdpa/frost CI request is still pending and will be tracked without a duplicate trigger.

@cudnn-ci-bot

Copy link
Copy Markdown

Pipeline not launched

Reason: @0z5a is not allowlisted to run this bot.

Ask an allowlisted maintainer to comment @cudnn-ci-bot run.

@YangXu1990uiuc

Copy link
Copy Markdown
Collaborator

@cudnn-ci-bot run python/sdpa/frost

@cudnn-ci-bot

cudnn-ci-bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Could not launch CI

The bot failed before the pipeline started. The details are in the bot's log; ask a maintainer to look, then try @cudnn-ci-bot run again.

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

Labels

area:global_attention cat-perf-bug Performance regressions or cases where behavior is correct but too slow. mod-frost orig-external Reported or requested by an external user, customer, or community contributor.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants