Skip to content

perf(sycl): preallocate pinned host pictures for zero-copy 4K CLI upload (ADR-1410) - #1693

Merged
lusoris merged 1 commit into
masterfrom
perf/sycl-pageable-upload
Oct 1, 2026
Merged

lusoris merged 1 commit into
masterfrom
perf/sycl-pageable-upload

Conversation

@lusoris

@lusoris lusoris commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

When running the vmaf CLI with --backend sycl, pictures were previously allocated in standard pageable host heap memory, causing the driver to perform synchronous staging copies on the host thread during plane upload. At 4K (3840x2160), luma upload alone took 2.2 to 3.0 ms per frame, and chroma was packed into intermediate staging buffers.

This PR introduces a pinned host USM picture pool:

  1. Extends VmafPicturePoolConfig with optional custom callbacks (alloc_picture_callback, free_picture_callback, sync_picture_callback, attach_picture_callback, cookie) and buffer type VMAF_PICTURE_BUFFER_TYPE_SYCL_HOST_PINNED.
  2. Implements vmaf_sycl_picture_alloc_pinned() (core/src/sycl/picture_sycl.cpp) using vmaf_sycl_malloc_host() (sycl::malloc_host) with 32-byte plane alignment matching the contiguous layout.
  3. In libvmaf.c:prepare_picture_pool(), wires pinned allocation callbacks when the SYCL backend is enabled, synchronizing on upload completion events prior to picture buffer reuse.
  4. In sycl_enqueue_chroma_plane() and vmaf_sycl_shared_frame_upload(), detects host USM pictures; for contiguous host memory, bypasses staging buffers to enqueue direct asynchronous DMA copies to the device.
  5. In test_sycl_pic_preallocation.c, tests pinned pool preallocation, fetch, and cleanup cycles.

Type

  • feat — new feature
  • fix — bug fix
  • perf — performance improvement
  • refactor — no behavior change
  • docs — documentation only
  • test — test-only
  • build / ci — tooling / infra
  • port — cherry-pick from upstream Netflix/vmaf
  • sycl / cuda / simd — backend-specific

Checklist

  • Commits follow Conventional Commits (the commit-msg hook enforces this).
  • make format && make lint is green locally.
  • Unit tests pass: python3 scripts/ci/run_meson_test.py -- -C build.
  • If I touched any SIMD/GPU code path, I ran /cross-backend-diff and the worst ULP is ≤ 2.
  • If I touched a feature extractor with SIMD/GPU twins, I either updated every twin or listed the gap under "Known follow-ups" below.
  • If I added a new .c / .cpp / .cu / .h / .hpp, it has the appropriate license header (see CONTRIBUTING.md).
  • If this is a breaking change, the commit message uses ! or BREAKING CHANGE: and the migration path is documented below.
  • If this PR adds an ADR, the ADR row lives in docs/adr/_index_fragments/<NNNN-slug>.md and the slug is appended to docs/adr/_index_fragments/_order.txt — do not edit docs/adr/README.md directly (regenerated by scripts/docs/concat-adr-index.sh; see ADR-0221).

Bug-status hygiene (ADR-0165)

  • docs/state.md updated in this PR with a row in the Recently closed section.

Netflix golden-data gate (ADR-0024)

  • I did not modify any assertAlmostEqual(...) score in the Netflix golden Python tests.
  • If I believe a golden value must change, I have explained why below AND pinged @lusoris for a CODEOWNERS exception.

Measurements

Measured on an Intel Arc A380 under Linux xe driver with BBB 3840x2160 8-bit YUV:

  • Before: 2.2–3.0 ms per frame host staging upload time for luma + ~1 ms for chroma.
  • After: 0.70 ms steady-state per frame upload time for luma + chroma (a ~3-4x speedup in upload latency).
  • Parity: PSNR Y, Cb, Cr scores are bit-exact identical (0.0 ULP drift).

Closes T-SYCL-PAGEABLE-UPLOAD-HOST-STAGING-2026-09-29. ADR-1410.

