Skip to content

Fix a regression in graph-capture session initialization that rejects an empty graph#29457

Merged
tianleiwu merged 3 commits into
mainfrom
adrastogi/dml-memcpy-fix
Jul 6, 2026
Merged

Fix a regression in graph-capture session initialization that rejects an empty graph#29457
tianleiwu merged 3 commits into
mainfrom
adrastogi/dml-memcpy-fix

Conversation

@adrastogi

@adrastogi adrastogi commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Description

InferenceSession::Initialize() validates, for any EP that has graph capture enabled and uses the ALLOW_CPU_FOR_SHAPES node-assignment policy (DirectML, WebGPU), that the partitioned graph is eligible for capture via AreAllComputeNodesAssignedToEpOrCpu(). That helper currently requires at least one node to be assigned to the EP:

return has_node_on_provider && !HasMemcpyNodes(graph);

For a graph with no nodes, like a model that is fully consumed by the EP's runtime graph fusion, or that trivially folds away (like a lone Constant  node), has_node_on_provider is false, so the session throws:

This session cannot use the graph capture feature as requested by the user as all compute graph nodes have not been partitioned to the DmlExecutionProvider

An empty graph contains nothing that violates the "all compute on the EP or CPU, no Memcpy" requirement, so it should be allowed. This change permits the empty-graph case:

return (has_node_on_provider || graph.NumberOfNodes() == 0) && !HasMemcpyNodes(graph);

Behavior is unchanged for all non-empty graphs (the expression collapses to the original  has_node_on_provider).

Adds  CApiTest.DmlGraphCaptureEmptyGraph : creates a DML session with  ep.dml.enable_graph_capture=1 on a single Constant model (folds to an empty graph) and asserts session creation does not throw. The test fails without this fix and passes with it.

Motivation and Context

#27958 refactored the graph-capture selection logic and replaced AreAllComputeNodesAssignedToCudaOrJsOrDmlEpWebGpuEp() (which returned true for an empty graph) with AreAllComputeNodesAssignedToEpOrCpu() and its new  has_node_on_provider  requirement. The behavior verified with a DLL-swap: onnxruntime-directml 1.24.x/1.25.2 create the session successfully; 1.27 throws.

The failure surfaces through ONNX Runtime GenAI on DirectML: GenAI creates a per-device "allocator-initialization" session on a Constant-only model with DML graph capture enabled to obtain a device allocator (model.cpp). Under ORT 1.27 that session throws at construction, which breaks every GroupQueryAttention-based GenAI LLM on the DirectML EP (observed as WinML EP certification failures across DeepSeek/Llama/Qwen/Phi models

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.

Pull request overview

Fixes a regression in InferenceSession::Initialize() where enabling graph capture for EPs using the ALLOW_CPU_FOR_SHAPES policy incorrectly rejected models that optimize/fold down to an empty graph. This restores expected behavior for constant-only / fully-fused graphs while keeping the existing validation for non-empty graphs.

Changes:

  • Allow empty graphs to pass AreAllComputeNodesAssignedToEpOrCpu() as long as there are no Memcpy nodes.
  • Add a DirectML regression test that enables DML graph capture on a Constant-only model and asserts session creation does not throw.
Show a summary per file
File Description
onnxruntime/test/shared_lib/test_inference.cc Adds a DML regression test for graph-capture session initialization on a model that folds to an empty graph.
onnxruntime/core/session/inference_session.cc Updates the graph-capture eligibility check to allow empty graphs under ALLOW_CPU_FOR_SHAPES when no Memcpy nodes exist.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment thread onnxruntime/test/shared_lib/test_inference.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.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Low

@adrastogi
adrastogi requested a review from yuslepukhin July 1, 2026 18:47

@tianleiwu tianleiwu 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.

I reviewed the current head. The graph-capture eligibility change looks correct for optimized-empty graphs, and the DML run/capture hooks make the empty replay path a no-op. I found one small style nit in the test updates.

Comment thread onnxruntime/test/shared_lib/test_inference.cc Outdated
@adrastogi

Copy link
Copy Markdown
Contributor Author

@tianleiwu thanks for taking a look; would you mind approving if it meets your bar? Thanks!

@tianleiwu
tianleiwu merged commit 0a62d6a into main Jul 6, 2026
86 of 87 checks passed
@tianleiwu
tianleiwu deleted the adrastogi/dml-memcpy-fix branch July 6, 2026 22:08
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.

3 participants