Skip to content

[WebGPU] Add buffer-region workspace preallocation - #32720

Draft
Chi Lo (chilo-ms) wants to merge 54 commits into
mainfrom
chilo/webgpu-workspace-buffer-region
Draft

Chi Lo (chilo-ms) wants to merge 54 commits into
mainfrom
chilo/webgpu-workspace-buffer-region

Conversation

@chilo-ms

@chilo-ms Chi Lo (chilo-ms) commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Stack and merge target

Depends on #32071. The WebGPU-specific changes were restacked onto its updated head (e964fed7b7), and current main at the time (34d838fbcd) was merged into this branch.

This draft targets main. Until #32071 lands, the PR diff also includes its prerequisite workspace-planning changes; merge the parent first.

Summary

  • Represent planned workspace as a provider-native buffer plus byte offset and usable size, while retaining the pointer-returning API for addressable allocations.
  • Preserve WebGPU buffer offsets through tensor views, bind groups, segmented bindings, transfers, indirect dispatch, and graph capture/replay.
  • Add workspace-only memory-pattern caching when ordinary activation patterns are disabled, including multiple independently tracked slots per kernel.
  • Wire WebGPU MatMulNBits DP4A activation/scales scratch and conditional subgroup activation-prepack scratch into planned regions, with dynamic-allocation fallback.
  • Add allocator high-water statistics, workspace-region regressions, and C++/ORT GenAI benchmarks with controlled cache/planner comparisons.

Integration notes

Conflict resolution preserves main's deferred pipeline dispatch, zero-initialized buffer reuse, and error propagation, along with #32071's diagnostic hooks and minimal-build exclusions. Workspace declarations use the current positional WorkspaceInputShape API. Plugin and minimal configurations retain dynamic scratch instead of requiring unavailable workspace interfaces.

Planning remains sequential and is disabled for multiple logical streams on one device. Ordinary WebGPU activation planning is unchanged. The base MatMulNBits kernel declares workspace for eligible DP4A and subgroup-prepack paths; this does not imply coverage of every MatMulNBits dispatch or fused operator.

Controlled WebGPU benchmark

The controlled benchmark report is the reference for these results. The superseded C++-only report has been removed to avoid presenting measurements with different cache settings and memory windows as equivalent.

Method: RTX 5090 Laptop GPU, Windows Release, Dawn Vulkan, driver 610.62. Both harnesses use enableInt64=1, graph capture off, NHWC, and explicit disabled/bucket storage-buffer caching. Each scratch/planned configuration uses five warmups, three measured requests, and two order-balanced fresh processes per phase. Latency and memory run in separate processes. The focused matrix comprises 96 workers: 80 successful and 16 OOM.

C++ measures a cached-prefill forward with repeated BOS tokens, one-token zero past cache, and full logits. GenAI uses seeded synthetic prompts and 128 generated tokens, with prefill and decode reported separately. Comparisons are controlled within each harness; these remain different workloads.

Latency

Values are scratch / planned, in seconds. GenAI decode covers the 127 tokens after the first generated token.

Model / prompt Cache C++ prefill GenAI prefill GenAI decode GenAI full scenario
Qwen 2.5 1.5B / 8K Disabled 1.887 / 1.792 1.828 / 1.822 1.657 / 2.070 3.491 / 3.898
Qwen 2.5 1.5B / 8K Bucket 1.662 / 1.648 1.797 / 1.770 1.494 / 1.472 3.315 / 3.262
Qwen 2.5 1.5B / 12K Disabled OOM / OOM OOM / OOM N/A OOM / OOM
Qwen 2.5 1.5B / 12K Bucket 3.054 / 3.024 3.143 / 3.150 1.819 / 2.566 4.983 / 5.737
Qwen 2.5 7B / 4K Disabled 1.770 / 1.668 1.615 / 1.599 2.280 / 2.760 3.903 / 4.366
Qwen 2.5 7B / 4K Bucket 1.508 / 1.499 1.560 / 1.561 2.106 / 2.112 3.689 / 3.697

Memory

Values are scratch / planned, in MiB. A single external nvidia-smi stream per memory worker covers process launch through exit; the child-reported measurement window selects the post-warmup samples. Both harnesses therefore use the same device-wide counter. These are sampled maxima, not exact allocator high-water marks.

Model / prompt Cache C++ whole-process peak C++ post-warmup peak GenAI whole-process peak GenAI post-warmup peak
Qwen 2.5 1.5B / 8K Disabled 17,606 / 17,392 17,392 / 14,824 19,576 / 17,264 17,602 / 14,992
Qwen 2.5 1.5B / 8K Bucket 4,941 / 5,101 4,941 / 5,101 4,933 / 5,093 4,933 / 5,093
Qwen 2.5 1.5B / 12K Bucket 23,655 / 23,655 23,655 / 17,985 23,639 / 23,639 23,639 / 17,969
Qwen 2.5 7B / 4K Disabled 21,151 / 20,517 21,151 / 17,559 21,067 / 20,475 20,577 / 18,257
Qwen 2.5 7B / 4K Bucket 7,328 / 7,488 7,328 / 7,488 7,320 / 7,480 7,320 / 7,480

Interpretation:

  • Storage-buffer caching explains most of the earlier C++/GenAI VRAM discrepancy. With bucket caching, their whole-process peaks agree within 8-16 MiB.
  • The 24% reduction at 1.5B/12K is post-warmup only. Whole-process peaks are unchanged because the first recording pass still uses scratch allocations.
  • Planning improves cache-disabled C++ prefill by about 5-6%, but GenAI decode is 21-25% slower in those configurations. At bucket-cached 12K, decode is 41.1% slower and the full scenario is 15.1% slower.
  • Both disabled-cache 12K modes OOM in both harnesses; both bucket-cache modes succeed. Caching, not planning, enables 12K capacity in this comparison.
  • Two process pairs do not establish precise small latency differences. Actual memory-sample spacing was median 15.99 ms, p95 16.09 ms, maximum gap 102.42 ms despite requesting 5 ms. The exact allocator/driver cause of decode regressions has not been established.

Validation

  • Windows Release WebGPU/Vulkan builds succeeded for onnxruntime_test_all and onnxruntime_provider_test; the provider-test target was rebuilt for the controlled instrumentation.
  • 22 targeted framework, memory-pattern, workspace-region, workspace-shape, and tensor-offset tests passed.
  • 5 targeted WebGPU workspace-helper and MatMul execution tests passed without skips, including a rerun after the WASM guard fixes.
  • The shared CUDA/WebGPU benchmark regression suite passed: 13 tests and 21 subtests.
  • The controlled 1K smoke matrix passed all 16 workers. The full focused matrix recorded the 80 successful workers and 16 expected-capacity OOM outcomes above.
  • Successful GenAI output hashes matched across cache/planner settings and latency/memory phases. Matching-option diagnostics confirmed planned-region consumption with both cache modes.
  • All 24 numerical report rows were checked against raw data; memory peaks were independently recomputed from timestamped samples.
  • Formatting and whitespace checks passed. The initial native-only/WASM helper compile issues were fixed in fc7463f156.

These are targeted checks, not a full-suite run or proof of planned-workspace consumption on every GPU path. The report includes reproduction commands, exact timing boundaries, provider options, runtime provenance, and measurement limitations.

