Skip to content

[ROCm] Add rocJPEG support for GPU JPEG decoding (backport of pytorch/vision#9342)#10

Merged
jithunnair-amd merged 1 commit into
ROCm:release/0.26from
ethanwee1:ethanwee/rocjpeg-decode-0.26
Jul 16, 2026
Merged

[ROCm] Add rocJPEG support for GPU JPEG decoding (backport of pytorch/vision#9342)#10
jithunnair-amd merged 1 commit into
ROCm:release/0.26from
ethanwee1:ethanwee/rocjpeg-decode-0.26

Conversation

@ethanwee1

@ethanwee1 ethanwee1 commented Jul 8, 2026

Copy link
Copy Markdown

What this does

Backports rocJPEG GPU JPEG decoding (upstream pytorch#9342) to release/0.26, so decode_jpeg(..., device="cuda") works on ROCm (MI300 / gfx94X) using rocJPEG's hardware backend for UNCHANGED, GRAY, and RGB modes. Gated by TORCHVISION_USE_ROCJPEG / ROCJPEG_FOUND, alongside the existing nvJPEG CUDA path.

Why this is a manual backport (not a cherry-pick)

#9342 was merged against main, which has since diverged significantly from release/0.26. A git cherry-pick does not apply. The change had to be re-implemented against the release/0.26 layout:

  • Stable ABI vs classic API: upstream uses the torch stable ABI (torch::stable::Tensor, STABLE_TORCH_LIBRARY_IMPL, common_stable.*, the separate image_stable extension). release/0.26 has none of that, so the decoder was rewritten with the classic torch::Tensor / at::empty / TORCH_CHECK API.
  • File placement / hipify: upstream hand-writes io/image/hip/decode_jpegs_cuda.cpp. On release/0.26 the ROCm build hipifies io/image/cuda/* into hip/, so the rocJPEG path lives in cuda/decode_jpegs_cuda.{cpp,h} guarded by #if ROCJPEG_FOUND and flows through hipify (verified: it transforms cleanly into hip/decode_jpegs_hip.cpp with the decode_jpegs_cuda symbol and all rocJpeg* calls intact).
  • Op registration: release/0.26 registers via a single .op("image::decode_jpegs_cuda", ...) in image.cpp, so the upstream dual #if !ROCJPEG_FOUND registration split was not needed.
  • setup.py: added USE_ROCJPEG + ROCJPEG_FOUND detection to make_image_extension (no STABLE_SOURCES / image_stable plumbing, which don't exist here).

Changes

  • torchvision/csrc/io/image/cuda/decode_jpegs_cuda.h - RocJpegDecoder class + CHECK_ROCJPEG/CHECK_HIP macros under #if ROCJPEG_FOUND.
  • torchvision/csrc/io/image/cuda/decode_jpegs_cuda.cpp - rocJPEG decode implementation (classic API); stub guard changed to #if !NVJPEG_FOUND && !ROCJPEG_FOUND.
  • setup.py - TORCHVISION_USE_ROCJPEG / ROCJPEG_FOUND detection and rocjpeg linkage.
  • test/test_image.py - IS_ROCM tolerance bump for decode; skip GPU JPEG encoder tests (rocJPEG is decode-only).
  • torchvision/io/image.py - docstring note about the rocJPEG path.

Capability notes

rocJPEG uses ROCJPEG_BACKEND_HARDWARE, which rejects images smaller than 64x64 and 4:1:1 / unknown chroma subsampling.

Validation

Built via TheRock "Multi-Arch Build Portable Linux PyTorch Wheels" against this pin: https://github.com/ROCm/TheRock/actions/runs/28960912700

  • Build (torch + rocJPEG torchvision, gfx94X, py3.12): success.
  • PyTorch test suite: 39627 passed; the only 4 failures are unrelated (test_unary_ufuncs.py uint8 threshold OverflowError), not JPEG/torchvision.

Companion PR

Pin bump in ROCm/pytorch release/2.11: ROCm/pytorch#3411

Backport of pytorch#9342 adapted to the release/0.26 (classic,
non stable-ABI) JPEG decoder layout.

Adds a rocJPEG-backed GPU JPEG decode path for ROCm builds, gated by
TORCHVISION_USE_ROCJPEG / ROCJPEG_FOUND, alongside the existing nvJPEG
CUDA path. This enables decode_jpeg(..., device="cuda") on ROCm for
UNCHANGED, GRAY and RGB modes using rocJPEG's hardware backend.

rocJPEG uses ROCJPEG_BACKEND_HARDWARE, which rejects images smaller than
64x64 and 4:1:1/unknown chroma subsampling.
ethanwee1 added a commit to ROCm/pytorch that referenced this pull request Jul 8, 2026
Points the release/2.11 torchvision pin at ROCm/vision#10
(backport of pytorch/vision#9342, rocJPEG GPU JPEG decode).

@jithunnair-amd jithunnair-amd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ethanwee1 Since this PR is a reimplemented version of the upstream PR, can you please run the torchvision tests that would test the decoding functionality to establish equivalence? Please post the results in the Validation section of the PR description.

@jithunnair-amd jithunnair-amd marked this pull request as ready for review July 16, 2026 16:09
@jithunnair-amd jithunnair-amd merged commit 3d50b21 into ROCm:release/0.26 Jul 16, 2026
6 of 57 checks passed
ethanwee1 added a commit to ROCm/pytorch that referenced this pull request Jul 16, 2026
Updates the release/2.11 torchvision pin to the merged ROCm/vision
release/0.26 commit 3d50b2155c02d26e78b9c09baf99f5c707d70215 (ROCm/vision#10).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants