Skip to content

Add opset 28 SpaceToDepth support - #32362

Open
Justin Chu (justinchuby) wants to merge 16 commits into
mainfrom
justinchuby-spacetodepth-opset-28
Open

Justin Chu (justinchuby) wants to merge 16 commits into
mainfrom
justinchuby-spacetodepth-opset-28

Conversation

@justinchuby

Copy link
Copy Markdown
Contributor

Summary

  • Add native ONNX opset-28 SpaceToDepth support for both DCR and CRD modes on CPU and CUDA, including internal NHWC kernels.
  • Version-split SpaceToDepth and DepthToSpace registrations at opset 28 across CPU, CUDA, DML, JS, and WebGPU; add DML ordered SpaceToDepth support and make QNN decline unsupported CRD nodes for fallback.
  • Add opset-28 CPU mode, shape-validation, non-square/blocksize, and native-vs-context-dependent-function parity coverage.

Validation

  • git diff --check
  • Source-level DCR/CRD layout checks against the pinned ONNX 1.23 function bodies.
  • build.py --config Debug --build --build_dir build\\windows-spacedepth --cmake_generator "Visual Studio 17 2022" --target onnxruntime_provider_test is blocked by the base branch's unrelated FP6 TensorProto datatype-map static assertion in tensorprotoutils.h, before producing a test binary.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Base automatically changed from justinchuby-onnx-1-23-opset-28-base to main September 30, 2026 15:34
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 1, 2026 18:16

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.

Copilot review overview

🟡 Changes recommended

The ONNX pin is inconsistent with the final wheel, other opset-28 schema changes remain unsupported, and generated documentation and provider coverage are incomplete.

Review effort: Balanced
Findings: 1 High severity · 3 Low severity

Open (4)
What changed in this PR

Adds ONNX opset-28 SpaceToDepth/DepthToSpace support and updates the ONNX dependency.

Changes:

  • Implements DCR/CRD behavior across CPU, CUDA, DML, and internal NHWC paths.
  • Splits opset-28 kernel registrations and raises provider opset ceilings.
  • Adds validation, function-parity tests, and updates ONNX package pins.
File Description
.github/​workflows/​linux_ci.yml Updates ONNX version documentation.
cmake/​deps.txt Pins ONNX 1.23 source.
cmake/​onnxruntime_unittests.cmake Parses commit-pin version metadata.
cmake/​vcpkg-ports/​onnx/​portfile.cmake Updates vcpkg ONNX source and hash.
cmake/​vcpkg-ports/​onnx/​vcpkg.json Bumps vcpkg ONNX version.
onnxruntime/​core/​graph/​contrib_ops/​internal_nhwc_onnx_schemas.cc Registers opset-28 NHWC schemas.
onnxruntime/​core/​optimizer/​transpose_optimization/​optimizer_api.h Enables opset-28 optimization.
onnxruntime/​core/​providers/​coreml/​builders/​impl/​base_op_builder.h Raises CoreML opset ceiling.
onnxruntime/​core/​providers/​cpu/​cpu_execution_provider.cc Registers opset-28 CPU kernels.
onnxruntime/​core/​providers/​cpu/​tensor/​space_depth_ops.cc Implements CPU CRD SpaceToDepth.
onnxruntime/​core/​providers/​cpu/​tensor/​space_depth_ops.h Reads and stores SpaceToDepth mode.
onnxruntime/​core/​providers/​cuda/​cuda_execution_provider.cc Registers opset-28 CUDA kernels.
onnxruntime/​core/​providers/​cuda/​cuda_nhwc_kernels.cc Registers opset-28 NHWC CUDA kernels.
onnxruntime/​core/​providers/​cuda/​tensor/​space_depth_ops.cc Implements CUDA CRD permutations.
onnxruntime/​core/​providers/​cuda/​tensor/​space_depth_ops.h Stores CUDA SpaceToDepth mode.
onnxruntime/​core/​providers/​dml/​DmlExecutionProvider/​src/​Operators/​DmlOperatorSpaceToDepth.cpp Adds ordered DML SpaceToDepth.
onnxruntime/​core/​providers/​dml/​DmlExecutionProvider/​src/​Operators/​OperatorRegistration.cpp Registers opset-28 DML operators.
onnxruntime/​core/​providers/​dml/​OperatorAuthorHelper/​OperatorVersions.h Defines DML opset-28 versions.
onnxruntime/​core/​providers/​js/​js_execution_provider.cc Registers split JS kernels.
onnxruntime/​core/​providers/​js/​operators/​depth_to_space.cc Splits JS DepthToSpace registration.
onnxruntime/​core/​providers/​nnapi/​nnapi_builtin/​builders/​impl/​base_op_builder.h Raises NNAPI opset ceiling.
onnxruntime/​core/​providers/​qnn/​builder/​opbuilder/​simple_op_builder.cc Rejects unsupported QNN CRD mode.
onnxruntime/​core/​providers/​vsinpu/​builders/​impl/​base_op_builder.h Raises VSINPU opset ceiling.
onnxruntime/​core/​providers/​webgpu/​tensor/​depth_to_space.cc Splits WebGPU registrations.
onnxruntime/​core/​providers/​webgpu/​webgpu_execution_provider.cc Registers opset-28 WebGPU kernels.
onnxruntime/​core/​providers/​webnn/​builders/​impl/​base_op_builder.h Raises WebNN opset ceiling.
onnxruntime/​test/​contrib_ops/​function_ops_test.cc Adds function/native parity tests.
onnxruntime/​test/​providers/​cpu/​tensor/​space_depth_ops_test.cc Adds opset-28 mode and validation tests.
onnxruntime/​test/​python/​onnx_node_test_equivalence_test.py Reads explicit ONNX version metadata.
onnxruntime/​test/​python/​requirements.txt Pins ONNX 1.23.
requirements-materialize-onnx-node-tests.txt Updates materialization dependency.
tools/​ci_build/​github/​linux/​docker/​inference/​aarch64/​python/​cpu/​scripts/​requirements.txt Updates AArch64 ONNX pin.
tools/​ci_build/​github/​linux/​docker/​scripts/​lort/​requirements.txt Updates LORT ONNX pin.
tools/​ci_build/​github/​linux/​docker/​scripts/​manylinux/​requirements.txt Updates manylinux ONNX pin.
tools/​ci_build/​github/​linux/​docker/​scripts/​requirements.txt Updates Docker ONNX pin.
tools/​ci_build/​github/​linux/​python/​requirements.txt Updates Linux ONNX pin.
tools/​ci_build/​github/​windows/​python/​requirements.txt Updates Windows ONNX pin.
tools/​python/​materialize_onnx_node_tests.py Enforces exact fixture arity.

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

