CUDA EP as a standalone plugin package (onnxruntime-ep-cuda) — explores #196 follow-up - #197
CUDA EP as a standalone plugin package (onnxruntime-ep-cuda) — explores #196 follow-up#197hmaarrfk wants to merge 56 commits into
Conversation
(cherry picked from commit bbb7162)
(cherry picked from commit a603d7a)
(cherry picked from commit 013a296)
(cherry picked from commit b9e50c1)
(cherry picked from commit b4ddaab)
(cherry picked from commit 8178088)
(cherry picked from commit b621bf2)
(cherry picked from commit 0c0eb26)
[cherry picked from commit 256790e; recipe changes only, rerender output dropped]
(cherry picked from commit 53d6eb8)
[cherry picked from commit d3457f3; recipe changes only, rerender output dropped]
(cherry picked from commit 0f79f21)
(cherry picked from commit 2332847)
(cherry picked from commit 9724cd6)
(cherry picked from commit de3e786)
(cherry picked from commit 8fa9d24)
(cherry picked from commit 68ded51)
(cherry picked from commit 8a294e1)
(cherry picked from commit 9417bea)
(cherry picked from commit f1211de)
(cherry picked from commit 739f3e5)
[cherry picked from commit 666a846; recipe changes only, rerender output dropped]
(cherry picked from commit 85eb668)
(cherry picked from commit af69e8d)
(cherry picked from commit 542e19a)
(cherry picked from commit 53c4f88)
(cherry picked from commit 0dfeb68)
(cherry picked from commit e041e7a)
(cherry picked from commit 6e420d1)
(cherry picked from commit b1f945d)
(cherry picked from commit 953701e)
(cherry picked from commit e901a3b)
[cherry picked from commit add924b; recipe changes only, rerender output dropped]
(cherry picked from commit 9dcca6c)
(cherry picked from commit ae48510)
(cherry picked from commit dd1d48d)
(cherry picked from commit eb1156e)
(cherry picked from commit 72e183d)
(cherry picked from commit 9407828)
(cherry picked from commit 8f432b4)
(cherry picked from commit 66edfee)
<details><summary>Claude's draft</summary> Adapt the cherry-picked rattler-build migration (conda-forge#171 by @cbourjau) to the current 1.28.0 feedstock state: - Bump version to 1.28.0 with the matching sha256 and add patches 0006/0007 (onnx-less test guards introduced for 1.28.0). - Re-enable the -novec variants that were skipped while debugging conda-forge#171; this required templating the staging output name in the `inherit:` keys. - Port CoreML execution provider support for osx-arm64 (conda-forge#182): onnxruntime_USE_COREML=ON, nlohmann_json host dep, provider test, BSD-3-Clause license and vendored license files. - Port Jetson Thor support (conda-forge#190): add 110-real to the CUDA 13.0 arch list. - Port nvcc_threads=2 (Windows CUDA 13.0 OOM mitigation). - Pin cmake <4 (vendored protobuf 3.21 does not build with CMake 4). - Match main's 1.28.0 runtime deps: drop sympy, add __cuda run dep on the python output. - Add onnxruntime_test --help entry-point test. Resume this Claude session: ``` cd /home/mark/git/feedstock/onnxruntime-feedstock claude --resume bceefe2e-0d08-4ad8-9b4c-3518466f1ccc ``` </details>
…026.08.08.17.43.08 Other tools: - conda-build 26.7.0 - rattler-build 0.72.2 - rattler-build-conda-compat 1.4.19
<details><summary>Claude's draft</summary> The top-level recipe name is a placeholder (onnxruntime-dummy), so the conda-smithy linter needs an explicit extra.feedstock-name: onnxruntime. Resume this Claude session: ``` cd /home/mark/git/feedstock/onnxruntime-feedstock claude --resume bceefe2e-0d08-4ad8-9b4c-3518466f1ccc ``` </details>
<details><summary>Claude's draft</summary> All CI jobs failed at cmake configure with "CMAKE_CXX_STANDARD must be at least 20. It is 17." — 1.28.0 enforces C++20 via onnxruntime_language_standard_versions.cmake. The C++17 choice in conda-forge#171 was a workaround for C++20 module-scanning issues at 1.24.4; upstream 1.28.0 now sets CMAKE_CXX_SCAN_FOR_MODULES=OFF itself (cmake/CMakeLists.txt:21), so C++20 is safe. This also matches main's build.py invocation which passed CMAKE_CXX_STANDARD=20. run_cpp_test.bat stays at /std:c++17: consuming the public headers only needs C++17 and main is green with that combination. Resume this Claude session: ``` cd /home/mark/git/feedstock/onnxruntime-feedstock claude --resume bceefe2e-0d08-4ad8-9b4c-3518466f1ccc ``` </details>
<details><summary>Claude's draft</summary>
Both Windows CUDA jobs failed at configure with "Could not find compiler
set in environment variable CC: cl.exe" while the Windows CPU job (which
skips the CUDA branch) proceeded fine.
Cause: on Windows, nushell exposes the search path as a *list* named
`Path`. The CUDA branch did
$env.PATH = $"($build_lib_prefix)/bin;($env.PATH)"
which interpolates that list into a string ("[C:\..., C:\...]") under the
separate key `PATH`, shadowing the real `Path` in child processes — so
cmake could no longer find cl.exe. Prepend to the `Path` list instead.
Resume this Claude session:
```
cd /home/mark/git/feedstock/onnxruntime-feedstock
claude --resume bceefe2e-0d08-4ad8-9b4c-3518466f1ccc
```
</details>
<details><summary>Claude's draft</summary> The Windows CUDA 12.9 job now compiles (PATH fix worked) but fails on every .cu file targeting sm_100a/sm_120a: CCCL's clusterlaunchcontrol.h inline asm uses long2, and long is 32-bit under MSVC, producing "asm operand type size(4) does not match constraint 'l'". main already carries the answer in bld.bat: SM 100+ is broken with CUDA 12.9 on Windows (fixed in 13.0), and SM 110 (Thor) is Linux-only. My 1.28.0 adaptation had wrongly applied the Linux arch lists to all platforms. Split the arch lists per platform to match main exactly: - win 12.9: 70..90-real (no 100/120) - win 13.0: 75..100-real,120 (no 110) - linux unchanged Resume this Claude session: ``` cd /home/mark/git/feedstock/onnxruntime-feedstock claude --resume bceefe2e-0d08-4ad8-9b4c-3518466f1ccc ``` </details>
<details><summary>Claude's draft</summary> The osx_arm64 jobs failed compiling onnxruntime_autoep_test: the vendored googletest's gtest-printers.h formats std::chrono::time_point via std::format, whose floating-point path needs std::to_chars — gated by libc++ availability to macOS 13.4+, while MACOSX_DEPLOYMENT_TARGET is 11.0. main never hits this because its meta.yaml keeps gmock in host, so onnxruntime's FetchContent FIND_PACKAGE_ARGS resolves conda-forge's gtest/gmock instead of vendoring one. Restore that dep, scoped to osx — Linux and Windows are green with the vendored copy, and the megabuild prefers a minimal host env to keep the shared cmake cache stable. Added to both the staging and python stages to keep their dependency sets identical (cache-sharing requirement). Resume this Claude session: ``` cd /home/mark/git/feedstock/onnxruntime-feedstock claude --resume bceefe2e-0d08-4ad8-9b4c-3518466f1ccc ``` </details>
<details><summary>Claude's draft</summary>
The osx jobs now compile, pass all 10 ctest suites, and install — but fail
at packaging with rattler-build's "No license files were copied". That
error fires when ANY itemized license path matches nothing (the detailed
missing-path list goes to a log level the CI does not surface), and the
set of vendored _deps differs per platform (CoreML adds coremltools/fp16/
psimd on osx; deps provided from conda-forge, e.g. nlohmann_json/gtest on
osx, may not be vendored at all).
Replace the itemized _deps license list with globs:
build-ci/Release/_deps/*/LICENSE*
build-ci/Release/_deps/*/COPYING*
This ships the license of every dep actually vendored into the build on
each platform — including several that are compiled in but were previously
not shipped (mp11, date, dlpack, kleidiai, cutlass on cuda) — and cannot
break when the vendored set changes.
Resume this Claude session:
```
cd /home/mark/git/feedstock/onnxruntime-feedstock
claude --resume bceefe2e-0d08-4ad8-9b4c-3518466f1ccc
```
</details>
<details><summary>Claude's draft</summary> Replace the license globs with an explicit list, conditioned on exactly the variants that vendor each dependency. The per-variant sets were read from the packaging logs of the passing glob-based CI run: - base (all variants): LICENSE + abseil, date, dlpack, eigen (COPYING.MPL2 only, EIGEN_MPL2_ONLY=ON), flatbuffers, gsl, onnx, protobuf, pytorch_cpuinfo, re2, safeint - nlohmann_json: not osx (conda-forge host dep there, not vendored) - googletest: only native non-CUDA builds (tests off ⇒ never fetched), and not osx (conda-forge gtest/gmock there) - kleidiai: ARM targets (linux-aarch64, osx-arm64) - microsoft_wil: win - coremltools/fp16/psimd: osx (CoreML EP) Verified with rattler-build --render-only that each variant's rendered list matches what its CI packaging log actually copied. Not itemized: cutlass / cudnn_frontend on CUDA builds (parity with main, which never shipped them); can be added once a CUDA packaging log confirms the paths. Resume this Claude session: ``` cd /home/mark/git/feedstock/onnxruntime-feedstock claude --resume bceefe2e-0d08-4ad8-9b4c-3518466f1ccc ``` </details>
<details><summary>Claude's draft</summary> Implements @cbourjau's suggestion from conda-forge#196: onnxruntime 1.28.0 ships an execution provider plugin system (onnxruntime_BUILD_CUDA_EP_AS_PLUGIN=ON, see docs/cuda_plugin_ep/ upstream) that builds the CUDA EP as a standalone, Python-independent shared library loading into any onnxruntime core >= 1.24.4 via the EP plugin API with load-time API version negotiation. Recipe reorganization: - New output onnxruntime-ep-cuda (mirrors upstream's onnxruntime-ep-cuda12/13 wheel naming), built only on CUDA variants: configures with onnxruntime_BUILD_CUDA_EP_AS_PLUGIN=ON, ENABLE_PYTHON=OFF, builds only the onnxruntime_providers_cuda_plugin target, and ships just libonnxruntime_providers_cuda.so / onnxruntime_providers_cuda.dll. - The staged onnxruntime-build / -cpp / python outputs become CPU-only (skip: cuda_enabled). The CUDA python builds disappear entirely — GPU support comes from installing onnxruntime-ep-cuda next to the CPU package and registering via onnxruntime.register_execution_provider_library. - cuDNN and cuFFT are needed at build time (headers) but loaded lazily at runtime by the plugin; host deps kept conservative for now. - run_constraints document the 1.24.4 minimum core version. EXPLORATORY skips (marked in the recipe, to be removed before merge): only the 6 linux/win CUDA jobs build while iterating, since the CPU/osx/novec outputs are unchanged from conda-forge#196 and already green. Resume this Claude session: ``` cd /home/mark/git/feedstock/onnxruntime-feedstock claude --resume bceefe2e-0d08-4ad8-9b4c-3518466f1ccc ``` </details>
…026.08.09.00.32.18 Other tools: - conda-build 26.7.0 - rattler-build 0.72.2 - rattler-build-conda-compat 1.4.19
|
Hi! This is the friendly automated conda-forge-linting service. I just wanted to let you know that I linted all conda-recipes in your PR ( I do have some suggestions for making it better though... For recipe/recipe.yaml:
Documentation on acceptable licenses can be found conda-forge.org > Docs > Maintainer Documentation > Contributing packages > SPDX Identifiers and Expressions. This message was generated by GitHub Actions workflow run https://github.com/conda-forge/conda-forge-webservices/actions/runs/31313606262. Examine the logs at this URL for more detail. |
<details><summary>Claude's draft</summary> The plugin builds compiled fine (~1100 targets) but failed at license packaging: with onnxruntime_ENABLE_PYTHON=OFF the plugin-only configure never fetches dlpack, so the unconditional dlpack license entry matched nothing (rattler-build then reports only "No license files were copied"). Condition dlpack on non-CUDA variants, and itemize the two deps the plugin build newly vendors — cutlass and cudnn_frontend (filenames verified against the exact archives pinned in upstream cmake/deps.txt, both LICENSE.txt at the root). Verified the rendered CUDA list matches the failed job's actual '-- Fetch' set one for one; kleidiai on aarch64 and microsoft_wil on win (unconditional on WIN32) were confirmed still fetched in plugin mode. Resume this Claude session: ``` cd /home/mark/git/feedstock/onnxruntime-feedstock claude --resume bceefe2e-0d08-4ad8-9b4c-3518466f1ccc ``` </details>
|
I think we should start with a clean slate here. A lot has changed upstream. We should be able to do a clean rattler-build migration without any staging outputs when using the EP-plugin. |
You know I’m using 100% Claude. do you prefer to use an AI yourself? I’ve had a lot of success with conda-forge stuff and Claude. I’m mostly trying to find the good ideas In your cleanups before trying to cleanup the whole shared library situation ;) ill give Claude your prompt, but I just don’t want you to think I’m adding too much human value to this particular effort (I do stand by our previous discussion regarding unvendorinf. That was before I learned how to use AI lol) |
Exploratory follow-up to #196, implementing @cbourjau's suggestion (comment): use upstream's new execution provider plugin system to decouple the expensive CUDA build from Python.
This branch contains everything from #196 plus the plugin reorganization. If #196 merges first this rebases to just the plugin commits.
Upstream mechanics (onnxruntime 1.28.0,
docs/cuda_plugin_ep/)onnxruntime_BUILD_CUDA_EP_AS_PLUGIN=ONbuildsonnxruntime_providers_cuda_plugin— a standalone shared module with the canonical provider filename (libonnxruntime_providers_cuda.so/onnxruntime_providers_cuda.dll) registered under the canonical nameCUDAExecutionProvider. The legacy in-tree CUDA provider is not built in this mode.plugin-ep-cuda/MIN_ONNXRUNTIME_VERSION).onnxruntime-ep-cuda12/onnxruntime-ep-cuda13wheels.Recipe reorganization
onnxruntime-ep-cuda(one per platform × CUDA version, no Python dimension): configures withBUILD_CUDA_EP_AS_PLUGIN=ON,ENABLE_PYTHON=OFF, builds only the plugin target, ships just the provider library (lib/on unix,Library/bin/on win, matching upstream's install rule).onnxruntime-build/-cpp/python become CPU-only. The CUDA python matrix (previously 5 python versions × 2 CUDA versions × 3 platforms of full CUDA rebuilds) is gone.run_constraints: onnxruntime >=1.24.4documents the minimum core;__cudarun dep avoids needless downloads.Exploratory CI restriction (revert before merge)
Per-recipe
EXPLORATORYskips limit the matrix to the 6 linux/win CUDA jobs — the CPU/osx/novec outputs are byte-identical to #196 and already green there. Removing the top-level exploratory skips restores them.Open questions for review
cuda-plugin-ep=1build info, so the bundled auto-registration path is inert. Options: patchonnxruntime/__init__.pyto also probe$CONDA_PREFIX/lib, ship a smallonnxruntime-ep-cuda-pythonshim (upstream'sonnxruntime_ep_cudamodule), or document explicit registration.cudnnhost run-exports) since most users want Conv; upstream's design treats it as optional. Could be relaxed torun_constrained.onnxruntime-ep-cuda(one name, CUDA version via variant/build string) vs upstream'sonnxruntime-ep-cuda12/13split names.-cppCUDA consumers need anything beyondEnv::RegisterExecutionProviderLibrary(the C++ path works with the plugin as-is).CC @cbourjau — this is the shape you suggested; keen on your take on the open questions.