Skip to content

Sync with Microsoft ONNX Runtime - 31102026 - #1376

Open
ai-fw-intg wants to merge 18 commits into
ovep-developfrom
sync_msft_31102026
Open

ai-fw-intg wants to merge 18 commits into
ovep-developfrom
sync_msft_31102026

Conversation

@ai-fw-intg

Copy link
Copy Markdown

Automated daily backmerge from ORT main to ovep-develop. No conflicts detected. Do NOT squash or rebase - use merge commit only.

tianleiwu and others added 18 commits October 29, 2026 13:39
…e and 4-lane warp-shuffle decode epilogue (microsoft#33738)

## Description

Optimizes `HyperConnectionLowRankMix` for both multi-row prefill and
small-M decode on CUDA:
1. **Prefill (`FusedPreMixInjectPostGateB4H2560Kernel<T>`)**: Fuses the
pre-mix projection (`Norm(streams) * sigmoid_gate * (2 * alpha_pre)`),
the `alpha_inj * streams + y` injection, and the `2 *
sigmoid(post_logits) * post_scale` post-gate into a single 320-thread
register-only kernel for the 4-branch, `hidden = 2560` shape (`num_rows
>= 8, rank == 320`), eliminating two intermediate `(num_rows, 4, 2560)`
global-memory round-trips and reducing prefill HyperConnection mix
latency by **25%** (`41.7 -> 31.4 us/launch` at `num_rows = 8192` on
H200).
2. **Decode (`HcDownKernel` and `HcUpPreKernel<T, 2, 4, 320>`)**: Adds a
4-lane warp-shuffle epilogue (`kFastEp4x320`) that eliminates the `sg`
shared-memory staging and third CTA barrier in `HcUpPreKernel`,
prefetches `norm_w` / `streams` before `griddepcontrol.wait`, caches
`w_reg8` / `w_reg9` in `HcDownKernel`, and unrolls `p.splits == 8`,
reducing combined `HcDown + HcUpPre` critical-path time in
Qwen3.8-Flash-Next decode by **94 us/cycle**.

## Summary of Changes

| File | Change |
|------|--------|
|
`onnxruntime/contrib_ops/cuda/bert/hyper_connection_low_rank_mix_impl.cu`
| Add `FusedPreMixInjectPostGateB4H2560Kernel<T>` for prefill and
`kFastEp4x320` 4-lane warp-shuffle epilogue + weight/stream prefetching
in `HcDownKernel` and `HcUpPreKernel<T, 2, 4, 320>` for decode |
|
`onnxruntime/test/contrib_ops/hyper_connection_low_rank_mix_op_test.cc`
| Add `(num_rows=11, num_branches=4, hidden=2560, rank=320)` FP16/BF16
coverage to `UnfusedManyRows` |

## Testing

- `onnxruntime_provider_test --gtest_filter='*HyperConnection*'`: **30 /
30 passed** (including new `(11, 4, 2560, 320)` prefill test cases and
`FusedDecodeShapeRank320`).
- End-to-end `engine_behaviours.py` on Qwen3.8-Flash-Next RC5
(`all_int4`, `top16`, `top08`): **27 / 27 PASS** on each package.

## Checklist

- [x] Tests added/updated
- [x] No breaking changes
- [x] `lintrunner` clean

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…soft#33404)

### Description
<!-- Describe your changes. -->

Refines the extensible runtime fusion design around EP-registered,
ordered patterns and the existing capability path:

- EPs own pattern registration and priority; ORT selects compatible
candidates in that order, subject to semantic, ownership, kernel, and
eventual memory-feasibility checks.
- Reuse `GetCapability`, `ComputeCapability`, `nodes_to_optimize`, and
`optimization_func` through validated adapters. Distinguish existing
application hooks from the additional recipe-description, ordering,
capability-update, and external-registration support still needed.
- Separate candidate description, selection, application, and
reconciliation. Baseline ordered selection comes first; target memory
estimation can connect to the same recipes before final budgeted
selection, without requiring the general placement planner.
- Replace the parallel post-partition hook and proposed `OrtRF*`
function table with logical recipe/lifetime contracts. Preserve optional
independent package delivery; defer exact public ABI additions until the
capability integration is established.
- Treat gramalingam#16 as an optional matcher implementation
to evaluate with small Qwen-derived fixtures and the model demo, not a
system-design prerequisite.
- Update the qualification plan, approval ledger, and milestones
consistently; retain CUDA mapping, state, numerical, and resource
requirements.

Design-only; no runtime implementation, build, GPU allocation, or model
qualification is included. Public interfaces and implementation
contracts remain subject to maintainer approval.

Validation: `git diff --check` passed. Documentation fences and stale
hook/API references were checked; no runtime tests were run.

### 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. -->

Keep canonical ONNX artifacts unchanged while allowing optional
matcher/adapter updates to reuse existing kernels. Align fusion with
capability-based EP ownership and the recipe/planning direction in
microsoft#33372 instead of introducing a separate selection pipeline. Qwen3.8-27B
remains the model-independent mechanism's pilot, not its API.

Fixes microsoft#33403.

---------

Signed-off-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: titaiwangms <18010845+titaiwangms@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 38c05fba-777a-447c-af24-f930f13e4021
## Description

Adds a `com.microsoft` `SwiGLU` contrib operator with a CUDA kernel,
plus a CUDA graph fusion that rewrites the decomposed SiLU-gated
activation that exporters emit today into the new operator.

`SwiGLU` exposes the clamped SwiGLU activation that `MoE`/`QMoE` already
apply internally, for dense feed-forward and shared-expert paths that do
not run through a grouped expert GEMM.

> This PR previously also added `MoERouter`. That operator is now in its
own PR: microsoft#32935.

## Summary of Changes

### `SwiGLU` operator

| File | Change |
|------|--------|
| `onnxruntime/core/graph/contrib_ops/contrib_defs.cc`, `ms_opset.h` |
Schema, shape inference and registration. |
| `onnxruntime/contrib_ops/cuda/math/swiglu.{h,cc}` | CUDA `OpKernel`:
validates shapes and handles the packed single-input form. |
| `onnxruntime/contrib_ops/cuda/math/swiglu_impl.{h,cu}` | Fused clamp +
gate kernel. |
| `onnxruntime/contrib_ops/cuda/cuda_contrib_kernels.cc` | Registration
for float, float16 and bfloat16. |

```
G      = clamp(gate, max=limit)
L      = clamp(up, min=-limit, max=limit)
output = G * Sigmoid(activation_alpha * G) * (L + activation_beta)
```

- Arithmetic is done in float regardless of `T`. A `limit` of zero or
less disables both clamps.
- The result is rounded to `T` once, after the multiply. The optional
INT attribute `round_activation` (default 0) additionally rounds `G *
Sigmoid(activation_alpha * G)` to `T` before the multiply by `(L +
activation_beta)`, as a `QuickGelu` followed by a `Mul` in `T` would.
- Uses the same `limit` / `activation_alpha` / `activation_beta`
contract as `MoE`/`QMoE`.
- `up` is optional. When omitted, `gate` holds both halves of one `[..,
2 * inter]` projection (gate first, then up), so a fused sibling GEMM
needs no `Split`.
- With `up` supplied and default `limit`/`activation_beta`, it matches
ONNX `SwiGLU` (opset 28) with `alpha = activation_alpha`.

### `SwiGluFusion` (CUDA EP, level 2)

| File | Change |
|------|--------|
| `onnxruntime/core/optimizer/swiglu_fusion.{h,cc}` | Rewrites
`QuickGelu(gate, alpha) * up` to `SwiGLU(gate, up,
activation_alpha=alpha, round_activation=1)`. |
| `onnxruntime/core/optimizer/graph_transformer_utils.cc` | Registers it
for CUDA right after `QuickGeluFusion`. |

`QuickGeluFusion` already turns `gate * Sigmoid(gate)` into `QuickGelu`,
so existing models with a decomposed SiLU-gated MLP now run the fused
kernel without being re-exported. The fusion only fires when `QuickGelu`
has a single consumer, the element type is float, float16 or bfloat16,
and `gate` and `up` provably share one shape (`Mul` broadcasts but
`SwiGLU` does not).

`round_activation=1` keeps `QuickGelu`'s rounding to `T` before the
multiply, so the fused graph is bit-identical to the unfused `QuickGelu`
+ `Mul` for float, float16 and bfloat16, including the negative tail
where the activation underflows in `T`.

### Shared helper

- `_Sigmoid(float)` added to
`onnxruntime/core/providers/cuda/cu_inc/common.cuh` next to
`_Exp`/`_Log`. It uses the same numerically stable form as `OP_Sigmoid`.

## Testing

- `onnxruntime/test/python/transformers/test_swiglu.py`: PyTorch
reference over float32/float16/bfloat16, with and without `up`, with and
without the clamp, non-default `activation_alpha`/`activation_beta`,
packed vs. split parity, and shape validation errors. Fusion-on vs.
fusion-off outputs must be exactly equal for float32/float16/bfloat16 on
negative-tail and bulk inputs, and both `round_activation` modes are
pinned.
- `onnxruntime/test/optimizer/swiglu_fusion_test.cc`: fusion fires in
either `Mul` operand order and carries `alpha` and `round_activation=1`.
It is skipped for broadcast `Mul`, a shared `QuickGelu` output and
CPU-assigned nodes. End-to-end CUDA parity (Level1 vs. Level2) is exact
(tolerance 0) for float, float16 and bfloat16, including negative-tail
inputs.

```
python -m pytest onnxruntime/test/python/transformers/test_swiglu.py          # 12 passed
onnxruntime_test_all --gtest_filter='*SwiGlu*:*SwiGLU*:*QuickGelu*'            # 27 passed, 2 skipped (WebGPU)
onnxruntime_test_all --gtest_filter='GraphTransformationTests*:*Fusion*:*SwiGlu*:*SwiGLU*:*QuickGelu*'   # 505 passed, 17 skipped (WebGPU)
# Two MobileClip CUDA attention-fusion tests need libcudnn on the library path; they pass when it is visible.
```

## Checklist

- [x] Tests added
- [x] No breaking changes
- [x] Documentation updated

---------

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

### Description
<!-- Describe your changes. -->
Adds a subgroup-matrix Conv path for the WebGPU EP that computes the
convolution as
an implicit GEMM. Covers F16, channels-last, `group == 1` convs on
devices reporting
an 8x16x16 subgroup-matrix config, and falls back to the existing Conv
paths
otherwise.

### 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. -->
Conv dominates runtime in vision models, but the existing WebGPU Conv
paths do not
use the subgroup-matrix units that the MatMul path already exploits on
Intel
Xe2/Xe3. This brings the same acceleration to Conv.
…mers/models/stable_diffusion/requirements/cuda12 (microsoft#33734)

Bumps [onnx](https://github.com/onnx/onnx) from 1.21.0 to 1.22.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/onnx/onnx/releases">onnx's
releases</a>.</em></p>
<blockquote>
<h2>v1.22.0</h2>
<p>ONNX v1.22.0 is now available with exciting new features! We would
like to thank everyone who contributed to this release!
Please visit <a href="https://onnx.ai/">onnx.ai</a> to learn more about
ONNX and associated projects.</p>
<h2>What's Changed</h2>
<h3>Breaking Changes and Deprecations</h3>
<ul>
<li>Swap qk_matmul_output_mode 1 &amp; 2 to match computation order by
<a href="https://github.com/titaiwangms"><code>@​titaiwangms</code></a>
in <a
href="https://redirect.github.com/onnx/onnx/pull/7913">onnx/onnx#7913</a></li>
</ul>
<h3>Spec and Operator</h3>
<p>Two new operators <code>LinearAttention-27</code> and
<code>CausalConvWithState-27</code> were introduced.</p>
<ul>
<li>Fix number of pad modes in doc_strings.cc by <a
href="https://github.com/assafpr"><code>@​assafpr</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7803">onnx/onnx#7803</a></li>
<li>Add FlexAttention Op to ai.onnx.preview opset by <a
href="https://github.com/mshr-h"><code>@​mshr-h</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7534">onnx/onnx#7534</a></li>
<li>Fix Attention op softcap ordering: apply before mask/bias by <a
href="https://github.com/titaiwangms"><code>@​titaiwangms</code></a> in
<a
href="https://redirect.github.com/onnx/onnx/pull/7867">onnx/onnx#7867</a></li>
<li>Add LinearAttention and CausalConvWithState operators (Opset 27) by
<a href="https://github.com/tadani3"><code>@​tadani3</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7950">onnx/onnx#7950</a></li>
<li>feat(generator): extend Range operator with float16 and bfloat16
support (opset 27) by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7923">onnx/onnx#7923</a></li>
</ul>
<h3>Reference Implementation</h3>
<ul>
<li>Fix missing 'mul' reduction in ScatterElements reference
implementation by <a
href="https://github.com/zdryan"><code>@​zdryan</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7842">onnx/onnx#7842</a></li>
<li>Fix QLinearMatMul output saturation by <a
href="https://github.com/karimbaidar"><code>@​karimbaidar</code></a> in
<a
href="https://redirect.github.com/onnx/onnx/pull/7868">onnx/onnx#7868</a></li>
<li>Fixed more bugs in the Scan reference op by <a
href="https://github.com/tadani3"><code>@​tadani3</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7964">onnx/onnx#7964</a></li>
</ul>
<h3>Utilities and Tools</h3>
<ul>
<li>Fix Slice shape inference crashes with SIGABRT on empty dimensions
by <a
href="https://github.com/titaiwangms"><code>@​titaiwangms</code></a> in
<a
href="https://redirect.github.com/onnx/onnx/pull/7738">onnx/onnx#7738</a></li>
<li>Rename misleading input_rank param to input_dim_value in
processSlice… by <a
href="https://github.com/titaiwangms"><code>@​titaiwangms</code></a> in
<a
href="https://redirect.github.com/onnx/onnx/pull/7739">onnx/onnx#7739</a></li>
<li>fix: Conv/Pool strides validation by <a
href="https://github.com/edgchen1"><code>@​edgchen1</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7764">onnx/onnx#7764</a></li>
<li>fix: add input/output bounds checks in version converter adapter by
<a href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7813">onnx/onnx#7813</a></li>
<li>Harden version conversion against malformed inputs by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7872">onnx/onnx#7872</a></li>
<li>fix: add input rank checks in Gemm version converter adapters by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7880">onnx/onnx#7880</a></li>
<li>Fix raw_data handling in version converter adapters by <a
href="https://github.com/cyyever"><code>@​cyyever</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7910">onnx/onnx#7910</a></li>
<li>Fix checker to use len() instead of sys.getsizeof() for protobuf
size check by <a
href="https://github.com/OmarAzizi"><code>@​OmarAzizi</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7760">onnx/onnx#7760</a></li>
<li>Add version macros by <a
href="https://github.com/cbourjau"><code>@​cbourjau</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7918">onnx/onnx#7918</a></li>
<li>Remove internal spec_to_yaml tool by <a
href="https://github.com/cbourjau"><code>@​cbourjau</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7985">onnx/onnx#7985</a></li>
<li>Address shape inference shortcomings by <a
href="https://github.com/yuslepukhin"><code>@​yuslepukhin</code></a> in
<a
href="https://redirect.github.com/onnx/onnx/pull/7997">onnx/onnx#7997</a></li>
<li>Add unifyInputShape / unifyInputShapePrefix shape inference
utilities by <a
href="https://github.com/gramalingam"><code>@​gramalingam</code></a> in
<a
href="https://redirect.github.com/onnx/onnx/pull/7999">onnx/onnx#7999</a></li>
<li>Add operator+ and operator- for Dim by <a
href="https://github.com/gramalingam"><code>@​gramalingam</code></a> in
<a
href="https://redirect.github.com/onnx/onnx/pull/8000">onnx/onnx#8000</a></li>
<li>Fix KeepAspectRatioHelper precision for scaled output dimensions by
<a href="https://github.com/elwhyjay"><code>@​elwhyjay</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/8007">onnx/onnx#8007</a></li>
<li>Fix heap buffer over-read in Conv/Pool shape inference for weight
rank mismatch by <a
href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/8037">onnx/onnx#8037</a></li>
</ul>
<h3>Build, CI and Tests</h3>
<ul>
<li>Add update into main.yml by <a
href="https://github.com/titaiwangms"><code>@​titaiwangms</code></a> in
<a
href="https://redirect.github.com/onnx/onnx/pull/7687">onnx/onnx#7687</a></li>
<li>Update check_urls.yml by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7716">onnx/onnx#7716</a></li>
<li>Update add_msvc_runtime_flag to work with MSVC_RUNTIME_LIBRARY by <a
href="https://github.com/Shadows-of-Fire"><code>@​Shadows-of-Fire</code></a>
in <a
href="https://redirect.github.com/onnx/onnx/pull/7660">onnx/onnx#7660</a></li>
<li>Try to fix renovate by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7742">onnx/onnx#7742</a></li>
<li>fix upload; Update release_win.yml by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7728">onnx/onnx#7728</a></li>
<li>Allow release CIs to run when a labeled PR receives new commits by
<a href="https://github.com/Copilot"><code>@​Copilot</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7741">onnx/onnx#7741</a></li>
<li>Update pixi.{toml,lock} by <a
href="https://github.com/cbourjau"><code>@​cbourjau</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7746">onnx/onnx#7746</a></li>
<li>hash for googletest by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7765">onnx/onnx#7765</a></li>
<li>Update RELEASE-MANAGEMENT.md by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7773">onnx/onnx#7773</a></li>
<li>Update doc CIPipeline by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7782">onnx/onnx#7782</a></li>
<li>use reviewdog to fix the pr_checks workflow by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7780">onnx/onnx#7780</a></li>
<li>Update copilot-setup-steps.yml; persist-credentials: false by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7768">onnx/onnx#7768</a></li>
<li>Update release_linux.yml; replace tag by hash by <a
href="https://github.com/andife"><code>@​andife</code></a> in <a
href="https://redirect.github.com/onnx/onnx/pull/7769">onnx/onnx#7769</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/onnx/onnx/commit/2bb50465112feca9003e1ed654d77f01ff1415ca"><code>2bb5046</code></a>
Fix windows workflows on rel-1.22.0 branch (<a
href="https://redirect.github.com/onnx/onnx/issues/8087">#8087</a>)</li>
<li><a
href="https://github.com/onnx/onnx/commit/eda03851c322d0132a937f983cef83fb33c0dd9b"><code>eda0385</code></a>
Update version number to 1.22.0 (<a
href="https://redirect.github.com/onnx/onnx/issues/8086">#8086</a>)</li>
<li><a
href="https://github.com/onnx/onnx/commit/b124e0188a8bc47c9de8157e3296df6c77fdc06b"><code>b124e01</code></a>
Bump version number to 1.22.0rc2 (<a
href="https://redirect.github.com/onnx/onnx/issues/8071">#8071</a>)</li>
<li><a
href="https://github.com/onnx/onnx/commit/8de2cf6aa47928e6515ac6d9e1a8b4758886a7df"><code>8de2cf6</code></a>
Cherrypicks for 1.22.0rc2 (<a
href="https://redirect.github.com/onnx/onnx/issues/8066">#8066</a>)</li>
<li><a
href="https://github.com/onnx/onnx/commit/53d61200c0b966f39027ea46ea4e3078363a0308"><code>53d6120</code></a>
Cherry-pick: Address shape inference issues in Conv (<a
href="https://redirect.github.com/onnx/onnx/issues/8051">#8051</a>) to
rel-1.22.0 (<a
href="https://redirect.github.com/onnx/onnx/issues/8">#8</a>...</li>
<li><a
href="https://github.com/onnx/onnx/commit/bc3be77bec2f628788796dff60819186bacf49df"><code>bc3be77</code></a>
Set version number to 1.22.0rc1 (<a
href="https://redirect.github.com/onnx/onnx/issues/8024">#8024</a>)</li>
<li><a
href="https://github.com/onnx/onnx/commit/e945daf7e12eaeb624ce1edd39ccdbb97879626d"><code>e945daf</code></a>
feat(generator): extend Range operator with float16 and bfloat16 support
(ops...</li>
<li><a
href="https://github.com/onnx/onnx/commit/293ad621a244fb501a5ed9660c01e666ba5e3e86"><code>293ad62</code></a>
Run lints also on Windows (<a
href="https://redirect.github.com/onnx/onnx/issues/8014">#8014</a>)</li>
<li><a
href="https://github.com/onnx/onnx/commit/8847da48ff3bcf9314cdebb1a44114f723a8de4d"><code>8847da4</code></a>
Follow up for scikit-build-core migration (<a
href="https://redirect.github.com/onnx/onnx/issues/8017">#8017</a>)</li>
<li><a
href="https://github.com/onnx/onnx/commit/882a5ef11bf987462e0fbaf9d95d5e640a7b82c7"><code>882a5ef</code></a>
Fix/sdist missing SBOM cdx json (<a
href="https://redirect.github.com/onnx/onnx/issues/8010">#8010</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/onnx/onnx/compare/v1.21.0...v1.22.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=onnx&package-manager=pip&previous-version=1.21.0&new-version=1.22.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/microsoft/onnxruntime/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…soft#33663)

### Description

`QDQSelectorActionTransformer` rewrites `DQ -> op -> Q` node groups in
two ways: it replaces them with a `QLinear*`/`QGemm` op, or it drops the
Q/DQ nodes around ops such as `MaxPool`, `Resize` and `Slice`. Neither
rewrite is valid for float8/float4 quantized types:

- The `QLinear*`/`QGemm` replacement ops only accept int8/uint8. The
schema of `QLinearConv`, `QLinearAdd`, `QLinearConcat`, `QGemm` and the
other ops rejects float8. `QLinearMatMul`-21 allows float8 in its
schema, but the CPU EP only registers int8/uint8 kernels for it.
- After the Q/DQ nodes are dropped, the target op receives the float8
tensor directly. Most of these ops (for example `MaxPool`, `Resize` and
`Slice`) either do not accept float8 in their schema or have no float8
kernel on the CPU EP.

So for a float8 QDQ model, session creation fails at
`ORT_ENABLE_EXTENDED` and `ORT_ENABLE_ALL`, while `ORT_DISABLE_ALL` and
`ORT_ENABLE_BASIC` run fine, because the CPU EP has float8
`QuantizeLinear`/`DequantizeLinear` kernels.

This PR makes `BaseSelector::Select` leave a node group unchanged when
any of its DQ inputs or Q outputs has a float8 or float4 type. The check
sits in `BaseSelector`, which only `QDQSelectorActionTransformer` uses.
It does not affect the `NodeGroupSelector` classes that EPs reuse for
QDQ node unit grouping.

One trade-off: for opset >= 21, `Transpose` and `Reshape` do support
float8, so dropping their Q/DQ nodes would still have been valid. Their
Q/DQ nodes are now kept for float8 as well. That costs only the lossless
drop-QDQ optimization for those two ops, and avoids encoding a per-op,
per-opset allow list in the selector.

### Motivation and Context

Fixes microsoft#33761.

Minimal repro (opset 21, CPU EP):

```python
import numpy as np
import onnxruntime as ort
from onnx import TensorProto, helper

F8 = TensorProto.FLOAT8E4M3FN
inits = [
    helper.make_tensor("s", TensorProto.FLOAT, [], [0.125]),
    helper.make_tensor("zp", F8, [], [0]),
    helper.make_tensor("w", F8, [4, 4, 3, 3], [0.25] * 144),
    helper.make_tensor("ws", TensorProto.FLOAT, [], [0.0625]),
]
nodes = [
    helper.make_node("QuantizeLinear", ["x", "s", "zp"], ["xq"]),
    helper.make_node("DequantizeLinear", ["xq", "s", "zp"], ["xdq"]),
    helper.make_node("DequantizeLinear", ["w", "ws", "zp"], ["wdq"]),
    helper.make_node("Conv", ["xdq", "wdq"], ["y"]),
    helper.make_node("QuantizeLinear", ["y", "s", "zp"], ["yq"]),
    helper.make_node("DequantizeLinear", ["yq", "s", "zp"], ["out"]),
]
graph = helper.make_graph(
    nodes, "fp8_qdq_conv",
    [helper.make_tensor_value_info("x", TensorProto.FLOAT, [1, 4, 8, 8])],
    [helper.make_tensor_value_info("out", TensorProto.FLOAT, None)],
    inits)
model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 21)], ir_version=10)

x = np.random.uniform(-2, 2, (1, 4, 8, 8)).astype(np.float32)
for level in [ort.GraphOptimizationLevel.ORT_DISABLE_ALL, ort.GraphOptimizationLevel.ORT_ENABLE_EXTENDED]:
    so = ort.SessionOptions()
    so.graph_optimization_level = level
    sess = ort.InferenceSession(model.SerializeToString(), so, providers=["CPUExecutionProvider"])
    sess.run(None, {"x": x})
```

With `ORT_ENABLE_EXTENDED`, this fails with:

```
INVALID_GRAPH : This is an invalid model. Type Error: Type 'tensor(float8e4m3fn)' of input parameter (xq) of operator (QLinearConv) in node () is invalid.
```

The same failure happens for float8 QDQ `Add`, `Mul`, `Concat`,
`AveragePool`, `GlobalAveragePool`, `Sigmoid`, `LeakyRelu`, `Softmax`,
`Gemm`, `MaxPool`, `Resize`, `Slice`, `Gather`, `Expand`, `Tile`,
`DepthToSpace` and `Squeeze`/`Unsqueeze`/`Flatten`. `MatMul` fails with
`NOT_IMPLEMENTED` for `QLinearMatMul(21)` instead.

The current workaround is to disable `QDQSelectorActionTransformer`
through `disabled_optimizers`, which also disables all int8 QDQ fusions
in the session.

### Testing

- Added `QDQTransformerTests.Float8QDQNodeGroupsAreNotFused`. It builds
float8 QDQ graphs for `Conv`, `MatMul`, `Add`, `Mul`, `AveragePool`,
`Softmax`, `Concat`, `MaxPool`, `Resize` and `Slice`, runs them at
Level1 and Level2, checks that the outputs match and that no
`QLinear*`/`QGemm` op is created. Without the selector change, all 10
cases fail with the errors above.
- Extended `GetZeroPointBytes` in the test graph builder to support
`FLOAT8E4M3FN` zero points.
- Ran locally on Linux x64 (Release, CPU EP), all passing:
`*QDQ*:*Qdq*:*Quant*:*NodeUnit*:*TransposeOpt*:GraphRuntimeOptimizationTest.*`
(409 tests) and `*Transform*:*Optimiz*:*Fusion*:*Selector*` (1044 tests,
of which 25 are skipped).

Co-authored-by: Cursor <cursoragent@cursor.com>
…oft#33745)

### Description
<!-- Describe your changes. -->

Guard the three disk-backed constant tests with `!defined(__wasm__)`,
matching existing optimizer external-data test coverage. Preserve all
native tests and WASM in-memory constant tests.

### 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. -->

Fix Web CI build failure.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
### Description
Adds a WebGPU `QuantizeLinear` kernel and int8 support in `Cast`, and fixes byte-lane packing in the segmented (>`maxStorageBufferBindingSize`) output setters. All gaps were found by the W3C WebNN conformance (WPT) suite running on the WebGPU EP with CPU fallback disabled.

Commits:
1. **Add WebNN regression test for 1-D blocked uint8 DequantizeLinear.** Adds the WebNN vector "dequantizeLinear uint8 1D tensor with 1D scale, implicit block_size = 2" (microsoft#32730) for f32 and f16 scales, with `block_size` both explicit and inferred. microsoft#32734 fixed this path but only tested int8 with block_size 4.
2. **Add QuantizeLinear kernel.**
   - f32/f16 input, int8/uint8 output. Registered for opsets 10-12, 13-18, 19-20, 21-22 and 23-24. From opset 23, x / y_scale is computed in the `precision` type (default: the y_scale type). The kernel divides in f32, so opset 23/24 is registered for f32 `y_scale` only. Both GetCapability paths (in-tree `webgpu_execution_provider.cc` and plugin `ep/ep.cc`) leave nodes with an explicit non-f32 `precision` to another EP.
   - Each invocation writes one packed u32 word (4 outputs), so output bytes are never shared between invocations.
   - DequantizeLinear's per-tensor/per-axis/blocked classification and shape validation (including block_size inference and the element-wise axis 0, block_size 1 form) is factored into a helper used by both kernels.
   - Adds an `Int8x4` case to `ShaderVariableHelper::SetByOffset` that packs the low byte of each lane.
   - WGSL f32 division is only accurate to 2.5 ULP, which flips results near .5 (e.g. `QuantizeLinearOpTest.Int8`: -5 / 0.039215686 = -127.4999...). The shader recomputes the quotient with integer long division when 0.25 <= |q| < 1024, so round-half-to-even matches the CPU kernel bit-exactly.
3. **Support int8 in Cast.** Adds int8 to T1/T2. Input is unpacked with `unpack4xI8` (sign-extending) on both the generic and to-int64 paths; output uses the new Int8x4 packing, which keeps each lane's low byte like a narrowing conversion.
4. **Pack byte lanes in segmented output setters.** Outputs larger than `maxStorageBufferBindingSize` are written through a generated per-segment setter that stored the packed u32 value unchanged. Uint8x4/Int8x4 writers (Cast, Expand, Gather, QuantizeLinear) pass one value per lane, so those shaders failed to compile. The setter now takes `vec4<u32>`/`vec4<i32>` lanes and packs them like the unsegmented `SetByOffset`. This also fixes a latent uint8 bug on main for Cast/Expand/Gather.

Tests (WebGPU-pinned, CPU EP fallback disabled) are in `onnxruntime/test/providers/webgpu/tensor/{quantize_linear_test,cast_op_test}.cc`. They cover the WebNN conformance vectors, ties, saturation, per-axis, blocked (first/last axis, partial block), all opsets, `precision` routing, near-tie quotients against the CPU reference, Q -> DQ round trip, int8 casts to/from f32/f16/int32/int64/uint8/bool, and outputs spanning buffer segments.

Validation (Windows ARM64, NVIDIA RTX Spark N1X / D3D12, Release):
- `build.py --use_webgpu ... --target onnxruntime_provider_test`, then `onnxruntime_provider_test --gtest_filter="*WebGpu*:CastOpTest.*:*QuantizeLinear*:*DequantizeLinear*:ExpandOpTest.*:GatherOpTest.*"`: 1159 tests, 1147 passed, 0 failed, 12 skipped. The skips existed before this change and are unrelated: `QuantizeLinearOpTest.*_DML*` (DML only) and hardware/build-feature skips in `WebGpuMatMulAlgorithmTest`, `WebGpuMatMulNBitsTest.DP4A*` and `WebGpuContextTest.AdapterIndexRejectsUnsupportedBuild`.
  - New tests that ran and passed: `WebGpuQuantizeLinearTest.*` (including `OpsetVersions` 10-24, `Opset23PrecisionOtherThanFloat`, `Opset23ExplicitFloatPrecision`, `SegmentedOutput`), `CastOpTest.Int8ToOtherTypes_WebGpu`, `CastOpTest.OtherTypesToInt8_WebGpu`, `CastOpTest.ByteOutputsAcrossBufferSegments_WebGpu` and `WebGpuDequantizeLinearTest.*`.
  - The existing CPU `QuantizeLinearOpTest.*` suite also runs on WebGPU and passes, including `Int8`, which depends on the exact-quotient rounding.
- Plugin EP build: `build.py --use_webgpu shared_lib --cmake_extra_defines onnxruntime_BUILD_UNIT_TESTS=OFF --target onnxruntime_providers_webgpu` succeeds. This compiles the `ep/ep.cc` GetCapability change.
- Sensitivity check: without the fixes, `Opset23PrecisionOtherThanFloat` returned 5 and 3 (expected 4 and 2), and `SegmentedOutput` and `CastOpTest.ByteOutputsAcrossBufferSegments_WebGpu` failed.

Related work: this overlaps with @edgchen1's branch [`edgchen1/webgpu_quantizelinear`](https://github.com/microsoft/onnxruntime/tree/edgchen1/webgpu_quantizelinear) (last updated 2026-04-10, no PR yet). That branch also adds int4/uint4 QuantizeLinear output, which this PR does not cover; int4/uint4 is planned as a follow-up PR.

### Motivation and Context
WebNN's `quantizeLinear`, qdq subgraphs and int8 `cast` lower to ONNX `QuantizeLinear`/`Cast`, which had no WebGPU kernel (or no int8 type), so graph build failed with CPU fallback disabled.

WPT results (webgfx/webnn-test full suite, Edge Canary 158 arm64, NVIDIA RTX Spark N1X (D3D12), ORT 1.28.3 runtime, WebGPU plugin EP). Before = plugin built from main at 8120434; after = plugin with this change and four companion WebGPU PRs applied, attributed by op. This PR's ops fix 67 subtests (57 required):

| WPT test | Before | After | Notes |
|---|---|---|---|
| quantizeLinear | 4/29 | 15/29 | remaining 14 are optional int4/uint4/int32 outputs |
| qdq_subgraph | 1/43 | 43/43 | |
| dequantizeLinear | 25/33 | 27/33 | "quantizeLinear then dequantizeLinear" cases |
| cast | 38/51 | 50/51 | all int8 casts; remaining failure is a separate f32->f16 rounding issue |

For context, with this PR and its four companions applied, failing WPT subtests drop from 343 to 68 (required failures 275 -> 11).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
### Description
<!-- Describe your changes. -->

Two WebGPU EP gaps found by running the W3C WebNN conformance (WPT) suite on the WebGPU EP.

**[WebGPU] Support channels-last bilinear Resize**
- A 4-D linear `Resize` can scale dims 1 and 2 with channels last (scales `[1, h, w, 1]`). Scale validation accepts this, and WebNN emits it for `resample2d` with `axes = [1, 2]`. The WebGPU EP keeps Resize NCHW-only, so this layout reaches the NCHW bilinear kernel, which always interpolated the last two dims.
- `ResizeBilinearProgram` now takes explicit `height_axis` / `width_axis`. For a rank-4 input with `scales[1] != 1` it interpolates dims 1 and 2; otherwise it keeps interpolating the last two dims. The layout is part of the program cache key.
- New `onnxruntime/test/providers/webgpu/tensor/resize_op_test.cc`: f32 and f16 channels-last linear upsample (WebNN conformance vector), pinned to WebGPU with CPU EP fallback disabled.

**[WebGPU] Add LpPool and GlobalLpPool kernels**
- Adds an Lp mode to the shared WebGPU pool program. It accumulates `sum(|x|^p)` in f32 so float16 windows don't overflow, then applies `^(1/p)`. Padding contributes 0. `p = 1` (abs-sum) and `p = 2` (`sqrt` of the sum of squares) are specialized, and other `p` use `pow`. Parallel reduction for large kernels uses an f32 shared buffer in Lp mode.
- `PoolProgram` now takes a `PoolType` and `p` instead of an `is_max_pool` flag. Average-pool-only paths (`count_include_pad`, count tracking) are now gated on `kAveragePool`.
- Registered in both the ONNX domain and the internal NHWC domain: `LpPool` 11–17, 18–21 and 22+, and `GlobalLpPool` 2–21 and 22+. The internal NHWC domain only defines LpPool 11/18 and GlobalLpPool 2, so LpPool before opset 11 stays on the CPU EP.
- New tests in `onnxruntime/test/providers/webgpu/nn/pool_op_test.cc` cover p=1/2/3, strides/pads/dilations, opsets 11/18/22, GlobalLpPool, a large kernel (parallel reduction) and a float16 no-overflow case. Each runs NCHW and NHWC against a double-precision reference, pinned to WebGPU with CPU EP fallback disabled.

#### Testing

Unit tests: Windows ARM64, NVIDIA RTX Spark N1X (D3D12), Release, built with `build.py --use_webgpu ... --target onnxruntime_provider_test` on this branch (main + these two commits).

- `onnxruntime_provider_test --gtest_filter="*WebGpu*:PoolTest.*:ResizeOpTest.*:UpsampleOpTest.*"`: 912 tests, **899 passed, 0 failed**, 13 skipped.
  - Skipped tests target other EPs (`PoolTest.*_Dml`, `ResizeOpTest.*_CudaRegression*`) or need hardware/build features this machine lacks (`WebGpuMatMulAlgorithmTest.ForcedSubgroupMatrix*` / `ForcedPackedSplitK*`, `WebGpuMatMulNBitsTest.DP4A*`, `WebGpuContextTest.AdapterIndexRejectsUnsupportedBuild`). None are related to this change.
  - The existing shared LpPool tests (`PoolTest.LpPool*`, `GlobalLpPool`, `LpPool_*` failure cases) now also run on WebGPU and pass.

WebNN conformance (webgfx/webnn-test, full WPT suite), Edge Canary 158 arm64, NVIDIA RTX Spark N1X (D3D12), ORT 1.28.3 runtime, private WebGPU plugin EP. Before = plugin built from main; after = plugin built with this PR plus the four related WebGPU PRs (subtest fixes attributed by op). This PR fixes 29 subtests, all of them required:

| WebNN op | Before | After | Cause |
|---|---|---|---|
| `l2Pool2d` | 2/30 | 30/30 | lowers to `LpPool`, which had no WebGPU kernel |
| `resample2d` | 13/14 | 14/14 | linear upsample with `axes = [1, 2]` (channels last) |

### 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. -->

WebNN `l2Pool2d` and channels-last `resample2d` either fell back to the CPU EP or gave wrong results on the WebGPU EP. This is one of five PRs from the WebNN conformance sweep of the WebGPU EP; the others cover elementwise kernels, precision fixes, quantization and f16 GRU/LSTM. With all five applied, failing WPT subtests drop from 343 to 68 and required failures from 275 to 11, compared with main.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…icrosoft#33652)

### Description
<!-- Describe your changes. -->

Draft pilot for EP-owned pattern rewriting through the existing
capability optimization callback.

**Prerequisite integrated:** microsoft#33631 merged as
`9d3dc81268ab91a925b103d8bc4cee9807799148`. This branch is rebased onto
`main` at `f809e08b988cc7613f2ed4ea40cdbc5c4c98aea4`; the aggregate diff
no longer includes the Rama prerequisite.

Review the two pilot commits:

- `9aa06ce4d2` — internal region-scoped rewriting and test-only EP
capability handoff.
- `13d14f0f6e` — function-expansion lifecycle documentation and
integration coverage.

The rebase preserves upstream constant-loading tests and semantics; it
does not revert the final merged Rama implementation.

- Add an internal region-scoped `PatternRewriter::Run` overload. Only
fully contained matches are eligible; existing rule ordering, provider
checks and iterative behavior remain intact.
- Track removed and newly emitted node IDs in the mutable region.
Preserve boundary values and document nontransactional failure behavior.
- Add a test-only CPU EP that owns ordered Transpose-composition
patterns, discovers a region without changing the graph, and attaches an
optimization callback to its capability. After ORT accepts the
capability, the callback rewrites the selected region, updates its node
list, and uses existing CPU kernels.
- Verify mixed graphs, unselected overlapping capabilities,
priority/fallback, outside consumers, scoped iteration and replacement
DAG tracking, invalid/deleted IDs, missing ONNX domain imports,
match-only mode and failures.
- Add function-expansion lifecycle coverage using a fixed model-local
function and a test-only CPU adapter. With AOT inlining enabled and
disabled, verify that discovery does not apply rewrites, a claimed
function survives until accepted application, and an unclaimed function
expands before fresh body-pattern discovery. This addition changes no
production code or expansion/partitioning policy.

#### Rebased-head validation

Qualified the pilot-only source at
`13d14f0f6e05f342a4f42c99f70bddcc981d64cb`, independently of the CUDA
fusion commits, in the existing Linux Release CUDA-enabled build. The
capability adapters under test use the CPU EP.

With the existing virtual environment, CUDA/cuDNN paths and build flags
retained:

```sh
timeout --signal=TERM --kill-after=30s 900s /usr/local/bin/cmake -S /home/titaiwang/workspace/ort-runtime-fusion-h200/cmake -B /mnt/data/titaiwang/runtime-fusion/build-cuda/Release -DFETCHCONTENT_FULLY_DISCONNECTED=ON -DFETCHCONTENT_UPDATES_DISCONNECTED=ON -DPython_EXECUTABLE=/mnt/data/titaiwang/runtime-fusion/venv/bin/python
timeout --signal=TERM --kill-after=30s 7200s /usr/local/bin/cmake --build /mnt/data/titaiwang/runtime-fusion/build-cuda/Release --config Release --parallel 8 --target onnxruntime_test_all onnxruntime_providers_cuda -- -v
```

Results: both commands passed. The build completed 1,460 Ninja actions,
compiling core/CUDA sources and linking the CUDA implementation
provider; this was not a cached-object/link-only qualification.

From `/mnt/data/titaiwang/runtime-fusion/build-cuda/Release`:

```sh
timeout --signal=TERM --kill-after=30s 900s ./onnxruntime_test_all '--gtest_filter=FunctionTest.*:CheckAndBindComponentTests.*:MatchComponentTests.*:PatternCapabilityTests.*:PatternComponentTests.*:PatternRewriterTests.*:ReplacementComponentTests.*' --gtest_output=xml:/mnt/data/titaiwang/runtime-fusion/rama-rebase-pilot-engine.xml
```

Result: **283/283 passed**, zero failures/errors/disabled/skips, with no
exclusions. This includes both tests previously excluded in the older
CPU-only environment. XML counts and log/XML hashes were independently
checked.

`git diff --check
f809e08..integration/ep-pattern-capability-rebase`
also passed. Exact commands, build provenance, configuration and
artifact hashes are retained locally in
`rama-rebase-qualification-report.json`.

#### Historical review and validation

The original pilot commit `826601e64f14cee31ec35d72faca2e09fc1601a0`
completed readability, implementation, critical, deep/spec and
integration reviews. No Critical/Major findings were reported. Minor
documentation/diagnostic clarification findings were resolved; the
missing-domain capability fallback was reproduced with a failing
regression test and fixed. The function-lifecycle addition and rebase
integration received direct review, not another five-reviewer round.

Before this rebase, the CPU-only build and scoped lint passed:

```sh
cmake --build build/cpu-capability/Release --target onnxruntime_test_all --parallel 24
lintrunner --take CLANGFORMAT onnxruntime/core/optimizer/pattern_rewriter.h onnxruntime/core/optimizer/pattern_rewriter.cc onnxruntime/test/optimizer/pattern_rewriter_components_test.cc
git diff --check
```

Results: all three commands passed on the old pilot revision. From that
build directory:

```sh
./onnxruntime_test_all --gtest_filter='PatternCapabilityTests.*:PatternComponentTests.*:PatternRewriterTests.*:FunctionTest.*-PatternRewriterTests.GroupSignaturesAreIndependentOfGlobalLocale:FunctionTest.TestInlinedLocalFunctionNotRemoved'
```

Result: **248/248 passed**. This was an older Linux CPU Release `-O1
-DNDEBUG` build with contrib/ML ops disabled and local-only GCC warning
exceptions; it is historical evidence, not qualification of the rebased
head. Two tests were explicitly excluded: the locale-signature test
segfaulted on both the pilot and a diagnostic executable with the
unchanged prerequisite engine; the retained-local-function test failed
on both the function-lifecycle addition and its unchanged prior
component-test source. Those outcomes are not counted as passes. The new
qualification above uses an unexcluded selector.

**Limits:** the generic scoped rewriter tracks multi-node replacement
results, but the capability adapters are test-only and deliberately
handle N-to-1 Transpose chains and one fixed model-local function
definition. Recognizing a function name alone is not production
function-equivalence checking. No production EP registration, general
N-to-M placement, resource accounting/memory estimation, external
registration ABI or Qwen qualification is included. The function probe
does not compare whole-function versus expanded-body placement
alternatives or change cross-EP priority. Full CI and non-Linux
platforms have not been validated locally.

**Open question (integration review, non-blocking):** production
integration must define rewrite policy during ORT-format `kAssignOnly`
export. The current optimization callback does not receive the
partitioner mode; this pilot does not establish or validate export
behavior.

### 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. -->

Pilot implementation toward microsoft#33403 and the EP-capability direction in
microsoft#33404.

An EP should be able to supply ordered patterns while ORT retains
placement decisions. The existing `nodes_to_optimize` /
`optimization_func` hook provides the acceptance-to-application seam;
the missing local primitive was restricting iterative rewriting to the
accepted region and returning its updated node membership.

This pilot reuses the merged microsoft#33631 matcher and mutation engine rather
than introducing a second rewrite pipeline or requiring ORT to select
every individual match. It is intended to collect feedback on the
region-scoped interface and capability handoff before adding production
patterns or memory planning.

---------

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: 38c05fba-777a-447c-af24-f930f13e4021
…microsoft#33736)

### Description
Skip the cuDNN include dir when it is one of the compiler's implicit
include directories; the compiler searches it anyway.

### Motivation and Context
When cuDNN is installed under the system prefix (e.g.
--cudnn_home=/usr), CUDA_PLUGIN_CUDNN_INCLUDE_DIR is /usr/include. CMake
drops that implicit directory from the plugin target's own compile
lines, but onnxruntime_unittests.cmake copies the target's
INCLUDE_DIRECTORIES onto moe_gemm_int2_test.cc as a source property,
which is not filtered. The file was then compiled with -isystem
/usr/include ahead of the libstdc++ headers, and <cstdlib>'s
#include_next <stdlib.h> failed with "stdlib.h: No such file or
directory".
### Description
<!-- Describe your changes. -->

Add standard ONNX `BitShift` to the CUDA EP using the existing
elementwise broadcasting dispatcher:

- Unsigned 8/16/32/64-bit integers for opsets 11–27; all eight
signed/unsigned integer types from opset 28.
- Both directions, arithmetic right shifts for signed inputs, and
wrapping left shifts implemented with unsigned intermediates and a
bit-preserving conversion.
- Counts are checked before shifting: negative or oversized counts
produce `-1` only for right shifts of negative signed inputs, otherwise
`0`, matching the current ONNX schema and CPU implementation. Negative
counts do **not** reverse direction.
- CUDA-only tests disable CPU fallback and cover integer extrema/high
64-bit patterns, zero/width-boundary/negative counts, scalar and
multidirectional broadcasts, per-channel paths, initializer counts,
empty tensors, and 2,051-element tails.
- Update only the CUDA `BitShift` rows in `OperatorKernels.md`.

This change is independent of the other bitwise kernel PRs.

**Validation:** Passed on an H200 (`sm90`), Linux, CUDA 13.3, cuDNN
9.10.2, Python 3.12, ORT 1.32.0 Release/QUICK_BUILD. The standalone
validation source was base `812043410eebd29c4bdd46b906447e2e5b77f7b2`
plus this branch through `a94f033211605b6352f75a371790e803cb648cb8`; no
XOR/AND/OR/NOT changes were present. All five compiled C++/CUDA source
files match the committed content after CRLF normalization.

Build/wheel command, run from the validation source directory —
**passed**, including nvcc compilation and device `memcpy`:

```bash
../.venv/bin/python tools/ci_build/build.py --config Release --build_dir /tmp/ort-cuda-bitwise-xor-8d05709c/build --update --build --build_wheel --skip_tests --skip_submodule_sync --use_cuda --cuda_home /usr/local/cuda --cudnn_home /usr/lib/python3.12/site-packages/nvidia/cudnn --cmake_generator Ninja --parallel 16 --disable_contrib_ops --disable_ml_ops --cmake_extra_defines CMAKE_CUDA_ARCHITECTURES=90 FETCHCONTENT_FULLY_DISCONNECTED=ON onnxruntime_QUICK_BUILD=ON onnxruntime_USE_FLASH_ATTENTION=OFF onnxruntime_USE_MEMORY_EFFICIENT_ATTENTION=OFF onnxruntime_USE_TRT_FUSED_ATTENTION=OFF onnxruntime_USE_XQA=OFF --targets onnxruntime_provider_test onnxruntime_pybind11_state
```

From the build's `Release` directory — **42/42 passed, no skips**: 18
new CUDA tests and 24 existing `BitShiftOpTest` tests:

```bash
CUDA_VISIBLE_DEVICES=4 LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/lib/python3.12/site-packages/nvidia/cudnn/lib ./onnxruntime_provider_test '--gtest_filter=*CudaBitShiftTest*:*BitShiftOpTest*'
```

Additional ad hoc numerical/profile probes, from `validated-shift` with
the same environment — **230/230 models passed**, CPU fallback disabled,
exact integer results, and all 230 profiled `BitShift` executions
assigned to `CUDAExecutionProvider`:

```bash
CUDA_VISIBLE_DEVICES=4 LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/lib/python3.12/site-packages/nvidia/cudnn/lib ../.venv/bin/python ../probe-remaining-bitwise.py --group shift
```

The probes include six exhaustive 8-bit pair models (all 256×256
value/count pairs for signed opset 28 and unsigned opsets 11/28, both
directions: 393,216 scalar results). The ad hoc probe script is
validation infrastructure, not an added repository test. The initial
224-model baseline also matched CPU before applying this patch.

Operator documentation generation, from the validation task root —
**passed**; generated `BitShift` rows match the committed rows:

```bash
PYTHONPATH=/tmp/ort-cuda-bitwise-xor-8d05709c/validated-shift/wheel-runtime LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/lib/python3.12/site-packages/nvidia/cudnn/lib .venv/bin/python src/tools/python/gen_opkernel_doc.py --providers cuda --output_path validated-shift/OperatorKernels.generated.md
```

Validation is limited to this configuration; the full suite, other GPU
architectures, and performance benchmarks were not run. The archive
build does not embed a Git revision; provenance was checked using
explicit source hashes. Validated wheel SHA256:
`791fbb2278876c4dba5df7cb78d43d795209a67edf4629a23cf2de22fb22f132`.

### 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. -->

CUDA currently lacks a standard ONNX `BitShift` kernel. Native integer
operations avoid CPU fallback and preserve exact wide-integer results
without floating-point emulation or hardware-modulo shift-count
behavior.

---------

Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
### Description
<!-- Describe your changes. -->

Remove `continue-on-error: true` / `continueOnError: true` from browser
WebGPU EP tests in GitHub Actions and Azure Pipelines, and from C#
delegate validation in the Windows WebGPU workflow. Update the migration
release-gate documentation.

### 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. -->

Make test failures errors.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
### Description
<!-- Describe your changes. -->

Schedule `Python - CUDA13 - Combined WHLs` (Lotus definition 2353) daily
at **09:00 UTC** from `main`. Set `always: true` so wheels are built
even when the source has not changed. Push and PR triggers remain
disabled, and the build continues to publish pipeline artifacts only.

The existing Package pipeline health automation has also been updated
separately to monitor definition 2353 explicitly.

### 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. -->

Generate combined CUDA 13 wheels every morning for downstream
publishing. The companion [release-pipelines PR
56020](https://aiinfra.visualstudio.com/Lotus/_git/release-pipelines/pullrequest/56020)
repoints the existing 1ES publisher to this pipeline's unified wheel
artifacts, preserving its feed options and `main`/`rel-*` completion
triggers.

Validation: YAML parsing and assertions passed for the exact cron,
main-only branch filter, and `always: true`; comparison against the
original YAML confirmed all other pipeline configuration is unchanged.
`git diff --check` passed. No build or publishing pipeline was queued.
The schedule takes effect after merge to `main`; the publishing
pipeline's new source resource still requires authorization.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
microsoft#28019)

### Description
Add CACHE when unsetting `CMAKE_CUDA_ARCHITECTURES` to ensure it's
empty.


### Motivation and Context

Recently, when building passing `CMAKE_CUDA_ARCHITECTURES=all`
configuring fails because `CMAKE_CUDA_ARCHITECTURES` is not being
correctly unsetted and then set to the curated list of architectures.
Error message:
```
-- Setting CMAKE_CUDA_ARCHITECTURES to all enables a list of architectures OnnxRuntime optimized for, not all architectures CUDA compiler supports.
CMake Error at external/cuda_configuration.cmake:154 (message):
  Unrecognized CUDA architecture: all
Call Stack (most recent call first):
  CMakeLists.txt:715 (setup_cuda_architectures)


-- Configuring incomplete, errors occurred!
```
I got this error both on Alma 9 and Ubuntu 24.04 and after this change
the build starts to compile.

---------

Co-authored-by: Juan Miguel Carceller <jmcarcell@users.noreply.github.com>
…nce (microsoft#33680)

### Description
<!-- Describe your changes. -->

Adds WebGPU EP kernels and integer type support for ops that the W3C
WebNN conformance (WPT) suite lowers to ONNX. Without them, graph build
fails when CPU EP fallback is disabled. Each commit includes
WebGPU-pinned unit tests with CPU fallback disabled.

| Commit | Change |
|---|---|
| [WebGPU] Add Or and Xor kernels | Registers `Or`/`Xor` (opset 7+,
bool) next to `And`. WGSL defines `\|` on `vec4<bool>` but not `^`, so
Xor uses `!=`. Tests cover scalar, element-wise (partial vec4),
non-vectorized broadcast (including 4-D to 5-D) and both vectorized
broadcast paths. |
| [WebGPU] Add IsNaN and IsInf kernels | Registers `IsNaN` (9-12, 13-19,
20) and `IsInf` (10-19 f32, 20 f32/f16). Values are classified on raw
IEEE-754 bits because WGSL lets implementations assume floats are
finite, so `x != x` checks can be folded away. f16 lanes are split out
of the raw words instead of being widened to f32. IsInf honors
`detect_positive`/`detect_negative`. |
| [WebGPU] Register Slice for int32 and uint32 | The Slice shader is
type-agnostic, so `T` widens from float types to f32/f16/i32/u32. |
| [WebGPU] Add Round, Sign and Softsign kernels | `Round` (11-21, 22;
f32/f16): WGSL `round()` rounds half to even. `Sign` (9-12, 13;
f32/f16/i32): WGSL `sign()` has no u32 overload. `Softsign` (1-21, 22;
f32/f16) is evaluated in f32 and returns ±1 once \|x\| >= 2^24. Dividing
directly returned 0 for ±FLT_MAX because GPUs flush the subnormal
reciprocal of the divisor. |
| [WebGPU] Accept an int64 exponent in Pow | Allows int64 for Pow's `T1`
(exponent) constraint when int64 is enabled. The shader already converts
the exponent to f32. An int64 base remains unsupported (existing TODO).
|
| [WebGPU] Support int32 in Abs and Neg | `Abs` accepts all supported
number types (u32 is the identity). `Neg` accepts f32/f16/i32. INT_MIN
wraps as in two's complement. |

#### Testing

Built on Windows ARM64 (Release, `build.py --use_webgpu ... --target
onnxruntime_provider_test`) and run on an NVIDIA RTX Spark N1X GPU
(D3D12):

```
onnxruntime_provider_test --gtest_filter="*WebGpu*:MathOpTest.*:ActivationOpTest.*:SliceTest.*:IsNaNOpTest.*:IsInfTest.*:RoundTest.*:SignTest.*:SoftsignTest.*:AbsTest.*:NegTest.*"
```

Result: 1214 tests, 1200 passed, 0 failed, 14 skipped. All 14 skips
already exist on main and are unrelated to this change:
-
`MathOpTest.MatMulInt32Type`/`MatMulUint32Type`/`MatMulZeroK*`/`MatMulFloat16SharedInitializerWithKernelOwnedPrepack`:
known WebGPU MatMul limitations.
- `SliceTest.Slice1D_WithNegativeSteps_EndOutOfBounds_2`: an
unconditional WebGPU skip on a float test.
-
`WebGpuMatMulAlgorithmTest.ForcedSubgroupMatrix*`/`ForcedPackedSplitK*`,
`WebGpuMatMulNBitsTest.DP4A*`,
`WebGpuContextTest.AdapterIndexRejectsUnsupportedBuild`: skipped because
the hardware or build doesn't support the feature.

`lintrunner` (clang-format, ruff) reports no issues on the changed
files.

### 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. -->

The W3C WebNN conformance suite found these ops failing on the WebGPU
EP. WebNN `logicalOr`/`logicalXor`, `isNaN`/`isInfinite`, `roundEven`,
`sign`, `softsign`, `abs`/`neg` (int32) and `slice` (int32) lower to the
ONNX ops above. Chromium lowers `reduceSumSquare` over no axes, or over
a 0-D input, to `Pow(x, int64 2)`.

WPT results (webgfx/webnn-test full suite, Edge Canary 158 arm64, NVIDIA
RTX Spark N1X (D3D12), ORT 1.28.3 runtime, WebGPU plugin EP). "Before"
is the plugin built from main at 8120434. "After" is the plugin built
with this PR plus four related WebGPU WebNN-conformance PRs; results are
attributed by op. This PR fixes 106 subtests (105 required):

| WebNN op | Before | After | Notes |
|---|---|---|---|
| logical_or | 2/17 | 17/17 | |
| logical_xor | 2/17 | 17/17 | |
| is_nan | 1/15 | 15/15 | |
| is_infinite | 1/18 | 18/18 | |
| round_even | 1/11 | 11/11 | |
| sign | 2/8 | 6/8 | remaining 2 are optional int8/int64 |
| softsign | 2/19 | 19/19 | |
| subgraph | 49/52 | 52/52 | conv2d/convTranspose2d/batchNormalization +
softsign |
| abs | 18/21 | 19/21 | int32; remaining are optional int8/int64 |
| neg | 17/20 | 18/20 | int32; remaining are optional int8/int64 |
| slice | 20/21 | 21/21 | |
| reduce_sum_square | 37/45 | 45/45 | via Pow(x, int64 2) |

With all five PRs applied, failing subtests drop from 343 to 68 compared
with main, and required failures from 275 to 11.

---------

Co-authored-by: Aditya Rastogi <adityar@ntdev.microsoft.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
### Description
<!-- Describe your changes. -->

Add CUDA execution for standard ONNX `BitwiseXor` (opset 18+) for
`int8`, `uint8`, `int16`, `uint16`, `int32`, `uint32`, `int64`, and
`uint64`. Reuse the existing binary elementwise implementation for
multidirectional broadcasting and empty tensors. Boolean `Xor` is
unchanged; this does not add other bitwise operators.

Add CUDA-only regressions with CPU fallback explicitly disabled,
covering all eight integer types at opsets 18 and 24, signed/unsigned
boundaries, scalar operands, multidirectional broadcasting in both
operand orders, empty outputs, and the INT64 `state XOR (state / 2048)`
RNG pattern. Update the CUDA operator support table.

Validation on Azure Linux 3 / NVIDIA H200 (physical GPU4), CUDA 13.3,
cuDNN 9.10.2, Python 3.12, Release/sm90; source based on main
`997d2d1b26` plus this patch:

- `python tools/ci_build/build.py --config Release --build_dir
/tmp/ort-cuda-bitwise-xor-8d05709c/build --build --build_wheel
--skip_tests --skip_submodule_sync --use_cuda --cuda_home
/usr/local/cuda --cudnn_home
/usr/lib/python3.12/site-packages/nvidia/cudnn --parallel 16
--disable_contrib_ops --disable_ml_ops --targets
onnxruntime_provider_test onnxruntime_pybind11_state` — **passed**,
producing an ORT 1.32.0 GPU wheel. The build was configured with Ninja,
`CMAKE_CUDA_ARCHITECTURES=90`, `onnxruntime_QUICK_BUILD=ON`, and
Flash/MEA/TRT-fused-attention/XQA disabled.
- From the build output directory: `CUDA_VISIBLE_DEVICES=4
LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/lib/python3.12/site-packages/nvidia/cudnn/lib
./onnxruntime_provider_test --gtest_filter=*Xor*` — **45 tests passed**,
no skips, including existing boolean XOR tests.
- Additional ad hoc wheel probe: **146/146** models produced
bit-identical NumPy results, and **146/146** profiled `BitwiseXor`
executions used `CUDAExecutionProvider`, with CPU fallback disabled.
This covers all integer types, opsets 18/24, full-width random values
(including upper 64-bit lanes), scalar/multidirectional/empty cases, and
integrated `Div → BitwiseXor` graphs over 4,103 INT64 RNG states. Before
installing the patched wheel, the same probes on ORT 1.28.0
(`0368187f84`) produced 146 CPU XOR executions; GPU-only initialization
failed as expected.
- `clang-format --dry-run --Werror` on all six changed C++/CUDA files —
**passed**; `git diff --check` — **passed**.

The initial untargeted contrib-disabled build encountered a pre-existing
`-Werror=unused-function` in
`onnxruntime/test/optimizer/nhwc_transformer_test.cc:71`; the relevant
provider-test and wheel targets above built successfully without
changing unrelated code. Full-suite, non-sm90, full-model fidelity, and
performance validation were not performed.

### 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. -->

Current main has CPU and DirectML `BitwiseXor` kernels but no CUDA
registration. Integer RNG hashing therefore falls back to CPU, even for
INT32/UINT32, introducing repeated device transfers in GPU inference.
This was observed while adding fishaudio/drama-3 support in
onnxruntime/mobius#793 (2,862 CPU XOR executions in one sampled
profile). Supporting the standard operator preserves the model's RNG
algorithm and exact integer outputs without a custom operator or graph
rewrite.

Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com>
Co-authored-by: Copilot App <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.