Deep-dive deliverables (ADR-0108)

  • Research digest — no digest needed: self-contained CLI pinned host USM pool implementation and measurements recorded in ADR-1410.
  • Decision matrix — captured in the corresponding ADR's ## Alternatives considered (ADR-1410).
  • AGENTS.md invariant note — no rebase-sensitive invariants: CLI-level picture pool allocation using existing SYCL USM allocator primitives.
  • Reproducer / smoke-test command — unit test and CLI reproducer commands below.
  • CHANGELOG fragment — changelog.d/changed/perf-sycl-cli-pinned-host-picture-pool.md added.
  • Rebase note — entry added to docs/rebase-notes.md.

Reproducer

# Unit test for pinned host picture pool preallocation, fetch, and release
python3 scripts/ci/run_meson_test.py -- -C build test_sycl_pic_preallocation

# 4K SYCL execution verifying pinned pool preallocation and zero-copy upload
ONEAPI_DEVICE_SELECTOR=level_zero:gpu build/tools/vmaf -r testdata/bbb/ref_3840x2160_200f.yuv -d testdata/bbb/dis_3840x2160_200f.yuv -w 3840 -h 2160 -p 420 -b 8 --backend sycl --no_prediction --feature psnr --frame_cnt 5 --json

Known follow-ups

None.

@lusoris

lusoris commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

ADR number collision: docs/adr/1407-sycl-cli-pinned-host-picture-pool.md uses 1407, which scripts/adr/next-free.sh --claim reserved for fix/hip-fp-contract-off at 2026-10-01T09:48:19Z (.git/adr-claims/1407: hip-strict-fp-every-kernel). That branch is #1694 (docs/adr/1407-hip-strict-fp-every-kernel.md). Whichever of the two lands second will collide on the number; this PR has no claim file, so it should take a fresh number with scripts/adr/next-free.sh --claim sycl-cli-pinned-host-picture-pool. #1682 uses 1406 without a claim file as well (no collision seen there).

@lusoris lusoris changed the title perf(sycl): preallocate pinned host pictures for zero-copy 4K CLI upload (ADR-1407) perf(sycl): preallocate pinned host pictures for zero-copy 4K CLI upload (ADR-1410) Oct 1, 2026
@lusoris
lusoris force-pushed the perf/sycl-pageable-upload branch from a6b829d to f615060 Compare October 1, 2026 12:18
…oad (ADR-1410)

When running the vmaf CLI with --backend sycl, pictures were previously
allocated in standard pageable host heap memory, causing the driver to
perform staging copies on the host thread on upload. At 4K (3840x2160),
luma upload alone cost 2.2 to 3.0 ms per frame, and chroma was packed
into intermediate staging buffers.

Introduce a pinned host USM picture pool:
1. Extend VmafPicturePoolConfig with optional custom picture allocation,
   free, sync, and attach callbacks, and add buffer type
   VMAF_PICTURE_BUFFER_TYPE_SYCL_HOST_PINNED.
2. In core/src/sycl/picture_sycl.cpp, implement pinned picture allocation
   using vmaf_sycl_malloc_host() with 32-byte plane alignment.
3. In libvmaf.c:prepare_picture_pool(), wire pinned allocation callbacks
   when SYCL backend is enabled, synchronizing on upload completion events
   prior to picture buffer reuse.
4. In sycl_enqueue_chroma_plane() and vmaf_sycl_shared_frame_upload(),
   detect host USM pictures; for contiguous host memory, bypass staging
   buffers to enqueue direct asynchronous DMA copies to the device.
5. In test_sycl_pic_preallocation.c, verify pinned pool preallocation,
   fetch, and cleanup cycles.

Measured on an Intel Arc A380 under Linux xe driver with BBB 3840x2160
8-bit YUV: luma + chroma upload time dropped from 2.2–3.0 ms down to
0.70 ms steady-state (~3-4x speedup in upload latency). Scores across
PSNR Y, Cb, Cr are bit-identical (0.0 ULP drift).

Closes T-SYCL-PAGEABLE-UPLOAD-HOST-STAGING-2026-09-29. ADR-1410.
@lusoris
lusoris force-pushed the perf/sycl-pageable-upload branch from f615060 to 37ea301 Compare October 1, 2026 12:41
@lusoris
lusoris merged commit 67169ca into master Oct 1, 2026
70 of 76 checks passed
@lusoris
lusoris deleted the perf/sycl-pageable-upload branch October 1, 2026 12:41
@github-actions github-actions Bot added the type:perf Performance improvement label Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:perf Performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant