Skip to content

Port CUDA jpeg encoder to stable ABI.#9535

Merged
NicolasHug merged 3 commits into
pytorch:mainfrom
adabeyta:encoder-jpg-stable
Jul 2, 2026
Merged

Port CUDA jpeg encoder to stable ABI.#9535
NicolasHug merged 3 commits into
pytorch:mainfrom
adabeyta:encoder-jpg-stable

Conversation

@adabeyta

Copy link
Copy Markdown
Collaborator

Ports CUDA jpeg encoder to the stable ABI. This reuses the image_stable extension that #9533 stood up.

Layout Changes

  • setup.py: encode_jpegs_cuda.cpp added to STABLE_SOURCES.

  • Removed cuda/encode_decode_jpegs_cuda.h. With both the decoder (Port CUDA jpeg decoder to stable ABI #9533) and now the encoder on the stable header they are no longer needed.

Stable-ABI audit (torch-abi-audit)

Ran torch-abi-audit against the built torchvision package to verify the migrated extension stays on the stable surface and never reaches into at:: / c10:: / torch::jit:: internals.

image_stable.so audits as STABLE — 67 stable-shim symbols, 0 unstable (up from 65 in #9533; the encoder added 2). The encoder's symbols also leave the legacy image.so, whose unstable count drops 71 → 48. The legacy image.so / _C.so stay UNSTABLE (expected: only nms, the jpeg decoder, and now the encoder have migrated), so the package-level verdict stays UNSTABLE until the rest move.


```text
Package: torchvision
  Torch ABI:   UNSTABLE
  CPython ABI: n/a
  Bundled libs: 4
  -- bundled libs --
    [UNSTABLE] [not-abi3        ] _C.so            (stable_shim=0,  unstable=110)
    [STABLE  ] [not-abi3        ] _C_stable.so     (stable_shim=67, unstable=0)
    [UNSTABLE] [uses-private-api] image.so         (stable_shim=0,  unstable=48)
    [STABLE  ] [not-abi3        ] image_stable.so  (stable_shim=67, unstable=0)

@pytorch-bot

pytorch-bot Bot commented Jun 30, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/vision/9535

Note: Links to docs will display an error until the docs builds have been completed.

✅ No Failures

As of commit ec4c519 with merge base 4c0fc5a (image):
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the cla signed label Jun 30, 2026
@adabeyta adabeyta requested a review from NicolasHug June 30, 2026 03:15

@NicolasHug NicolasHug left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the PR @adabeyta , it looks like there some failures on the wheel-building job. I'm not sure about the Windows one, but the Rocm ones are failing with:

  File "/__w/vision/vision/pytorch/vision/test/smoke_test.py", line 119, in main
torchvision: 0.29.0.dev20260630+rocm7.1
    print(f"{torch.ops.image._jpeg_version() = }")
  File "/__w/_temp/conda_environment_28416352816/lib/python3.10/site-packages/torch/_ops.py", line 1393, in __getattr__
torch.cuda.is_available: False
    raise AttributeError(
AttributeError: '_OpNamespace' 'image' object has no attribute '_jpeg_version'

I suspect it's because there's no rocm encoder yet and we might need to slightly change the build process. I also left a comment below which might be related. Hopefully this should transitively address the Windows stuff too.

Note that by default, the ROCm unittests job won't run on PRs - only the wheel building job. If you want to test the rocm stuff, you can just push a branch against the origin repo (this one), instead of pushing to your fork. You have write permissions so you should be able to do that.

Comment thread setup.py Outdated
Comment on lines 448 to 460

@NicolasHug NicolasHug Jun 30, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We shouldn't need this here in image anymore, since this should all be in image_stable now

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Nice catch, now that both ops live in image_stable we no longer need to link nvjpeg or build as a CUDAExt.

@adabeyta adabeyta force-pushed the encoder-jpg-stable branch 2 times, most recently from 07c716a to 0b078d9 Compare July 1, 2026 03:29
@adabeyta

adabeyta commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

Thanks for the PR @adabeyta , it looks like there some failures on the wheel-building job. I'm not sure about the Windows one, but the Rocm ones are failing with:

  File "/__w/vision/vision/pytorch/vision/test/smoke_test.py", line 119, in main
torchvision: 0.29.0.dev20260630+rocm7.1
    print(f"{torch.ops.image._jpeg_version() = }")
  File "/__w/_temp/conda_environment_28416352816/lib/python3.10/site-packages/torch/_ops.py", line 1393, in __getattr__
torch.cuda.is_available: False
    raise AttributeError(
AttributeError: '_OpNamespace' 'image' object has no attribute '_jpeg_version'

I suspect it's because there's no rocm encoder yet and we might need to slightly change the build process. I also left a comment below which might be related. Hopefully this should transitively address the Windows stuff too.

Note that by default, the ROCm unittests job won't run on PRs - only the wheel building job. If you want to test the rocm stuff, you can just push a branch against the origin repo (this one), instead of pushing to your fork. You have write permissions so you should be able to do that.

Thanks @NicolasHug. Looks like there were two issues. For Windows image_stable links nvjpeg and once the encoder left image, nothing preloaded it. Then for ROCm the build dropped image.cpp but since CUDA migrated out there was nothing to hippify. Let me know what you think of the loading approach.

@adabeyta adabeyta requested a review from NicolasHug July 1, 2026 04:32
Comment thread torchvision/csrc/io/image/cuda/encode_jpegs_cuda.cpp Outdated
Comment thread setup.py Outdated
Comment thread setup.py Outdated
# system CUDA it may not be on the loader path and image_stable fails to load. We try to
# locate nvjpeg in the CUDA toolkit (CUDA_PATH/CUDA_HOME, then nvcc) and preload it; on
# Windows a .pyd import does not search PATH, so we also scan PATH, where the CUDA
# installer's DLL dir lands. No-op if already loaded or not found.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should avoid doing that kind of thing if we can. We didn't need it before when the encoder was in image and the decoder was already in image_stable, so there must be a simpler and cleaner solution?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Adding image_stable to the relocate list (Linux + Windows) so it gets bundled should also solve this.

@adabeyta adabeyta force-pushed the encoder-jpg-stable branch from 0b078d9 to 908c62b Compare July 1, 2026 17:34
@adabeyta adabeyta force-pushed the encoder-jpg-stable branch from 908c62b to ec4c519 Compare July 1, 2026 18:01
@adabeyta adabeyta requested a review from NicolasHug July 1, 2026 19:26

@NicolasHug NicolasHug left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @adabeyta , LGTM! I was able to verify that the rocm tests are still passing in #9537

@NicolasHug NicolasHug merged commit 05d3441 into pytorch:main Jul 2, 2026
56 checks passed
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Hey @NicolasHug!

You merged this PR, but no labels were added.
The list of valid labels is available at https://github.com/pytorch/vision/blob/main/.github/process_commit.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants