99#include " ggml-impl.h"
1010#include " ggml-wgsl-shaders.hpp"
1111
12+ #ifdef __EMSCRIPTEN__
13+ # include < emscripten/emscripten.h>
14+ #endif
15+
1216#include < webgpu/webgpu_cpp.h>
1317
1418#include < atomic>
@@ -2382,13 +2386,17 @@ static ggml_backend_dev_t ggml_backend_webgpu_reg_get_device(ggml_backend_reg_t
23822386
23832387 webgpu_context ctx = reg_ctx->webgpu_ctx ;
23842388
2389+ wgpu::RequestAdapterOptions options = {};
2390+
2391+ #ifndef __EMSCRIPTEN__
23852392 // TODO: track need for these toggles: https://issues.chromium.org/issues/42251215
23862393 const char * const adapterEnabledToggles[] = { " vulkan_enable_f16_on_nvidia" , " use_vulkan_memory_model" };
23872394 wgpu::DawnTogglesDescriptor adapterTogglesDesc;
23882395 adapterTogglesDesc.enabledToggles = adapterEnabledToggles;
23892396 adapterTogglesDesc.enabledToggleCount = 2 ;
2390- wgpu::RequestAdapterOptions options = {};
23912397 options.nextInChain = &adapterTogglesDesc;
2398+ #endif
2399+
23922400 ctx->instance .WaitAny (ctx->instance .RequestAdapter (
23932401 &options, wgpu::CallbackMode::AllowSpontaneous,
23942402 [&ctx](wgpu::RequestAdapterStatus status, wgpu::Adapter adapter, const char * message) {
@@ -2438,7 +2446,11 @@ static ggml_backend_dev_t ggml_backend_webgpu_reg_get_device(ggml_backend_reg_t
24382446
24392447 // Initialize device
24402448 std::vector<wgpu::FeatureName> required_features = { wgpu::FeatureName::ShaderF16,
2441- wgpu::FeatureName::ImplicitDeviceSynchronization };
2449+ #ifndef __EMSCRIPTEN__
2450+ wgpu::FeatureName::ImplicitDeviceSynchronization
2451+ #endif
2452+ };
2453+
24422454 if (ctx->supports_subgroup_matrix ) {
24432455 required_features.push_back (wgpu::FeatureName::Subgroups);
24442456 required_features.push_back (wgpu::FeatureName::ChromiumExperimentalSubgroupMatrix);
@@ -2448,19 +2460,6 @@ static ggml_backend_dev_t ggml_backend_webgpu_reg_get_device(ggml_backend_reg_t
24482460 required_features.push_back (wgpu::FeatureName::TimestampQuery);
24492461#endif
24502462
2451- // Enable Dawn-specific toggles to increase native performance
2452- // TODO: Don't enable for WASM builds, they won't have an effect anyways
2453- // TODO: Maybe WebGPU needs a "fast" mode where you can request compilers skip adding checks like these,
2454- // only for native performance?
2455- const char * const deviceEnabledToggles[] = { " skip_validation" , " disable_robustness" , " disable_workgroup_init" ,
2456- " disable_polyfills_on_integer_div_and_mod" };
2457- const char * const deviceDisabledToggles[] = { " timestamp_quantization" };
2458- wgpu::DawnTogglesDescriptor deviceTogglesDesc;
2459- deviceTogglesDesc.enabledToggles = deviceEnabledToggles;
2460- deviceTogglesDesc.enabledToggleCount = 4 ;
2461- deviceTogglesDesc.disabledToggles = deviceDisabledToggles;
2462- deviceTogglesDesc.disabledToggleCount = 1 ;
2463-
24642463 wgpu::DeviceDescriptor dev_desc;
24652464 dev_desc.requiredLimits = &ctx->limits ;
24662465 dev_desc.requiredFeatures = required_features.data ();
@@ -2478,7 +2477,23 @@ static ggml_backend_dev_t ggml_backend_webgpu_reg_get_device(ggml_backend_reg_t
24782477 GGML_ABORT (" ggml_webgpu: Device error! Reason: %d, Message: %s\n " , static_cast <int >(reason),
24792478 std::string (message).c_str ());
24802479 });
2480+
2481+ #ifndef __EMSCRIPTEN__
2482+ // Enable Dawn-specific toggles to increase native performance
2483+ // TODO: Maybe WebGPU needs a "fast" mode where you can request compilers skip adding checks like these,
2484+ // only for native performance?
2485+ const char * const deviceEnabledToggles[] = { " skip_validation" , " disable_robustness" , " disable_workgroup_init" ,
2486+ " disable_polyfills_on_integer_div_and_mod" };
2487+ const char * const deviceDisabledToggles[] = { " timestamp_quantization" };
2488+ wgpu::DawnTogglesDescriptor deviceTogglesDesc;
2489+ deviceTogglesDesc.enabledToggles = deviceEnabledToggles;
2490+ deviceTogglesDesc.enabledToggleCount = 4 ;
2491+ deviceTogglesDesc.disabledToggles = deviceDisabledToggles;
2492+ deviceTogglesDesc.disabledToggleCount = 1 ;
2493+
24812494 dev_desc.nextInChain = &deviceTogglesDesc;
2495+ #endif
2496+
24822497 ctx->instance .WaitAny (ctx->adapter .RequestDevice (
24832498 &dev_desc, wgpu::CallbackMode::AllowSpontaneous,
24842499 [ctx](wgpu::RequestDeviceStatus status, wgpu::Device device, wgpu::StringView message) {
@@ -2576,18 +2591,27 @@ ggml_backend_reg_t ggml_backend_webgpu_reg() {
25762591 ctx.name = GGML_WEBGPU_NAME;
25772592 ctx.device_count = 1 ;
25782593
2579- const char * const instanceEnabledToggles[] = { " allow_unsafe_apis" };
2580-
2581- wgpu::DawnTogglesDescriptor instanceTogglesDesc;
2582- instanceTogglesDesc.enabledToggles = instanceEnabledToggles;
2583- instanceTogglesDesc.enabledToggleCount = 1 ;
25842594 wgpu::InstanceDescriptor instance_descriptor{};
25852595 std::vector<wgpu::InstanceFeatureName> instance_features = { wgpu::InstanceFeatureName::TimedWaitAny };
25862596 instance_descriptor.requiredFeatures = instance_features.data ();
25872597 instance_descriptor.requiredFeatureCount = instance_features.size ();
2588- instance_descriptor.nextInChain = &instanceTogglesDesc;
2598+
2599+ #ifndef __EMSCRIPTEN__
2600+ const char * const instanceEnabledToggles[] = { " allow_unsafe_apis" };
2601+ wgpu::DawnTogglesDescriptor instanceTogglesDesc;
2602+ instanceTogglesDesc.enabledToggles = instanceEnabledToggles;
2603+ instanceTogglesDesc.enabledToggleCount = 1 ;
2604+ instance_descriptor.nextInChain = &instanceTogglesDesc;
2605+ #endif
25892606
25902607 webgpu_ctx->instance = wgpu::CreateInstance (&instance_descriptor);
2608+
2609+ #ifdef __EMSCRIPTEN__
2610+ if (webgpu_ctx->instance == nullptr ) {
2611+ GGML_LOG_ERROR (" ggml_webgpu: Failed to create WebGPU instance. Make sure either -sASYNCIFY or -sJSPI is set\n " );
2612+ return nullptr ;
2613+ }
2614+ #endif
25912615 GGML_ASSERT (webgpu_ctx->instance != nullptr );
25922616
25932617 static ggml_backend_reg reg = {
0 commit comments