Skip to content

perf(cuda): ms_ssim_decimate smem tiling + adm_cm register reduction (ADR-0744) - #79

Merged
lusoris merged 2 commits into
masterfrom
perf/cuda-ms-ssim-decimate-adm-cm-ncu-driven-20260528
May 28, 2026
Merged

lusoris merged 2 commits into
masterfrom
perf/cuda-ms-ssim-decimate-adm-cm-ncu-driven-20260528

Conversation

@lusoris

@lusoris lusoris commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Opt A: ms_ssim_decimate — adds a (2*BLOCK_X+2*LPF_HALF+1) x (2*BLOCK_Y+2*LPF_HALF) = 41x24 float shared-memory tile per CTA (3936 B). Converts 81 global/L2 reads per output pixel to L1 hits. mirror_idx boundary applied once in cooperative load phase; hot 9x9 convolution loop reads smem unconditionally. +1 width pad (TILE_W_PAD=41) prevents bank aliasing per ADR-0454 convention.
  • Opt B: adm_cm_line_kernel_8 — adds __launch_bounds__(128, 8) to the ADM_CM_LINE macro. Hints ptxas to target <=64 regs/thread, raising theoretical occupancy from 33% to ~67% on Ampere, matching the fused scale 1-3 kernel.

ncu-estimated deltas (pending hardware measurement)

Kernel Metric Before After (est.)
ms_ssim_decimate DRAM reads/output px 81 ~1 (amortised tile load)
ms_ssim_decimate Local speedup (1080p) baseline +68-93%
adm_cm_line_kernel_8 Registers/thread 114 <=64
adm_cm_line_kernel_8 Theoretical occupancy 33% ~67%
adm_cm_line_kernel_8 Local speedup (1080p) baseline +66.7%

Reproducer / smoke test

# Correctness: Netflix golden gate (CPU)
make test-netflix-golden

# CUDA vs CPU parity (ADR-0214 places=4)
docker exec vmaf-dev-mcp python scripts/ci/cross_backend_parity_gate.py \
    --features float_ms_ssim adm --backends cpu cuda --places 4 \
    --ref  python/test/resource/yuv/checkerboard_1920_1080_10_3_0_0.yuv \
    --dis  python/test/resource/yuv/checkerboard_1920_1080_10_3_1_0.yuv \
    --width 1920 --height 1080 --pix_fmt yuv420p10le

# ncu baseline vs optimised (run in vmaf-dev-mcp:cuda13.3)
ncu --section LaunchStats --section MemoryWorkloadAnalysis \
    --kernel-name ms_ssim_decimate \
    vmaf --reference ... --distorted ... --backend cuda --features float_ms_ssim

ncu --section LaunchStats --section OccupancyEstimation \
    --kernel-name adm_cm_line_kernel_8 \
    vmaf --reference ... --distorted ... --backend cuda --features adm

Deliverables checklist

  • Research digest: docs/research/research-0744-cuda-ms-ssim-adm-cm-perf-impl.md
  • ADR decision matrix: docs/adr/0744-cuda-ms-ssim-adm-cm-ncu-driven-perf.md (Alternatives considered)
  • AGENTS.md invariant: core/src/feature/cuda/AGENTS.md (two new sections)
  • Reproducer: ncu commands in research digest + PR description above
  • Changelog fragment: changelog.d/perf/cuda-ms-ssim-adm-cm-ncu-driven.md
  • Rebase notes: docs/rebase-notes.md entry added
  • Per-surface docs: docs/backends/cuda/overview.md kernel performance section added
  • docs/state.md perf row added
  • ADR index row: docs/adr/README.md

Notes for reviewer

  • DRAFT: actual ncu measurements on RTX 4090 (vmaf-dev-mcp:cuda13.3) needed before marking ready.
  • No correctness risk: Opt A is a pure memory-access reorganisation (same arithmetic, same accumulation order); Opt B is a ptxas register-budget hint with no arithmetic change.
  • If Opt B causes register spill that degrades throughput on a specific arch, reduce minBPSM from 8 to 4 in adm_cm.cu line ~365 — no other files need updating.

🤖 Generated with Claude Code

@lusoris
lusoris force-pushed the perf/cuda-ms-ssim-decimate-adm-cm-ncu-driven-20260528 branch from 06a6a00 to 361afe3 Compare May 28, 2026 22:01
@lusoris

lusoris commented May 28, 2026

Copy link
Copy Markdown
Contributor Author

Hardware measurement complete (Research-0749 / ADR-0750)

Device: RTX 4090 (CC 8.9, 128 SMs), CUDA 13.3, ncu 2026.2.0, vmaf-dev-mcp:cuda13.3.
Method: isolated worktrees, optimized libvmaf.so via LD_PRELOAD, privileged container for PMU access.
Correctness: bit-exact (max_diff = 0.0 at ADR-0214 places=4 on both workloads).

ms_ssim_decimate smem tiling — REGRESSION

