From 5a9dc6aea26a0e18b1bc0468eccd6729413e84c0 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 24 Sep 2026 03:26:42 +0000 Subject: [PATCH 1/6] onnxsim: Add version 0.7.3 Mirrors build-onnxoptimizer.yml: onnxsim vendors onnx-optimizer (which vendors onnx) as git submodules and links onnx/protobuf statically, the same shape already ported. cp310 is dropped for the same reason (onnxoptimizer has no riscv64 onnx wheel there); cp312's abi3 wheel serves 3.12+. --- .github/workflows/build-onnxsim.yml | 134 ++++++++++++++++++++++++++++ docs/packages/onnxsim.yaml | 16 ++++ 2 files changed, 150 insertions(+) create mode 100644 .github/workflows/build-onnxsim.yml create mode 100644 docs/packages/onnxsim.yaml diff --git a/.github/workflows/build-onnxsim.yml b/.github/workflows/build-onnxsim.yml new file mode 100644 index 0000000000..42acb69651 --- /dev/null +++ b/.github/workflows/build-onnxsim.yml @@ -0,0 +1,134 @@ +# SPDX-FileCopyrightText: 2026 The RISE Project +# SPDX-License-Identifier: MIT +--- +# This workflow is based on: https://github.com/onnxsim/onnxsim/blob/v0.7.3/.github/workflows/build-and-test.yml +name: Build onnxsim wheels (riscv64) + +on: + workflow_dispatch: + inputs: + version: + description: 'Version glob to (re)build; empty builds every version of docs/packages/onnxsim.yaml not released yet' + required: false + default: '' + pull_request: + branches: [main] + paths: + - '.github/workflows/build-onnxsim.yml' + - 'docs/packages/onnxsim.yaml' + push: + branches: [main] + paths: + - '.github/workflows/build-onnxsim.yml' + - 'docs/packages/onnxsim.yaml' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read # to fetch code (actions/checkout) + +env: + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 + +jobs: + setup: + uses: $/.github/workflows/_setup.yml + with: + package: onnxsim + version: ${{ inputs.version }} + + build_wheels: + needs: [setup] + if: needs.setup.outputs.versions != '[]' + name: Build onnxsim ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64 + runs-on: ubuntu-24.04-riscv + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + # Upstream ships cp310/cp311/cp312-abi3 (no free-threaded wheel here: our + # matrix mirrors onnxoptimizer's, which onnxsim vendors and links the + # same way). cp310 is dropped: onnx (the runtime dependency) has no + # riscv64 wheel for it on our registry, at any version, and no + # py3-none-any fallback either (it's a compiled extension). cp311 stays: + # onnx ships a riscv64 cp311 wheel, and nanobind/protobuf (the other + # build-time dependencies) resolve too, via their py3-none-any fallback + # wheels. + include: + - python: cp311 + # No riscv64 onnxruntime wheel on cp311; the rest of the suite still + # runs (onnxsim falls back to onnx's reference evaluator). + onnxruntime: '' + - python: cp312 + onnxruntime: onnxruntime + + env: + ONNXSIM_VERSION: ${{ matrix.version }} + + steps: + - name: Checkout onnxsim v${{ env.ONNXSIM_VERSION }} + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + repository: onnxsim/onnxsim + ref: v${{ env.ONNXSIM_VERSION }} + submodules: recursive + persist-credentials: false + + - name: Build wheels + uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 + with: + output-dir: wheelhouse/ + only: ${{ matrix.python }}-manylinux_riscv64 + env: + # The riscv64 manylinux image's own cmake (3.31.8) already satisfies + # CMakeLists.txt's cmake_minimum_required(3.22); upstream's own + # CIBW_BEFORE_BUILD only pip-installs cmake/ninja for its manylinux_2_28 + # x86_64/aarch64 images. + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} + CIBW_ENVIRONMENT: >- + CMAKE_ARGS=" + -DONNX_USE_PROTOBUF_SHARED_LIBS=OFF + -DProtobuf_USE_STATIC_LIBS=ON + -DONNX_USE_LITE_PROTO=ON + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + " + PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ + # nanobind builds the onnxsim_cpp2py_export extension (CMakeLists.txt's + # ONNXSIM_PYTHON path); CMake locates it via `python -m nanobind + # --cmake_dir`, so it must already be importable before configure runs + # or CMake falls back to fetching it from GitHub. protobuf is needed + # for the same reason as onnxoptimizer's build. Both ship a + # py3-none-any wheel, so they install on any interpreter/arch. + CIBW_BEFORE_BUILD_LINUX: pip install nanobind protobuf + # Upstream's own suite additionally exercises onnxscript/torch/timm/ + # sympy/onnxslim/ultralytics/rfdetr paths, all guarded by + # pytest.importorskip; none of those have riscv64 wheels, so those + # paths are left to skip rather than installed. onnxruntime does have + # a riscv64 wheel on our registry, but only from cp312 (matrix.onnxruntime). + CIBW_TEST_REQUIRES: pytest pytest-xdist ${{ matrix.onnxruntime }} + CIBW_TEST_COMMAND: pytest {project}/tests/ + + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: onnxsim-${{ env.ONNXSIM_VERSION }}-${{ matrix.python }}-manylinux_riscv64 + path: wheelhouse/*.whl + if-no-files-found: error + + publish: + name: Publish onnxsim ${{ matrix.version }} + needs: [setup, build_wheels] + if: needs.setup.outputs.versions != '[]' + strategy: + fail-fast: false + matrix: + version: ${{ fromJSON(needs.setup.outputs.versions) }} + permissions: + contents: write + pull-requests: write + uses: $/.github/workflows/_publish-wheel.yml + secrets: + app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }} + with: + artifact-pattern: onnxsim-${{ matrix.version }}-*-manylinux_riscv64 diff --git a/docs/packages/onnxsim.yaml b/docs/packages/onnxsim.yaml new file mode 100644 index 0000000000..e27aab2717 --- /dev/null +++ b/docs/packages/onnxsim.yaml @@ -0,0 +1,16 @@ +package-name: onnxsim +source-code: https://github.com/onnxsim/onnxsim +license: MIT AND (Apache-2.0 OR BSD-2-Clause) +warning: | + onnxsim vendors onnx-optimizer as a git submodule, which in turn vendors + onnx (MIT) as its own submodule; onnxsim links both, plus protobuf + (BSD-3-Clause), statically. protobuf pulls in abseil-cpp (Apache-2.0) the + same way onnx's own standalone build does (see docs/packages/onnx.yaml). + Abseil ships no NOTICE file to propagate, and onnx-optimizer is + Apache-2.0, so the wheel's own LICENSE already covers it. The Python + extension is built with nanobind rather than pybind11; nanobind ships a + single py3-none-any wheel with no compiled code of its own (it only + emits code into the extension it builds), so it needs no riscv64-specific + handling. +versions: +- version: 0.7.3 From 38cd3c89859fa21993df231c66fc6d7b997e83ad Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 24 Sep 2026 03:30:39 +0000 Subject: [PATCH 2/6] onnxsim: fix matrix so both cp311 and cp312 actually build An include list whose entries share no key with the base matrix collapses onto a single job instead of adding one per entry (confirmed against onnxoptimizer's own CI run, which built only cp312 despite listing cp311 too). Make python a real matrix dimension so include only attaches onnxruntime to the matching combination. --- .github/workflows/build-onnxsim.yml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build-onnxsim.yml b/.github/workflows/build-onnxsim.yml index 42acb69651..e72c017a44 100644 --- a/.github/workflows/build-onnxsim.yml +++ b/.github/workflows/build-onnxsim.yml @@ -48,14 +48,17 @@ jobs: fail-fast: false matrix: version: ${{ fromJSON(needs.setup.outputs.versions) }} - # Upstream ships cp310/cp311/cp312-abi3 (no free-threaded wheel here: our - # matrix mirrors onnxoptimizer's, which onnxsim vendors and links the - # same way). cp310 is dropped: onnx (the runtime dependency) has no - # riscv64 wheel for it on our registry, at any version, and no - # py3-none-any fallback either (it's a compiled extension). cp311 stays: - # onnx ships a riscv64 cp311 wheel, and nanobind/protobuf (the other - # build-time dependencies) resolve too, via their py3-none-any fallback - # wheels. + # Upstream ships cp310/cp311/cp312-abi3 (no free-threaded wheel here). + # cp310 is dropped: onnx (the runtime dependency) has no riscv64 wheel + # for it on our registry, at any version, and no py3-none-any fallback + # either (it's a compiled extension). cp311 stays: onnx ships a + # riscv64 cp311 wheel, and nanobind/protobuf (the other build-time + # dependencies) resolve too, via their py3-none-any fallback wheels. + # `python` is a real matrix dimension (not folded into `include` + # alone) so both entries actually produce a job: an `include` list + # whose entries share no key with the base matrix collapses onto a + # single combination instead of adding one job per entry. + python: [cp311, cp312] include: - python: cp311 # No riscv64 onnxruntime wheel on cp311; the rest of the suite still From d6481a8d4242c757d4d0cab0cba8bca6c40d5ca8 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 24 Sep 2026 08:26:12 +0000 Subject: [PATCH 3/6] onnxsim: ignore test files with unguarded torch/timm/onnxruntime imports CI confirmed the wheel itself builds and passes abi3audit on both interpreters, but pytest aborts collection outright on test_python_api.py, test_simple.py, test_timm.py, test_rfdetr.py and test_yolo.py: each does a module-level import of torch, timm or onnxruntime with no pytest.importorskip guard, so a missing module is a collection error (exit code 2) rather than a skip. None of those packages have riscv64 wheels (onnxruntime only from cp312, which still lacks timm/rfdetr/ ultralytics/torch), so ignore the files themselves. --- .github/workflows/build-onnxsim.yml | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-onnxsim.yml b/.github/workflows/build-onnxsim.yml index e72c017a44..33cac3167e 100644 --- a/.github/workflows/build-onnxsim.yml +++ b/.github/workflows/build-onnxsim.yml @@ -106,12 +106,22 @@ jobs: # py3-none-any wheel, so they install on any interpreter/arch. CIBW_BEFORE_BUILD_LINUX: pip install nanobind protobuf # Upstream's own suite additionally exercises onnxscript/torch/timm/ - # sympy/onnxslim/ultralytics/rfdetr paths, all guarded by - # pytest.importorskip; none of those have riscv64 wheels, so those - # paths are left to skip rather than installed. onnxruntime does have - # a riscv64 wheel on our registry, but only from cp312 (matrix.onnxruntime). + # sympy/onnxslim/ultralytics/rfdetr paths; most guard the import with + # pytest.importorskip, so they collect fine and just skip without + # riscv64 wheels for those. onnxruntime does have a riscv64 wheel on + # our registry, but only from cp312 (matrix.onnxruntime). Five files + # import torch/timm/onnxruntime unconditionally at module level + # (no importorskip), which aborts collection outright rather than + # skipping when the import fails - not just deselecting their tests, + # so ignore the files themselves. CIBW_TEST_REQUIRES: pytest pytest-xdist ${{ matrix.onnxruntime }} - CIBW_TEST_COMMAND: pytest {project}/tests/ + CIBW_TEST_COMMAND: >- + pytest {project}/tests/ + --ignore={project}/tests/test_python_api.py + --ignore={project}/tests/test_simple.py + --ignore={project}/tests/test_timm.py + --ignore={project}/tests/test_rfdetr.py + --ignore={project}/tests/test_yolo.py - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: From 7122a87bf0f0cfa1ebeb77655ac9958faf143504 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 24 Sep 2026 14:18:40 +0000 Subject: [PATCH 4/6] onnxsim: pin ir_version in test_profiling's _foldable_model cp312-manylinux_riscv64's test step failed all 10 tests in tests/test_profiling.py: RuntimeError: Your model ir_version 14 is higher than the checker's (13). _foldable_model() builds its onnx.ModelProto via helper.make_model() with no ir_version, so the model is stamped with whatever onnx.IR_VERSION the installed onnx package currently defines - and our registry's newest riscv64 onnx build for cp312 is 1.23.0. onnxsim statically links a vendored onnx (via the onnx-optimizer git submodule, frozen at a pinned commit) whose checker only recognizes up to ir_version 13, so any onnx installed newer than that submodule's pin breaks every caller of _foldable_model() before the test gets to what it actually means to check. Every other test file that builds a model by hand pins ir_version explicitly; test_profiling.py's _foldable_model() was the one holdout. Match the existing convention (ir_version=10) so the fixture stays valid across the range of onnx versions the unpinned runtime dependency can resolve to. Adds the checkout/apply-patches step pair (mirroring build-py-spy.yml) and patches/onnxsim/** to path triggers. --- .github/workflows/build-onnxsim.yml | 11 ++++ docs/packages/onnxsim.yaml | 1 + ...n-in-test_profiling-s-foldable-model.patch | 64 +++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 patches/onnxsim/0.7.3/0001-tests-pin-ir_version-in-test_profiling-s-foldable-model.patch diff --git a/.github/workflows/build-onnxsim.yml b/.github/workflows/build-onnxsim.yml index 33cac3167e..aa35a8ad71 100644 --- a/.github/workflows/build-onnxsim.yml +++ b/.github/workflows/build-onnxsim.yml @@ -16,11 +16,13 @@ on: paths: - '.github/workflows/build-onnxsim.yml' - 'docs/packages/onnxsim.yaml' + - 'patches/onnxsim/**' push: branches: [main] paths: - '.github/workflows/build-onnxsim.yml' - 'docs/packages/onnxsim.yaml' + - 'patches/onnxsim/**' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -79,6 +81,15 @@ jobs: submodules: recursive persist-credentials: false + - name: Checkout python-wheels + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + path: python-wheels + persist-credentials: false + + - name: Apply patches + run: git apply -v python-wheels/patches/onnxsim/${{ env.ONNXSIM_VERSION }}/*.patch + - name: Build wheels uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 with: diff --git a/docs/packages/onnxsim.yaml b/docs/packages/onnxsim.yaml index e27aab2717..7bbf039677 100644 --- a/docs/packages/onnxsim.yaml +++ b/docs/packages/onnxsim.yaml @@ -14,3 +14,4 @@ warning: | handling. versions: - version: 0.7.3 + patched: true diff --git a/patches/onnxsim/0.7.3/0001-tests-pin-ir_version-in-test_profiling-s-foldable-model.patch b/patches/onnxsim/0.7.3/0001-tests-pin-ir_version-in-test_profiling-s-foldable-model.patch new file mode 100644 index 0000000000..10189f2176 --- /dev/null +++ b/patches/onnxsim/0.7.3/0001-tests-pin-ir_version-in-test_profiling-s-foldable-model.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ludovic Henry +Date: Thu, 24 Sep 2026 00:00:00 +0000 +Subject: [PATCH] tests: pin ir_version in test_profiling's _foldable_model + +Every other test file that builds an onnx.ModelProto by hand pins +ir_version explicitly (test_python_api.py, test_function_rewriter.py, +test_constant_fold_determinism.py, etc. all pass ir_version=... to +helper.make_model()). test_profiling.py's _foldable_model() is the one +holdout: it calls helper.make_model(graph, opset_imports=[...]) with no +ir_version, so the model is stamped with whatever onnx.IR_VERSION the +currently installed onnx package defines. + +onnxsim statically links a vendored onnx (via the onnx-optimizer git +submodule, frozen at a pinned commit) into its C++ core, and that +core's checker enforces its own, older notion of the max supported IR +version. Once the *installed* onnx package (an unpinned "onnx" runtime +dependency in pyproject.toml) is newer than whatever onnx-optimizer's +submodule was pinned to at release time, every one of +_foldable_model()'s callers in this file fails identically: + + RuntimeError: Your model ir_version 14 is higher than the + checker's (13). + +before reaching any of what the test actually means to check (the +profiler's spans, the OrtSession nesting, the env var save/restore). +This is a real ambient-versioning gap, not a riscv64-only symptom: the +same break reproduces on any platform the moment pip resolves an onnx +release newer than the vendored submodule tolerates, which is exactly +why every sibling test file already pins ir_version defensively - +test_profiling.py just missed doing the same for its one hand-built +model. + +Match the existing convention used throughout the suite (ir_version=10 +regardless of opset) so the fixture stays valid across the wide range +of onnx versions the unpinned runtime dependency can resolve to. + +Upstream-Status: To upstream [no push/issue access to onnxsim/onnxsim from this environment - only riseproject-dev/python-wheels is attached; the fix is a one-line ir_version pin matching every sibling test file's existing convention] + +Signed-off-by: Ludovic Henry +--- +diff --git a/tests/test_profiling.py b/tests/test_profiling.py +--- a/tests/test_profiling.py ++++ b/tests/test_profiling.py +@@ -29,7 +29,18 @@ + x = helper.make_tensor_value_info("x", TensorProto.FLOAT, [1, 4]) + y = helper.make_tensor_value_info("y", TensorProto.FLOAT, [1, 4]) + graph = helper.make_graph([add_const, add_x], "g", [x], [y], [a, b]) +- model = helper.make_model(graph, opset_imports=[helper.make_opsetid("", 17)]) ++ model = helper.make_model( ++ graph, ++ opset_imports=[helper.make_opsetid("", 17)], ++ # Pin ir_version like every other model-building test in this suite ++ # already does (test_python_api.py, test_function_rewriter.py, etc.): ++ # onnx.helper.make_model() otherwise stamps the installed onnx package's ++ # current onnx.IR_VERSION, which floats upward with each onnx release and ++ # can exceed what the vendored onnx-optimizer/onnx submodule's checker ++ # (frozen at a pinned commit) accepts, e.g. "Your model ir_version 14 is ++ # higher than the checker's (13)" once a newer onnx is installed. ++ ir_version=10, ++ ) + onnx.checker.check_model(model) + return model + From 958d26680c8d285573c613086b90d11dbb510676 Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 25 Sep 2026 10:49:19 +0000 Subject: [PATCH 5/6] onnxsim: deselect the two Conv+BN fusion checks on cp311 cp311 has no riscv64 onnxruntime wheel, so onnxsim's check_n equivalence check runs through onnx's ReferenceEvaluator instead. For opset 9-13 that dispatches BatchNormalization to BatchNormalization_9, whose inference path is guarded by `if momentum is None` -- but OpRun fills the attribute with its schema default 0.9, so it always takes the momentum branch and blends the batch's own mean/var into the running statistics. The unsimplified Conv+BN model is therefore evaluated wrongly, and the correctly fused single Conv is reported as a mismatch (max diff 5.33 in the riscv64 log). Not riscv64-specific and not a precision issue: onnxsim 0.7.3's PyPI x86_64 wheel with onnx 1.23.0 / numpy 2.4.6 and no onnxruntime fails the same two tests every run (max diff 1.3-3.7). Against a float64 numpy reference, the fused Conv is within 3.7e-6 while the reference evaluator's Conv+BN is off by 16.3 and matches the momentum-blended formula to 2.3e-6. With onnxruntime installed (cp312 here, and every leg of upstream's CI) both tests pass. onnx main still has the same BatchNormalization_9 code. --- .github/workflows/build-onnxsim.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/build-onnxsim.yml b/.github/workflows/build-onnxsim.yml index aa35a8ad71..48ca6a3eaf 100644 --- a/.github/workflows/build-onnxsim.yml +++ b/.github/workflows/build-onnxsim.yml @@ -66,8 +66,15 @@ jobs: # No riscv64 onnxruntime wheel on cp311; the rest of the suite still # runs (onnxsim falls back to onnx's reference evaluator). onnxruntime: '' + # onnx's reference BatchNormalization_9 (opset 9-13) always takes its + # momentum branch (the attribute defaults to 0.9, never None) and mixes + # batch statistics into the inference output, so the equivalence check + # rejects the correctly fused Conv; same failure on x86_64 without + # onnxruntime. Upstream CI always installs onnxruntime. + pytest_k: not test_fuse_conv_bn_into_conv and not test_fuse_convtranspose_bn - python: cp312 onnxruntime: onnxruntime + pytest_k: '' env: ONNXSIM_VERSION: ${{ matrix.version }} @@ -128,6 +135,7 @@ jobs: CIBW_TEST_REQUIRES: pytest pytest-xdist ${{ matrix.onnxruntime }} CIBW_TEST_COMMAND: >- pytest {project}/tests/ + -k "${{ matrix.pytest_k }}" --ignore={project}/tests/test_python_api.py --ignore={project}/tests/test_simple.py --ignore={project}/tests/test_timm.py From 2dc4bc061e600d719b21dd96d9f17c62597d6bae Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Fri, 25 Sep 2026 10:49:34 +0000 Subject: [PATCH 6/6] onnxsim: set ONNXSIM_RELEASE so the wheel is 0.7.3, not 0.7.3.dev0 setup.py appends `.dev` from `git rev-list --count v..HEAD` whenever git is available, which it is in the cibuildwheel container, so the previous run built onnxsim-0.7.3.dev0-*.whl. The publish job titles the release from the wheel metadata and would have shipped onnxsim-v0.7.3.dev0. Upstream's own tag builds set ONNXSIM_RELEASE for exactly this; mirror that. --- .github/workflows/build-onnxsim.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-onnxsim.yml b/.github/workflows/build-onnxsim.yml index 48ca6a3eaf..1339b7eb6d 100644 --- a/.github/workflows/build-onnxsim.yml +++ b/.github/workflows/build-onnxsim.yml @@ -115,6 +115,7 @@ jobs: -DONNX_USE_LITE_PROTO=ON -DCMAKE_POLICY_VERSION_MINIMUM=3.5 " + ONNXSIM_RELEASE=${{ env.ONNXSIM_VERSION }} PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ # nanobind builds the onnxsim_cpp2py_export extension (CMakeLists.txt's # ONNXSIM_PYTHON path); CMake locates it via `python -m nanobind