Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3694c53
Implement EP API for WebGPU EP
fs-eire Mar 3, 2026
7f0b143
integrate with adapters change of LoggingManager
fs-eire Mar 8, 2026
ebf1a1c
add pipeline job for plugin EP build
fs-eire Feb 26, 2026
078cb4a
resolve comments - update upsamplebase.h
fs-eire Mar 11, 2026
9336a63
remove out-of-dated todos.
fs-eire Mar 11, 2026
53c8942
Apply suggestions from code review
fs-eire Mar 12, 2026
b5a9004
resolve comments - lock on kernel registry access
fs-eire Mar 12, 2026
42e458e
substr
fs-eire Mar 12, 2026
51edd07
unittest
fs-eire Mar 12, 2026
8a51859
resolve comments (part.1)
fs-eire Mar 14, 2026
fd6bd72
resolve comments (part.2)
fs-eire Mar 14, 2026
17bcb6c
resolve comments (part.3)
fs-eire Mar 14, 2026
569f048
resolve comments (part.4)
fs-eire Mar 14, 2026
ea5a74a
resolve comments (part.5)
fs-eire Mar 14, 2026
d11b669
use onnxruntime_add_shared_library_module
fs-eire Mar 14, 2026
16503cd
build vulkan also
fs-eire Mar 16, 2026
f509662
allow lazy initialized allocator
fs-eire Mar 19, 2026
741e083
resolve comments (MakeEP)
fs-eire Mar 19, 2026
666772c
resolve comments (MakeEP, part.2)
fs-eire Mar 19, 2026
399c419
Update onnxruntime/test/util/default_providers.cc
fs-eire Mar 20, 2026
76fa10b
resolve comments (exceptions)
fs-eire Mar 20, 2026
8fa7314
resolve comments (forward declaration)
fs-eire Mar 20, 2026
cdabb41
resolve comments (candidate nodes)
fs-eire Mar 21, 2026
74606d9
Revert "resolve comments (forward declaration)"
fs-eire Mar 21, 2026
3ad62f5
resolve comments (CopyTensorImpl)
fs-eire Mar 21, 2026
2e6f36e
resolve comments
fs-eire Mar 23, 2026
c11dcb3
resolve comments
fs-eire Mar 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .github/workflows/windows_webgpu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,86 @@ jobs:
working-directory: ${{ github.workspace }}\csharp
continue-on-error: true

webgpu_plugin_build_x64_RelWithDebInfo:
runs-on: [
"self-hosted",
"1ES.Pool=onnxruntime-github-Win2022-GPU-A10",
"JobId=webgpu_plugin_build_x64_RelWithDebInfo-${{ github.run_id }}-${{ github.run_number }}-${{ github.run_attempt }}"
]
timeout-minutes: 300
env:
OnnxRuntimeBuildDirectory: ${{ github.workspace }}
setVcvars: true
ALLOW_RELEASED_ONNX_OPSET_ONLY: "0"
DocUpdateNeeded: false
NVIDIA_TF32_OVERRIDE: "0"
ONNXRUNTIME_TEST_GPU_DEVICE_ID: "0"
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
submodules: none

- name: Setup Python 3.12
uses: actions/setup-python@v6
with:
python-version: "3.12"
architecture: x64

- name: Locate vcvarsall and Setup Env
uses: ./.github/actions/locate-vcvarsall-and-setup-env
with:
architecture: x64

- name: Install python modules
run: python -m pip install -r tools\ci_build\github\windows\python\requirements.txt
shell: cmd
working-directory: ${{ github.workspace }}

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "20.x"

- uses: actions/cache@v5
id: onnx-node-tests-cache
with:
path: ${{ github.workspace }}/js/test/
key: onnxnodetests-${{ hashFiles('js/scripts/prepare-onnx-node-tests.ts') }}

