Skip to content

Fix WebGPU context memory identity and test host-owned caches - #33110

Merged
Mustapha Jaber (mustjab) merged 4 commits into
mainfrom
fix/webgpu-external-host-device-cache
Oct 8, 2026
Merged

Mustapha Jaber (mustjab) merged 4 commits into
mainfrom
fix/webgpu-external-host-device-cache

Conversation

@mustjab

@mustjab Mustapha Jaber (mustjab) commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Native external-Dawn hosts can supply a Dawn instance and device with a positive
ORT context ID. WebGPU allocators previously advertised memory-device ID zero
regardless of that context, leaving allocator lookup, streams, and transfer
routing unable to distinguish separate Dawn memory domains. Plugin stream
validation exposed this mismatch during custom-context session initialization.

This PR fixes the identity mismatch rather than weakening the stream check:

  • Propagate the context ID through WebGPU session allocators and the plugin's
    default memory device, with range validation before context creation.
  • Forward the requested memory device to plugin stream creation and retain the
    owning-context identity check.
  • Route shared WebGPU transfers using tensor memory-device IDs and reject GPU
    copies between distinct contexts or foreign GPU vendors.
  • Extend the native external-host test with host-created devices, synchronized
    cache callbacks, cache isolation keys, lifetime checks, and failure cases.
  • Keep default and host-owned sessions alive together; verify distinct allocator
    and GPU-output IDs, CPU/GPU and same-context GPU/GPU transfers, and rejection
    of cross-context copies.
  • Exercise the native host through existing Windows source-based, package-backed
    built-in, and plugin CI paths, and document device/callback ownership.

Our current deployment uses built-in WebGPU with external Dawn and a host-owned
device. Plugin and concurrent-context tests are additional regression coverage,
not a claim that the deployment has migrated to plugins or requires a default
session alongside the host-owned session. Context IDs identify Dawn memory
domains, not physical GPU indices. No new public API is introduced.

Validation

Windows x64 Release with native Dawn:

  • Refreshed source-based built-in, package-backed built-in, and package-backed
    plugin builds passed all five host modes, with CPU fallback disabled.
  • All three exercised default/custom context allocation and GPU-bound outputs,
    same-context transfers, and cross-context rejection.
  • All three observed three actual warm-cache hits and no additional hits under a
    different isolation key, and verified host-device use after ORT teardown.
  • Required-feature rejection, callback failure containment, and missing-proc-table
    rejection passed with their expected diagnostics.
  • All 35 plugin framework tests passed, including the requested stream-device
    forwarding regression.
  • All four WebGPU transfer tests and the device-ID parser rejection test passed.
  • All 15 changed C++ files passed scoped ORT lintrunner formatting checks.

Other native platforms remain unvalidated locally. Cache reuse is tested across
devices within one process; persistence across process restarts is not covered.

@mustjab
Mustapha Jaber (mustjab) requested a balanced review from Copilot October 5, 2026 15:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

Review effort: Lite
Findings: 1 High severity · 1 Medium severity · 1 Low severity

Open (3)
What changed in this PR

This PR fixes WebGPU stream validation for custom external-Dawn contexts and expands the external host test coverage to validate host-owned devices and shader-cache callbacks across multiple devices/isolation keys.

Changes:

  • Validate WebGPU session streams against the session allocator’s actual memory-device ID (rather than the ORT context/deviceId).
  • Extend the external Dawn host test to create and inject host-owned Dawn instances/devices, exercise cache callbacks, and verify device usability after ORT teardown.
  • Update CI and build wiring to link Dawn’s proc table library and run the new host-device/cache test modes.
File Description
onnxruntime/​test/​webgpu/​external_dawn/​main.cc Adds host-owned device + shader cache callback testing (cold/warm/isolated) and a required-feature rejection case.
onnxruntime/​core/​providers/​webgpu/​ep/​ep.cc Fixes stream validation to compare against allocator memory-device ID instead of the custom context ID.
docs/​WebGPU_External_Dawn.md Documents host-owned device handles, deviceId semantics, callback lifetime/ownership, and new test modes.
cmake/​onnxruntime_unittests.cmake Links the external Dawn host test against dawn::dawn_proc to support direct proc-table calls.
.github/​workflows/​windows_webgpu.yml Runs the new --host_device and --no_implicit_sync host-owned device/cache CI checks (source, package, plugin).

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread onnxruntime/test/webgpu/external_dawn/main.cc
Comment thread onnxruntime/test/webgpu/external_dawn/main.cc
Comment thread onnxruntime/test/webgpu/external_dawn/main.cc Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

Native Dawn ownership, plugin teardown, and cache callback behavior warrant final human review despite comprehensive Windows coverage.

Review effort: Balanced
Findings: None

Resolved since last review (3)

Comment thread onnxruntime/core/providers/webgpu/ep/ep.cc Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Custom WebGPU context IDs still accept undocumented negative values that propagate into allocator and stream identity.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)

Comment thread onnxruntime/core/providers/webgpu/allocator.h

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

It changes cross-layer WebGPU context ownership and plugin stream routing, while native validation is currently Windows-only.

Review effort: Balanced
Findings: None

