fix(gpu): collapse the four divergent ADM angle_flag predicates onto one - #1342
Draft
lusoris wants to merge 5 commits into
Draft
fix(gpu): collapse the four divergent ADM angle_flag predicates onto one#1342lusoris wants to merge 5 commits into
lusoris wants to merge 5 commits into
Conversation
lusoris
force-pushed
the
fix/t-upstream-930-adm-angle-flag-predicate-
branch
from
September 6, 2026 03:04
5719c79 to
a6a10ff
Compare
lusoris
force-pushed
the
fix/t-upstream-930-adm-angle-flag-predicate-
branch
from
September 6, 2026 06:40
a6a10ff to
7a961d7
Compare
lusoris
pushed a commit
that referenced
this pull request
Sep 6, 2026
…md move Two loose ends on top of the ADR-1194 change: 1. `adm_angle_flag_i64()` tripped `readability-function-size` (71 lines against the 60-line threshold) once clang-tidy was pointed at the new header with `-header-filter='adm_angle_flag\.h'` — the default filter is anchored at `^core/` and so misses it when the build dir is a sibling. ADR-0141 wants the file clean, not suppressed, so the right-hand-side rounding is now `adm_angle_flag_round53_v()`. Pure extraction: no expression changes, and `core/test/test_adm_angle_flag.c` still passes 7/7. `metal/integer_adm.metal` gets the same split so the manual MSL mirror stays line-for-line (the AGENTS.md lockstep invariant). 2. `docs/state.md` still carried T-UPSTREAM-930 under **Open bugs** with a comment claiming it had moved: an earlier duplicate-row cleanup dropped the Recently-closed copy instead of the stale open one. The open row is gone and the closed row is back at the head of Recently closed, citing PR #1342 and ADR-1194 (the previous text cited a commit sha that the rebase invalidated). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lusoris
force-pushed
the
fix/t-upstream-930-adm-angle-flag-predicate-
branch
from
September 6, 2026 09:51
7a961d7 to
21ac8d2
Compare
lusoris
pushed a commit
that referenced
this pull request
Sep 6, 2026
…md move Two loose ends on top of the ADR-1194 change: 1. `adm_angle_flag_i64()` tripped `readability-function-size` (71 lines against the 60-line threshold) once clang-tidy was pointed at the new header with `-header-filter='adm_angle_flag\.h'` — the default filter is anchored at `^core/` and so misses it when the build dir is a sibling. ADR-0141 wants the file clean, not suppressed, so the right-hand-side rounding is now `adm_angle_flag_round53_v()`. Pure extraction: no expression changes, and `core/test/test_adm_angle_flag.c` still passes 7/7. `metal/integer_adm.metal` gets the same split so the manual MSL mirror stays line-for-line (the AGENTS.md lockstep invariant). 2. `docs/state.md` still carried T-UPSTREAM-930 under **Open bugs** with a comment claiming it had moved: an earlier duplicate-row cleanup dropped the Recently-closed copy instead of the stale open one. The open row is gone and the closed row is back at the head of Recently closed, citing PR #1342 and ADR-1194 (the previous text cited a commit sha that the rebase invalidated). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lusoris
force-pushed
the
fix/t-upstream-930-adm-angle-flag-predicate-
branch
from
September 6, 2026 11:09
21ac8d2 to
d308cfe
Compare
lusoris
pushed a commit
that referenced
this pull request
Sep 6, 2026
…md move Two loose ends on top of the ADR-1194 change: 1. `adm_angle_flag_i64()` tripped `readability-function-size` (71 lines against the 60-line threshold) once clang-tidy was pointed at the new header with `-header-filter='adm_angle_flag\.h'` — the default filter is anchored at `^core/` and so misses it when the build dir is a sibling. ADR-0141 wants the file clean, not suppressed, so the right-hand-side rounding is now `adm_angle_flag_round53_v()`. Pure extraction: no expression changes, and `core/test/test_adm_angle_flag.c` still passes 7/7. `metal/integer_adm.metal` gets the same split so the manual MSL mirror stays line-for-line (the AGENTS.md lockstep invariant). 2. `docs/state.md` still carried T-UPSTREAM-930 under **Open bugs** with a comment claiming it had moved: an earlier duplicate-row cleanup dropped the Recently-closed copy instead of the stale open one. The open row is gone and the closed row is back at the head of Recently closed, citing PR #1342 and ADR-1194 (the previous text cited a commit sha that the rebase invalidated). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lusoris
force-pushed
the
fix/t-upstream-930-adm-angle-flag-predicate-
branch
from
September 6, 2026 18:26
d308cfe to
4543cab
Compare
31 tasks
lusoris
pushed a commit
that referenced
this pull request
Sep 7, 2026
…md move Two loose ends on top of the ADR-1194 change: 1. `adm_angle_flag_i64()` tripped `readability-function-size` (71 lines against the 60-line threshold) once clang-tidy was pointed at the new header with `-header-filter='adm_angle_flag\.h'` — the default filter is anchored at `^core/` and so misses it when the build dir is a sibling. ADR-0141 wants the file clean, not suppressed, so the right-hand-side rounding is now `adm_angle_flag_round53_v()`. Pure extraction: no expression changes, and `core/test/test_adm_angle_flag.c` still passes 7/7. `metal/integer_adm.metal` gets the same split so the manual MSL mirror stays line-for-line (the AGENTS.md lockstep invariant). 2. `docs/state.md` still carried T-UPSTREAM-930 under **Open bugs** with a comment claiming it had moved: an earlier duplicate-row cleanup dropped the Recently-closed copy instead of the stale open one. The open row is gone and the closed row is back at the head of Recently closed, citing PR #1342 and ADR-1194 (the previous text cited a commit sha that the rebase invalidated). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lusoris
force-pushed
the
fix/t-upstream-930-adm-angle-flag-predicate-
branch
from
September 7, 2026 17:03
4543cab to
63440da
Compare
`decouple()`'s 1-degree `angle_flag` test had four different spellings in
the tree. The CPU, AVX2 and AVX-512 paths narrow the exact int64 operands
to `float` and then compare in `double` — the form the Netflix golden gate
freezes. CUDA and HIP scale 0 compared the *exact* int64 products in
`double` (a strictly more accurate angle test, and therefore a different
one); SYCL did the whole comparison in `float`; Metal narrowed the exact
products to `float`. CUDA/HIP scales 1-3 already used the golden form, so
`s0` and `s123` disagreed inside a single backend.
`angle_flag` selects the enhancement-gain-limited branch of `decouple()`,
so a flipped flag moves the adm scores. Instrumenting the scalar CPU
decouple shows the divergence is reachable on the Netflix golden pair
itself: of 1 540 608 scale-0 pixels, the legacy SYCL form flips 2 and the
legacy Metal form flips 3; on a full-contrast 1080p noise clip the counts
are 11 / 11 / 18 (CUDA/HIP, SYCL, Metal).
The predicate now lives once, in `core/src/feature/adm_angle_flag.h`:
* `adm_angle_flag_fp64()` — the golden expression, verbatim. The scalar
CPU path, CUDA and HIP call it at both scales.
* `adm_angle_flag_i64()` — a bit-identical evaluation in 64-bit integer
arithmetic that uses no floating point of any width. SYCL calls it
(Intel Arc A-series and most iGPUs expose no fp64, and one fp64
instruction anywhere in that translation unit makes the runtime reject
the whole SPIR-V module); `metal/integer_adm.metal` mirrors it in MSL
(MSL has no `double` type).
Verified: `integer_adm.c` compiles to byte-identical machine code against
origin/master, so the CPU/golden lane cannot have moved. On the golden
576x324 pair with `adm_enhn_gain_limit=1.2`, the SYCL-vs-CPU adm gap drops
from 1.175e-05 to 8.220e-07 on the Arc A380. `adm_angle_flag_i64()` was
fuzzed against the golden expression over 200 M scale-0 quadruples and
104 M boundary-walk triples spanning all 62 magnitude classes, under gcc
and clang at -O0/-O2/-O3: zero mismatches.
Closes T-UPSTREAM-930-ADM-ANGLE-FLAG-PREDICATE-DIVERGENCE-2026-09-03.
Refs Netflix/vmaf#930.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Each dropped row restates one origin/master already carries; master is the authoritative record. Verified with scripts/ci/check-state-md-rows.sh. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…md move Two loose ends on top of the ADR-1194 change: 1. `adm_angle_flag_i64()` tripped `readability-function-size` (71 lines against the 60-line threshold) once clang-tidy was pointed at the new header with `-header-filter='adm_angle_flag\.h'` — the default filter is anchored at `^core/` and so misses it when the build dir is a sibling. ADR-0141 wants the file clean, not suppressed, so the right-hand-side rounding is now `adm_angle_flag_round53_v()`. Pure extraction: no expression changes, and `core/test/test_adm_angle_flag.c` still passes 7/7. `metal/integer_adm.metal` gets the same split so the manual MSL mirror stays line-for-line (the AGENTS.md lockstep invariant). 2. `docs/state.md` still carried T-UPSTREAM-930 under **Open bugs** with a comment claiming it had moved: an earlier duplicate-row cleanup dropped the Recently-closed copy instead of the stale open one. The open row is gone and the closed row is back at the head of Recently closed, citing PR #1342 and ADR-1194 (the previous text cited a commit sha that the rebase invalidated). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lusoris
force-pushed
the
fix/t-upstream-930-adm-angle-flag-predicate-
branch
from
September 7, 2026 18:35
63440da to
a0b06a6
Compare
…TS.md A previous rebase committed unresolved markers: integer_adm_sycl.cpp kept both sides of an #include hunk and core/src/feature/AGENTS.md kept both sides of an appended section. Both are additive — the includes are distinct headers and the sections document different invariants — so both sides are kept. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
What
decouple()'s integer-ADM 1-degreeangle_flagtest had four differentspellings in the tree (T-UPSTREAM-930, Netflix/vmaf#930):
integer_adm.c,adm_avx2.c,adm_avx512.cfloat, compare indouble— the golden-frozen formdecouple_angle_flag_s0doubledecouple_angle_flag_s123s0ands123disagreed inside one backendinteger_adm_sycl.cpp(both scales)floatiadm_angle_flag_s0floatangle_flagselects the enhancement-gain-limited branch ofdecouple(), so aflipped flag moves
admscores.The predicate now lives once, in
core/src/feature/adm_angle_flag.h:adm_angle_flag_fp64()— the golden expression, verbatim. Scalar CPU, CUDAand HIP call it, at both scales.
adm_angle_flag_i64()— a bit-identical evaluation in 64-bit integerarithmetic using no floating point of any width. SYCL calls it (Intel Arc
A-series and most iGPUs expose no fp64, and one fp64 instruction anywhere in
that TU makes the runtime reject the whole SPIR-V module — the binary
confirms it:
SYCL: device lacks native fp64);metal/integer_adm.metalmirrors it in MSL, which has no
doubletype at all.The CPU expression is untouched —
core/src/feature/integer_adm.ccompiles tobyte-identical machine code against
origin/master.Why it is reachable
Instrumenting the scalar CPU
adm_decouple()to evaluate all four historicalforms per scale-0 pixel:
src01_hrc00/hrc01_576x324(the Netflix golden pair)sparks_ref/dis_480x27010-bitReproducer / smoke-test command
Evidence
Regression test, both directions. With
adm_angle_flag_i64()'s bodytemporarily replaced by the pre-fix SYCL all-float predicate:
With the shipped helper:
SYCL on the Arc A380, golden 576x324 pair, 48 frames,
adm_enhn_gain_limit=1.2:CUDA on the RTX 4090, synthetic noise clip,
adm_enhn_gain_limit=1.2:Only scale 0 moves — exactly the site the CUDA/HIP change touches. At the
shipped default
adm_enhn_gain_limit = 1.0the flag gates only theMIN(rst, t)clamp, which is frequently a no-op, and the CUDAadmoutput onthat clip is byte-identical before and after.
Fuzz.
adm_angle_flag_i64()vs the golden expression: 200 000 000 scale-0band quadruples and 103 813 779 boundary-walk triples spanning all 62 magnitude
classes plus a 20x20x20 edge-operand cube — 0 mismatches, repeated under
gccandclangat-O0,-O2 -ffp-contract=offand-O3 -march=native.Suite.
meson test -C core/build-cpu --suite=fast→Ok: 115, Fail: 0.Lint.
clang-tidy -p core/build-tidyreports 0 diagnostics on bothcore/src/feature/integer_adm.candcore/test/test_adm_angle_flag.c(
-Db_lto=false, per the tidy-lane note).pre-commit run --files <all touched>is clean.
Not verified here
for this helper) but not executed — the AMD iGPU lane was not exercised.
review against the C header that the unit test pins.
core/src/feature/AGENTS.mdnow records that the mirror is manual and must be edited in lockstep.
cuda/hip/syclclang-tidy ratchet lanes (they do notrun on PRs) may report a stale-high baseline for the three touched backend
files, since the change removes inline expressions from them. The
cpulane —the one that gates PRs — is unaffected: neither touched cpu-lane file appears
in
scripts/ci/tidy-baseline-cpu.jsonand both measure 0.Deep-dive deliverables
Research digest —
docs/research/2030-adm-angle-flag-fp64-free.mdDecision matrix — ADR-1194
## Alternatives considered(six rows)AGENTS.md invariant note —
core/src/feature/AGENTS.md, "angle_flaghas exactly one definition"Reproducer / smoke-test command — above
CHANGELOG fragment —
changelog.d/fixed/adm-angle-flag-predicate-divergence.mdRebase note —
docs/rebase-notes.md, "fix/t-upstream-930-adm-angle-flag"ADR:
docs/adr/1194-adm-angle-flag-single-source.md+ index rowdocs/state.mdupdated (row moved to Recently closed)no docs needed: no user-discoverable surface changes — no new CLI flag, C API,
build option, feature name or output key; the only user-visible effect is that
GPU
admvalues move toward the CPU reference, which is what the ADR and thechangelog fragment record.
no ffmpeg patch impact: no public header, CLI flag or
meson_options.txtentry changes.
Closes T-UPSTREAM-930-ADM-ANGLE-FLAG-PREDICATE-DIVERGENCE-2026-09-03.
Refs Netflix/vmaf#930.
🤖 Generated with Claude Code