Comment thread cmake/deps.txt Outdated
Comment thread onnxruntime/core/providers/cpu/tensor/space_depth_ops.cc
Comment thread onnxruntime/core/providers/cuda/tensor/space_depth_ops.cc
Comment thread onnxruntime/core/providers/qnn/builder/opbuilder/simple_op_builder.cc Outdated
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Regenerate the WebGPU operator table and let the new opset 28 coverage bypass released-opset validation on a per-test basis.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Correct CRD CPU layout and test vectors, permit internal NHWC schemas through the latest ONNX opset, and propagate unreleased-opset policy through function model construction. Keep minimal-build model loading on its supported buffer path and constrain CPU error assertions to the CPU provider.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Run SpaceToDepth mode parity only on its CPU kernel and apply the unreleased-opset test policy while constructing QNN test models.

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

Copy link
Copy Markdown
Contributor

/azp run Linux Android Emulator QNN CI Pipeline

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@gramalingam

Copy link
Copy Markdown
Contributor

/azp run Linux Android Emulator QNN CI Pipeline

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

Mark Harfouche (hmaarrfk) added a commit to hmaarrfk/onnxruntime-feedstock that referenced this pull request Oct 6, 2026
<details><summary>Claude's draft</summary>

libonnx 1.23.1 on conda-forge reports opset 28 as the last released
ai.onnx opset, so models built at the default opset are now opset 28.
onnxruntime 1.30.0 with the 0013 backport only has opset-28 kernels for
Mod and BitShift; the other re-versioned operators have open-ended
registrations, which KernelRegistry::VerifyVersion does not match
against a newer schema version. On the last CI run that failed 24 unit
tests on linux-64, win-64 and osx-arm64 CPU builds (more on macOS) with

    Failed to find kernel for Cast(28)

Add patch 0014. For the 15 operators whose opset-28 schema differs
from the previous one only in its type constraints, give the newest CPU
registration an explicit end version of 28: Cast, Celu, Compress,
DepthToSpace, DequantizeLinear, QuantizeLinear, Einsum, OneHot,
Optional, OptionalHasElement, OptionalGetElement, ReduceLogSum,
ReduceLogSumExp, ReverseSequence and Unique. No kernel code changes.

