Skip to content

Add packed attention workspace estimates - #32321

Merged
Ti-Tai Wang (titaiwangms) merged 6 commits into
mainfrom
titaiwangms/packed-attention-workspace-l1-l2
Sep 4, 2026
Merged

Ti-Tai Wang (titaiwangms) merged 6 commits into
mainfrom
titaiwangms/packed-attention-workspace-l1-l2

Conversation

@titaiwangms

@titaiwangms Ti-Tai Wang (titaiwangms) commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Add MatMulNBits-equivalent operator-side workspace estimation for CUDA
PackedAttention and PackedMultiHeadAttention:

  • Level 1 derives a conservative estimate from the node, resolved input shapes,
    CUDA device properties, and the EP's resolved attention options.
  • Level 2 declares the same estimate from positional WorkspaceInputShape
    metadata and constructed kernel state.
  • Existing graph-free runtime recipes remain the single source of truth for
    workspace bytes and layouts.
  • PackedAttention declares one 256-byte-aligned root in slot 0, with internal
    projection and attention regions.
  • PackedMultiHeadAttention declares one 256-byte-aligned attention root in slot 0.

Level 1 is log-only, matching the current MatMulNBits pilot. This PR does not
add #32071-specific planner APIs or change runtime GetScratchBuffer() behavior.

Route aggregation

Runtime routes are mutually exclusive, so the estimate uses:

PackedAttention:
  align_up(projection_bytes, 256) + max(feasible TRT, MEA, unfused recipes)

PackedMultiHeadAttention:
  max(feasible Flash, TRT, MEA, unfused recipes)

Route reachability is evaluated conservatively for every runtime shape up to
the supplied maximum geometry. This is necessary because Flash/MEA thresholds
and attention-bias alignment gates are not monotonic when moving from a maximum
shape to a smaller runtime shape. Unfused fallback is always retained, and a
failure to size any included route makes the estimate unavailable rather than
silently underestimating.

Shape and zero semantics

  • Missing mandatory inputs, shapeless required inputs, unknown dimensions,
    malformed geometry, and checked-arithmetic overflow produce no estimate.
  • WorkspaceInputShape does not carry max-shape provenance, so zero-shaped
    framework hints are conservatively treated as unavailable.
  • Exact zero behavior remains supported by the graph-free runtime recipes.
  • At the current Level-2 boundary, both unavailable and zero are represented by
    an empty requirements list.

Planner integration

  • Both operators fit Integrate CUDA workspace with activation memory patterns #32071's current one-slot pilot. Generic framework
    multi-slot support remains unchanged.
  • A declaration alone is not planner opt-in. SupportsPreallocatedWorkspace(),
    slot-0 retrieval, and PA root slicing must land atomically in the planner
    integration.
  • Until then, PA retains its two dynamic allocations and PMHA retains its one
    dynamic allocation.

Build boundaries

The framework adapters and kernel overrides are excluded from:

  • CUDA minimal builds
  • DISABLE_CONTRIB_OPS builds
  • CUDA plugin EP builds

The graph-free workspace recipes remain available to the shared BERT attention
infrastructure where required.

Validation

  • 18/18 PA/PMHA workspace estimator tests
    • includes direct production-kernel Level-2 declaration tests
    • route-threshold, max-not-sum, aligned-root padding/no-padding,
      optional-hole, zero, overflow, and malformed geometry coverage
  • 23/23 existing packed-attention workspace recipe tests
  • 20/20 existing hand-calculated runtime parity cases
  • 26/26 PackedAttention/PackedMultiHeadAttention runtime operator tests
  • CUDA provider-test build
  • 145 CUDA internal tests executed: 143 passed, 2 unrelated LeanAttention skips
  • DISABLE_CONTRIB_OPS and CUDA-minimal compile-guard probes
  • C++ formatting and diff checks

Dependency

This is a stacked follow-up to #32312. The base should change to main after
#32312 merges.

Tracking: #29775

Comment thread onnxruntime/core/providers/cuda/cuda_execution_provider.cc
@xadupre

Xavier Dupré (xadupre) commented Aug 31, 2026

Copy link
Copy Markdown
Member

Is it possible to add a link to the main document designing the feature, it is difficult to understand how this bricks is connected with the others.

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

Adds conservative CUDA workspace estimates and Level-2 declarations for packed attention operators. No actionable issues found.

Changes:

  • Aggregates mutually exclusive backend workspace recipes safely.
  • Adds graph/kernel adapters and stable workspace slots.
  • Adds extensive estimator, boundary, and integration tests.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
cuda_execution_provider.cc Logs Level-1 estimates.
packed_attention.h Declares Level-2 override.
packed_attention.cc Implements PA declaration.
packed_multihead_attention.h Declares Level-2 override.
packed_multihead_attention.cc Implements PMHA declaration.
packed_attention_workspace.h Defines masks and aggregates.
packed_attention_workspace.cc Aggregates route recipes.
packed_attention_workspace_estimate.h Defines estimator API.
packed_attention_workspace_estimate.cc Implements shape and route estimation.
packed_attention_workspace_estimate_test.cc Adds estimator coverage.
cuda_kernel_workspace_inventory.md Documents workspace slots.
attention_workspace_estimation.md Documents framework integration.

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

@titaiwangms

Ti-Tai Wang (titaiwangms) commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Thanks Xavier Dupré (@xadupre). The Related design and rollout section at the top of the Attention workspace roadmap now links #29775, the generic framework design, #32312, #32071, and this PA/PMHA adapter PR. The latest update also documents the one-aligned-root contract and explicit planner opt-in so the dependency chain and runtime transition are visible from the document.

@titaiwangms
Ti-Tai Wang (titaiwangms) force-pushed the titaiwangms/packed-attention-workspace-l1-l2 branch 2 times, most recently from 38b5052 to cf916be Compare September 2, 2026 00:41
@titaiwangms

Copy link
Copy Markdown
Contributor Author

Follow-up after the planner discussion with Chi Lo (@chilo-ms): PA no longer declares two framework slots. The two slots mirrored its current projection and Attention GetScratchBuffer() allocations, but they are not an inherent planner requirement. PA now declares one 256-byte-aligned slot-0 root with an aligned Attention subregion; PMHA declares one aligned Attention root. Generic framework multi-slot support remains unchanged. Neither kernel opts into planning yet: SupportsPreallocatedWorkspace(), root retrieval, and PA slicing must land atomically with the #32071 integration, while the current dynamic allocations remain unchanged.

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.

🟡 Changes recommended

Dynamic head-size bounds can omit a reachable MEA route and produce an undersized workspace declaration.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (1)

onnxruntime/contrib_ops/cuda/bert/packed_attention_workspace_estimate.cc:407

  • PMHA has the same max-head-only reachability gap. A packed FP16 maximum shape [1, 1, 3, 1032] excludes MEA here and declares only the 6,704-byte unfused workspace, while the valid smaller runtime shape [1, 1, 3, 1024] can select MEA and requires 10,240 bytes. Enumerate backend support boundaries for variable head dimensions, not just sequence-length thresholds, so every runtime geometry up to the hint is covered.
      has_memory_efficient_attention(
          sm, problem.element_size == 2, false,
          problem.qk_head_size, problem.v_head_size);
  • Files reviewed: 12/12 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread onnxruntime/contrib_ops/cuda/bert/packed_attention_workspace_estimate.cc Outdated
Base automatically changed from titaiwangms/workspace-optional-input-shapes to main September 4, 2026 03:07
Copilot AI added 6 commits September 3, 2026 20:07
Add route-aware Level-1 estimates and Level-2 workspace declarations for PackedAttention and PackedMultiHeadAttention while preserving the shared runtime recipes and dynamic allocation fallback.

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

Copilot-Session: c04148cc-7ace-4cf4-b981-0ddc92334e78
Connect the PA and PMHA roadmap to the framework contract, planner, and tracking issue so the stacked workspace changes are easier to follow.

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

Copilot-Session: c04148cc-7ace-4cf4-b981-0ddc92334e78
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: c04148cc-7ace-4cf4-b981-0ddc92334e78
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: c04148cc-7ace-4cf4-b981-0ddc92334e78
Keep the single-root formulas readable without fragile manual column padding.

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

Copilot-Session: c04148cc-7ace-4cf4-b981-0ddc92334e78
Use backend-owned reachability predicates for smaller supported head sizes while preserving exact attribute-derived geometry and sizing all reachable routes at the componentwise maximum.

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

Copilot-Session: c04148cc-7ace-4cf4-b981-0ddc92334e78
@titaiwangms
Ti-Tai Wang (titaiwangms) force-pushed the titaiwangms/packed-attention-workspace-l1-l2 branch from 9583415 to e59acd7 Compare September 4, 2026 03:07
@titaiwangms
Ti-Tai Wang (titaiwangms) merged commit 51df5b5 into main Sep 4, 2026
94 checks passed
@titaiwangms
Ti-Tai Wang (titaiwangms) deleted the titaiwangms/packed-attention-workspace-l1-l2 branch September 4, 2026 18:03
Ti-Tai Wang (titaiwangms) added a commit that referenced this pull request Sep 14, 2026
## Summary

Add the graph-free workspace preparation foundation for CUDA
`GroupQueryAttention`, following the checked-recipe architecture
established by #32321.

- model windowed KV-cache staging and compaction without changing
runtime allocations;
- model 3-vector/6-vector sequence metadata and Flash fast-decode
suppression;
- model route-selected QKV preprocessing requirements;
- use checked arithmetic and one internally 256-byte-aligned preparation
layout;
- distinguish transient staging/compaction from output KV cache and
persistent/prepacked state.

## Scope

This is the first GQA workspace-estimation PR in the #29775 rollout. It
intentionally does **not** add backend-internal workspace recipes, route
aggregation, Level-1 estimation, Level-2 declaration, cuDNN workspace
queries, or #32071 planner integration. Existing `GetScratchBuffer()`
allocation count, size, lifetime, and pointer layout are unchanged.

Follow-up PRs will add:

1. XQA and Flash regular/fast-decode workspace recipes.
2. CUTLASS MEA and unfused fallback recipes plus the complete route
aggregate.
3. Optional-aware Level-1/Level-2 adapters with one 256-byte-aligned
operator root.
4. cuDNN support only if an exact runtime-parity workspace query can be
established.

## Validation

- 30 GQA workspace recipe and validation tests passed.
- 73 related GroupQueryAttention runtime tests passed; 12 WebGPU-only
tests skipped because WebGPU EP was unavailable.
- CUDA provider test target built successfully.

Tracking: #29775

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b24d04bb-12ab-41a0-8941-76eb9769005d
Chi Lo (chilo-ms) pushed a commit that referenced this pull request Sep 17, 2026
Add MatMulNBits-equivalent operator-side workspace estimation for CUDA
`PackedAttention` and `PackedMultiHeadAttention`:

- Level 1 derives a conservative estimate from the node, resolved input
shapes,
  CUDA device properties, and the EP's resolved attention options.
- Level 2 declares the same estimate from positional
`WorkspaceInputShape`
  metadata and constructed kernel state.
- Existing graph-free runtime recipes remain the single source of truth
for
  workspace bytes and layouts.
- PackedAttention declares one 256-byte-aligned root in slot 0, with
internal
  projection and attention regions.
- PackedMultiHeadAttention declares one 256-byte-aligned attention root
in slot 0.

Level 1 is log-only, matching the current MatMulNBits pilot. This PR
does not
add #32071-specific planner APIs or change runtime `GetScratchBuffer()`
behavior.

Runtime routes are mutually exclusive, so the estimate uses:

```text
PackedAttention:
  align_up(projection_bytes, 256) + max(feasible TRT, MEA, unfused recipes)

PackedMultiHeadAttention:
  max(feasible Flash, TRT, MEA, unfused recipes)
```

