Skip to content

[cuda] Score autotune picks with one event tick of tolerance, on longer kernels - #23635

Draft
Gasoonjia wants to merge 2 commits into
mainfrom
gasoonjia/autotune-regret-timer-resolution
Draft

Gasoonjia wants to merge 2 commits into
mainfrom
gasoonjia/autotune-regret-timer-resolution

Conversation

@Gasoonjia

@Gasoonjia Gasoonjia commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

SaturatedCpuExportTest (test_cuda_graph_timing.py) and Int4AutotunePickTest score each autotune decision by its regret: the pick's reference time divided by the best candidate's. Event timing is quantized: cudaEventElapsedTime steps by 0.512 µs on the A10G CI GPU, and hipEventElapsedTime by about 1 µs. A reading is the difference of two quantized timestamps, so it can fall on either side of the true time by about a tick. On a kernel of a few microseconds, that is a large ratio. The A10G job failed on (https://github.com/pytorch/executorch/actions/runs/37835437673/job/113511485001):

AssertionError: 1.2000000727595779 not less than or equal to 1.2 :
Pick(kind='inductor', name='triton_poi_fused__unsafe_view_add_transpose_copy_view_copy_9', candidates=2, regret=1.2000000727595779)

That is exactly fp32(6 × 0.512 µs) / fp32(5 × 0.512 µs).

Changes

  1. One tick of tolerance: _regret() credits the best candidate one tick, pick / (best + 1 tick), floored at 1.0, with margins for the float32 event times.
    • A difference the timer can't resolve no longer counts as a worse pick.
    • Anything larger is charged in proportion, so there's no jump at one tick and the limits stay meaningful at every scale.
    • No thresholds change.
  2. Longer kernels, so one tick is a small fraction of them:
    • SaturatedCpuExportTest's model now uses widths (512, 1536, 3072) and 4096 tokens (was (256, 768, 1536) and 64).
    • Int4AutotunePickTest's smallest weight is now 8192×2048 (was 2048×2048).
    • summarize() now also prints the fastest kernel's reference time, so CI shows how far above one tick the shortest kernel runs.

Tests

RegretTest runs on CPU and covers both the CUDA and the HIP tick:

  • one tick apart scores 1.0, checked up to 31250-tick kernels;
  • two ticks apart is charged, checked up to ~1 s;
  • larger gaps score pick / (best + 1).

Test plan

CI: unittest-cuda / unittest-cuda-quantized-gemm should show RegretTest, SaturatedCpuExportTest and Int4AutotunePickTest passing, the "fastest kernel" line in their output, and how long the two pick tests now take.

@pytorch-bot

pytorch-bot Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/23635

Note: Links to docs will display an error until the docs builds have been completed.

❌ You can merge normally! (1 Unrelated Failure), 4 Unclassified Failures

As of commit 09a91f7 with merge base f2575be (image):

UNCLASSIFIED FAILURES - DrCI could not classify the following jobs because the workflow did not run on the merge base. The failures may be pre-existing on trunk or introduced by this PR:

FLAKY - The following job failed but was likely due to flakiness present on trunk:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 9, 2026
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

@Gasoonjia
Gasoonjia deployed to upload-benchmark-results October 9, 2026 11:46 — with GitHub Actions Active
@Gasoonjia
Gasoonjia deployed to upload-benchmark-results October 9, 2026 23:08 — with GitHub Actions Active
@Gasoonjia
Gasoonjia force-pushed the gasoonjia/autotune-regret-timer-resolution branch from 95031ed to 6d128a8 Compare October 9, 2026 23:48
@Gasoonjia Gasoonjia changed the title [cuda] Count autotune candidates one event tick apart as a tie in the pick tests [cuda] Score autotune picks with one event tick of tolerance, on longer kernels Oct 9, 2026
…er kernels

SaturatedCpuExportTest and Int4AutotunePickTest score each autotune decision
by the regret of the pick: its reference time over the best candidate's.
Event timing is quantized (cudaEventElapsedTime steps by 0.512 us on the A10G
CI GPU, hipEventElapsedTime by about 1 us), and a reading is the difference
of two quantized timestamps, so it can fall either side of the true time by
about a tick. On a kernel of a few microseconds that is a large ratio. The
A10G unittest-cuda job failed on

  AssertionError: 1.2000000727595779 not less than or equal to 1.2 :
  Pick(kind='inductor', name='triton_poi_fused__unsafe_view_add_transpose_
  copy_view_copy_9', candidates=2, regret=1.2000000727595779)

which is exactly fp32(6 * 0.512 us) / fp32(5 * 0.512 us).

Two changes:

- _regret() credits the best candidate one tick: pick / (best + 1 tick),
  floored at 1.0, with margins for the float32 event times. A difference the
  timer cannot resolve no longer counts as a worse pick; anything larger is
  charged in proportion, so the limits stay meaningful at every scale.
- The tests' kernels run longer, so a tick is a small fraction of them:
  SaturatedCpuExportTest's model uses widths (512, 1536, 3072) and 4096
  tokens (was (256, 768, 1536) and 64), and Int4AutotunePickTest's smallest
  weight is 8192x2048 (was 2048x2048). summarize() now also prints the
  fastest kernel's reference time, so CI shows how far above a tick it is.

RegretTest checks, on CPU, for both the CUDA and the HIP tick: one tick apart
is 1.0 (up to 31250-tick kernels), two ticks apart is charged (up to ~1 s),
and pick / (best + 1) beyond that.
Gasoonjia added a commit that referenced this pull request Oct 12, 2026
unittest-cuda is cancelled at its 90-minute timeout on every recent main
commit. #23605 moved the quantized GEMM kernel suites into
unittest-cuda-quantized-gemm, but the same push added
test_int4_large_quantized_gemm.py (~7.7 min on the A10G) and
test_int6_large_quantized_gemm.py (~5.1 min), which still run in
unittest-cuda. On #23635 its backends/cuda/tests pytest alone took 62 min and
the job was cancelled during the Gemma 4 tests that follow.

Run both in the second quantized-GEMM shard, renamed
large-int5-int6-int8-graph-timing (that shard took 44 min; the int4 shard
already takes ~60). unittest-cuda ignores them. No test is dropped.
@Gasoonjia
Gasoonjia deployed to upload-benchmark-results October 12, 2026 02:37 — with GitHub Actions Active

This branch was successfully deployed

2 active deployments
upload-benchmark-results — 09a91f74 Deployed Oct 12, 2026 by Gasoonjia via upload-benchmark-results #20701
cadence — 09a91f74 Deployed Oct 12, 2026 by Gasoonjia via hifi-op-test / hifi4 #32880
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant