Skip to content

Commit 94e7a1c

Browse files
authored
Initial change to enable WebGPU EP to suport plugin API (#25705)
### Description This is the first PR among a list of PRs to make WebGPU EP able to use the plugin API (EP ABI). This PR adds new build flags for WebGPU: - `--use_webgpu shared_lib` to enable building WebGPU EP based on the plugin API (EP ABI). - keep `--use_webgpu` or `--use_webgpu static_lib` behavior no change. Currently `--use_webgpu shared_lib` will fail, but it is fine because no one is using it. #### Why making small changes Huge PR is very difficult to review. Splitting a huge PR into multiple ones has the benefits that each small PR is relatively easier to review. #### Plan - [x] STEP.1 - Introduce build flags (this PR) - [ ] STEP.2 - Changes some macros and util functions to support both static and shared - [ ] STEP.3 - Core implementation of EP API based WebGPU EP - [ ] STEP.4 - Builds/Tests/etc.
1 parent 7ad0de5 commit 94e7a1c

22 files changed

+264
-39
lines changed

cmake/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ option(onnxruntime_USE_XNNPACK "Build with XNNPACK support. Provides an alternat
142142
option(onnxruntime_USE_WEBNN "Build with WebNN support. Enable hardware acceleration in web browsers." OFF)
143143
option(onnxruntime_USE_WEBGPU "Build with WebGPU support. Enable WebGPU via C/C++ interface." OFF)
144144
option(onnxruntime_WGSL_TEMPLATE "Specify the code generator for WGSL template. Default is static." "static")
145+
option(onnxruntime_BUILD_WEBGPU_EP_STATIC_LIB "Build WebGPU EP as a static library" OFF)
145146
option(onnxruntime_USE_EXTERNAL_DAWN "Build with treating Dawn as external dependency. Will not link Dawn at build time." OFF)
146147
option(onnxruntime_CUSTOM_DAWN_SRC_PATH "Path to custom Dawn src dir.")
147148
option(onnxruntime_BUILD_DAWN_SHARED_LIBRARY "Build Dawn as a shared library" OFF)
@@ -978,8 +979,13 @@ if (onnxruntime_USE_WEBGPU)
978979
endif()
979980

980981
if (onnxruntime_BUILD_DAWN_SHARED_LIBRARY)
981-
list(APPEND ORT_PROVIDER_FLAGS -DBUILD_DAWN_SHARED_LIBRARY=1)
982+
if (onnxruntime_BUILD_WEBGPU_EP_STATIC_LIB)
983+
list(APPEND ORT_PROVIDER_FLAGS -DBUILD_DAWN_SHARED_LIBRARY=1)
984+
else()
985+
message(FATAL_ERROR "onnxruntime_BUILD_WEBGPU_EP_STATIC_LIB=OFF is not supported with onnxruntime_BUILD_DAWN_SHARED_LIBRARY=ON")
986+
endif()
982987
endif()
988+
983989
if (onnxruntime_USE_EXTERNAL_DAWN)
984990
list(APPEND ORT_PROVIDER_FLAGS -DUSE_EXTERNAL_DAWN=1)
985991
endif()

cmake/onnxruntime.cmake

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,6 @@ set(onnxruntime_INTERNAL_PROVIDER_LIBRARIES
225225
${PROVIDERS_RKNPU}
226226
${PROVIDERS_VSINPU}
227227
${PROVIDERS_XNNPACK}
228-
${PROVIDERS_WEBGPU}
229228
${PROVIDERS_WEBNN}
230229
${PROVIDERS_AZURE}
231230
${PROVIDERS_INTERNAL_TESTING}
@@ -235,6 +234,10 @@ if (onnxruntime_BUILD_QNN_EP_STATIC_LIB)
235234
list(APPEND onnxruntime_INTERNAL_PROVIDER_LIBRARIES onnxruntime_providers_qnn)
236235
endif()
237236

237+
if (onnxruntime_BUILD_WEBGPU_EP_STATIC_LIB)
238+
list(APPEND onnxruntime_INTERNAL_PROVIDER_LIBRARIES onnxruntime_providers_webgpu)
239+
endif()
240+
238241
# This list is a reversed topological ordering of library dependencies.
239242
# Earlier entries may depend on later ones. Later ones should not depend on earlier ones.
240243
set(onnxruntime_INTERNAL_LIBRARIES

cmake/onnxruntime_providers_webgpu.cmake

Lines changed: 111 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
endif()
77

88
add_compile_definitions(USE_WEBGPU=1)
9+
if(onnxruntime_BUILD_WEBGPU_EP_STATIC_LIB)
10+
add_compile_definitions(BUILD_WEBGPU_EP_STATIC_LIB=1)
11+
endif()
12+
913
if (onnxruntime_ENABLE_WEBASSEMBLY_THREADS)
1014
add_definitions(-DENABLE_WEBASSEMBLY_THREADS=1)
1115
endif()
@@ -20,20 +24,108 @@
2024
elseif (NOT onnxruntime_WGSL_TEMPLATE STREQUAL "static")
2125
message(FATAL_ERROR "Unsupported value for onnxruntime_WGSL_TEMPLATE: ${onnxruntime_WGSL_TEMPLATE}. Supported values are 'static' or 'dynamic'.")
2226
endif()
27+
2328
file(GLOB_RECURSE onnxruntime_providers_webgpu_cc_srcs CONFIGURE_DEPENDS
2429
"${ONNXRUNTIME_ROOT}/core/providers/webgpu/*.h"
2530
"${ONNXRUNTIME_ROOT}/core/providers/webgpu/*.cc"
2631
)
2732
if(NOT onnxruntime_DISABLE_CONTRIB_OPS)
28-
source_group(TREE ${ONNXRUNTIME_ROOT} FILES ${onnxruntime_webgpu_contrib_ops_cc_srcs})
2933
list(APPEND onnxruntime_providers_webgpu_cc_srcs ${onnxruntime_webgpu_contrib_ops_cc_srcs})
3034
endif()
3135

32-
source_group(TREE ${REPO_ROOT} FILES ${onnxruntime_providers_webgpu_cc_srcs})
33-
onnxruntime_add_static_library(onnxruntime_providers_webgpu ${onnxruntime_providers_webgpu_cc_srcs})
34-
target_compile_features(onnxruntime_providers_webgpu PRIVATE cxx_std_20)
35-
onnxruntime_add_include_to_target(onnxruntime_providers_webgpu
36-
onnxruntime_common onnx onnx_proto flatbuffers::flatbuffers Boost::mp11 safeint_interface)
36+
if(onnxruntime_BUILD_WEBGPU_EP_STATIC_LIB)
37+
#
38+
# Build WebGPU EP as a static library
39+
#
40+
41+
# For static library build, exclude the 'ep' folder
42+
file(GLOB_RECURSE ep_files_to_exclude
43+
"${ONNXRUNTIME_ROOT}/core/providers/webgpu/ep/*.h"
44+
"${ONNXRUNTIME_ROOT}/core/providers/webgpu/ep/*.cc"
45+
)
46+
list(REMOVE_ITEM onnxruntime_providers_webgpu_cc_srcs ${ep_files_to_exclude})
47+
48+
source_group(TREE ${ONNXRUNTIME_ROOT} FILES ${onnxruntime_providers_webgpu_cc_srcs})
49+
onnxruntime_add_static_library(onnxruntime_providers_webgpu ${onnxruntime_providers_webgpu_cc_srcs})
50+
onnxruntime_add_include_to_target(onnxruntime_providers_webgpu
51+
onnxruntime_common onnx onnx_proto flatbuffers::flatbuffers Boost::mp11 safeint_interface)
52+
else()
53+
#
54+
# Build WebGPU EP as a shared library
55+
#
56+
if(WIN32)
57+
# Sets the DLL version info on Windows: https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource
58+
list(APPEND onnxruntime_providers_webgpu_cc_srcs "${ONNXRUNTIME_ROOT}/core/providers/webgpu/ep/versioninfo.rc")
59+
endif()
60+
source_group(TREE ${ONNXRUNTIME_ROOT} FILES ${onnxruntime_providers_webgpu_cc_srcs})
61+
62+
onnxruntime_add_shared_library(onnxruntime_providers_webgpu ${onnxruntime_providers_webgpu_cc_srcs})
63+
onnxruntime_add_include_to_target(onnxruntime_providers_webgpu
64+
${REPO_ROOT}/include/onnxruntime/core/session
65+
onnxruntime_common
66+
onnx
67+
onnx_proto
68+
flatbuffers::flatbuffers
69+
Boost::mp11
70+
safeint_interface)
71+
72+
target_link_libraries(onnxruntime_providers_webgpu PRIVATE
73+
onnxruntime_optimizer
74+
onnxruntime_providers
75+
onnxruntime_lora
76+
onnxruntime_framework
77+
onnxruntime_graph
78+
onnxruntime_util
79+
${ONNXRUNTIME_MLAS_LIBS}
80+
onnxruntime_common
81+
onnxruntime_flatbuffers
82+
${onnxruntime_EXTERNAL_LIBRARIES}
83+
)
84+
85+
# Add ONNX compiler definitions
86+
add_definitions("-DONNX_ML=1")
87+
add_definitions("-DONNX_NAMESPACE=onnx")
88+
add_definitions("-DONNX_USE_LITE_PROTO=1")
89+
90+
# Set preprocessor definitions used in onnxruntime_providers_webgpu.rc
91+
if(WIN32)
92+
set(WEBGPU_DLL_FILE_DESCRIPTION "ONNX Runtime WebGPU Provider")
93+
94+
target_compile_definitions(onnxruntime_providers_webgpu PRIVATE FILE_DESC=\"${WEBGPU_DLL_FILE_DESCRIPTION}\")
95+
target_compile_definitions(onnxruntime_providers_webgpu PRIVATE FILE_NAME=\"onnxruntime_providers_webgpu.dll\")
96+
endif()
97+
98+
# Set linker flags for function(s) exported by EP DLL
99+
if(UNIX)
100+
if (APPLE)
101+
set_property(TARGET onnxruntime_providers_webgpu APPEND_STRING PROPERTY LINK_FLAGS
102+
"-Xlinker -dead_strip")
103+
elseif (NOT CMAKE_SYSTEM_NAME MATCHES "AIX")
104+
target_link_options(onnxruntime_providers_webgpu PRIVATE
105+
"LINKER:--version-script=${ONNXRUNTIME_ROOT}/core/providers/webgpu/ep/version_script.lds"
106+
"LINKER:--gc-sections"
107+
"LINKER:-rpath=\$ORIGIN")
108+
# TODO: -z noexecstack
109+
endif()
110+
elseif(WIN32)
111+
set_property(TARGET onnxruntime_providers_webgpu APPEND_STRING PROPERTY LINK_FLAGS
112+
"-DEF:${ONNXRUNTIME_ROOT}/core/providers/webgpu/ep/symbols.def")
113+
else()
114+
message(FATAL_ERROR "onnxruntime_providers_webgpu unknown platform, need to specify shared library exports for it")
115+
endif()
116+
117+
set_target_properties(onnxruntime_providers_webgpu PROPERTIES LINKER_LANGUAGE CXX)
118+
119+
if (onnxruntime_BUILD_CACHE)
120+
message(FATAL_ERROR "WebGPU EP shared library build does not support build cache. Please disable build cache or use static library build.")
121+
endif()
122+
if (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
123+
message(FATAL_ERROR "WebGPU EP shared library build is not supported on Emscripten. Please use static library build.")
124+
endif()
125+
endif()
126+
127+
set_target_properties(onnxruntime_providers_webgpu PROPERTIES CXX_STANDARD_REQUIRED ON)
128+
set_target_properties(onnxruntime_providers_webgpu PROPERTIES FOLDER "ONNXRuntime")
37129

38130
if (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
39131
# target "emdawnwebgpu_c" is created by Dawn, including "-fno-exceptions" in its compile options by default.
@@ -89,7 +181,7 @@
89181
set(onnxruntime_providers_webgpu_dll_deps)
90182

91183
if (onnxruntime_BUILD_DAWN_SHARED_LIBRARY)
92-
target_link_libraries(onnxruntime_providers_webgpu dawn::webgpu_dawn)
184+
target_link_libraries(onnxruntime_providers_webgpu PUBLIC dawn::webgpu_dawn)
93185

94186
if (WIN32)
95187
if (onnxruntime_ENABLE_DELAY_LOADING_WIN_DLLS)
@@ -116,9 +208,9 @@
116208
list(APPEND onnxruntime_providers_webgpu_dll_deps "$<TARGET_FILE:dawn::webgpu_dawn>")
117209
else()
118210
if (NOT onnxruntime_USE_EXTERNAL_DAWN)
119-
target_link_libraries(onnxruntime_providers_webgpu dawn::dawn_native)
211+
target_link_libraries(onnxruntime_providers_webgpu PRIVATE dawn::dawn_native)
120212
endif()
121-
target_link_libraries(onnxruntime_providers_webgpu dawn::dawn_proc)
213+
target_link_libraries(onnxruntime_providers_webgpu PRIVATE dawn::dawn_proc)
122214
endif()
123215

124216
if (WIN32 AND onnxruntime_ENABLE_DAWN_BACKEND_D3D12)
@@ -153,7 +245,8 @@
153245
endif()
154246
endif()
155247

156-
add_dependencies(onnxruntime_providers_webgpu ${onnxruntime_EXTERNAL_DEPENDENCIES})
248+
target_compile_features(onnxruntime_providers_webgpu PRIVATE cxx_std_20)
249+
add_dependencies(onnxruntime_providers_webgpu onnx ${onnxruntime_EXTERNAL_DEPENDENCIES})
157250

158251
if (onnxruntime_WGSL_TEMPLATE)
159252
# Define the WGSL templates directory and output directory
@@ -239,7 +332,7 @@
239332
# Add the generated directory to include paths
240333
target_include_directories(onnxruntime_providers_webgpu PRIVATE ${WGSL_GENERATED_ROOT})
241334
elseif(onnxruntime_WGSL_TEMPLATE STREQUAL "dynamic")
242-
target_link_libraries(onnxruntime_providers_webgpu duktape_static)
335+
target_link_libraries(onnxruntime_providers_webgpu PRIVATE duktape_static)
243336
onnxruntime_add_include_to_target(onnxruntime_providers_webgpu duktape_static)
244337

245338
# Define the path to the generated templates.js file
@@ -251,4 +344,10 @@
251344
add_dependencies(onnxruntime_providers_webgpu onnxruntime_webgpu_wgsl_generation)
252345
endif()
253346

254-
set_target_properties(onnxruntime_providers_webgpu PROPERTIES FOLDER "ONNXRuntime")
347+
if (NOT onnxruntime_BUILD_SHARED_LIB)
348+
install(TARGETS onnxruntime_providers_webgpu EXPORT ${PROJECT_NAME}Targets
349+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
350+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
351+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
352+
FRAMEWORK DESTINATION ${CMAKE_INSTALL_BINDIR})
353+
endif()

cmake/onnxruntime_python.cmake

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,15 @@ set(onnxruntime_pybind11_state_static_providers
192192
${PROVIDERS_ACL}
193193
${PROVIDERS_ARMNN}
194194
${PROVIDERS_XNNPACK}
195-
${PROVIDERS_WEBGPU}
196195
${PROVIDERS_AZURE}
197196
)
198197

199198
if(onnxruntime_BUILD_QNN_EP_STATIC_LIB)
200199
list(APPEND onnxruntime_pybind11_state_static_providers PRIVATE onnxruntime_providers_qnn)
201200
endif()
201+
if(onnxruntime_BUILD_WEBGPU_EP_STATIC_LIB)
202+
list(APPEND onnxruntime_pybind11_state_static_providers PRIVATE onnxruntime_providers_webgpu)
203+
endif()
202204
if(WIN32)
203205
# onnxruntime_pybind11_state is a DLL
204206
target_sources(onnxruntime_pybind11_state PRIVATE "${ONNXRUNTIME_ROOT}/core/dll/dllmain.cc")

cmake/onnxruntime_unittests.cmake

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -644,10 +644,6 @@ if(onnxruntime_USE_JSEP)
644644
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_js)
645645
endif()
646646

647-
if(onnxruntime_USE_WEBGPU)
648-
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_webgpu)
649-
endif()
650-
651647
if(onnxruntime_USE_RKNPU)
652648
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_rknpu)
653649
endif()
@@ -682,7 +678,6 @@ set(ONNXRUNTIME_TEST_STATIC_PROVIDER_LIBS
682678
${PROVIDERS_NNAPI}
683679
${PROVIDERS_VSINPU}
684680
${PROVIDERS_JS}
685-
${PROVIDERS_WEBGPU}
686681
${PROVIDERS_SNPE}
687682
${PROVIDERS_RKNPU}
688683
${PROVIDERS_DML}
@@ -696,6 +691,9 @@ set(ONNXRUNTIME_TEST_STATIC_PROVIDER_LIBS
696691
if (onnxruntime_BUILD_QNN_EP_STATIC_LIB)
697692
list(APPEND ONNXRUNTIME_TEST_STATIC_PROVIDER_LIBS onnxruntime_providers_qnn)
698693
endif()
694+
if (onnxruntime_BUILD_WEBGPU_EP_STATIC_LIB)
695+
list(APPEND ONNXRUNTIME_TEST_STATIC_PROVIDER_LIBS onnxruntime_providers_webgpu)
696+
endif()
699697

700698
set(ONNXRUNTIME_TEST_LIBS
701699
onnxruntime_session
@@ -754,7 +752,7 @@ if(onnxruntime_USE_JSEP)
754752
list(APPEND onnxruntime_test_providers_libs onnxruntime_providers_js)
755753
endif()
756754

757-
if(onnxruntime_USE_WEBGPU)
755+
if(onnxruntime_USE_WEBGPU AND onnxruntime_BUILD_WEBGPU_EP_STATIC_LIB)
758756
list(APPEND onnxruntime_test_framework_src_patterns ${TEST_SRC_DIR}/providers/webgpu/*)
759757
list(APPEND onnxruntime_test_providers_dependencies onnxruntime_providers_webgpu)
760758
list(APPEND onnxruntime_test_providers_libs onnxruntime_providers_webgpu)

onnxruntime/core/dll/delay_load_hook.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,13 @@
2121
// - https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#alternate-search-order-for-unpackaged-apps
2222
//
2323
// The DLL DelayLoad hook is only enabled when the compiler is MSVC and at least one of the following is True:
24-
// - both USE_WEBGPU and BUILD_DAWN_SHARED_LIBRARY are defined
24+
// - all of the following are defined:
25+
// - USE_WEBGPU
26+
// - BUILD_WEBGPU_EP_STATIC_LIB
27+
// - BUILD_DAWN_SHARED_LIBRARY
2528
// - USE_DML is defined
2629
//
27-
#if defined(USE_WEBGPU) && defined(BUILD_DAWN_SHARED_LIBRARY)
30+
#if defined(USE_WEBGPU) && defined(BUILD_WEBGPU_EP_STATIC_LIB) && defined(BUILD_DAWN_SHARED_LIBRARY)
2831
#define ORT_DELAY_LOAD_WEBGPU_DAWN_DLL 1
2932
#else
3033
#define ORT_DELAY_LOAD_WEBGPU_DAWN_DLL 0

onnxruntime/core/providers/get_execution_providers.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ constexpr ProviderInfo kProvidersInPriorityOrder[] =
158158
},
159159
{
160160
kWebGpuExecutionProvider,
161-
#ifdef USE_WEBGPU
161+
#if defined(USE_WEBGPU) && defined(BUILD_WEBGPU_EP_STATIC_LIB)
162162
true,
163163
#else
164164
false,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
## The `ep` folder
2+
3+
The current folder contains the implementation of EP ABI adapter for WebGPU.
4+
5+
### Design considerations
6+
7+
To ensure both static library and dynamic library builds work, we need to make as few changes to existing code as possible. A few design decisions are as below:
8+
9+
- No changes to static library build. It should still work as before.
10+
11+
- For dynamic library:
12+
13+
- use and only use the EP ABI. (no support for `GetProvider`)
14+
15+
- still depends on onnxruntime targets.
16+
17+
- use a bridge to connect EP ABI and the internal classes
18+
19+
### Missing parts
20+
21+
This section describes what is missing.
22+
23+
- need a way to do WebGPU cleanup (`OrtEnv::~OrtEnv()` currently calls `webgpu::CleanupWebGpuContexts()` in static lib build)
24+
25+
- need a way to setup "default configurations" for WebGPU. (currently missing for both static lib and shared lib)
26+
- we want something like `SetCurrentGpuDeviceId` in ORT C-API, which set a global state and is directly available to user.
27+
- to make it general, it can be something like:
28+
```c++
29+
ORT_API2_STATUS(SetEpDefaultConfig, _In_ const char* ep_name, _In_ const char* key, _In_ const char* value);
30+
```
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
LIBRARY "onnxruntime_providers_webgpu.dll"
2+
EXPORTS
3+
CreateEpFactories @1
4+
ReleaseEpFactory @2
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
VERS_1.0.0 {
2+
global:
3+
CreateEpFactories;
4+
ReleaseEpFactory;
5+
local:
6+
*;
7+
};

0 commit comments

Comments
 (0)