XPU oneDNN: bind matmul execution to live SYCL queue (graph-capture safe) - #2280
Conversation
Co-authored-by: luoyu-intel <108715795+luoyu-intel@users.noreply.github.com>
There was a problem hiding this comment.
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.
Pull request overview
Fixes XPU oneDNN graph-capture correctness by ensuring oneDNN execution is bound to the live SYCL queue (avoiding stale cached streams) while keeping engine reuse, and adds a regression test to prevent frozen outputs on replay.
Changes:
- Reworked
DnnlContextto cache engines per(device, sycl::context)and create streams from the current queue. - Aligned scratch-buffer keying to be context-aware to avoid cross-context reuse.
- Added an XPU regression test covering warmup-on-one-queue + capture-on-another + replay-with-new-inputs.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| auto_round_extension/ark/test/test_weightonly.py | Adds a regression test ensuring WOQ GEMM graph capture uses the live queue and replay updates outputs. |
| auto_round_extension/ark/auto_round_kernel/wrapper/include/utils.hpp | Refactors oneDNN engine/stream management to be queue-correct and context-aware, plus scratch-key changes. |
| auto_round_extension/ark/auto_round_kernel/wrapper/include/dnnl_wrapper.hpp | Removes GETCTX() macro and explicitly derives engine + live stream from the passed queue. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
/azp run Unit-Test-CUDA-AutoRound |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: luoyu-intel <108715795+luoyu-intel@users.noreply.github.com>
Co-authored-by: luoyu-intel <108715795+luoyu-intel@users.noreply.github.com>
Co-authored-by: luoyu-intel <108715795+luoyu-intel@users.noreply.github.com>
|
/azp run Unit-Test-CUDA-AutoRound |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
|
/azp run Unit-Test-CUDA-AutoRound |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
Co-authored-by: luoyu-intel <108715795+luoyu-intel@users.noreply.github.com>
|
@copilot A vLLM worker can use multiple SYCL queues concurrently while those queues belong to the same SYCL context. With the current design, those queues still share the same release(it->second, q);
auto newptr = allocate(size, q);This can cause cross-stream data corruption or use-after-free. Please make scratch allocation lifetime-safe before merging. The preferred options are:
If the queue-aware approach is selected, the scratch key should include a stable queue identity in addition to Please also add a regression test with two queues from the same SYCL context and overlapping asynchronous oneDNN operations, including the buffer-growth path. The current test validates cross-context isolation and live-queue graph capture, but does not cover same-context multi-queue scratch reuse or in-flight release. |
Co-authored-by: luoyu-intel <108715795+luoyu-intel@users.noreply.github.com>
Addressed in |
luoyu-intel
left a comment
There was a problem hiding this comment.
Thanks for addressing the review feedback.
The latest changes correctly address the main correctness issues:
- oneDNN engines are reused per
(device, SYCL context); - oneDNN streams are created from the live call queue;
- scratch-buffer identity is now queue-aware, preventing reuse across different queues in the same SYCL context;
- scratch map accesses are protected by a mutex;
- the growth path waits before releasing an existing allocation;
- regression coverage now includes same-context multi-queue scratch isolation and graph-capture behavior.
This is important for vLLM, where a single worker may use multiple SYCL queues concurrently.
A few non-blocking follow-ups remain:
-
The scratch-pool mutex is held while waiting on
q->wait()during buffer growth. This guarantees correctness, but can serialize unrelated scratch allocations and introduce host-side latency. A future improvement could detach the old allocation under the lock, release the lock, and then wait/free it, or use event-based deferred reclamation. -
Queue and context identities are retained by process-lifetime singletons. This is acceptable for the usual vLLM worker lifetime, but repeated creation of queues or contexts could grow the cached metadata and retain SYCL resources longer than necessary. An explicit teardown or cleanup policy would improve long-running or dynamic-runtime scenarios.
-
The queue-identity implementation should continue to be validated against the supported oneAPI/SYCL runtimes, especially the equality semantics used to distinguish queues. The current regression test is useful and should be retained.
-
It would be valuable to run an end-to-end vLLM XPU test covering graph capture/replay together with concurrent same-context streams, rather than only testing the lower-level debug probes.
These are follow-up improvements rather than blockers for the original stale oneDNN stream issue. With the current queue-aware scratch management and regression coverage, the PR now addresses the reported graph-capture correctness problem.
This comment has been minimized.
This comment has been minimized.
|
/azp run Unit-Test-CUDA-AutoRound |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
Signed-off-by: chensuyue <suyue.chen@intel.com>
|
/azp run Unit-Test-CUDA-AutoRound |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
|
/azp run Unit-Test-CUDA-AutoRound |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
…h capture The wait() added in 33c470d ('fix: wait before scratch grow free on XPU queues') blocks the host on queue.wait() whenever a scratch slab needs to grow. This is illegal when the queue is in command-graph capture mode (torch.xpu.graph), so any woq_gemm call that hits the grow path during a capture run crashes with: RuntimeError: wait cannot be called for a queue which is recording The wait is also redundant for correctness: * The scratch slab is now keyed per-queue (device+context+queue), so only work enqueued on the same queue q can reference it. * Both sycl::free (release) and sycl::aligned_alloc_device (allocate) are associated with the same in-order queue q, so the SYCL runtime guarantees the old slab is retired before any subsequent kernel on q can alias it. * The same pattern (free without wait, relying on queue in-order semantics) is already used in sycl_tla_moe_prefill_fp8_native.hpp. Removing the call eliminates both the graph-capture crash and the unnecessary host-side stall on every growth. Verified on Arc B60 (G21), torch 2.13+xpu, oneAPI 2026.1: - int8 TLA path: m=1..16 same & separate stream -> all pass - fp16 oneDNN path: m=1..16 same & separate stream -> all pass - existing UT: 306 passed, 17 skipped (test_weightonly.py)
Description
Issue #2206 reports that XPU oneDNN stream caching was keyed too coarsely (device UUID), so later calls could execute on a stale queue instead of the active
torch.xpugraph-capture queue;m > 1WOQ GEMM then escaped capture and replay produced frozen/zero outputs.This PR makes oneDNN execution queue-correct while preserving engine reuse.
Root cause / scope
DnnlContextcacheddnnl::streamper device; stream stayed bound to first queue seen.woq_gemm(m > 1, fp16/fp32 oneDNN path) executed via that stale stream.Queue-correct execution model
DnnlContext:(device, sycl::context)(reused for performance),Call-chain cleanup
GETCTX()usage from active oneDNN GEMM/quant paths.gemm/dyn_quant_s8/igemm_s8s8now explicitly derive engine+stream from passedq.Regression coverage
m > 1, replay with changed inputs; replay output must track eager reference (not frozen).Type of Change
Bug fix
Related Issues
Tracked in repository issue tracker (auto-linking handled by system).
Checklist Before Submitting
/azp run Unit-Test-CUDA-AutoRound.