Skip to content

fix(cuda): download every plane of device input for CPU extractors - #1754

Merged
lusoris merged 1 commit into
masterfrom
fix/cuda-device-input-chroma-download
Oct 1, 2026
Merged

lusoris merged 1 commit into
masterfrom
fix/cuda-device-input-chroma-download

Conversation

@lusoris

@lusoris lusoris commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Summary

With the pictures in device memory and an extractor that runs on the CPU, libvmaf copied the luma plane into the host picture only; the chroma planes stayed as vmaf_picture_alloc() left them and the CPU extractor scored them without an error: psnr_cb came out as the 60 dB cap where the CPU gives 12.54 dB. The device-to-host copy now takes every plane the picture has.

Closes T-CUDA-DEVICE-INPUT-CHROMA-NOT-DOWNLOADED-2026-10-01 (found and closed here). Netflix/vmaf#1613 reports the same line on upstream. RC3, correctness (ADR-1421).

Cause

translate_picture_device() in core/src/libvmaf.c called vmaf_cuda_picture_download_async(pic, pic_host, 0x1). The host-to-device upload next to it takes 0x7 (0x1 for 4:0:0). A CPU extractor gets a device picture's host copy when a registered extractor has no CUDA twin or the context carries a gpumask; the CUDA twins read the device pictures directly, so the default model on CUDA is not affected (psnr_cuda y/cb/cr equal the CPU on the Netflix pair, host input, at --threads 0 and 4: 0.0 difference over 48 frames).

Output on an RTX 4090

test_cuda_device_input_host_extractors (4 frames of noise on every plane at 192x128, pictures from the DEVICE preallocation pool, gpumask = 1 so psnr runs on the CPU, every psnr_y / psnr_cb / psnr_cr compared with == against a CPU-only run on the same pictures, n_threads 0 and 4):

Result
Before (run twice) threads=0 frame 0 psnr_cb: cpu=12.543948908054073 device-input=60, fail
After (run twice) pass, both thread counts

Type

  • fix — bug fix

Deep-dive deliverables (ADR-0108)

  • Research digest — no digest needed: a one-constant fix; the evidence is in the state row.
  • Decision matrix — no alternatives: only-one-way fix (every plane the picture has).
  • AGENTS.md invariant note — core/src/cuda/AGENTS.md, "Device-to-host picture download takes every plane".
  • Reproducer / smoke-test command — under "Reproducer" below.
  • CHANGELOG fragment — changelog.d/fixed/cuda-device-input-chroma-download.md.
  • Rebase note — docs/rebase-notes.md, "translate_picture_device() downloads every plane".

Reproducer

flock ~/.cache/vmafx-locks/cuda-4090.lock timeout 120 build/test/test_cuda_device_input_host_extractors

Notes

  • core/src/libvmaf.c is also touched by the ownership PR (ADR-1431) in vmaf_read_pictures() and check_ring_buffer(); this change is in translate_picture_device().
  • Touches core/test/meson.build (one block). No public API, ABI or FFmpeg patch impact. No Netflix golden assertion changed.

…1754)

* fix(cuda): download every plane of device input for CPU extractors

translate_picture_device() copied the luma plane of a device picture into the
host picture only. With device-resident input and an extractor on the CPU the
chroma planes stayed uninitialised, and psnr_cb came out as the 60 dB cap where
the CPU gives 12.54 dB, with no error (Netflix/vmaf#1613). The download now
takes every plane the picture has, as the upload already does.

test_cuda_device_input_host_extractors compares psnr y/cb/cr of device input
with a CPU-only run at n_threads 0 and 4; it fails without the fix.

* docs: regenerate the indexes and the citation map after rebasing
@lusoris
lusoris force-pushed the fix/cuda-device-input-chroma-download branch from f8bbfce to c88f080 Compare October 1, 2026 21:41
@lusoris
lusoris merged commit c88f080 into master Oct 1, 2026
10 of 78 checks passed
@lusoris
lusoris deleted the fix/cuda-device-input-chroma-download branch October 1, 2026 21:41
@github-actions github-actions Bot added the type:bug Something isn't working label Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant