Lower CUDA plugin EP minimum ORT version to 1.24.4 with version-gated callbacks (#28824)
## Description
Lowers the minimum supported ONNX Runtime runtime version for the
standalone CUDA plugin EP from **1.26.0** to **1.24.4**, so the plugin
binary (built against the latest ORT headers) can be loaded by older ORT
runtimes. The plugin negotiates the API version at load time and only
advertises EP callbacks the negotiated runtime actually supports, so
newer features degrade gracefully on older runtimes instead of crashing.
## Motivation
The plugin is shipped as a separate package and is intended to run
against a range of base `onnxruntime` runtimes. The previous hard floor
of 1.26.0 was stricter than necessary: an audit of the `\since`
annotations shows the plugin only calls APIs introduced in 1.24 or
earlier (apart from the optional EP profiler, which is now
version-gated). 1.24.4 is also the floor already used by the WebGPU
plugin EP, so this aligns the two.
## Key Changes
| Area | Change |
|---|---|
| `plugin-ep-cuda/MIN_ONNXRUNTIME_VERSION` | `1.26.0` → `1.24.4` (single
source of truth for the floor) |
| `cmake/onnxruntime_providers_cuda_plugin.cmake` | Reads
`MIN_ONNXRUNTIME_VERSION` and bakes it into the DLL as the
`ORT_PLUGIN_EP_MIN_ORT_VERSION` compile definition |
| `cuda_plugin_ep.cc` | `CreateEpFactories()` negotiates the runtime API
version via `onnxruntime::ep::ApiInit(...)` instead of hard-coding
`GetApi(26)` |
| `cuda_plugin_utils.h` | Adds `CudaPluginEpOrtVersionSupported() =
min(CurrentOrtApiVersion(), ORT_API_VERSION)`; removes the hard-coded
min-version constant |
| 13 callback structs | Report `ort_version_supported`/`version` =
`CudaPluginEpOrtVersionSupported()` |
| `cuda_ep.cc` | **Defensive capability gating**: installs each newer
`OrtEp` callback only when the negotiated runtime is new enough —
`Sync`/`CreateProfiler` require ≥1.25, graph-capture set +
`GetAvailableResource` require ≥1.26; otherwise left null |
| `plugin-linux-cuda-test-stage.yml` | Adds a CI step that installs the
floor (`MIN_ONNXRUNTIME_VERSION`) base `onnxruntime` and runs the plugin
test against it, catching any accidental dependency on a newer API |
| Docs | New §2.6 "API Version Audit and Defensive Capability Gating" in
the design doc; QUICK_START min-version test recipe |
## API Version Audit
| API surface | Newest `\since` used |
|---|---|
| `OrtApi` direct calls | 1.23 |
| `OrtEpApi` direct calls | 1.24 |
| EP profiler API (only with `ENABLE_CUDA_PROFILING`) | 1.25 |
Apart from the optional EP profiler, every API the plugin calls is
`\since 1.24` or older, justifying the 1.24.4 floor. The profiler's
three `\since 1.25` functions are made unreachable on older runtimes by
gating the `CreateProfiler` callback.
## Testing Notes
- Incremental build on CUDA 12.8 / SM90 — clean, plugin `.so` relinked.
- `test_cuda_plugin_ep.py` against the latest runtime (1.28): **87/87
tests pass**.
- Plugin (built against latest headers) loaded into
`onnxruntime==1.24.4`: registers, enumerates all 8 GPUs, and runs
inference correctly with the newer callbacks left null.
- `lintrunner` clean on changed files.
- New CI step validates the plugin against the declared floor
automatically.