Resolved since last review (1)

@xiaofeihan1

Copy link
Copy Markdown
Contributor

Hi Mustapha Jaber (@mustjab), I have two questions about the intended deployment scenario:

  1. This failure seems specific to the WebGPU plugin EP path. I had thought you used the external-Dawn with the built-in WebGPU EP. Have you also migrated your usage to the WebGPU plugin EP?
  2. When using external Dawn with a host-owned device, do you also create a default WebGPU Session in the same process where ORT creates the Dawn device for context 0? In other words, is the concurrent default-context + host-owned-context scenario representative of your actual usage, or mainly regression coverage?

@xiaofeihan1

Copy link
Copy Markdown
Contributor

Jiajia Qin (@qjia7) I wonder whether this is more closely tied to multi-context/multi-GPU support. The allocator/context device-ID mismatch appears to have existed for a long time, and the new check

static_cast<int64_t>(
    Api().ep.MemoryDevice_GetDeviceId(memory_device)) ==
    ep.GetDeviceId()

seems to be what exposed it. Would it make sense to remove or relax this check as a minimal unblock, and address distinct allocator/tensor memory-device IDs together with multi-context or multi-GPU support?

@mustjab Mustapha Jaber (mustjab) changed the title Fix custom WebGPU context stream validation and test host-owned caches Fix WebGPU context memory identity and test host-owned caches Oct 7, 2026
@mustjab

Copy link
Copy Markdown
Contributor Author

Xiaofei Han (@xiaofeihan1), replying to your comment:

Our current deployment uses external Dawn with the built-in WebGPU EP and a
host-owned device. We have not migrated that path to the WebGPU plugin EP.
The concurrent default-context + host-owned-context test was added as regression
coverage, not because that combination is a current deployment requirement.

@mustjab

Copy link
Copy Markdown
Contributor Author

Xiaofei Han (@xiaofeihan1), replying to your comment:

The stream check exposed an existing allocator/context identity mismatch.
Removing it would unblock initialization, but allocations from different Dawn
contexts would still advertise memory-device ID zero. That affects allocator
lookup and transfer routing as well as streams; sequential CPU-input/output
inference does not exercise all of those boundaries.

Following Jiajia's feedback, this PR now propagates the context ID through the
session allocator, default memory device, stream validation, and transfer
routing. It keeps the stream identity check and rejects cross-context GPU
copies. Distinct Dawn devices can exist on one physical GPU, so this is memory
domain correctness rather than adding physical multi-GPU selection.

I would keep that complete fix and the concurrent default/external-session
regression coverage here rather than accept the hard-coded allocator ID as a
minimal unblock. The built-in host/cache tests remain coverage for our current
deployment; the plugin tests address the additional correctness issue.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The cross-platform allocator, plugin-stream, context-lifetime, and transfer-routing changes warrant final human review despite strong Windows coverage.

0 open findings

🧠 Review effort: Balanced

Comment thread onnxruntime/core/providers/webgpu/webgpu_provider_factory.cc
Comment thread onnxruntime/core/providers/webgpu/webgpu_provider_factory.cc
@xiaofeihan1

Copy link
Copy Markdown
Contributor

Cool, I'm OK with this PR. I'm just curious how you identified this issue. It seems to be caused by the external Dawn + WebGPU Plugin EP setup, but you mentioned that you're using the built-in EP.

@mustjab
Mustapha Jaber (mustjab) merged commit 78cf3eb into main Oct 8, 2026
@mustjab
Mustapha Jaber (mustjab) deleted the fix/webgpu-external-host-device-cache branch October 8, 2026 16:16
Mustapha Jaber (mustjab) added a commit that referenced this pull request Oct 9, 2026
## Summary

Follow-up to the review of #33110.

The shared WebGPU data-transfer wrapper does not need to own a context.
A session stream already supplies its owning execution provider's
transfer state, while a streamless copy can select its registered
context from the GPU tensor's memory-device ID.

- Remove the cached context, initialization mutex, and context-ID
argument from the internal transfer creator.
- Route session copies directly through their stream. Retain the
tensor-selected registered context only for each streamless copy,
including context zero, and flush successful streamless GPU-to-GPU
copies.
- Document that memory-device identity does not register Dawn objects,
the current Env/global allocator context-zero restriction, and the
registration requirements for external-context copies.

Allocator/session context IDs and the public C API are unchanged. This
does not add pre-session external-context registration.

## Validation

- Scoped C++ lintrunner and staged whitespace checks passed.
- Fresh Windows x64 Release external-Dawn plugin build on upstream main
`864d87126864c64651f58a9b51d9006ad71b2c78` passed.
- All five native-host modes passed against the fresh ORT/plugin DLLs:
baseline, host-device, missing-sync, callback-failure, and
missing-proc-table. The host executable was reused after verifying its
source was unchanged.
- Host-device coverage includes coexisting default/external context
allocation and transfers, shader-cache reuse/isolation, and device
usability after ORT teardown. Negative modes rejected invalid inputs or
contained callback failures as expected.
- The same follow-up also passed the five host modes in both built-in
and plugin configurations before rebasing onto current main.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants