WEBGPU_LOG_DEBUG("ggml_backend_webgpu_reg()");
static ggml_backend_webgpu_reg_context ctx;
+ static ggml_backend_reg reg = {
+ /* .api_version = */ GGML_BACKEND_API_VERSION,
+ /* .iface = */ ggml_backend_webgpu_reg_i,
+ /* .context = */ &ctx,
+ };
+
ctx.name = GGML_WEBGPU_NAME;
- ctx.device_count = 1;
+ ctx.device_count = 0;
wgpu::InstanceDescriptor instance_descriptor{};
std::vector<wgpu::InstanceFeatureName> instance_features = { wgpu::InstanceFeatureName::TimedWaitAny };
ctx.webgpu_global_ctx = webgpu_global_context(new webgpu_global_context_struct());
ctx.webgpu_global_ctx->instance = std::move(inst);
-#ifdef __EMSCRIPTEN__
- if (ctx.webgpu_global_ctx->instance == nullptr) {
- GGML_LOG_ERROR("ggml_webgpu: Failed to create WebGPU instance. Make sure either -sASYNCIFY or -sJSPI is set\n");
- return nullptr;
+ wgpu::Adapter adapter;
+ if (ctx.webgpu_global_ctx->instance != nullptr) {
+ wgpu::RequestAdapterOptions options = {};
+
+ // probe for adapter support
+ ctx.webgpu_global_ctx->instance.WaitAny(
+ ctx.webgpu_global_ctx->instance.RequestAdapter(
+ &options, wgpu::CallbackMode::AllowSpontaneous,
+ [&adapter](wgpu::RequestAdapterStatus status, wgpu::Adapter _adapter, const char * message) {
+ if (status != wgpu::RequestAdapterStatus::Success) {
+ GGML_LOG_ERROR("ggml_webgpu: Failed to get an adapter: %s\n", message);
+ return;
+ }
+ adapter = std::move(_adapter);
+ }),
+ UINT64_MAX);
+ }
+
+ if (adapter != nullptr) {
+ ctx.device_count = 1;
}
-#endif
- GGML_ASSERT(ctx.webgpu_global_ctx->instance != nullptr);
- static ggml_backend_reg reg = {
- /* .api_version = */ GGML_BACKEND_API_VERSION,
- /* .iface = */ ggml_backend_webgpu_reg_i,
- /* .context = */ &ctx,
- };
return ®
}