Repository navigation
[CUDA] Bound GQA non-windowed workspace via the KV-length envelope (route-aware L1 estimate) - #33016
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Valid static-cache executions can exceed the estimate when allocated past capacity is larger than the declared total-length envelope.
1 open finding
What changed in this PR
Adds opt-in, envelope-bounded workspace estimation for non-windowed CUDA GroupQueryAttention.
Changes:
- Uses the configured KV-length envelope for non-windowed estimates.
- Accounts for partial-alias past-cache preservation scratch.
- Adds envelope and monotonicity tests.
| File | Description |
|---|---|
group_query_attention_workspace_estimate_test.cc |
Tests non-windowed envelope behavior and preservation accounting. |
cuda_execution_provider.cc |
Updates envelope-consumption commentary. |
group_query_attention_workspace_estimate.h |
Documents the active envelope configuration. |
group_query_attention_workspace_estimate.cc |
Builds non-windowed bounds from the envelope. |
group_query_attention_workspace_bounds.h |
Adds preservation-scratch accounting state. |
group_query_attention_workspace_bounds.cc |
Adds preservation bytes to aggregate workspace. |
onnxruntime_session_options_config_keys.h |
Documents the session option’s behavior. |
resource_accountant.h |
Removes obsolete reader-only wording. |
🧠 Review effort: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Ti-Tai Wang (titaiwangms)
left a comment
There was a problem hiding this comment.
Reviewed at a17ecc6de4ee533fbdf58ee42edfaf4fca226210.
No blocking source finding established. The bound now accounts for allocated cache capacity independently of the active KV envelope, and adds partial-alias preservation on top of the backend maximum. The explicit L1-only scope and the absence of runtime envelope enforcement are appropriate for this slice; missing L2 forwarding is not a blocker for this PR.
Two small documentation updates would help:
- The bounds header still says callers must separately account for partial-alias preservation, although the new flag makes the aggregate account for it. See the inline comment.
- Please update
docs/annotated_partitioning/attention_workspace_estimation.md, which still describes successful graph-adapter estimation as sliding-window-only. Describe positive-envelope non-windowed eligibility, remaining decline conditions such as a reachable cuDNN route without an oracle, and the unchanged generic accountant fallback when estimation is unavailable.
Validation evidence: In the existing exact-head Linux CUDA CI, the static-cache preservation and MEA-expansion tests, plus the envelope tests, executed and passed. I did not run a local ORT build or tests. This review does not establish a runtime-enforced capacity or no-OOM guarantee, nor does it validate a combined tree with #32071.
|
Thanks for the exact-head review. Both documentation findings are addressed in the prepared local hardening stack at
The final policy intentionally requires a proven GQA bound for capacity-aware CUDA placement: unavailable GQA estimation declines assignment, while generic fallback remains unchanged for unrelated operators and profile data cannot substitute for the missing proof. The update is committed locally but will be published after #33118 merges so the old duplicated sizing stack can be dropped cleanly. The public head remains |
a17ecc6 to
1f175d3
Compare
## Summary Complete the preparation-sizing half of Stage 1 in the policy-based, route-aware workspace-estimation design (#32944). This combines the agreed QKV-preprocessing refactor and the remaining cache/sequence preparation sizing into one PR. Builds on #32945, now merged into `main`, which consolidates MEA, unfused, XQA and Flash backend scratch sizing. - Share checked cache-row, past-preservation, staging, compaction, sequence-vector and QKV-preprocessing calculations between `ComputeInternal` and `GetGQAPreparationRecipe`. - Remove the duplicate `GQABufferRequirements` implementation. - Keep the existing separate allocations, ownership, pointer wiring, dispatch priorities and lifetimes. - Preserve the preparation recipe's aligned layout and full validation; the live kernel calls narrow sizing helpers rather than inheriting unrelated recipe-admission restrictions. This is sizing-code consolidation, not a missing-buffer fix. It does not activate dispatch policies, exclude routes from L1, coalesce allocations, or change static-preallocation strategy. ## Compatibility details - Cache sizing runs before backend selection and retains the original present-cache capacity. Windowed staging still changes the runtime extent from `C` to `C + S`. - Past preservation uses the aliased tensor's physical row width; staging uses the physical output row width; compaction retains its packed-row interpretation. INT4 rows are not packed a second time. - QKV sizing runs after the existing backend selection and receives the effective post-staging capacity. cuDNN retains the existing generic Q-materialization behavior. - Flash fast decode still reuses the device sequence-length input instead of allocating sequence vectors, and still suppresses the QKV-preprocessing buffer. - Existing healthy-input byte counts are retained. Arithmetic overflow and invalid sizing inputs produce explicit sizing statuses at the runtime boundary. ## Coverage and validation - Fresh standalone build of the existing preparation Google Test source: **50 tests passed**, including the legacy QKV feature matrix, dense/byte/INT4 cache geometry, physical packed rows, sequence-vector suppression, invalid dimensions and overflow. - MSVC `/W4 /WX` compilation of the actual CUDA GQA runtime translation unit in both shared-provider and plugin-adapter configurations, with Flash, MEA, FP8 and INT4 enabled. - MSVC `/W4 /WX` compilation of the graph-time estimator and XQA/Flash sizing-test translation units. - MSVC `/W4 /WX` compilation of the CUDA GQA operator-test translation unit. - Four new CUDA regressions compare packed and separate QKV on unfused/Flash paths, including windowed staging. They reuse the aliasing helper, which disables CPU fallback and verifies actual backend dispatch. - `clang-format --dry-run --Werror` and `git diff --check` passed. **Full CUDA inference execution is not validated locally against a freshly linked provider.** The new operator regressions and existing GQA tests need full CUDA build/test CI. ## Stack Base: `main`. The conflict-resolution merge retains the early preparation-sizing initialization, the upstream seq-free eligibility helpers, and the INT8/FP8 storage-width normalization. The envelope and policy-reader PRs (#33014, #33016 and #33042) remain independent of this refactor. Committed-policy resolution, coverage/envelope enforcement, bounded fallback and policy-bound estimates remain follow-up work. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7fa98d07-aec3-41b7-92b8-b0ec317a95bf
…oute-aware L1 estimate) Make the GQA Level-1 workspace estimator produce a sound bound for the non-windowed KV-cache case instead of declining. Previously BuildBounds returned nullopt for every non-windowed node because total_sequence_length is a runtime scalar not recoverable from shapes. It now uses the declared KV-length envelope (config.max_total_sequence_length, from session option ep.cuda.gqa_workspace_max_total_sequence_length, plumbed in the prior PR) as present_kv_cache_capacity_bound and evaluates the existing route-aware, phase-cornered aggregate over it. Opt-in and default-off: when the envelope is unset (== 0) the non-windowed path still returns nullopt, so behavior is byte-identical to today. The windowed path is untouched -- every change is guarded by the windowed flag. Soundness: - Backend workspace is non-decreasing in KV length and the runtime sizes non-windowed scratch from total_sequence_length <= envelope (GetGQAEffectiveWorkspaceKvLength), so capacity_bound = envelope is an upper bound. - Non-windowed partial aliasing (exactly one past/present K/V pair shared) copies the full past cache into preservation scratch that coexists with the backend workspace. This is now charged on top of the per-route maximum via GQAWorkspaceBounds::account_partial_alias_preservation, bounded by the envelope and head_size_bound. Windowed GQA rejects non-shared buffers, so it never incurs this copy. - cuDNN (when reachable) and attention bias conservatively decline (nullopt), keeping the estimate an upper bound. The small seq_lens buffer remains an unmodeled pre-existing gap shared with the windowed path. Tests (onnxruntime_provider_test): non-windowed without an envelope still declines; with an envelope it is bounded and monotonic in the envelope; the preservation copy is additive on top of the selected route. Part of the policy-based workspace estimation effort; see docs/annotated_partitioning/policy_based_workspace_estimation.md and the PR chain (#32944, #32945, #33001, #33014). Base retargets to main after #33014 merges. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7fa98d07-aec3-41b7-92b8-b0ec317a95bf
Use the larger of allocated past capacity and the total-KV envelope to cover MEA expansion and full partial-alias preservation. Keep the query-length envelope check independent and add static-cache and runtime-ABI regressions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7fa98d07-aec3-41b7-92b8-b0ec317a95bf
Reject out-of-ABI envelopes during initialization, require a proven route-aware GQA estimate for capacity-aware CUDA placement, and keep the caller-declared envelope contract explicit. Share the validated parser for Level-2 reuse and cover invalid values plus fail-closed placement. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ti-Tai Wang (titaiwangms)
left a comment
There was a problem hiding this comment.
Reviewed the four-commit delta from the approved #33118 head (80292cc) to 1f175d3. The branch contains that exact preparation baseline; the divergent main comparison results from the squash merge, not missing preparation changes.
No blocking source findings. The non-windowed estimate covers the greater of allocated cache capacity and the declared envelope, plus worst-case partial-alias preservation. The shared parser preserves zero/unset semantics while rejecting values outside the runtime int32 ABI. In the in-tree capacity-aware CUDA path, an unavailable GQA estimate now declines assignment before generic fallback or profile accounting; ordinary placement without an accountant is unchanged. The corresponding placement and parser boundary tests are present, and the previously noted stale envelope documentation has been updated.
Nonblocking documentation follow-up: please qualify the new fail-closed guarantee as applying to the in-tree CUDA estimation path. BUILD_CUDA_EP_AS_PLUGIN still excludes the GQA Level-1 estimation block and its integration tests, so this PR does not establish the same guarantee for CUDA-plugin placement.
Validation caveat: at the latest check snapshot for this exact head, 27 checks succeeded, one was neutral, 57 were pending, and none had failed. The CUDA jobs were still running, so I have not verified execution of the new placement/static-cache boundary tests on this revision. This is a source-review approval, not an assertion that CI is complete or that the declared envelope is runtime-enforced. No local build or tests were run.
1f175d3 to
3633cea
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: c132130a-b0c7-422c-9ff7-75826b6ea3fc
Reject new capacity-aware CUDA plugin GQA assignments until analytical estimates reach host accounting, including fused groups. Preserve normal placement and previously accounted nodes, document the limitation, and add regression coverage for generic and profiled accounting. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b95559c4-5cbe-4787-8dd7-ffa45a2157f9
Use IndexedSubGraph::IsAccountingEnabled() instead of accessing its private resource_accountant member. Preserve the accounting assertion while fixing the cross-platform CI compilation failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b95559c4-5cbe-4787-8dd7-ffa45a2157f9
Ti-Tai Wang (titaiwangms)
left a comment
There was a problem hiding this comment.
Reviewed the isolated change from 11cba206fbff12b570264ac8e188cf3841cd9487 to 83019a940215caaff5694eaec613df1ad8237e3c with the five-role review team. No introduced Major/Critical blocker was established.
The admission behavior is appropriately fail-closed: unavailable analytical GQA proof is rejected before profile/accountant selection, and the plugin path rejects the entire proposed CUDA group rather than partially accepting it. The bound accounts for allocated cache capacity and partial-alias preservation, not just active KV length. The real CUDA plugin uses the canonical provider name matched by this guard.
Non-blocking suggestion: add an in-tree CUDA placement regression combining an available low-cost CSV row with unavailable analytical proof. The production ordering is correct, but the plugin regression exercises a different implementation path.
Validation evidence: actual logs from exact-head jobs 115974061041 and 116000568459 show passes for PluginExecutionProviderTest.GetCapability_CudaGqaRequiresProvenEstimate, RealAccountantTest.FactoryParsesGqaWorkspaceEnvelope, and RealAccountantTest.FactoryRejectsInvalidGqaWorkspaceEnvelope. These framework/plugin results are not evidence that the in-tree CUDA workspace tests executed. No local build, Run test, sanitizer, benchmark, concurrent-Run stress, or physical-memory measurement was performed.
The envelope remains a caller-declared workload bound, not a runtime sequence-length clamp or a whole-session no-OOM guarantee. CUDA placement rejection may leave a model without a supported CPU fallback; this review does not promise successful fallback for every dtype/cache configuration.
### Description <!-- Describe your changes. --> Make `NchwcOptimizerTests.ConvWithZeroInputChannelsIsNotTransformed` a graph-only regression instead of running the zero-channel convolution through `NchwcOptimizerTester`. - Build and resolve the same zero-input-channel Conv with and without bias. - Assign the Conv to the CPU EP and apply `NchwcTransformer` directly, following the adjacent rank-validation regression's pattern. - Assert that the transformer reports no modification, the ordinary Conv remains, and no NCHWc Conv, ReorderInput, or ReorderOutput nodes are inserted. - Explicitly skip platforms without NCHWc support. No production optimizer or kernel changes. The zero-output-channel regression and other numerical optimizer tests are unchanged. Validation: whitespace (`git diff --check`) and changed-range clang-format checks passed. No local build or C++ test run, as requested. ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> Follow-up to #33346. The new regression currently executes the degenerate Conv at optimization levels 2 and 3 and compares the outputs. macOS arm64 CI reports NaN-versus-zero mismatches at `nchwc_optimizer_test.cc:235`, despite this test's intended contract being that NCHWc conversion is skipped. The same assertion is confirmed independently on upstream `main` and multiple PRs: - [main at 9cdf0f1, macOS WebGPU arm64 Release](https://github.com/microsoft/onnxruntime/actions/runs/38675468798/job/116227944699) - [#33016, macOS WebGPU arm64 Debug](https://github.com/microsoft/onnxruntime/actions/runs/38599291872/job/116132732574) - [#33347, macOS WebGPU arm64 Debug](https://github.com/microsoft/onnxruntime/actions/runs/38707806696/job/116332127965) Check the optimizer's graph contract directly without making this regression depend on zero-channel Conv execution. This is a test-only CI fix, not a correction to CPU Conv's zero-channel numerical behavior. Co-authored-by: Chi Lo <lochi@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b95559c4-5cbe-4787-8dd7-ffa45a2157f9
Include the graph-only zero-input-channel NCHWc regression fix from PR #33398 while preserving the GQA workspace estimation hardening. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b95559c4-5cbe-4787-8dd7-ffa45a2157f9
### Description <!-- Describe your changes. --> Make `NchwcOptimizerTests.ConvWithZeroInputChannelsIsNotTransformed` a graph-only regression instead of running the zero-channel convolution through `NchwcOptimizerTester`. - Build and resolve the same zero-input-channel Conv with and without bias. - Assign the Conv to the CPU EP and apply `NchwcTransformer` directly, following the adjacent rank-validation regression's pattern. - Assert that the transformer reports no modification, the ordinary Conv remains, and no NCHWc Conv, ReorderInput, or ReorderOutput nodes are inserted. - Explicitly skip platforms without NCHWc support. No production optimizer or kernel changes. The zero-output-channel regression and other numerical optimizer tests are unchanged. Validation: whitespace (`git diff --check`) and changed-range clang-format checks passed. No local build or C++ test run, as requested. ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> Follow-up to #33346. The new regression currently executes the degenerate Conv at optimization levels 2 and 3 and compares the outputs. macOS arm64 CI reports NaN-versus-zero mismatches at `nchwc_optimizer_test.cc:235`, despite this test's intended contract being that NCHWc conversion is skipped. The same assertion is confirmed independently on upstream `main` and multiple PRs: - [main at 9cdf0f1, macOS WebGPU arm64 Release](https://github.com/microsoft/onnxruntime/actions/runs/38675468798/job/116227944699) - [#33016, macOS WebGPU arm64 Debug](https://github.com/microsoft/onnxruntime/actions/runs/38599291872/job/116132732574) - [#33347, macOS WebGPU arm64 Debug](https://github.com/microsoft/onnxruntime/actions/runs/38707806696/job/116332127965) Check the optimizer's graph contract directly without making this regression depend on zero-channel Conv execution. This is a test-only CI fix, not a correction to CPU Conv's zero-channel numerical behavior. Co-authored-by: Chi Lo <lochi@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b95559c4-5cbe-4787-8dd7-ffa45a2157f9 (cherry picked from commit 1988019)
… estimator (reader-only) Adds the hardware-neutral session option session.attention_dispatch_policy and threads its value through to the CUDA GroupQueryAttention Level-1 workspace estimator. This is the Tier-1 intent knob from the policy-based workspace estimation design: "latency" favors high-workspace fast routes, "memory" favors low-workspace routes (so more nodes fit on GPU), and "safe" assumes the bounded fallback everywhere. Unset (default) or any unrecognized value means "auto" and keeps the current route-aware behavior. This is a pure no-functional-change reader. The raw string is parsed (WorkspaceEstimatorConfig::attention_dispatch_policy -> AttentionDispatchPolicy enum via ParseAttentionDispatchPolicy) and stored on GQAWorkspaceEstimateConfig::dispatch_policy, but the estimator does not yet consume it, so every policy value produces the identical estimate. A follow-up PR biases route selection on the committed policy (coverage validation and the bounded fallback land in their own PRs). Plumbing mirrors the ep.cuda.gqa_workspace_max_total_sequence_length reader. The enum/parser live in the CUDA GQA estimator header because it is the only consumer today; hoist to a neutral header when a second op consumes it. Tests: extends the FactoryRetainsNarrowWorkspaceEstimatorConfig framework test (config string -> WorkspaceEstimatorConfig field, CPU CI) and adds a provider-test asserting the token parsing (exact-match, unknown -> Auto) and the reader-only invariant (no policy value changes the estimate). Part of the policy-based workspace estimation effort; see docs/annotated_partitioning/policy_based_workspace_estimation.md and the PR chain (#32944, #32945, #33001, #33014, #33016). Base retargets toward main as the stack merges. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b95559c4-5cbe-4787-8dd7-ffa45a2157f9
### Description <!-- Describe your changes. --> Make `NchwcOptimizerTests.ConvWithZeroInputChannelsIsNotTransformed` a graph-only regression instead of running the zero-channel convolution through `NchwcOptimizerTester`. - Build and resolve the same zero-input-channel Conv with and without bias. - Assign the Conv to the CPU EP and apply `NchwcTransformer` directly, following the adjacent rank-validation regression's pattern. - Assert that the transformer reports no modification, the ordinary Conv remains, and no NCHWc Conv, ReorderInput, or ReorderOutput nodes are inserted. - Explicitly skip platforms without NCHWc support. No production optimizer or kernel changes. The zero-output-channel regression and other numerical optimizer tests are unchanged. Validation: whitespace (`git diff --check`) and changed-range clang-format checks passed. No local build or C++ test run, as requested. ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> Follow-up to #33346. The new regression currently executes the degenerate Conv at optimization levels 2 and 3 and compares the outputs. macOS arm64 CI reports NaN-versus-zero mismatches at `nchwc_optimizer_test.cc:235`, despite this test's intended contract being that NCHWc conversion is skipped. The same assertion is confirmed independently on upstream `main` and multiple PRs: - [main at 9cdf0f1, macOS WebGPU arm64 Release](https://github.com/microsoft/onnxruntime/actions/runs/38675468798/job/116227944699) - [#33016, macOS WebGPU arm64 Debug](https://github.com/microsoft/onnxruntime/actions/runs/38599291872/job/116132732574) - [#33347, macOS WebGPU arm64 Debug](https://github.com/microsoft/onnxruntime/actions/runs/38707806696/job/116332127965) Check the optimizer's graph contract directly without making this regression depend on zero-channel Conv execution. This is a test-only CI fix, not a correction to CPU Conv's zero-channel numerical behavior. Co-authored-by: Chi Lo <lochi@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b95559c4-5cbe-4787-8dd7-ffa45a2157f9
### Description <!-- Describe your changes. --> Add reader-only plumbing for the hardware-neutral session option `session.kernel_dispatch_policy`. The intent is generic across operators and EPs. `KernelDispatchPolicy` and the shared, header-only `TryParseKernelDispatchPolicy` live in `core/framework/kernel_dispatch_policy.h`, with no CUDA or graph dependencies. CUDA GQA is the first consumer, not the owner of the policy. For valid values, **no policy changes runtime dispatch, workspace estimates, or partitioning** in this PR. `latency`, `memory`, and `safe` remain intent metadata for future policy resolution. In particular, `memory` does not reduce the reservation, and `safe` does not select a bounded fallback or provide a no-OOM guarantee. #### Reader contract - Unset, empty, and explicit `auto` resolve to `Auto`. The other valid tokens are exactly `latency`, `memory`, and `safe`. - Unknown, differently cased, whitespace-only, and whitespace-padded non-empty values fail session initialization with `INVALID_ARGUMENT`; they never silently resolve to `Auto`. Validation runs even when partitioning is disabled. - The accountant factory retains the validated raw optional string without changing other settings. The CUDA consumer enforces successful parsing rather than silently accepting an invalid configuration. - `GetGroupQueryAttentionWorkspaceEstimateConfig` accepts `dispatch_policy = KernelDispatchPolicy::Auto` alongside the envelope and initializes both fields in one place. The node-estimator overload and CUDA test bridge forward the policy through that helper. - Setting the policy alone does not enable partitioning or non-windowed GQA estimation without a KV envelope. - This replaces the earlier, unreleased attention-specific option name; there is no compatibility alias. #### Integration and regression coverage Preserve #33014/#33016's envelope validation against `[0, INT32_MAX]`, invalid-value diagnostics, and fail-closed GQA placement when no proven estimate is available. Reuse the exported graph-config helper instead of duplicating node parsing. Keep envelopes, eligibility, and sizing local to GQA; other operators and EPs can adopt the shared intent independently. Framework regressions cover valid-token parsing, rejected tokens (including `Memory`, `SAFE`, `memroy`, and ` memory `), unchanged parser output on failure, validation with partitioning enabled and disabled, raw-token retention, unset defaults, and policy-only configuration not enabling partitioning. Existing KV-envelope boundary tests remain intact. CUDA metadata regressions cover default and explicit policy forwarding through the node-config helper/test bridge, identical bytes/backend sets for windowed and non-windowed estimation, and unchanged decline without a non-windowed envelope. #### Validation for this review update - Changed-file lintrunner/clang-format check: passed for all 10 edited C++ files. - `git diff --check`: passed. - No full ORT build or C++ regression suites were run locally for this update, as requested. Earlier-head build evidence does not validate this head; full framework/CUDA validation is left to CI. ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> Provide a generic policy representation and reader without coupling other consumers to GQA or CUDA. Rejecting typos now prevents future enforcement (including #33316's committed policies) from silently falling back to `Auto` and bypassing the requested restrictions. This PR builds on #33016, which is now merged, and targets `main`. Committed policies, operator/EP-specific resolution, route restrictions, runtime coverage/envelope enforcement, bounded fallback, and reduced policy-bound estimates remain separate follow-ups. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Chi Lo <lochi@microsoft.com> Copilot-Session: b95559c4-5cbe-4787-8dd7-ffa45a2157f9 Copilot-Session: 24b20465-fd4d-4a64-8174-aa0622c5164d

Summary
Adds opt-in, route-aware Level-1 workspace estimation for non-windowed CUDA GroupQueryAttention using the declared total-KV envelope from
ep.cuda.gqa_workspace_max_total_sequence_length.The present-cache capacity bound is
max(allocated past-cache capacity, declared total-KV envelope). Static caches may be larger than the active sequence: GQA permitstotal_sequence_length <= past_sequence_lengthand retains that allocated capacity. Bounding only the envelope would underestimate MEA expansion and partial-alias preservation.The existing graph-free aggregate sizes reachable routes and admitted prompt/decode phase corners; this PR does not introduce a second sizing engine.
Envelope validation and caller contract
[0, INT32_MAX], matching the runtime ABI. Malformed, negative, overflowing, and greater-than-INT32_MAXvalues fail initialization.Workspace accounting and proof policy
Regression coverage
INT32_MAX; rejectedINT32_MAX + 1,INT64_MAX, decimal overflow, malformed text, and negative values.Dependencies
Targets
main, which now includes #33118's shared preparation-sizing implementation. The duplicated sizing commits were dropped during the post-merge rebase; this PR contains only its envelope-estimation, hardening, test, and documentation changes.Part of the policy-based workspace-estimation series described in #32944. Committed per-
(node, phase)route policy and runtime workload-envelope enforcement remain follow-up work.