Skip to content

Commit 3f34cd9

Browse files
committed
Update
[ghstack-poisoned]
1 parent c581935 commit 3f34cd9

8 files changed

Lines changed: 290 additions & 49 deletions

File tree

.ci/scripts/setup-webgpu-linux-deps.sh

Lines changed: 61 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,71 @@
55
# This source code is licensed under the BSD-style license found in the
66
# LICENSE file in the root directory of this source tree.
77

8+
# Vendor Dawn (Tint) + SwiftShader for the WebGPU backend CI WITHOUT hosting a
9+
# private prebuilt:
10+
# * Dawn : Google's official nightly prebuilt, downloaded directly from
11+
# github.com/google/dawn/releases (pinned tag+rev+sha256) -- the same
12+
# "fetch upstream's published binary" pattern as setup-wgpu-native.sh.
13+
# * SwiftShader : reuse the prebuilt ALREADY on the ossci-android bucket (the one
14+
# setup-vulkan-linux-deps.sh uses). No new S3 uploads anywhere.
15+
# Dawn (Chrome's WebGPU impl; its WGSL compiler Tint is the spec reference) on
16+
# SwiftShader gives a headless, deterministic, spec-faithful CLI backend.
17+
#
18+
# Exports Dawn_DIR / VK_ICD_FILENAMES / LD_LIBRARY_PATH for the cmake build+run.
19+
# Local/rig override: set DAWN_PREBUILT_DIR=<dir containing lib64/cmake/Dawn> to
20+
# skip the Dawn download.
821
set -ex
922

10-
# SwiftShader: software Vulkan adapter for GPU-less CI (LunarG SDK not needed).
11-
install_swiftshader() {
12-
_https_amazon_aws=https://ossci-android.s3.amazonaws.com
13-
_swiftshader_archive=swiftshader-abe07b943-prebuilt.tar.gz
14-
_swiftshader_dir=/tmp/swiftshader
15-
mkdir -p $_swiftshader_dir
23+
# --- pinned versions (bump rev+sha together when upgrading Dawn) --------------
24+
DAWN_TAG="${DAWN_TAG:-v20260423.175430}"
25+
DAWN_REV="${DAWN_REV:-31e25af254ab572c77054edec4946d2244e184dd}"
26+
DAWN_SHA256="${DAWN_SHA256:-ac76fac090162dc1ecea5ed0f28a557bb8f49efc47faab01886105ace82b7b64}"
27+
SWIFTSHADER_ARCHIVE="${SWIFTSHADER_ARCHIVE:-swiftshader-abe07b943-prebuilt.tar.gz}"
1628

17-
_tmp_archive="/tmp/${_swiftshader_archive}"
29+
_dawn_dir="${DAWN_PREBUILT_DIR:-/tmp/dawn-ci}"
30+
_ss_dir=/tmp/swiftshader
1831

19-
curl --silent --show-error --location --fail --retry 3 --retry-all-errors \
20-
--output "${_tmp_archive}" "$_https_amazon_aws/${_swiftshader_archive}"
32+
# --- toolchain prereqs --------------------------------------------------------
33+
# Dawn dlopens the system Vulkan loader at runtime (libvulkan1). And the
34+
# ubuntu-latest prebuilt is built with a bleeding-edge GCC: it references
35+
# libstdc++ symbols newer than ubuntu-22.04's default (e.g. _M_replace_cold,
36+
# GCC 13+), so the static .a won't link against the stock runtime. Pull a current
37+
# libstdc++ from the ubuntu-toolchain-r PPA when the symbol floor isn't met. All
38+
# of this is scoped to the WebGPU CI job; newer libstdc++ is backward-compatible.
39+
if command -v apt-get >/dev/null 2>&1; then
40+
_SUDO=""; command -v sudo >/dev/null 2>&1 && _SUDO="sudo"
41+
${_SUDO} apt-get update -y || true
42+
${_SUDO} apt-get install -y libvulkan1 software-properties-common || true
43+
if ! strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 2>/dev/null \
44+
| grep -q "GLIBCXX_3.4.32"; then
45+
${_SUDO} add-apt-repository -y ppa:ubuntu-toolchain-r/test || true
46+
${_SUDO} apt-get update -y || true
47+
${_SUDO} apt-get install -y libstdc++6 || true # newest GCC runtime
48+
fi
49+
fi
2150

22-
tar -C "${_swiftshader_dir}" -xzf "${_tmp_archive}"
51+
# --- Dawn: official prebuilt from GitHub (no S3) ------------------------------
52+
mkdir -p "${_dawn_dir}"
53+
if [[ ! -d "${_dawn_dir}/lib64/cmake/Dawn" ]]; then
54+
_dawn_tar="/tmp/Dawn-${DAWN_REV}-ubuntu-latest-Release.tar.gz"
55+
curl --silent --show-error --location --fail --retry 3 --retry-all-errors \
56+
--output "${_dawn_tar}" \
57+
"https://github.com/google/dawn/releases/download/${DAWN_TAG}/Dawn-${DAWN_REV}-ubuntu-latest-Release.tar.gz"
58+
echo "${DAWN_SHA256} ${_dawn_tar}" | sha256sum -c -
59+
# archive top dir is Dawn-<rev>-ubuntu-latest-Release/{lib64,include,bin}
60+
tar -C "${_dawn_dir}" --strip-components=1 -xzf "${_dawn_tar}"
61+
fi
2362

24-
export VK_ICD_FILENAMES="${_swiftshader_dir}/swiftshader/build/Linux/vk_swiftshader_icd.json"
25-
export LD_LIBRARY_PATH="${_swiftshader_dir}/swiftshader/build/Linux/:${LD_LIBRARY_PATH}"
26-
export ETVK_USING_SWIFTSHADER=1
27-
}
63+
# --- SwiftShader: reuse the existing ossci prebuilt (no new upload) -----------
64+
if [[ ! -f "${_ss_dir}/swiftshader/build/Linux/vk_swiftshader_icd.json" ]]; then
65+
_ss_aws=https://ossci-android.s3.amazonaws.com
66+
mkdir -p "${_ss_dir}"
67+
curl --silent --show-error --location --fail --retry 3 --retry-all-errors \
68+
--output "/tmp/${SWIFTSHADER_ARCHIVE}" "${_ss_aws}/${SWIFTSHADER_ARCHIVE}"
69+
tar -C "${_ss_dir}" -xzf "/tmp/${SWIFTSHADER_ARCHIVE}"
70+
fi
2871

