Repository navigation
refactor(feature): bring the NEON float ADM kernels to the lint and HISS standard (ADR-1142) - #1865
Merged
Merged
Conversation
…ISS standard (ADR-1142) (#1865) * refactor(feature): bring the NEON float ADM kernels to the lint and HISS standard (ADR-1142) float_adm_dwt2_neon(), the float ADM wavelet that adm.c dispatches on aarch64, was one function of 136 lines. It keeps its name and signature and loops over the output rows, calling - dwt2_vertical_row_neon(): the 4-tap vertical pass of one row, the 4-wide loop over dwt2_vertical_4_neon() (once with the low-pass taps, once with the high-pass taps), then the scalar tail - dwt2_horizontal_row_neon(): the scalar horizontal pass of one row Every sum still starts at +0 and adds one product per statement, in the same order, with the same float temporaries; no helper boundary cuts an expression. Each function carries the GCC optimize("-ffp-contract=off") attribute, as adm_dwt2_s() and its two helpers do. float_adm_neon.c: one declaration per line and (ptrdiff_t)i * stride for the row pointers. SPDX lines added to both files and to x86/adm_avx2.c and x86/adm_avx512.c. adm_tools.c: a NOLINTNEXTLINE(readability-function- size) on adm_dwt2_s() suppressed nothing and is removed, and the comment that said the wavelet stays one function describes the three functions it is. clang-tidy, arm64 lane: 6 to 0 and 5 to 0 (6 bugprone-implicit-widening- of-multiplication-result, 4 readability-isolate-declaration, 1 readability-function-size), baseline tightened by the ratchet's scoped write. adm_tools.c, adm_avx2.c and adm_avx512.c stay at 0 on every lane that reads them. HISS: one row removed, 247 to 246. Not one bit moves. aarch64 GCC under qemu: 1066 of 1066 cases (127 704 values) of the adm / float_adm record identical for scalar and NEON dispatch; the two kernels' objects are the only ones that differ from the base build; test_float_adm_dwt2_neon and test_float_adm_neon (bit-exact against the scalar references, signed zero included) pass; old against new on 35 920 inputs: no difference. x86: no object differs from the base build. Netflix golden gate: 271 passed, 12 skipped on x86 GCC and aarch64 GCC, before and after. * docs: regenerate the indexes and the citation map after rebasing
lusoris
force-pushed
the
refactor/float-adm-neon-standards
branch
from
October 2, 2026 15:42
57b0ef4 to
9607894
Compare
This was referenced Oct 2, 2026
refactor(simd): bring the integer motion SIMD kernels to the lint and HISS standard (ADR-1142)
#1868
Merged
Merged
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
Fourth and last PR of standards batch B1 (the ADM family, plan in #1856): the two NEON float ADM kernel files are at the lint and HISS standard, and the three remaining batch files that had no findings left get their SPDX line or lose a dead suppression. No bit of any score moves.
core/src/feature/arm64/float_adm_dwt2_neon.c, clang-tidycore/src/feature/arm64/float_adm_neon.c, clang-tidycore/src/feature/adm_tools.ccore/src/feature/x86/adm_avx2.c,adm_avx512.cscripts/ci/tidy-baseline-<lane>.jsonHISS: the row of
float_adm_dwt2_neon.cis gone (136 lines):.standards-baseline.json247 → 246, recorded withpraetorctl baseline --record; the README count follows. Suppressions left in the five files: the two citedreadability-non-const-parameterones in each ofadm_avx2.c/adm_avx512.c, untouched.Base: master
25fe95d73, which has #1856 and #1859. This PR and #1864 both change.standards-baseline.jsonand the README count; the second to land needs the baseline re-recorded (praetorctl baseline --record; 244 with both). Their tidy baselines do not overlap (#1864: cpu, cuda, hip, sycl; this one: arm64).What changed
The findings, by check (arm64 lane):
float_adm_dwt2_neon.cfloat_adm_neon.cbugprone-implicit-widening-of-multiplication-result(ptrdiff_t)i * stridereadability-isolate-declarationint i, j;became loop-scoped declarationsreadability-function-sizefloat_adm_dwt2_neon()is the waveletadm.cdispatches on aarch64. It keeps its name and signature and loops over the output rows:dwt2_vertical_4_neon()acc = vaddq_f32(acc, vmulq_laneq_f32(sN, f, N))steps from+0for four columns; called with the low-pass taps, then with the high-pass tapsdwt2_vertical_row_neon()dwt2_horizontal_row_neon()This is the shape of the scalar reference (
adm_dwt2_s()overadm_dwt2_vert_pass_s()andadm_dwt2_horiz_pass_s()inadm_tools.c). Every sum still starts at+0(signed-zero parity with the scalar code) and adds one product per statement in the same order, with the samefloattemporaries; no helper boundary cuts an expression. Each function carries the GCCoptimize("-ffp-contract=off")attribute, as the scalar three do: GCC'sarm_neon.himplementsvaddq_f32andvmulq_laneq_f32as plain+and*, so the guard matters for a build outside the meson carve-out. The compiled object has one symbol (all helpers are inlined) and no fused multiply-add instruction.The vector sum sits in its own helper because clang's
arm_neon.himplements the intrinsics as statement expressions: with the sum inline, the vertical helper counted 129 statements against the limit of 120.The other three files:
adm_tools.c:// NOLINTNEXTLINE(readability-function-size)onadm_dwt2_s(), 28 lines long, suppressed nothing and is removed; the comment above the wavelet said it "stays a single function on purpose" while it is three functions, and now describes them. No code changes.x86/adm_avx2.c,x86/adm_avx512.c: SPDX line (BSD-2-Clause-Patent; Netflix files, upstream has both). No other change.BSD-2-Clause-Patent, the licence their headers state).Not one bit moves
513d2a6fcbefore the batch started (this PR's base25fe95d73reproduces it, x86 and aarch64): everyadmandfloat_admoutput withdebug=trueunder 21 option sets and the model scores at--precision max, Netflix 576x324 at 8, 10, 12 and 16 bit, both 1080p checkerboards, BBB 3840x2160, 14 small sizes from 17x17, for scalar and NEON dispatch: 1066 of 1066 cases identical (127,704 values). The NEON cases run the refactored wavelet.test_float_adm_dwt2_neon(bit-exact againstadm_dwt2_s(), geometry sweep, signed zero) andtest_float_adm_neon(bit-exact against the scalar references of the other three kernels): pass before and after. All 20 ADM test binaries of the aarch64 build pass. x86--suite=fast: 243 of 243.-D) and the new ones linked into one driver, every output byte compared: widths 2 to 200 at nine heights and five large frames, five input classes (picture data, signed fractions, arbitrary bit patterns with NaN and infinities, signed zeros, 16-bit data), all four functions. 35,920 comparisons, 0 differences. Six changes planted in the new code are each detected (8543, 5870, 8977, 5000, 117 and 7286 differences).adm_tools.chas no code change; nothing to re-run.scripts/dev/preflight.sh --stage msvcism: pass.Type
feat— new featurefix— bug fixperf— performance improvementrefactor— no behavior changedocs— documentation onlytest— test-onlybuild/ci— tooling / infraport— cherry-pick from upstream Netflix/vmafsycl/cuda/simd— backend-specificChecklist
make format && make lintis green locally. (clang-format and the commit hooks; clang-tidy 0 for every touched file on every lane that reads it.)python3 scripts/ci/run_meson_test.py -- -C build. (--suite=faston a CPU build: 243 of 243; the aarch64 ADM tests under qemu: 20 of 20.)/cross-backend-diffand the worst ULP is ≤ 2. (NEON against scalar is bit-identical: the two unit tests and the 1066-case record.).c/.cpp/.cu/.h/.hpp, it has the appropriate license header (seeCONTRIBUTING.md). (None added; SPDX lines added to four files.)!orBREAKING CHANGE:and the migration path is documented below. (Not breaking.)docs/adr/_index_fragments/<NNNN-slug>.md. (No ADR: ADR-1142 is the rule.)Bug-status hygiene (ADR-0165)
docs/state.mdupdated in this PR. no state delta: refactor to the lint and HISS standard; no open row names these files' debt.Netflix golden-data gate (ADR-0024)
assertAlmostEqual(...)score in the Netflix golden Python tests.Deep-dive deliverables (ADR-0108)
AGENTS.mdinvariant note —core/src/feature/arm64/AGENTS.md, new bullet "float_adm_dwt2_neon()row helpers": the helper map, the attribute every helper needs, why the vector sum is its own helper.changelog.d/changed/float-adm-neon-lint-hiss-standard.md.docs/rebase-notes.md, "The NEON float ADM wavelet kernel is split into row helpers", with the map from the former single function to the helpers.Reproducer
Known follow-ups
core/test/test_float_adm_dwt2_neon.c(4 findings) andcore/test/test_float_adm_neon.c(7) on the arm64 lane belong to batch B11 (core/test) and are not touched here.adm_tools.h,adm_csf_tools.h,adm_options.handinteger_adm.hin the tidy baselines are still at their old counts (see refactor(feature): bring the ADM headers to the lint standard (ADR-1142) #1856): the ratchet's scoped write covers translation units only.