Research-0095 — ATOM_FEATURES port (3dee9666 + 7209110e) blocker¶
Date: 2026-05-10 Status: Blocked — port requires C-side adm_cm API change, not just Python sync. Tracker: T-PY-FEXT-ATOM-SYNC in docs/state.md (remains Open).
Why a simple cherry-pick doesn't work¶
The Netflix upstream commits the fork is missing:
3dee9666— movesvif_scale0..3,adm_scale0..3,adm2,adm3,motion3fromDERIVED_ATOM_FEATUREStoATOM_FEATURESinpython/vmaf/core/feature_extractor.py. Pure Python.7209110e— recalibrates ~40assertAlmostEqualvalues acrosspython/test/feature_extractor_test.py,python/test/quality_runner_test.py, andpython/test/vmafexec_test.pyto match the new derivation path.
Naive cherry-pick produces 16/65 failures in feature_extractor_test.py — chiefly KeyError: VMAF_feature_aim_score and family. AIM is one of the derived features that 3dee9666 expects the binary to emit but the fork's binary does not. That's the blocker.
What the fork's adm_cm_s is missing¶
Upstream's AIM derivation calls adm_cm twice:
adm_cm(decouple_a, csf_a, csf_f, …, noise_weight=0.0, …)— noise-masking disabled for the AIM half.adm_cm(decouple_r, csf_a, csf_f, …, noise_weight=DEFAULT, …)— noise-masking enabled (= the existing DLM-style call).
The fork's adm_cm_s (in core/src/feature/adm_tools.c) hardcodes noise_weight = DEFAULT_ADM_NOISE_WEIGHT = 0.03125 via its internal adm_sum_cube_s(csf_a, …) call — there is no parameter to disable it.
So the AIM-derived aim_score cannot be produced by the fork's binary today; the test recalibrations in 7209110e expect specific AIM values (e.g., 0.026559020833333336) that depend on the noise-weight=0 variant.
What a real port requires¶
- C-side: extend
adm_cm_s(and the integer/SIMD/CUDA/SYCL/ Vulkan/HIP equivalents — that's ~12 sites) to take anoise_weightparameter. Plumb it throughadm_run_s→adm_scoreand friends. - Python-side: the cherry-pick from 3dee9666 + 7209110e then becomes plumbing — once the binary emits
aim_score, the test values match.
Estimated scope: ~400–600 LOC across the C tree (one parameter threaded through ~12 implementations) + the trivial Python cherry-pick. ADR required (changes a public extractor's output set).
Why this is deferred, not done in tonight's train¶
Tonight's train fixed 35 PRs of bugs — single-cause, narrow-scope issues with clear remediation. This port is a feature port that extends the C API surface. It deserves a focused PR with its own ADR, its own benchmarking pass (does adding a noise-weight parameter regress ADM scoring perf?), and its own GPU-backend update sweep.
Acceptance criteria when work resumes¶
python/test/feature_extractor_test.pypasses 65/65 against the fork's binary.python/test/quality_runner_test.pypasses excluding any tests fork-locally added (e.g., theassertEqualversion probes bumped in PR #729).- The Netflix golden CPU pairs (
src01_hrc01, two checkerboard variants) still produce within ±5e-05 of their golden assertions (CLAUDE §1, §8). - ADR documenting the
adm_cmAPI extension lands alongside the C changes.
References¶
- Upstream commits:
3dee9666,7209110eon https://github.com/Netflix/vmaf master. - Fork-local PRs that touch the same surface and must be preserved on any future port attempt:
- PR #715 (VERSION 0.2.7 → 0.2.21)
- PR #716 (PyPsnrFeatureExtractor case fix + Pypsnr* deprecated subclass)
- PR #717 (corpus adapter DX)
- PR #724 (json log roundtrip — numpy 2.x compat)
- PR #729 (version-string assertion bumps)
T-PY-FEXT-ATOM-SYNCindocs/state.md.