Chi Lo (chilo-ms) and others added 30 commits September 18, 2026 23:43
Add an opt-in sequential static-workspace pilot that reuses one aligned buffer per device and routes MatMulNBits slot zero through it with dynamic fallback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cdd38fe6-fcf3-45c2-acea-b8e6206a7839
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cdd38fe6-fcf3-45c2-acea-b8e6206a7839
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cdd38fe6-fcf3-45c2-acea-b8e6206a7839
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cdd38fe6-fcf3-45c2-acea-b8e6206a7839
Use the cached fpA/intB tactic for fixed small-M shapes, while retaining conservative workspace declarations for cache misses and CUTLASS GEMM.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cdd38fe6-fcf3-45c2-acea-b8e6206a7839
Compare scratch and planned MatMulNBits execution with a controlled BFCArena strategy and verify that workspace overlap reduces second-run CUDA allocation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cdd38fe6-fcf3-45c2-acea-b8e6206a7839
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cdd38fe6-fcf3-45c2-acea-b8e6206a7839
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cdd38fe6-fcf3-45c2-acea-b8e6206a7839
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cdd38fe6-fcf3-45c2-acea-b8e6206a7839
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: cdd38fe6-fcf3-45c2-acea-b8e6206a7839
Track live reserved allocations separately from BFC regions and report initialization slack and internal fragmentation in the workspace benchmark.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Increase the workspace benchmark sequence length to 1024 tokens and record refreshed RTX 5090 memory and latency results.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add Qwen 3.5 hybrid-cache and Qwen 2.5 7B benchmark profiles, and record their RTX 5090 memory and latency results.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add legacy workspace sizing and planned-workspace retrieval, allocator diagnostics, CUDA coverage, and HY-MT2 memory analysis.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use fixed-capacity aliased past/present buffers to approximate ORT GenAI generation and document the RTX 5090 results.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Document the Qwen 2.5 1.5B ABBA rerun and distinguish stable memory findings from variable fresh-process latency.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Report trimmed means and stall rates, document the balanced Qwen 2.5 1.5B rerun, and record traced prefill/decode workspace usage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the matched 3-warmup, 130-sample no-shrink benchmark as the single source of truth and retain shrink only as allocator-attribution evidence.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Chi Lo and others added 24 commits September 18, 2026 23:46
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add bounded non-windowed GQA workspace estimation, conservative cache-alias sizing, slot-0 runtime consumption with scratch fallback, and Qwen benchmark results.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add the fresh-process ORT GenAI benchmark, runtime workspace-consumption diagnostics, and separate Python benchmark results from the C++ provider report.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add compact three-configuration tables for TTFT, scenario latency, TPOT, and peak VRAM across both tested Qwen models.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Organize the compact results by model and define the dispatch paths, latency metrics, and workspace-planning configurations.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Trace workspace patterns in training builds, cover oversized cached requests, and reset MatMulNBits instrumentation before early returns. Preserve CUDA plugin and no-fpA builds, Linux internal test exports, tensor-only profiling, and minimal-build size. Keep arena diagnostic outputs unchanged on failure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the public frame output API and attach the memory profiler in the new regression. Avoid unsupported workspace validation in minimal builds and unnecessary formatting for literal diagnostic errors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the dynamic scratch fallback without unused workspace vtable entries. Match other unsupported experimental APIs by returning not-implemented directly in minimal builds, with documented behavior and output-preservation coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Serialize the complete statistics table through one loop instead of duplicating conversion and insertion at each field. Preserve all 11 keys, including ReservedBytes, and add output-shape regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add offset-aware provider buffer regions, multiple MatMulNBits workspace slots, and workspace-only memory-pattern planning when WebGPU activation patterns are disabled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Track WebGPU allocator high-water statistics and compare Qwen 2.5 1.5B workspace planning with process-local WDDM sampling.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Report three balanced Qwen 2.5 1.5B runs with allocator, WDDM, and latency metrics.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add selectable Qwen profiles and report balanced Qwen 2.5 7B allocator, WDDM, and latency measurements.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the subgroup tile-size helper visible wherever its implementation is compiled and scope native-only workspace variables accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Make the Qwen benchmark sequence length configurable, capture WDDM residency after each warmup, and document long-context latency, memory, and capacity results.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Extend the shared GenAI benchmark for WebGPU and add matched cache/planner controls with separate latency and whole-process/post-warmup memory measurements. Document the focused comparison and replace the superseded C++-only report.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

1 participant