fix(cuda): reassemble the int64 warp reduction, correct the ADM doc, add nvcc --threads - #1385
Draft
lusoris wants to merge 1 commit into
Draft
fix(cuda): reassemble the int64 warp reduction, correct the ADM doc, add nvcc --threads#1385lusoris wants to merge 1 commit into
lusoris wants to merge 1 commit into
Conversation
lusoris
force-pushed
the
fix/cuda-audit-followups
branch
2 times, most recently
from
September 7, 2026 10:14
b44c574 to
07a40dc
Compare
…add nvcc --threads Three findings from the CUDA Tile C++ adoption audit (ADR-1224), which concluded Tile should not be adopted. The audit's incidental findings are worth more than its headline. 1. integer_ssim_score.cu split the int64_t per-pixel weight into lo/hi 32-bit halves and summed each INDEPENDENTLY across the warp, recombining only after the reduction. A carry out of the low half was silently dropped, and `lo` itself could overflow a signed int32 (undefined behaviour). Not reachable today -- the 9-tap weight sum stays far below 2^31 -- but wrong in a way that only appears at large frame sizes or under a future weight scaling. `warp_reduce(int64_t)` in cuda_helper.cuh already reassembles the halves into an int64 before adding; use it instead of a second, subtly different hand-rolled copy. 2. docs/backends/cuda/overview.md contradicted itself. One bullet said integer_adm_cuda lacks adm_csf_mode: 2 and that libvmaf falls back to the CPU reference extractor; a section dated the same day said the whole ADM family runs on the device for the default model. The code (integer_adm_cuda.c:840 declares adm_csf_mode), the closed ticket T-GPU-ADM-CSF-MODE-NOT-PORTED-2026-09-05, and a live CUDA run of the default model emitting no CPU-fallback notice all agree with the later section. The stale bullet is corrected. 3. New `nvcc_threads` meson option (default 4) passes --threads to the per-kernel fatbin compiles. nvcc parallelises across the six gencode architectures, so this shortens the critical path: adm_cm.cu 8.5s -> 2.1s, serial wall 41.9s -> 14.2s. Verified byte-identical here, not assumed: all 22/22 fatbins compare equal (cmp) between --threads 4 and --threads 1, so it cannot move a score. ninja already builds the 22 fatbin targets concurrently, so the effective thread count is this value times the ninja job count -- hence an option rather than a hardcoded number. Deliberately NOT adopted from the same audit: --split-compile, which produced three different fatbin hashes across three identical invocations. That breaks build reproducibility, which the keyless Sigstore/SLSA release story depends on. meson test --suite=fast: 164/164. ADR-1224. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lusoris
force-pushed
the
fix/cuda-audit-followups
branch
from
September 7, 2026 12:16
07a40dc to
5ff8834
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three findings from the CUDA Tile C++ adoption audit (ADR-1224),
which concluded Tile should not be adopted. The incidental findings turned
out to be worth more than the headline.
1. Dropped carry in an
int64warp reductioninteger_ssim_score.cusplit theint64_tper-pixel weight intolo/hi32-bit halves and summed each independently across the warp, recombining
only afterwards:
A carry out of the low half is dropped, and
loitself can overflow a signedint32(undefined behaviour, C17 6.3.1.4p1).warp_reduce(int64_t)atcuda_helper.cuh:119already reassembles the shuffled halves into anint64before adding — this was a second, subtly different hand-rolled copy.
Not reachable today: the 9-tap per-pixel weight sum stays far below 2³¹, so
no score is currently wrong. It would surface at large frame sizes or under a
future weight scaling.
2.
docs/backends/cuda/overview.mdcontradicted itselfOne bullet said
integer_adm_cudalacksadm_csf_mode: 2and that libvmaffalls back to the CPU reference extractor. A section dated the same day said
the whole ADM family runs on the device for the default model. Three independent
checks agree with the later section:
integer_adm_cuda.c:840declaresadm_csf_modeT-GPU-ADM-CSF-MODE-NOT-PORTED-2026-09-05is closedcomputing it on the CPUnoticeThe stale bullet is corrected.
3.
nvcc --threadsNew
nvcc_threadsmeson option (default4). nvcc parallelises across the sixgencode architectures, so this shortens the critical-path kernel:
adm_cm.cu8.5 s → 2.1 s, serial wall 41.9 s → 14.2 s.Verified byte-identical here, not assumed — all 22/22 fatbins compare
equal between
--threads 4and--threads 1, so it cannot move a score. ninjaalready builds the 22 fatbin targets concurrently, so the effective thread count
is this value × the ninja job count; hence an option rather than a hardcoded
number.
Reproducer / smoke test
Measured on this workstation (RTX 4090, nvcc 13.3.73):
byte-identical: 22 / 22.Deliberately not adopted
--split-compile— three identical invocations produced three differentfatbin hashes. That breaks build reproducibility, which the keyless
Sigstore/SLSA release story depends on. Recorded in the ADR so it is not tried
again.
Why Tile itself is out
Summarised in the ADR. The short version: integer
ct::mma()is 8-bit-operandonly and ~⅔ of the tree is int16/32/64; the longest contraction anywhere is a
17-tap constant filter;
adm_csf_den.cu:101andadm_cm.cu:266apply arounding shift inside the accumulation, which is not a sum of products at
any dtype; tile extents must be powers of two (
cuda_tile.h:749) and our rowsare 576 and 1920 wide;
ct::sum()has no association parameter and no publishedreduction-order guarantee; and
--fatbin/--tilefatbinare not composable, with--tilefatbinemitting no PTX at all.The ADR also records what would change the answer, and explicitly retires
three arguments that did not survive verification — the architecture floor,
the CI pin, and a "not user-controllable" quote that does not exist in NVIDIA's
documentation.
Deep-dive deliverables (ADR-0108)
docs/adr/1224-cuda-tile-not-adopted.md## Alternatives considered(four options; the runner-up "adopt for SpEED's covariance" fails on four independent grounds).int64fix removes a local copy in favour of an existing shared helper, and the build option is fork-local.changelog.d/fixed/1224-cuda-int64-warp-carry.md,changelog.d/fixed/1224-cuda-adm-doc-contradiction.md,changelog.d/changed/1224-nvcc-threads.md.docs/rebase-notes.md— entryADR-1224 — CUDA Tile not adopted; audit findings banked (2026-09-07).Docs (rule 10)
docs/backends/cuda/overview.md— the staleADM bullet is corrected.
nvcc_threadsis documented incore/meson_options.txtwith the oversubscription caveat.Bug status (rule 13 / ADR-0165)
docs/state.md— closesT-CUDA-SSIM-INT64-WARP-CARRY-2026-09-07, opensT-CUDA-ADM-CM-REGISTER-PRESSURE-2026-09-07(REG:255 with 336–344 B spill on the default model's hot path; its own measured PR).🤖 Generated with Claude Code