Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 167 additions & 0 deletions .github/workflows/build-onnxsim.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# 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'
- '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 }}
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).
# 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
# 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 }}

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: 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:
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
"
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
# --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; 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/
-k "${{ matrix.pytest_k }}"
--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:
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
17 changes: 17 additions & 0 deletions docs/packages/onnxsim.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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
patched: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ludovic Henry <git@ludovic.dev>
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 <git@ludovic.dev>
---
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

Loading