The baseline kernel already achieves 95% L1 hit rate at both 576p and 1080p — it was never DRAM-bound. The smem cooperative-load breaks the hardware prefetcher, causing L1 hit rate to drop from 95% to 24%:

Workload Baseline duration Optimized duration L1 hit (base) L1 hit (opt)
WL1 576p, largest launch 5120 ns 6368 ns 95.5% 24.5%
WL2 1080p, largest launch 18656 ns 20224 ns 95.6% 23.9%

Kernel is +24% slower (WL1) and +8% slower (WL2). The estimated +68–93% was based on an incorrect DRAM-bound assumption.

adm_cm_line_kernel_8 launch_bounds — CONFIRMED POSITIVE

Workload Baseline duration Optimized duration Registers (base) Registers (opt)
WL1 576p ~14.2 µs ~14.9 µs (noise) 114 64
WL2 1080p ~68.4 µs ~62.0 µs (-9.3%) 114 64

Register reduction 114→64 (-44%) is confirmed. -9.3% kernel duration at 1080p is consistent with theoretical occupancy 33%→50%.

End-to-end (3-run median, --feature float_ms_ssim_cuda --backend cuda)

Workload Baseline Optimized Delta
WL1: 576x324 48f 2469 fps 2587 fps +4.8%
WL2: 1080p 3f 482 fps 501 fps +3.9%

Positive end-to-end delta is driven by adm_cm alone.

Verdict: PARTIAL REVERT RECOMMENDED

  • Keep: adm_cm_line_kernel_8 __launch_bounds__(128, 8) — measured -9.3% at 1080p, correctness passes.
  • Revert: ms_ssim_decimate smem tiling — measured +8-24% kernel regression. The optimization path for ms_ssim_decimate at 1080p is occupancy tuning (baseline 80% occupancy) or horiz/vert fusion, not smem tiling.

Full digest at docs/research/0749-cuda-ms-ssim-decimate-adm-cm-1080p-measure.md (PR #89).

lusoris added a commit that referenced this pull request May 28, 2026
…op ms_ssim smem tiling

Per PR #89 hardware measurement on RTX 4090 (vmaf-dev-mcp:cuda13.3):

- REVERT: ms_ssim_decimate smem tiling.  The baseline kernel was already
  L1-resident (95% hit rate).  Cooperative load + __syncthreads() broke
  the hardware prefetcher and raised kernel duration +8–24% at all
  tested resolutions (576p and 1080p).  The non-tiled kernel is restored.

- KEEP: adm_cm_line_kernel_8 __launch_bounds__(128, 8).  Confirmed −9.3%
  kernel duration at 1080p; registers 114→64 per thread.  End-to-end
  net: +3.9–4.8% fps driven solely by this occupancy gain.

ADR-0744 updated from stub to Accepted with full revert rationale and
alternatives table.  docs/state.md row added.

Correctness: ADR-0214 places=4 parity gate confirmed bit-exact before
and after (max_diff=0.0, per ADR-0750 Research-0749).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lusoris

lusoris commented May 28, 2026

Copy link
Copy Markdown
Contributor Author

Partial revert applied per PR #89 measurement: ms_ssim_decimate smem tiling reverted (L1-resident baseline made it a regression — +8 to +24% kernel duration; cooperative load broke hardware prefetcher). adm_cm launch_bounds(128, 8) kept (−9.3% at 1080p, registers 114→64 confirmed). End-to-end net: +3.9–4.8% fps from adm_cm occupancy gain alone. ADR-0744 updated to Accepted. Marking ready.

@lusoris
lusoris marked this pull request as ready for review May 28, 2026 22:34
@lusoris
lusoris enabled auto-merge (squash) May 28, 2026 22:34
lusoris and others added 2 commits May 29, 2026 00:34
…(ADR-0744)

Opt A: ms_ssim_decimate shared-memory tile
  Converts 81 global/L2 reads per output pixel to L1 hits via a
  (2*BLOCK_X+2*LPF_HALF+1) x (2*BLOCK_Y+2*LPF_HALF) = 41x24 float smem
  tile per CTA (3936 B). Cooperative load applies mirror_idx once in the
  load phase only; the hot 9x9 LPF convolution loop reads smem at
  tile[2*ty+kv][2*tx+ku] unconditionally. TILE_W_PAD=41 (+1 pad) prevents
  bank aliasing per the ADR-0454 / filter1d.cu convention.
  Estimated: -30 to -40% DRAM throughput; +68-93% local speedup at 1080p+.

Opt B: adm_cm_line_kernel_8 __launch_bounds__(128, 8)
  Hints ptxas to target <=64 regs/thread (65536/(8x128)) matching the
  fused scale 1-3 kernel, raising theoretical occupancy from 33% to ~67%
  on Ampere. Block size 128 (BLOCKX=32 x BLOCKY=4) is fixed by the host
  launcher in integer_adm_cuda.c.
  Estimated: +66.7% local kernel throughput at 1080p+.

Both changes are correctness-neutral; verified by ADR-0214 parity gate
at places=4. ncu measurement commands documented in Research-0744.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…op ms_ssim smem tiling

Per PR #89 hardware measurement on RTX 4090 (vmaf-dev-mcp:cuda13.3):

- REVERT: ms_ssim_decimate smem tiling.  The baseline kernel was already
  L1-resident (95% hit rate).  Cooperative load + __syncthreads() broke
  the hardware prefetcher and raised kernel duration +8–24% at all
  tested resolutions (576p and 1080p).  The non-tiled kernel is restored.

- KEEP: adm_cm_line_kernel_8 __launch_bounds__(128, 8).  Confirmed −9.3%
  kernel duration at 1080p; registers 114→64 per thread.  End-to-end
  net: +3.9–4.8% fps driven solely by this occupancy gain.

ADR-0744 updated from stub to Accepted with full revert rationale and
alternatives table.  docs/state.md row added.

Correctness: ADR-0214 places=4 parity gate confirmed bit-exact before
and after (max_diff=0.0, per ADR-0750 Research-0749).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lusoris
lusoris force-pushed the perf/cuda-ms-ssim-decimate-adm-cm-ncu-driven-20260528 branch from 5c83151 to 3009610 Compare May 28, 2026 22:35
@lusoris
lusoris merged commit c1a8508 into master May 28, 2026
20 of 37 checks passed
@lusoris
lusoris deleted the perf/cuda-ms-ssim-decimate-adm-cm-ncu-driven-20260528 branch May 28, 2026 22:36
lusoris added a commit that referenced this pull request May 28, 2026
…m (Research-0749 / ADR-0750)

Add hardware benchmark results for PR #79 (ms_ssim_decimate smem tiling +
adm_cm register reduction) on 1080p content, research digest 0749, and
ADR-0750 documenting the measurement methodology.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 28, 2026
…m (Research-0749 / ADR-0750) (#89)

Add hardware benchmark results for PR #79 (ms_ssim_decimate smem tiling +
adm_cm register reduction) on 1080p content, research digest 0749, and
ADR-0750 documenting the measurement methodology.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@lusoris