Not covered, and still rejected at session creation rather than
computed wrongly: the types opset 28 adds (bfloat16, float6), and
SpaceToDepth, whose new mode attribute the kernel does not implement.
CUDA registrations are untouched, so an opset-28 node of these
operators runs on the CPU kernel in GPU builds.

This is a conda-forge patch, not an upstream one. Upstream's per-operator
work is in the open PRs microsoft/onnxruntime#32362, #32372, #32378,
#32381 and #32393.

Built locally: linux-64 CPU, Python 3.13, against libonnx 1.23.1.
ctest reports 100% tests passed (11 of 11) and both package test
phases pass.

Resume this Claude session:
```
cd /home/mark/git/feedstock/onnxruntime-feedstock
claude --resume c16b7120-814d-4a38-9b1f-2afd9f75d054
```
</details>

Claude-Session: https://claude.ai/code/session_01XZa8BwzZpVJtREiCoVo1k6
Mark Harfouche (hmaarrfk) added a commit to hmaarrfk/onnxruntime-feedstock that referenced this pull request Oct 11, 2026
<details><summary>Claude's draft</summary>

libonnx 1.23.1 on conda-forge reports opset 28 as the last released
ai.onnx opset, so models built at the default opset are now opset 28.
onnxruntime 1.30.0 with the 0013 backport only has opset-28 kernels for
Mod and BitShift; the other re-versioned operators have open-ended
registrations, which KernelRegistry::VerifyVersion does not match
against a newer schema version. On the last CI run that failed 24 unit
tests on linux-64, win-64 and osx-arm64 CPU builds (more on macOS) with

    Failed to find kernel for Cast(28)

Add patch 0014. For the 15 operators whose opset-28 schema differs
from the previous one only in its type constraints, give the newest CPU
registration an explicit end version of 28: Cast, Celu, Compress,
DepthToSpace, DequantizeLinear, QuantizeLinear, Einsum, OneHot,
Optional, OptionalHasElement, OptionalGetElement, ReduceLogSum,
ReduceLogSumExp, ReverseSequence and Unique. No kernel code changes.

Not covered, and still rejected at session creation rather than
computed wrongly: the types opset 28 adds (bfloat16, float6), and
SpaceToDepth, whose new mode attribute the kernel does not implement.
CUDA registrations are untouched, so an opset-28 node of these
operators runs on the CPU kernel in GPU builds.

This is a conda-forge patch, not an upstream one. Upstream's per-operator
work is in the open PRs microsoft/onnxruntime#32362, #32372, #32378,
#32381 and #32393.

Built locally: linux-64 CPU, Python 3.13, against libonnx 1.23.1.
ctest reports 100% tests passed (11 of 11) and both package test
phases pass.

Resume this Claude session:
```
cd /home/mark/git/feedstock/onnxruntime-feedstock
claude --resume c16b7120-814d-4a38-9b1f-2afd9f75d054
```
</details>

Claude-Session: https://claude.ai/code/session_01XZa8BwzZpVJtREiCoVo1k6
Ti-Tai Wang (titaiwangms) pushed a commit that referenced this pull request Oct 12, 2026
### Description
<!-- Describe your changes. -->

Reintegrate the ONNX 1.23 base plumbing originally introduced by #32359
and reverted by #33073, now using ONNX **1.23.2**.

- Coordinate source/submodule, FetchContent, vcpkg, and Python
dependency pins and raise the relevant opset ceilings to 28.
- Restore Float6 public element-type mappings and conversion coverage,
preserving subsequent independent type-support changes.
- Update existing-type Cast registrations, CPU/CUDA Mod boundaries,
signed BitShift support, provider compatibility, backend
filters/tolerances, and operator documentation.
- Materialize the removed upstream node-test corpus with exact-version
and minimum-case guards, and cover backend serialization and
released-opset policy.
- Keep matching FetchContent/vcpkg compatibility patches; remove the
released-opset correction now fixed upstream in 1.23.2.
- Address review feedback: OpenVINO rejects BitShift-28; CPU/CUDA legacy
SpaceToDepth kernels stop at 27; DirectML accepts only safe DCR;
unverified graph providers defer SpaceToDepth-28. Full builds use ONNX
function expansion for CRD, with literal-output and routing regressions.
Avoid creating unsupported SpaceToDepth-28 nodes in the post-expansion
Slice/Concat fusion.
- Use shared ABI-safe tensor-element conversion in the native ONNX node
runner, fixing INT2/UINT2/FLOAT8E8M0 corpus decoding after the main
merge.

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