29-
install_swiftshader
30-
bash backends/webgpu/scripts/setup-wgpu-native.sh
72+
export Dawn_DIR="${_dawn_dir}/lib64/cmake/Dawn"
73+
export VK_ICD_FILENAMES="${_ss_dir}/swiftshader/build/Linux/vk_swiftshader_icd.json"
74+
export LD_LIBRARY_PATH="${_ss_dir}/swiftshader/build/Linux/:${LD_LIBRARY_PATH:-}"
75+
export WEBGPU_USING_SWIFTSHADER=1

.ci/scripts/test_backend.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,10 @@ if [[ "$FLOW" == *vulkan* ]]; then
5858
fi
5959

6060
if [[ "$FLOW" == *webgpu* ]]; then
61-
# Setup swiftshader (software Vulkan adapter for GPU-less runners) and wgpu-native,
62-
# which are required to build and run the WebGPU delegate.
61+
# Dawn (Tint) + SwiftShader, the spec-faithful headless WebGPU backend.
6362
source .ci/scripts/setup-webgpu-linux-deps.sh
6463

65-
EXTRA_BUILD_ARGS+=" -DEXECUTORCH_BUILD_WEBGPU=ON"
64+
EXTRA_BUILD_ARGS+=" -DEXECUTORCH_BUILD_WEBGPU=ON -DDawn_DIR=$Dawn_DIR"
6665
fi
6766