lusoris commented May 28, 2026

Copy link
Copy Markdown
Contributor Author

4K measurement (Research-0751): adm_cm launch_bounds kernel delta at 3840x2160 is -0.3% (noise), compared to -9.3% at 1080p. The register-bound regime that the optimization targets is 8-32 waves; at 4K (32.2 waves) the scheduler is wave-saturated and the register reduction does not further improve throughput. End-to-end adm CUDA delta at 4K is +1.9% (within ±5% noise). Recommendation: ship the launch_bounds change -- it costs nothing at 4K, wins measurably at 1080p (-9.3% kernel, +3.9% end-to-end), and is bit-exact at all resolutions. The ms_ssim smem-tiling revert is confirmed correct at 4K (kernel already L1-resident, 88.1% active warps at full resolution).

lusoris added a commit that referenced this pull request May 29, 2026
…Research-0751) (#90)

Establishes the first measured 4K (3840x2160) CUDA throughput baseline on RTX 4090
and A/B tests the PR #79 adm_cm __launch_bounds__(128,8) change at 4K resolution.

Key findings:
- vif CUDA: 147 fps, adm CUDA: 161 fps, motion CUDA: 176 fps (24-frame medians)
- filter1d_8_horizontal: fully saturated at 4K (253 waves, 69.7% active warps)
  versus 0.84 waves at 576p. PR #76 optimization is fully expressed at 4K.
- adm_cm __launch_bounds__: zero gain at 4K (-0.3%, noise) vs -9.3% at 1080p.
  The register-bound regime ends at ~32 waves (1080p boundary). At 4K (32.2 waves)
  the scheduler is wave-saturated regardless of register count.
- ms_ssim_decimate scale 0: 88.1% active warps at 4K (126 waves) -- smem-tiling
  revert from Research-0749 confirmed correct at 4K.

Deliverables: Research-0751, changelog fragment, rebase-notes sentinel,
state.md update, research README entry (also resolves pre-existing conflict marker).

no rebase impact: research/docs-only change, no source code modified.
no per-surface docs needed: no user-discoverable surface changed.
no ADR needed: measurement digest, no architectural decision.
no AGENTS.md update needed: no rebase-sensitive invariants.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@lusoris lusoris added this to the 1.0.0 — First release milestone Sep 4, 2026
lusoris pushed a commit to Tualua/vmafx that referenced this pull request Oct 6, 2026
…ialised (HISS-10) (VMAFx#2154)

* fix(interop): re-vendor Pelorus with the x265 CSV column indices initialised (HISS-10)

The vendored pelorus_qp_report_csv.c raised seven -Wmaybe-uninitialized
warnings at gcc 16 -O2 -Wall -Wextra. The cause is fixed in VMAFx/pelorus
(VMAFx#79, merge 42cb17106a2d: every csv_cols index starts at -1); the pin moves
and the mirror is re-rendered with scripts/sync-pelorus-interop.sh --update.
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.

1 participant