From b832ac3abc3de37e8529850abe28b8cef7e7e042 Mon Sep 17 00:00:00 2001 From: Prathik Rao Date: Tue, 30 Jun 2026 14:31:42 -0700 Subject: [PATCH 1/4] revert --- .../ep_detection/webgpu_ep_bootstrapper.cc | 119 +++++++++--------- 1 file changed, 57 insertions(+), 62 deletions(-) diff --git a/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc b/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc index eb4b3bed..6fa952aa 100644 --- a/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc +++ b/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc @@ -3,23 +3,21 @@ #include "ep_detection/webgpu_ep_bootstrapper.h" #include "ep_detection/ep_utils.h" -#include "http/http_client.h" #include "http/http_download.h" #include "logger.h" #include "util/file_lock.h" -#include "util/sha256.h" #include "utils.h" #include "util/zip_extract.h" #include -#include -#include #include #include #include #include #include +#include +#include namespace { @@ -29,11 +27,32 @@ constexpr const char* kStagingDirName = "webgpu-ep-staging"; constexpr const char* kUserAgent = "FoundryLocal"; constexpr int kMaxInstallAttempts = 5; -// Manifest URL — always uses prod. -constexpr const char* kManifestUrl = - "https://foundrypackages-ffhrdhbxb7gpdreh.b02.azurefd.net/webgpu_ep_prod.json"; +struct WebGpuPackageMetadata { + const char* download_url; + const char* provider_sha256; +}; + +const std::unordered_map kPackageMetadataByPlatform = { + {"win-arm64", + {"https://foundrypackages-ffhrdhbxb7gpdreh.b02.azurefd.net/webgpu_ep_0.1.0_win-arm64.zip", + "C4A77911BDBFC6E2870D1895DA3F5BE476CE3398D772C02AFDDD2B2C49C66659"} + }, + {"win-x64", + {"https://foundrypackages-ffhrdhbxb7gpdreh.b02.azurefd.net/webgpu_ep_0.1.0_win-x64.zip", + "591E286A211B133E3C4E5C833FEBF2D594B7B548433A2490407B11B906A9271B"} + }, + {"macos-arm64", + {"https://foundrypackages-ffhrdhbxb7gpdreh.b02.azurefd.net/webgpu_ep_0.1.0_macos-arm64.zip", + "A08BCEBE097B555E23938FCC71A5FAAD461F586CAB0B63DC9D21E970F6CA4C87"} + }, + {"linux-x64", + {"https://foundrypackages-ffhrdhbxb7gpdreh.b02.azurefd.net/webgpu_ep_0.1.0_linux-x64.zip", + "CBDFF74E6569E3CF66B46F0D194D87CD3CF49E83B7AA46552C39B0218D58B215"} + }, +}; -// Platform key used to look up this platform's package in the manifest. +// Platform-specific package metadata is baked into the binary to avoid +// manifest fetch complexity and to keep verification inputs fixed at build time. #if defined(_WIN32) && defined(_M_ARM64) constexpr const char* kPlatformKey = "win-arm64"; #elif defined(_WIN32) @@ -44,6 +63,17 @@ constexpr const char* kPlatformKey = "macos-arm64"; constexpr const char* kPlatformKey = "linux-x64"; #endif +const WebGpuPackageMetadata& GetPackageMetadata() { + auto it = kPackageMetadataByPlatform.find(kPlatformKey); + + if (it == kPackageMetadataByPlatform.end()) { + throw std::runtime_error( + fmt::format("WebGPU EP: no package metadata configured for platform '{}'", kPlatformKey)); + } + + return it->second; +} + // Platform-specific EP library filename. #if defined(_WIN32) constexpr const char* kWebGpuProviderLib = "onnxruntime_providers_webgpu.dll"; @@ -56,51 +86,6 @@ constexpr const char* kWebGpuProviderLib = "libonnxruntime_providers_webgpu.so"; constexpr const char* kRegistrationName = "Foundry.WebGPU"; constexpr const char* kWebGpuProviderOverrideEnv = "FOUNDRY_LOCAL_WEBGPU_EP_LIBRARY"; -/// Parsed manifest entry for a single platform. -struct ManifestPackageInfo { - std::string url; - std::string sha256; // expected SHA256 hash of kWebGpuProviderLib -}; - -/// Fetch the manifest JSON from CDN and extract the package info for this platform. -ManifestPackageInfo FetchManifest(fl::ILogger& logger) { - logger.Log(fl::LogLevel::Debug, fmt::format("WebGPU EP: fetching manifest from {}", kManifestUrl)); - - fl::http::HttpRequestOptions options; - options.user_agent = kUserAgent; - auto body = fl::http::HttpGetWithRetry(kManifestUrl, logger, options); - auto manifest = nlohmann::json::parse(body); - - if (!manifest.contains("packages") || !manifest["packages"].is_object()) { - throw std::runtime_error( - fmt::format("WebGPU EP: manifest is invalid — missing 'packages' field. " - "Raw content (first 200 chars): {}", - body.substr(0, 200))); - } - - const auto& packages = manifest["packages"]; - if (!packages.contains(kPlatformKey)) { - std::string available; - for (auto it = packages.begin(); it != packages.end(); ++it) { - if (!available.empty()) available += ", "; - available += it.key(); - } - throw std::runtime_error( - fmt::format("WebGPU EP: manifest does not contain a package for platform '{}'. " - "Available platforms: {}", - kPlatformKey, available)); - } - - const auto& pkg = packages[kPlatformKey]; - ManifestPackageInfo info; - info.url = pkg.at("url").get(); - info.sha256 = pkg.at("sha256").at(kWebGpuProviderLib).get(); - - logger.Log(fl::LogLevel::Information, - fmt::format("WebGPU EP: manifest fetched for platform '{}'", kPlatformKey)); - return info; -} - } // anonymous namespace namespace fl { @@ -135,6 +120,7 @@ bool WebGpuEpBootstrapper::DownloadAndRegister(bool force, auto ep_dir = std::filesystem::path(ep_dir_); auto parent_dir = ep_dir.parent_path(); + const auto& package_metadata = GetPackageMetadata(); try { auto override_path = Utils::GetEnv(kWebGpuProviderOverrideEnv); @@ -175,12 +161,13 @@ bool WebGpuEpBootstrapper::DownloadAndRegister(bool force, return true; } - // Fetch manifest before acquiring lock (avoid holding lock during network I/O) - auto manifest = FetchManifest(logger); - // Check if package already exists and is valid - if (!force && VerifyEpPackage(ep_dir, {{kWebGpuProviderLib, manifest.sha256}}, "WebGPU EP", logger)) { - logger.Log(LogLevel::Debug, "WebGPU EP: local binaries match manifest, skipping download"); + if (!force && VerifyEpPackage( + ep_dir, + {{kWebGpuProviderLib, package_metadata.provider_sha256}}, + "WebGPU EP", + logger)) { + logger.Log(LogLevel::Debug, "WebGPU EP: local binaries match expected hashes, skipping download"); } else { // Ensure parent directory exists for the lock file std::filesystem::create_directories(parent_dir); @@ -190,7 +177,11 @@ bool WebGpuEpBootstrapper::DownloadAndRegister(bool force, FileLock lock(lock_path); // Re-check after acquiring lock (another process may have completed the update) - if (!force && VerifyEpPackage(ep_dir, {{kWebGpuProviderLib, manifest.sha256}}, "WebGPU EP", logger)) { + if (!force && VerifyEpPackage( + ep_dir, + {{kWebGpuProviderLib, package_metadata.provider_sha256}}, + "WebGPU EP", + logger)) { logger.Log(LogLevel::Debug, "WebGPU EP: another process already completed the update"); } else { // Download and extract to staging directory for atomic swap @@ -206,7 +197,7 @@ bool WebGpuEpBootstrapper::DownloadAndRegister(bool force, logger.Log(LogLevel::Information, fmt::format("WebGPU EP: downloading for {} from CDN", kPlatformKey)); logger.Log(LogLevel::Debug, - fmt::format("WebGPU EP: download URL is {}", manifest.url)); + fmt::format("WebGPU EP: download URL is {}", package_metadata.download_url)); std::atomic cancel_flag{false}; auto download_progress = [&](float pct) { @@ -218,7 +209,7 @@ bool WebGpuEpBootstrapper::DownloadAndRegister(bool force, } }; - if (!HttpDownloadFile(manifest.url, zip_path, kUserAgent, + if (!HttpDownloadFile(package_metadata.download_url, zip_path, kUserAgent, &cancel_flag, download_progress, logger)) { logger.Log(LogLevel::Warning, "WebGPU EP: download failed (see prior log for details)"); return false; @@ -238,7 +229,11 @@ bool WebGpuEpBootstrapper::DownloadAndRegister(bool force, std::filesystem::remove(zip_path); // Verify staging - if (!VerifyEpPackage(staging_dir, {{kWebGpuProviderLib, manifest.sha256}}, "WebGPU EP", logger)) { + if (!VerifyEpPackage( + staging_dir, + {{kWebGpuProviderLib, package_metadata.provider_sha256}}, + "WebGPU EP", + logger)) { logger.Log(LogLevel::Warning, fmt::format("WebGPU EP: verification failed after extraction (attempt {})", attempts_)); From 3e16aebbe53386f60008547d4100293b938171e9 Mon Sep 17 00:00:00 2001 From: Prathik Rao Date: Tue, 30 Jun 2026 14:53:15 -0700 Subject: [PATCH 2/4] filter --- .../src/ep_detection/winml_ep_bootstrapper.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sdk_v2/cpp/src/ep_detection/winml_ep_bootstrapper.cc b/sdk_v2/cpp/src/ep_detection/winml_ep_bootstrapper.cc index 98b6d582..9a9036db 100644 --- a/sdk_v2/cpp/src/ep_detection/winml_ep_bootstrapper.cc +++ b/sdk_v2/cpp/src/ep_detection/winml_ep_bootstrapper.cc @@ -120,6 +120,16 @@ void CALLBACK EnsureReadyProgressThunk(WinMLAsyncBlock* async, double progress) } } +constexpr const char* kWinMLWebGpuProviderName = "WebGpuExecutionProvider"; + +bool IsWinMLWebGpuProvider(const WinMLEpInfo* info) { + if (!info || !info->name) { + return false; + } + + return info->name == std::string{kWinMLWebGpuProviderName}; +} + } // namespace WinMLEpBootstrapper::WinMLEpBootstrapper(std::string name, EpRegistrationCallback register_ep, @@ -286,6 +296,15 @@ std::vector> WinMLEpBootstrapper::DiscoverP [](WinMLEpHandle ep, const WinMLEpInfo* info, void* context) -> BOOL { auto* ctx = static_cast(context); + if (IsWinMLWebGpuProvider(info)) { + std::string provider_name = (info && info->name) ? info->name : ""; + ctx->logger->Log( + LogLevel::Information, + fmt::format("WinML EP filtered out: {} (reason: prefer Foundry Local WebGPU EP)", + provider_name)); + return TRUE; // continue enumeration + } + std::string provider_name = info->name ? info->name : ""; ctx->logger->Log( From 1d46afe6cd027ff416806b9f549971199e52601e Mon Sep 17 00:00:00 2001 From: Prathik Rao Date: Tue, 30 Jun 2026 15:07:13 -0700 Subject: [PATCH 3/4] copilot Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc b/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc index 6fa952aa..e41db0f0 100644 --- a/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc +++ b/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -120,9 +121,9 @@ bool WebGpuEpBootstrapper::DownloadAndRegister(bool force, auto ep_dir = std::filesystem::path(ep_dir_); auto parent_dir = ep_dir.parent_path(); - const auto& package_metadata = GetPackageMetadata(); try { + const auto& package_metadata = GetPackageMetadata(); auto override_path = Utils::GetEnv(kWebGpuProviderOverrideEnv); if (override_path.has_value() && !override_path->empty()) { std::filesystem::path provider_path(*override_path); From 4ba786d127df86f49c473852e613aa8ba581c6ba Mon Sep 17 00:00:00 2001 From: Prathik Rao Date: Tue, 30 Jun 2026 15:08:43 -0700 Subject: [PATCH 4/4] comments --- sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc | 4 ++-- sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.h | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc b/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc index e41db0f0..4bb6a5e9 100644 --- a/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc +++ b/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.cc @@ -52,8 +52,8 @@ const std::unordered_map kPackageMetada }, }; -// Platform-specific package metadata is baked into the binary to avoid -// manifest fetch complexity and to keep verification inputs fixed at build time. +// Platform-specific package metadata is baked into the binary to keep +// verification inputs fixed at build time. #if defined(_WIN32) && defined(_M_ARM64) constexpr const char* kPlatformKey = "win-arm64"; #elif defined(_WIN32) diff --git a/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.h b/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.h index 2cc8e52e..e80d4651 100644 --- a/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.h +++ b/sdk_v2/cpp/src/ep_detection/webgpu_ep_bootstrapper.h @@ -13,10 +13,8 @@ class ILogger; /// Bootstrapper for the WebGPU execution provider. /// -/// Fetches a manifest from Azure CDN to discover the current WebGPU EP -/// package URL and expected SHA-256 hash, downloads the binary, verifies -/// integrity, then registers with ORT. The manifest-driven approach allows -/// updating WebGPU EP binaries without shipping a new Foundry Local release. +/// Uses platform-specific package metadata (download URL and SHA-256 hash), +/// downloads the binary, verifies integrity, then registers with ORT. /// /// Supports Windows x64/ARM64, Linux x64, and macOS ARM64. class WebGpuEpBootstrapper : public IEpBootstrapper {