Repository navigation
Conversation
lusoris
force-pushed
the
fix/cuda-adm-cm-border-scales-1-3
branch
from
October 2, 2026 05:24
739f9d0 to
474af5a
Compare
… 3 as the CPU does
i4_adm_cm_line_kernel() steps the three neighbours of a sample with
offset_i and offset_j. At i == 0 (j == 0) with top <= 0 (left <= 0) it
reads rows {1, 2, 3} (columns likewise) and takes the centre sample from
row 2, where the CPU's I4_ADM_CM_THRESH_S_* macros mirror {1, 0, 1} around
row 0. At the bottom and right borders both sides replicate
{n - 2, n - 1, n - 1}.
The border branches are live whenever a band of scale 1 to 3 has 14
samples or fewer in a dimension (top or left is then 0), which at scale 3
is a frame of 224 pixels or fewer in that dimension.
Take the three positions as min(abs(p - 1), n - 1), p and
min(p + 1, n - 1). That reproduces the CPU's index pattern at every
border, and no position leaves the band.
Add test_cuda_adm_cm_border, which compares integer_adm_scale1 to
integer_adm_scale3 of adm_cuda with the scalar CPU adm on frames of 33x33
to 130x40 at 8 and 10 bits.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
lusoris
force-pushed
the
fix/cuda-adm-cm-border-scales-1-3
branch
from
October 2, 2026 18:45
474af5a to
7a9778b
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.
integer_adm_scale1tointeger_adm_scale3ofadm_cudadiffer from the CPU on every frame that is small in either dimension: up to 1.0e-2 at scale 1, 5.6e-2 at scale 2 and 2.7e-1 at scale 3 on frames of 17 to 64 pixels, and 1.7e-3 on a real 160x90 clip. This is bug 1 of #1564; the other bugs of that issue are separate changes.Cause
i4_adm_cm_line_kernel()(libvmaf/src/feature/cuda/integer_adm/adm_cm.cu) steps the three neighbours of a sample withoffset_iandoffset_j. Ati == 0(j == 0) withtop <= 0(left <= 0) it reads the rows{1, 2, 3}(columns likewise) and takes the centre sample from row 2. The CPU'sI4_ADM_CM_THRESH_S_*macros (integer_adm.c) mirror around row 0:{1, 0, 1}, centre in row 0. At the bottom and right borders both sides replicate,{n - 2, n - 1, n - 1}.topandleftare 0 whenever a band has 14 samples or fewer in that dimension. At scale 3 that is a frame of 224 pixels or fewer, at scale 2 of 112 or fewer, at scale 1 of 56 or fewer, so the border branches are live on small frames.Reproducer
Master
8e7a1ac4e,-Denable_cuda=true, RTX 4090. The CLI prints six digits. Real clip, the 160x90 pair of the Netflix test resources (ref_test_0_1_src01_hrc00_576x324_576x324_vs_src01_hrc01_576x324_576x324_q_160x90.yuv, 48 frames), CPU scalar againstadm_cuda:integer_adm_scale0integer_adm_scale1integer_adm_scale2integer_adm_scale3integer_adm2Synthetic frames, 17x17 to 64x64 and fifteen other sizes up to 320x180, 8 and 10 bits, random and structured content, two frames each (212 configurations; the generator is the one in the new test).
adm_cudaagainst the scalar CPU, compared at%.17gthrough the C API. Largest absolute difference over the configurations of the size group:For frames with a side of 32 pixels or fewer the scalar CPU on master is itself wrong at scale 3 (#1599); those rows use the scalar CPU with the fixes of #1599, #1600, #1602 and #1633 merged locally as the reference. Both dimensions of 33 or more give the same scalar CPU scores on master and with those fixes (checked on all 212 configurations).
Fix
The three positions of a neighbourhood are taken as
min(abs(p - 1), n - 1),pandmin(p + 1, n - 1). That is{1, 0, 1}at the top and left border,{n - 2, n - 1, n - 1}at the bottom and right border, and no position leaves the band. The interior is unchanged. This is the index scheme #1564 proposes for bug 1.Tests
test_cuda_adm_cm_border(new,libvmaf/test/, built withenable_cuda; it reports a skip when no CUDA device can be opened) comparesinteger_adm_scale1tointeger_adm_scale3ofadm_cudawith the scalar CPUadmon frames of 33x33, 48x48, 66x34, 100x33 and 130x40 at 8 and 10 bits, random and structured content, with a tolerance of 1e-9. Unpatched master fails it (33x33, 8 bit, random content: 1.83e-2); this branch passes it. The sizes keep both dimensions at 33 or more, so that the test does not depend on the CPU fixes.Validation
Master
8e7a1ac4e, 2026-10-01. x86-64 Linux, GCC 16.2.1, nvcc 13.4, RTX 4090.Rebased on master
9e48141b(2026-10-02). On that base, with-Denable_cuda=true -Denable_float=true -Denable_checkasm=true,meson testgives 28 of 29 (the failure istest_cuda_pic_preallocation, which also fails on unpatched9e48141b, 27 of 28 there), and the CPU-Db_sanitize=address,undefined -Db_lto=falsebuild gives 22 of 25 on master and here (test_predictandtest_pic_preallocationabort under LeakSanitizer andcheckasmaborts on a heap-buffer-overflow inadm_dwt2_16(integer_adm.c:2603); all three also abort on unpatched9e48141b). The CLI output of the three Netflix pairs (--gpumask 0,vmaf_v0.6.1) against unpatched9e48141b: identical on all three pairs (src01 76.668905, checkerboard 1 px 35.068667, 10 px 7.985899). The sweeps and the other measurements below were taken on8e7a1ac4eand not repeated; the files and x86 code paths they depend on are unchanged since (the one upstream change in between is an arm64-only ADM kernel).libvmaf/test/meson.build, where every branch adds its test at the same place.adm_cudaat%.17g(integer_adm2, scales 0 to 3 and the numerators and denominators):src01576x324 8 bit (48 frames) and 10 bit (3 frames), checkerboard 1 px and 10 px 1920x1080 (3 frames each), KristenAndSara 1280x720,akiyo352x288,sparks480x270 10 bit (5 frames): identical to master and to the scalar CPU. No golden assertion changes.compute-sanitizer --tool memcheckreports no error for master and for the merge of the five branches at 24x24, 20x36, 33x33 and 48x48: the rows past the band that the old scheme reads are inside the allocation.meson teston the merge of the five branches: 28 of 29 pass.test_cuda_pic_preallocationaborts with SIGSEGV intest_cuda_picture_preallocation_method_host_pinned; it does the same on unpatched master.The workflow run on this PR needs a maintainer's approval.