This is a redo of #32359 after its rollback in #33073. ONNX 1.23.2
includes the external tensor read/re-save fix from onnx/onnx#8472 for
onnx/onnx#8471 and the released-opset metadata fix from onnx/onnx#8544
for onnx/onnx#8529. The redundant local `LastReleaseVersionMap` patch
has been removed. Remaining FetchContent/vcpkg patches are
byte-identical and apply against the pinned release.

**Scope:** This PR establishes dependency/runtime base integration. Full
per-operator opset-28 support remains separate follow-up work; see
#32362, #32369, #32372, #32378, #32381, and #32393. These references
describe staged scope, not a claim that every follow-up has landed or
every opset-28 operator is supported. Runtime function expansion is a
full-build fallback, not minimal/ORT-format runtime coverage.

### Local validation

Completed on Windows with retained CPU-only Ninja/MSVC `RelWithDebInfo`
builds and strict released-opset policy:

- Built `onnxruntime_provider_test`, `onnxruntime_test_all`,
`onnx_test_runner`, and Python bindings against ONNX 1.23.2; retained
build remains available for incremental work.
- Source-built and installed the exact patched ONNX 1.23.2 Python wheel.
- Separate `--minimal_build extended` shared runtime configured,
compiled, and linked successfully with ML/contrib ops and unit tests
disabled. This exercises `ONNX_MINIMAL_BUILD=ON`; it is not a
minimal-runtime function-op execution test.
- Mod/BitShift/SpaceToDepth/Cast provider tests: **247 passed**, no
skips. SpaceToDepth checks default DCR, explicit DCR, and CRD with
distinct literal expected outputs, expansion, and legacy opset
boundaries.
- Slice/Concat fusion and type-info/tensor-proto framework tests: **27
passed**, no skips.
- Python backend tests: **22 passed**, plus **2 subtests passed**.
- Full Python backend series: **4,066 tests**, **2,685 skipped**, zero
failures. Skipped/unsupported coverage is not a pass.
- Materialized **1,884 node cases**. Native CPU runner with `-m 1500`
collected **1,760 cases**: **1,590 succeeded**, **170 not implemented**,
**zero failed**, exit 0. These results do not establish complete
opset-28 support.
- Generated CPU operator documentation matches the rebuilt kernel
registry; verified archive hashes, patch identity/application, submodule
SHA, and changed-file lint.

**Remaining validation/infrastructure limits:** GPU and other EP
execution relies on CI; optional-provider routing checks are compiled
into the relevant builds but were unavailable locally. Full unfiltered
C++ suites and the ancillary broad `ALL` target were not rerun. The
oracle-dependent corpus equivalence test skips because upstream no
longer ships the corpus. The new ONNX 1.23.2 tarball currently returns
**404 from the Microsoft vcpkg asset mirror**; it still needs
Terrapin/infra seeding before read-only `x-block-origin` vcpkg legs can
download it. FetchContent and the successful minimal build are
mirror-independent. New-head CI is pending.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: gramalingam <10075881+gramalingam@users.noreply.github.com>
Keep opset-28 provider support compatible with the reintegrated ONNX base, including DirectML CRD fallback and updated generated kernel docs.

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

Copy link
Copy Markdown
Contributor

/azp run Linux Android Emulator QNN CI Pipeline

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
No pipelines were found matching this branch/path.

PR #33134 added SpaceToDepthOpset28ModesAndProviderRouting with an expectation
that opset 28 nodes expand via ONNX function expansion (EXPECT_FALSE(has_space_to_depth)),
because native opset 28 kernels were intentionally deferred to this PR (#32362).

Now that native opset 28 SpaceToDepth kernels are implemented for CPU and CUDA,
update the test to assert that the node remains SpaceToDepth (EXPECT_TRUE),
routes to CPU for CPUExecutionProvider, routes to CUDA for CUDAExecutionProvider,
and falls back from DML to CPU for CRD mode while DCR routes to DML.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Check provider assignment for DirectML and OpenVINO fused nodes instead of requiring the original SpaceToDepth operator. Preserve native CPU/CUDA and opset-28 CPU fallback checks, excluding inserted memory-copy nodes from the computation count.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The CUDA provider does not support opset-28 SpaceToDepth natively, so ONNX function expansion can leave Transpose/Reshape nodes assigned to CUDA. Keep checking the provider assignment and output, but require the native SpaceToDepth node only for CPU and explicit CPU fallbacks.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Distinguish the NCHW and NHWC CUDA provider instances, which report the same provider type. Require one native SpaceToDepth node for both, plus exactly two layout transposes for NHWC. Preserve provider assignment checks for every computation and layout node and retain the existing graph-EP fallback checks.

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.

4 participants