Route reachability is evaluated conservatively for every runtime shape
up to
the supplied maximum geometry. This is necessary because Flash/MEA
thresholds
and attention-bias alignment gates are not monotonic when moving from a
maximum
shape to a smaller runtime shape. Unfused fallback is always retained,
and a
failure to size any included route makes the estimate unavailable rather
than
silently underestimating.

- Missing mandatory inputs, shapeless required inputs, unknown
dimensions,
malformed geometry, and checked-arithmetic overflow produce no estimate.
- `WorkspaceInputShape` does not carry max-shape provenance, so
zero-shaped
  framework hints are conservatively treated as unavailable.
- Exact zero behavior remains supported by the graph-free runtime
recipes.
- At the current Level-2 boundary, both unavailable and zero are
represented by
  an empty requirements list.

- Both operators fit #32071's current one-slot pilot. Generic framework
  multi-slot support remains unchanged.
- A declaration alone is not planner opt-in.
`SupportsPreallocatedWorkspace()`,
slot-0 retrieval, and PA root slicing must land atomically in the
planner
  integration.
- Until then, PA retains its two dynamic allocations and PMHA retains
its one
  dynamic allocation.

The framework adapters and kernel overrides are excluded from:

- CUDA minimal builds
- `DISABLE_CONTRIB_OPS` builds
- CUDA plugin EP builds

The graph-free workspace recipes remain available to the shared BERT
attention
infrastructure where required.

- 18/18 PA/PMHA workspace estimator tests
  - includes direct production-kernel Level-2 declaration tests
  - route-threshold, max-not-sum, aligned-root padding/no-padding,
    optional-hole, zero, overflow, and malformed geometry coverage
- 23/23 existing packed-attention workspace recipe tests
- 20/20 existing hand-calculated runtime parity cases
- 26/26 PackedAttention/PackedMultiHeadAttention runtime operator tests
- CUDA provider-test build
- 145 CUDA internal tests executed: 143 passed, 2 unrelated
LeanAttention skips
- `DISABLE_CONTRIB_OPS` and CUDA-minimal compile-guard probes
- C++ formatting and diff checks

This is a stacked follow-up to #32312. The base should change to `main`
after

Tracking: #29775

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Copilot-Session: c04148cc-7ace-4cf4-b981-0ddc92334e78
Chi Lo (chilo-ms) pushed a commit that referenced this pull request Sep 17, 2026
## Summary

Add the graph-free workspace preparation foundation for CUDA
`GroupQueryAttention`, following the checked-recipe architecture
established by #32321.

- model windowed KV-cache staging and compaction without changing
runtime allocations;
- model 3-vector/6-vector sequence metadata and Flash fast-decode
suppression;
- model route-selected QKV preprocessing requirements;
- use checked arithmetic and one internally 256-byte-aligned preparation
layout;
- distinguish transient staging/compaction from output KV cache and
persistent/prepacked state.

## Scope

This is the first GQA workspace-estimation PR in the #29775 rollout. It
intentionally does **not** add backend-internal workspace recipes, route
aggregation, Level-1 estimation, Level-2 declaration, cuDNN workspace
queries, or #32071 planner integration. Existing `GetScratchBuffer()`
allocation count, size, lifetime, and pointer layout are unchanged.

Follow-up PRs will add:

1. XQA and Flash regular/fast-decode workspace recipes.
2. CUTLASS MEA and unfused fallback recipes plus the complete route
aggregate.
3. Optional-aware Level-1/Level-2 adapters with one 256-byte-aligned
operator root.
4. cuDNN support only if an exact runtime-parity workspace query can be
established.

## Validation

- 30 GQA workspace recipe and validation tests passed.
- 73 related GroupQueryAttention runtime tests passed; 12 WebGPU-only
tests skipped because WebGPU EP was unavailable.
- CUDA provider test target built successfully.

Tracking: #29775

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: b24d04bb-12ab-41a0-8941-76eb9769005d
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.

5 participants