6867
if [[ "$FLOW" == *arm* ]]; then
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Test WebGPU Native (Dawn)
2+
3+
# The substantive WebGPU op-coverage gate. The shared operators suite only
4+
# delegates add.Tensor to WebGPU (everything else is CPU fallback), so the real
5+
# Dawn coverage comes from the native test executables (rms_norm, multi-dispatch
6+
# ordering, scratch). This runs them on Dawn (Tint) + SwiftShader, headless, on a
7+
# CPU runner -- separate from _test_backend.yml so that reusable template stays
8+
# untouched.
9+
10+
on:
11+
schedule:
12+
- cron: 0 2 * * *
13+
push:
14+
branches:
15+
- main
16+
- release/*
17+
tags:
18+
- ciflow/nightly/*
19+
pull_request:
20+
workflow_dispatch:
21+
22+
concurrency:
23+
group: ${{ github.workflow }}--${{ github.event.pull_request.number || github.sha }}-${{ github.event_name == 'workflow_dispatch' }}
24+
cancel-in-progress: true
25+
26+
jobs:
27+
test-webgpu-native:
28+
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
29+
with:
30+
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
31+
runner: linux.4xlarge.memory
32+
docker-image: ci-image:executorch-ubuntu-22.04-clang12
33+
submodules: recursive
34+
timeout: 120
35+
script: |
36+
set -eux
37+
38+
# Build the Python package + runtime deps (provides the .pte exporters the
39+
# model-driven executables consume), mirroring test_backend.sh.
40+
PYTHON_EXECUTABLE=python bash .ci/scripts/setup-linux.sh --build-tool cmake
41+
42+
# Vendor Dawn (Tint) + SwiftShader, then build + run the native executables.
43+
source .ci/scripts/setup-webgpu-linux-deps.sh
44+
bash backends/webgpu/scripts/test_webgpu_native_ci.sh

backends/webgpu/CMakeLists.txt

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -54,29 +54,10 @@ target_include_directories(
5454

5555
target_link_libraries(webgpu_backend PRIVATE vulkan_schema executorch_core)
5656

57-
# Native build: link against wgpu-native
58-
set(WGPU_NATIVE_DIR
59-
"${CMAKE_CURRENT_SOURCE_DIR}/third-party/wgpu-native"
60-
CACHE PATH "Path to wgpu-native installation"
61-
)
62-
63-
# Link the shared lib; the static .a carries LLVM bitcode that breaks LTO.
64-
# Suffix resolves per platform: .so on Linux, .dylib on macOS.
65-
set(WGPU_LIB_NAME "libwgpu_native${CMAKE_SHARED_LIBRARY_SUFFIX}")
66-
set(WGPU_LIB "${WGPU_NATIVE_DIR}/lib/${WGPU_LIB_NAME}")
67-
if(NOT EXISTS "${WGPU_LIB}")
68-
message(FATAL_ERROR "wgpu-native not found at ${WGPU_NATIVE_DIR}. "
69-
"Run: bash backends/webgpu/scripts/setup-wgpu-native.sh"
70-
)
71-
endif()
72-
73-
add_library(wgpu_native SHARED IMPORTED)
74-
set_target_properties(wgpu_native PROPERTIES IMPORTED_LOCATION "${WGPU_LIB}")
75-
76-
target_include_directories(
77-
webgpu_backend PUBLIC $<BUILD_INTERFACE:${WGPU_NATIVE_DIR}/include>
78-
)
79-
target_link_libraries(webgpu_backend PRIVATE wgpu_native)
57+
# Native WebGPU backend: Dawn (Tint) + SwiftShader; deps script sets Dawn_DIR.
58+
find_package(Dawn REQUIRED)
59+
set(WEBGPU_GPU_LIB dawn::webgpu_dawn)
60+
target_link_libraries(webgpu_backend PUBLIC dawn::webgpu_dawn)
8061

8162
if(APPLE)
8263
target_link_libraries(
@@ -106,13 +87,12 @@ if(EXECUTORCH_BUILD_WEBGPU_TEST)
10687

10788
target_include_directories(
10889
webgpu_native_test PRIVATE $<BUILD_INTERFACE:${EXECUTORCH_ROOT}/..>
109-
"${WGPU_NATIVE_DIR}/include"
11090
)
11191

11292
target_link_libraries(
11393
webgpu_native_test
11494
PRIVATE webgpu_backend
115-
wgpu_native
95+
${WEBGPU_GPU_LIB}
11696
executorch_core
11797
extension_module_static
11898
extension_data_loader
@@ -137,13 +117,12 @@ if(EXECUTORCH_BUILD_WEBGPU_TEST)
137117

138118
target_include_directories(
139119
webgpu_rms_norm_test PRIVATE $<BUILD_INTERFACE:${EXECUTORCH_ROOT}/..>
140-
"${WGPU_NATIVE_DIR}/include"
141120
)
142121

143122
target_link_libraries(
144123
webgpu_rms_norm_test
145124
PRIVATE webgpu_backend
146-
wgpu_native
125+
${WEBGPU_GPU_LIB}
147126
executorch_core
148127
extension_module_static
149128
extension_data_loader
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
#pragma once
10+
11+
#include <webgpu/webgpu.h>
12+
13+
#if defined(__EMSCRIPTEN__)
14+
#include <emscripten/emscripten.h>
15+
#else
16+
#include <chrono>
17+
#include <thread>
18+
#endif
19+
20+
namespace executorch::backends::webgpu {
21+
22+
// Drive pending callbacks; callers loop until their done flag is set. The
23+
// native (Dawn) build pumps the instance event queue then briefly yields the
24+
// CPU so the caller's wait loop does not busy-spin a core at 100%
25+
// (wgpuInstanceProcessEvents is non-blocking); the browser yields to the JS
26+
// event loop.
27+
inline void webgpu_poll(WGPUInstance instance, WGPUDevice device) {
28+
#if defined(__EMSCRIPTEN__)
29+
(void)instance;
30+
(void)device;
31+
emscripten_sleep(0);
32+
#else
33+
(void)device;
34+
wgpuInstanceProcessEvents(instance);
35+
std::this_thread::sleep_for(std::chrono::microseconds(50));
36+
#endif
37+
}
38+
39+
} // namespace executorch::backends::webgpu

backends/webgpu/runtime/WebGPUDevice.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,11 @@ WebGPUContext create_webgpu_context() {
101101
adapter_cb.callback = on_adapter_request;
102102
adapter_cb.userdata1 = &adapter_result;
103103

104-
wgpuInstanceRequestAdapter(ctx.instance, nullptr, adapter_cb);
104+
// No bundled fallback adapter in the release; SwiftShader via the Vulkan ICD.
105+
WGPURequestAdapterOptions adapter_opts = {};
106+
adapter_opts.backendType = WGPUBackendType_Vulkan;
107+
adapter_opts.forceFallbackAdapter = false;
108+
wgpuInstanceRequestAdapter(ctx.instance, &adapter_opts, adapter_cb);
105109
while (!adapter_result.done) {
106110
wgpuInstanceProcessEvents(ctx.instance);
107111
}

backends/webgpu/runtime/WebGPUGraph.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
#include <executorch/backends/vulkan/serialization/schema_generated.h>
1313
#include <executorch/runtime/core/named_data_map.h>
1414

15+
#include <executorch/backends/webgpu/runtime/WebGPUCompat.h>
1516
#include <executorch/backends/webgpu/runtime/WebGPUDevice.h>
16-
#include <webgpu/wgpu.h>
1717

1818
#include <cstring>
1919
#include <stdexcept>
@@ -510,7 +510,17 @@ void WebGPUGraph::copy_outputs(std::vector<std::pair<void*, size_t>>& outputs) {
510510
cb_info);
511511
}
512512

513-
wgpuDevicePoll(device_, true, nullptr);
513+
bool all_mapped = false;
514+
while (!all_mapped) {
515+
webgpu_poll(instance_, device_);
516+
all_mapped = true;
517+
for (size_t i = 0; i < count; i++) {
518+
if (outputs[i].second != 0 && !cb_data[i].done) {
519+
all_mapped = false;
520+
break;
521+
}
522+
}
523+
}
514524

515525
for (size_t i = 0; i < count; i++) {
516526
if (outputs[i].second == 0) {

0 commit comments

Comments
 (0)