[Plugin EP] Add plugin EP Sync API (#27538)
This pull request introduces a new synchronization API for plugin
execution providers (EPs) in ONNX Runtime, and adds comprehensive test
infrastructure to verify its usage. The main theme is enabling EPs to
synchronize device operations, which is particularly important for IO
binding and async execution scenarios. The changes also update the test
framework to support and validate this new capability.
**Synchronization API for Plugin EPs:**
* Added a new optional `Sync` method to the `OrtEp` C API interface,
allowing EPs to block until all preceding device tasks are complete.
This is primarily used by IO binding to ensure device inputs are ready
before execution.
(`include/onnxruntime/core/session/onnxruntime_ep_c_api.h`)
* Implemented the `Sync` method in the example plugin EP, with a test
hook that increments a counter for verification purposes.
(`onnxruntime/test/autoep/library/example_plugin_ep/ep.cc`,
`onnxruntime/test/autoep/library/example_plugin_ep/ep.h`)
[[1]](diffhunk://#diff-60ddcfdf7fe7273a7f06c4c1eb39933737e6fe8c2f00bdf2e5f49c2d1f911fa4R187)
[[2]](diffhunk://#diff-60ddcfdf7fe7273a7f06c4c1eb39933737e6fe8c2f00bdf2e5f49c2d1f911fa4R589-R601)
[[3]](diffhunk://#diff-5e9391ab7d2d558c5fa992b5fc373add5c52225aa43ce1af323ffbd8c2b86733R105-R106)
**Test Infrastructure and Verification:**
* Added test hooks (`ExampleEpTestHooks_ResetSyncCount`,
`ExampleEpTestHooks_GetSyncCount`) to the example plugin EP, allowing
tests to reset and retrieve the sync call count.
(`onnxruntime/test/autoep/library/example_plugin_ep/ep_test_hooks.h`,
`onnxruntime/test/autoep/library/example_plugin_ep/ep_test_hooks.cc`)
[[1]](diffhunk://#diff-a587d529618260bec7cbecf107513dacb795fff9fb34ae99c3a2db36bdcc8befR1-R23)
[[2]](diffhunk://#diff-7123fbca69d2580f0483d6589817e275c05b086c1fb56281a83f0fb895bdc06fR1-R11)
* Updated test execution logic to load these hooks dynamically and
verify that the `Sync` method is called exactly once during inference
with IO binding. (`onnxruntime/test/autoep/test_execution.cc`)
[[1]](diffhunk://#diff-3e289607015487374dcf7d9ab1d73a2ca3c3e5a44cab5958e4334afcdd5f4e28R299-R358)
[[2]](diffhunk://#diff-3e289607015487374dcf7d9ab1d73a2ca3c3e5a44cab5958e4334afcdd5f4e28R1099-R1119)
**Plugin EP Interface Updates:**
* Extended the `PluginExecutionProvider` C++ interface to support the
new `Sync` method, delegating to the plugin EP if implemented.
(`onnxruntime/core/session/plugin_ep/ep_plugin_provider_interfaces.h`,
`onnxruntime/core/session/plugin_ep/ep_plugin_provider_interfaces.cc`)
[[1]](diffhunk://#diff-db92123bb63f8b1cc0a776ba3dcad95118826d031c8f65e79969cfaddb8c3e0aR117-R118)
[[2]](diffhunk://#diff-6dac10650c4e1c5a55b95378173b33e95b300bf7c2350d8476088693b98652a5R632-R638)
**Performance Test Framework Enhancements:**
* Added logic to detect if a plugin EP uses an NVIDIA GPU device,
enabling CUDA IO binding automatically in performance tests when
appropriate. (`onnxruntime/test/perftest/common_utils.cc`,
`onnxruntime/test/perftest/utils.h`,
`onnxruntime/test/perftest/ort_test_session.cc`)
[[1]](diffhunk://#diff-2b8b7de0106a523d40c40f901f6ff170bff722b0c147fbfec36b269e21c9526bR203-R221)
[[2]](diffhunk://#diff-228a0b2557ae67945d94db8f9e74bb523517c2aa738db91fcfdda0958fa65f6cR40-R41)
[[3]](diffhunk://#diff-f3908cf4d2982fd2b008beb8c951d9cab67b28cb07077493b8d1dd8b448d6e18R98-R108)
* Ensured that async execution is used in performance tests with IO
binding, relying on the new synchronization mechanism.
(`onnxruntime/test/perftest/ort_test_session.cc`)
[[1]](diffhunk://#diff-f3908cf4d2982fd2b008beb8c951d9cab67b28cb07077493b8d1dd8b448d6e18L57)
[[2]](diffhunk://#diff-f3908cf4d2982fd2b008beb8c951d9cab67b28cb07077493b8d1dd8b448d6e18R66-R69)
These changes collectively improve device synchronization support for
plugin EPs and provide robust testing to ensure correct behavior.This
pull request introduces support for synchronizing plugin execution
providers, especially for NVIDIA GPU devices, and refines the logic for
CUDA I/O binding in performance tests. The main changes include adding a
new `Sync` API for execution providers, updating the plugin EP interface
to use this API, and improving test session configuration for CUDA
devices.
### API and Interface Updates
* Added a new optional `Sync` method to the `OrtEp` struct in
`onnxruntime_ep_c_api.h`, allowing execution providers to block until
all device tasks are complete. This is primarily used to ensure inputs
are copied to the device before execution starts.
* Implemented the `Sync` method in the `PluginExecutionProvider` class
and its interface, enabling plugin EPs to support device synchronization
if available.
[[1]](diffhunk://#diff-6dac10650c4e1c5a55b95378173b33e95b300bf7c2350d8476088693b98652a5R632-R638)
[[2]](diffhunk://#diff-db92123bb63f8b1cc0a776ba3dcad95118826d031c8f65e79969cfaddb8c3e0aR117-R118)
### Performance Test Improvements
* Added a utility function `UsesNvidiaDevice` to detect if any
registered plugin EP uses an NVIDIA GPU device, improving test
configuration logic.
[[1]](diffhunk://#diff-2b8b7de0106a523d40c40f901f6ff170bff722b0c147fbfec36b269e21c9526bR203-R221)
[[2]](diffhunk://#diff-228a0b2557ae67945d94db8f9e74bb523517c2aa738db91fcfdda0958fa65f6cR40-R41)
### Motivation and Context
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->