[Cuda Plugin] Refactor CUDA ops — Move more shared CPU/CUDA helper code from .cc to headers (Part 2) (#27628)
## Description
This PR continues the refactoring effort started in PR #27617, moving
additional CPU operator helper function implementations from `.cc` files
into `.h` headers using the `#ifdef SHARED_PROVIDER` / `#else` inline
pattern. This is a prerequisite for the **CUDA Plugin EP** work, where
CUDA kernels are built into a standalone shared library
(`libonnxruntime_providers_cuda_plugin.so`) that cannot link against the
CPU provider's `.cc` object files.
### Why This Refactoring Is Needed
The CUDA Plugin EP compiles CUDA operator kernels into a separate shared
library that communicates with the ORT core through the ORT EP Plugin
API. In this architecture, kernel source files **cannot** depend on
framework-internal symbols that live in the CPU provider static library
(`libonnxruntime_providers.a`). Many CUDA kernels inherit from CPU base
classes and call shared helper/validation methods whose implementations
currently live in CPU `.cc` files.
In the in-tree CUDA EP build (`SHARED_PROVIDER` mode), these helpers are
accessed through the `ProviderHostCPU` DLL-boundary virtual table
bridge. However, the plugin EP does not use this bridge — it uses EP API
adapters and force-included headers instead. To make these helpers
available in the plugin build without duplicating code, this PR moves
the implementations into headers as `inline` functions under `#ifndef
SHARED_PROVIDER` guards. The `SHARED_PROVIDER` (in-tree) build path
retains the existing declaration-only signatures that route through
`ProviderHostCPU`.
### Refactoring Patterns Used
1. **Inline move**: Function body moved from `.cc` to `.h`, wrapped in
`#ifndef SHARED_PROVIDER` with `inline` linkage. The `#ifdef
SHARED_PROVIDER` path keeps the original declaration.
2. **Template-on-context**: Methods like `PrepareCompute`,
`PrepareForCompute`, and `GetPresent` are templatized on
`KernelContextType` so they work with both `OpKernelContext` (in-tree)
and the plugin EP's adapter context.
3. **Template-on-info**: Constructors and initialization methods (e.g.,
`RoiAlignBase`, `CropBase`, `SpaceDepthBase`) are templatized on
`KernelInfoType` with `info.template GetAttr<T>(...)` calls, making them
compatible with both `OpKernelInfo` and the plugin's
`OpKernelInfoAdapter`.
4. **Helper extraction**: Free helper functions (e.g.,
`CheckROIAlignValidInput`, `GetAxis`, `AdjustOutputSizeAsPolicy`) moved
inline into headers.
## Summary of Changes
### Helper functions moved from `.cc` to `.h` (inline under `#ifndef
SHARED_PROVIDER`)
| Operator | Header File | Functions Moved |
|----------|-------------|-----------------|
| **AttentionBase** | `contrib_ops/cpu/bert/attention_base.h` |
`AttentionBase::CheckInputs` (both overloads),
`AttentionBase::CheckMask`, `AttentionBase::GetPresent` (templatized on
`TOpKernelContext`) |
| **LongformerAttentionBase** |
`contrib_ops/cpu/bert/longformer_attention_base.h` |
`LongformerAttentionBase::CheckInputs` |
| **CumSum** | `cpu/math/cumsum.h` | `GetAxis` (free function) |
| **RoiAlign** | `cpu/object_detection/roialign.h` |
`CheckROIAlignValidInput` (free function), `RoiAlignBase` constructor
templatized on `TKernelInfo` |
| **Concat** | `cpu/tensor/concatbase.h` |
`ConcatBase::PrepareForCompute` (templatized, delegates to
`PrepareForComputeImpl`) |
| **Gather** | `cpu/tensor/gatherbase.h` |
`GatherBase::PrepareForCompute` (templatized, delegates to
`PrepareForComputeImpl`) |
| **Unsqueeze** | `cpu/tensor/unsqueeze.h` |
`UnsqueezeBase::PrepareCompute` (templatized on `KernelContextType`) |
| **Upsample** | `cpu/tensor/upsamplebase.h` |
`UpsampleBase::AdjustOutputSizeAsPolicy`,
`upsamplebase_helper::AdjustOutputSizeAsPolicy` (free helper) |
### Constructor templatization (for plugin EP adapter compatibility)
| Class | Header File | Change |
|-------|-------------|--------|
| **CropBase** | `contrib_ops/cpu/crop.h` | Constructor templatized on
`KernelInfoType`, `GetAttrsOrDefault` calls use `info.template` syntax |
| **SpaceDepthBase** | `cpu/tensor/space_depth_ops.h` | Constructor
templatized on `KernelInfoType`, `GetAttr` call uses `info.template`
syntax |
| **RoiAlignBase** | `cpu/object_detection/roialign.h` | Constructor
templatized on `TKernelInfo`, all `GetAttr` calls use `info.template`
syntax |
### CUDA-side updates
| File | Change |
|------|--------|
| `cuda/tensor/upsample.cc` | Added explicit template instantiations for
`Upsample<float>`, `Upsample<double>`, `Upsample<MLFloat16>`,
`Upsample<int32_t>`, `Upsample<uint8_t>` (needed because
`AdjustOutputSizeAsPolicy` implementation moved to header) |
### Files with code removed (moved to headers)
| Source File | Lines Removed | Moved To |
|-------------|---------------|----------|
| `contrib_ops/cpu/bert/attention_base.cc` | ~333 | `attention_base.h` |
| `contrib_ops/cpu/bert/longformer_attention_base.cc` | ~133 |
`longformer_attention_base.h` |
| `cpu/math/cumsum.cc` | ~23 | `cumsum.h` |
| `cpu/object_detection/roialign.cc` | ~74 | `roialign.h` |
| `cpu/tensor/concat.cc` | ~8 | `concatbase.h` |
| `cpu/tensor/gather.cc` | ~4 | `gatherbase.h` |
| `cpu/tensor/unsqueeze.cc` | ~51 | `unsqueeze.h` |
| `cpu/tensor/upsample.cc` | ~44 | `upsamplebase.h` |
## Testing
- Existing unit tests cover all affected operators (Attention,
LongformerAttention, CumSum, RoiAlign, Concat, Gather, Unsqueeze,
Upsample, Crop, SpaceToDepth/DepthToSpace).
- No behavioral changes — all function logic is identical; only the
location (header vs. source) and linkage (inline vs. external) changed.
- The `SHARED_PROVIDER` code path (in-tree CUDA EP build) is unchanged —
declarations remain and route through the existing `ProviderHostCPU`
bridge.
## Motivation and Context
This is part of the ongoing CUDA Plugin EP effort to build CUDA kernels
as a standalone shared library that can be updated independently of the
ORT core. The refactoring enables additional CUDA operators to compile
in the plugin build by making their CPU-side validation and preparation
helpers available as header-inline functions.
This PR is a direct continuation of PR #27617 which applied the same
pattern to Slice, Split, ScatterND, Tile, Pad, BiasGelu, EmbedLayerNorm,
and NonMaxSuppression operators.