- name: Build and Test
shell: pwsh
run: |
python.exe ${{ github.workspace }}\tools\ci_build\build.py `
--config RelWithDebInfo `
--build_dir ${{ github.workspace }} `
--skip_submodule_sync `
--parallel `
--use_binskim_compliant_compile_flags `
--cmake_generator "Visual Studio 17 2022" `
--enable_onnx_tests `
--use_webgpu shared_lib `
--wgsl_template static `
--use_vcpkg --use_vcpkg_ms_internal_asset_cache `
--cmake_extra_defines onnxruntime_BUILD_UNIT_TESTS=ON onnxruntime_ENABLE_DAWN_BACKEND_D3D12=1 onnxruntime_ENABLE_DAWN_BACKEND_VULKAN=1 `
--disable_rtti `
--enable_lto

if ($lastExitCode -ne 0) {
exit $lastExitCode
}

- name: Publish artifacts
uses: actions/upload-artifact@v4
with:
name: webgpu-plugin-binaries
path: |
${{ github.workspace }}/RelWithDebInfo/RelWithDebInfo/onnxruntime_providers_webgpu.dll
${{ github.workspace }}/RelWithDebInfo/RelWithDebInfo/onnxruntime_providers_webgpu.pdb
${{ github.workspace }}/RelWithDebInfo/RelWithDebInfo/dxcompiler.dll
${{ github.workspace }}/RelWithDebInfo/RelWithDebInfo/dxil.dll

webgpu_external_dawn_build_x64_RelWithDebInfo:
runs-on: [
"self-hosted",
Expand Down
8 changes: 7 additions & 1 deletion cmake/onnxruntime_providers_webgpu.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
endif()
source_group(TREE ${ONNXRUNTIME_ROOT} FILES ${onnxruntime_providers_webgpu_cc_srcs})

onnxruntime_add_shared_library(onnxruntime_providers_webgpu ${onnxruntime_providers_webgpu_cc_srcs})
onnxruntime_add_shared_library_module(onnxruntime_providers_webgpu ${onnxruntime_providers_webgpu_cc_srcs})
onnxruntime_add_include_to_target(onnxruntime_providers_webgpu
${REPO_ROOT}/include/onnxruntime/core/session
onnxruntime_common
Expand Down Expand Up @@ -119,6 +119,12 @@
if (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
message(FATAL_ERROR "WebGPU EP shared library build is not supported on Emscripten. Please use static library build.")
endif()

# Configure precompiled headers for shared library build
# PCH ensures ep/adapters.h is included first and improves compilation speed
target_precompile_headers(onnxruntime_providers_webgpu PRIVATE
"${REPO_ROOT}/include/onnxruntime/ep/adapters.h"
)
Comment thread
fs-eire marked this conversation as resolved.
endif()

set_target_properties(onnxruntime_providers_webgpu PROPERTIES CXX_STANDARD_REQUIRED ON)
Expand Down
13 changes: 13 additions & 0 deletions cmake/onnxruntime_unittests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,18 @@ function(onnxruntime_apply_test_target_workarounds target)
endif()
endfunction()

# Set environment variables for plugin EP tests when run via CTest.
function(onnxruntime_set_plugin_ep_test_environment target)
if(onnxruntime_USE_WEBGPU AND onnxruntime_USE_EP_API_ADAPTERS)
set(ORT_PLUGIN_EP_JSON_CONFIG "{\"ep_library_registration_name\": \"WebGPU_PluginEP\", \"ep_library_path\": \"$<TARGET_FILE_NAME:onnxruntime_providers_webgpu>\", \"selected_ep_name\": \"WebGpuExecutionProvider\"}")
set_tests_properties(${target} PROPERTIES
ENVIRONMENT "ORT_UNIT_TEST_MAIN_DYNAMIC_PLUGIN_EP_CONFIG_JSON=${ORT_PLUGIN_EP_JSON_CONFIG}"
)
# TODO: add for other plugin EPs if needed
# elseif()
endif()
endfunction()

function(onnxruntime_apply_emscripten_test_link_settings target)
if (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
set_target_properties(${target} PROPERTIES LINK_DEPENDS ${TEST_SRC_DIR}/wasm/onnxruntime_test_adapter.js)
Expand Down Expand Up @@ -1250,6 +1262,7 @@ block()
)

onnxruntime_apply_test_target_workarounds(onnxruntime_provider_test)
onnxruntime_set_plugin_ep_test_environment(onnxruntime_provider_test)

# Expose QNN SDK headers to unit tests via an interface target
if(onnxruntime_USE_QNN)
Expand Down
37 changes: 33 additions & 4 deletions include/onnxruntime/ep/adapter/allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,50 @@ namespace adapter {
/// </summary>
class Allocator : public OrtAllocator {
public:
/**
* Create from an existing AllocatorPtr.
*/
explicit Allocator(const OrtMemoryInfo* memory_info, AllocatorPtr impl)
: OrtAllocator{}, memory_info_(memory_info), impl_(impl) {
: Allocator{memory_info} {
ORT_ENFORCE(impl != nullptr, "Allocator implementation cannot be null.");
impl_ = impl;
}

using AllocatorFactory = AllocatorPtr (*)(const OrtMemoryInfo& memory_info);

/**
* Create from an AllocatorFactory, which will be called lazily when the first allocation is made.
*/
explicit Allocator(const OrtMemoryInfo* memory_info, AllocatorFactory get_allocator_impl)
: Allocator{memory_info} {
get_allocator_impl_ = get_allocator_impl;
}

private:
explicit Allocator(const OrtMemoryInfo* memory_info)
: OrtAllocator{}, memory_info_(memory_info) {
version = ORT_API_VERSION;
Alloc = AllocImpl;
Free = FreeImpl;
Info = InfoImpl;
}
AllocatorPtr GetImpl() {
if (!impl_) {
std::call_once(init_flag_, [this]() {
impl_ = get_allocator_impl_(*memory_info_);
});
}
Comment thread
fs-eire marked this conversation as resolved.
return impl_;
}

private:
static void* ORT_API_CALL AllocImpl(OrtAllocator* this_ptr, size_t size) noexcept {
auto* allocator = static_cast<Allocator*>(this_ptr);
return allocator->impl_->Alloc(size);
return allocator->GetImpl()->Alloc(size);
}

static void ORT_API_CALL FreeImpl(OrtAllocator* this_ptr, void* p) noexcept {
auto* allocator = static_cast<Allocator*>(this_ptr);
allocator->impl_->Free(p);
allocator->GetImpl()->Free(p);
}

static const OrtMemoryInfo* ORT_API_CALL InfoImpl(const OrtAllocator* this_ptr) noexcept {
Expand All @@ -44,6 +71,8 @@ class Allocator : public OrtAllocator {

const OrtMemoryInfo* memory_info_;
AllocatorPtr impl_;
AllocatorFactory get_allocator_impl_;
std::once_flag init_flag_;
};

} // namespace adapter
Expand Down
1 change: 1 addition & 0 deletions include/onnxruntime/ep/adapter/ep.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class Ep : public OrtEp {
profiler_{impl_->GetProfiler()},
temp_space_cpu_allocator_{temp_space_cpu_allocator},
temp_space_allocator_{temp_space_allocator} {
ort_version_supported = ORT_API_VERSION;
}

public:
Expand Down
2 changes: 1 addition & 1 deletion include/onnxruntime/ep/adapter/op_kernel_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "tensor_helper.h"

namespace onnxruntime {
struct DataTransferManager;
class DataTransferManager;
struct IExecutionProvider;
} // namespace onnxruntime

Expand Down
21 changes: 21 additions & 0 deletions include/onnxruntime/ep/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,24 @@
OrtStatus* _status = (status_expr); \
Ort::Status _ignored{_status}; \
} while (false)

// Helper macros to convert exceptions to OrtStatus* return values.
// Usage:
// EXCEPTION_TO_RETURNED_STATUS_BEGIN
// ... code that may throw ...
// EXCEPTION_TO_RETURNED_STATUS_END
#define EXCEPTION_TO_RETURNED_STATUS_BEGIN try {
#define EXCEPTION_TO_RETURNED_STATUS_END \
} \
catch (const Ort::Exception& ex) { \
Ort::Status status(ex); \
return status.release(); \
} \
catch (const std::exception& ex) { \
Ort::Status status(ex.what(), ORT_EP_FAIL); \
return status.release(); \
} \
catch (...) { \
Ort::Status status("Unknown exception", ORT_EP_FAIL); \
return status.release(); \
}
13 changes: 11 additions & 2 deletions onnxruntime/core/providers/cpu/tensor/upsamplebase.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,17 @@ class UpsampleBase {
if (scales_input_idx_ > 0) {
const Tensor* scale;
bool get_scale = info.TryGetConstantInput(scales_input_idx_, &scale);
auto x_shape = node.InputDefs()[0]->Shape();
int64_t rank = x_shape ? x_shape->dim_size() : -1;
int64_t rank = -1;
if constexpr (std::is_same_v<KernelInfoType, onnxruntime::OpKernelInfo>) {
auto x_shape = node.InputDefs()[0]->Shape();
if (x_shape != nullptr) {
rank = x_shape->dim_size();
}
} else {
auto type_info = info.GetKernelInfo().GetInputTypeInfo(0);
auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
rank = static_cast<int64_t>(tensor_info.GetDimensionsCount());
}
Comment thread
fs-eire marked this conversation as resolved.
if (get_scale && scale->Shape().Size() > 0 && ((opset < 18) || (rank > 0 && opset >= 18))) {
ORT_THROW_IF_ERROR(ParseScalesData(scale, scales_, rank));
scales_cached_ = true;
Expand Down
4 changes: 4 additions & 0 deletions onnxruntime/core/providers/webgpu/compute_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ class ComputeContextBase {
// Get the logger.
//
inline const logging::Logger& Logger() const {
#if defined(ORT_USE_EP_API_ADAPTERS)
return ep_.GetEpLogger();
#else
return *ep_.GetLogger();
#endif
}

//
Expand Down
16 changes: 15 additions & 1 deletion onnxruntime/core/providers/webgpu/controlflow/if.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@

#include "core/providers/webgpu/controlflow/if.h"

#if defined(ORT_USE_EP_API_ADAPTERS)
#include "core/framework/error_code_helper.h"
#endif

using namespace ONNX_NAMESPACE;
using namespace onnxruntime::common;

Expand Down Expand Up @@ -68,10 +72,20 @@ ONNX_OPERATOR_KERNEL_EX(If,
.TypeConstraint("V", DataTypeImpl::AllFixedSizeTensorTypes()),
If);

#if !defined(ORT_USE_EP_API_ADAPTERS)
Status If::Compute(OpKernelContext* ctx) const {
// call the base CPU version.
return onnxruntime::If::Compute(ctx);
}
#else
Status If::CreateControlFlowKernelImpl(const OrtKernelInfo* info, OrtKernelImpl** impl) {
return ToStatusAndRelease(ep::Api().ep.CreateIfKernel(info, impl));
}

Status If::Compute(OpKernelContext* /*ctx*/) const {
return ORT_MAKE_STATUS(ONNXRUNTIME, EP_FAIL, "If operator should be handled by ORT core.");
}
#endif

} // namespace webgpu
} // namespace onnxruntime
} // namespace onnxruntime
15 changes: 14 additions & 1 deletion onnxruntime/core/providers/webgpu/controlflow/if.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
namespace onnxruntime {
namespace webgpu {

#if !defined(ORT_USE_EP_API_ADAPTERS)

// Use the CPU implementation for the logic
class If final : public onnxruntime::If {
public:
Expand All @@ -18,5 +20,16 @@ class If final : public onnxruntime::If {
Status Compute(OpKernelContext* ctx) const override;
};

#else

class If final : public OpKernel {
public:
If(const OpKernelInfo& info) : OpKernel(info) {}

Status CreateControlFlowKernelImpl(const OrtKernelInfo* info, OrtKernelImpl** impl) override;
Status Compute(OpKernelContext* ctx) const override;
};
#endif

} // namespace webgpu
} // namespace onnxruntime
} // namespace onnxruntime
Loading
Loading