|
| 1 | +# SPDX-FileCopyrightText: 2026 The RISE Project |
| 2 | +# SPDX-License-Identifier: MIT |
| 3 | +--- |
| 4 | +# This workflow is based on: https://gitlab.arm.com/tosa/tosa-tools/-/blob/v2026.08.0/ci/templates/python_wheels.yml |
| 5 | +name: Build tosa-tools wheels (riscv64) |
| 6 | + |
| 7 | +on: |
| 8 | + workflow_dispatch: |
| 9 | + inputs: |
| 10 | + version: |
| 11 | + description: 'Version glob to (re)build; empty builds every version of docs/packages/tosa-tools.yaml not released yet' |
| 12 | + required: false |
| 13 | + default: '' |
| 14 | + pull_request: |
| 15 | + branches: [main] |
| 16 | + paths: |
| 17 | + - '.github/workflows/build-tosa-tools.yml' |
| 18 | + - 'docs/packages/tosa-tools.yaml' |
| 19 | + push: |
| 20 | + branches: [main] |
| 21 | + paths: |
| 22 | + - '.github/workflows/build-tosa-tools.yml' |
| 23 | + - 'docs/packages/tosa-tools.yaml' |
| 24 | + |
| 25 | +concurrency: |
| 26 | + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} |
| 27 | + cancel-in-progress: true |
| 28 | + |
| 29 | +permissions: |
| 30 | + contents: read |
| 31 | + |
| 32 | +env: |
| 33 | + MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 |
| 34 | + |
| 35 | +jobs: |
| 36 | + setup: |
| 37 | + uses: $/.github/workflows/_setup.yml |
| 38 | + with: |
| 39 | + package: tosa-tools |
| 40 | + version: ${{ inputs.version }} |
| 41 | + |
| 42 | + build_wheels: |
| 43 | + needs: [setup] |
| 44 | + if: needs.setup.outputs.versions != '[]' |
| 45 | + name: Build tosa-tools ${{ matrix.version }} manylinux_riscv64 |
| 46 | + runs-on: ubuntu-24.04-riscv |
| 47 | + timeout-minutes: 1440 |
| 48 | + strategy: |
| 49 | + fail-fast: false |
| 50 | + matrix: |
| 51 | + version: ${{ fromJSON(needs.setup.outputs.versions) }} |
| 52 | + |
| 53 | + env: |
| 54 | + TOSA_TOOLS_VERSION: ${{ matrix.version }} |
| 55 | + |
| 56 | + steps: |
| 57 | + # Upstream zero-pads the month in its tags (v2026.08.0), not in the wheel version. |
| 58 | + - id: tag |
| 59 | + run: | |
| 60 | + IFS=. read -r year month patch <<< "${TOSA_TOOLS_VERSION}" |
| 61 | + printf 'ref=v%s.%02d.%s\n' "${year}" "${month}" "${patch}" >> "$GITHUB_OUTPUT" |
| 62 | +
|
| 63 | + - name: Checkout tosa-tools ${{ steps.tag.outputs.ref }} |
| 64 | + run: | |
| 65 | + git clone --depth 1 --branch "${{ steps.tag.outputs.ref }}" https://gitlab.arm.com/tosa/tosa-tools.git tosa-tools |
| 66 | + echo "LLVM_COMMIT=$(sed -n 's/^ *value: "\([0-9a-f]*\)".*/\1/p' tosa-tools/ci/vars/llvm-sha.yml)" >> "$GITHUB_ENV" |
| 67 | +
|
| 68 | + # The wheel links LLVM/MLIR, FlatBuffers, googletest, pybind11, nlohmann/json, cxxopts |
| 69 | + # and musl-derived libm code; upstream's wheel ships none of their notices. |
| 70 | + - name: Stage the bundled dependencies' licences |
| 71 | + working-directory: tosa-tools |
| 72 | + run: | |
| 73 | + set -euo pipefail |
| 74 | + curl -fsSL --retry 5 "https://raw.githubusercontent.com/llvm/llvm-project/${LLVM_COMMIT}/mlir/LICENSE.TXT" -o LICENSE.llvm |
| 75 | + curl -fsSL --retry 5 https://raw.githubusercontent.com/google/flatbuffers/v25.2.10/LICENSE -o LICENSE.flatbuffers |
| 76 | + curl -fsSL --retry 5 https://raw.githubusercontent.com/google/googletest/v1.14.0/LICENSE -o LICENSE.googletest |
| 77 | + curl -fsSL --retry 5 https://raw.githubusercontent.com/pybind/pybind11/v3.0.4/LICENSE -o LICENSE.pybind11 |
| 78 | + curl -fsSL --retry 5 https://raw.githubusercontent.com/nlohmann/json/v3.11.3/LICENSE.MIT -o LICENSE.nlohmann-json |
| 79 | + curl -fsSL --retry 5 https://raw.githubusercontent.com/jarro2783/cxxopts/v3.3.1/LICENSE -o LICENSE.cxxopts |
| 80 | + cp reference_model/reference_model/src/ops/math/COPYRIGHT LICENSE.musl |
| 81 | +
|
| 82 | + - name: Build wheels |
| 83 | + uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 |
| 84 | + with: |
| 85 | + package-dir: tosa-tools |
| 86 | + output-dir: wheelhouse |
| 87 | + env: |
| 88 | + CIBW_BUILD: cp312-manylinux_riscv64 cp313-manylinux_riscv64 cp314-manylinux_riscv64 |
| 89 | + CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} |
| 90 | + CIBW_ENVIRONMENT_PASS_LINUX: LLVM_COMMIT |
| 91 | + # Upstream's cmdflow.py builds all of LLVM/MLIR for every backend. Build only the |
| 92 | + # libraries tosa-opt links (its CMake LIBS, closed over their link interfaces), for |
| 93 | + # the host backend, to fit the riscv64 runner; no zstd, as upstream's tosa-opt has none. |
| 94 | + CIBW_BEFORE_ALL_LINUX: | |
| 95 | + set -euxo pipefail |
| 96 | + manylinux-install-clang -v v22.1.6.0 |
| 97 | + rm -rf /var/cache/dnf /project/llvm-project |
| 98 | + curl -fL --retry 5 --retry-all-errors --retry-delay 10 -o /tmp/llvm.tar.gz "https://codeload.github.com/llvm/llvm-project/tar.gz/${LLVM_COMMIT}" |
| 99 | + tar -xzf /tmp/llvm.tar.gz -C /project |
| 100 | + rm /tmp/llvm.tar.gz |
| 101 | + mv /project/llvm-project-* /project/llvm-project |
| 102 | + cd /project/llvm-project |
| 103 | + cmake -S llvm -B build -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_BUILD_TYPE=Release \ |
| 104 | + -DLLVM_APPEND_VC_REV=OFF -DLLVM_ENABLE_PROJECTS=mlir -DLLVM_ENABLE_ASSERTIONS=ON \ |
| 105 | + -DLLVM_TARGETS_TO_BUILD=host -DLLVM_ENABLE_ZSTD=OFF |
| 106 | + targets="$(/opt/python/cp312-cp312/bin/python - MLIRParser MLIRSupport MLIRIR MLIROptLib MLIRPass MLIRTosaDialect MLIRTosaTransforms MLIRFuncDialect <<'EOF' |
| 107 | + import re, sys |
| 108 | + text = open("build/lib/cmake/llvm/LLVMExports.cmake").read() + open("build/lib/cmake/mlir/MLIRTargets.cmake").read() |
| 109 | + kind = dict(re.findall(r"^add_library\((\S+) (\S+) IMPORTED\)", text, re.M)) |
| 110 | + deps = dict(re.findall(r'set_target_properties\((\S+) PROPERTIES\n INTERFACE_LINK_LIBRARIES "([^"]*)"', text)) |
| 111 | + todo, seen = sys.argv[1:], set() |
| 112 | + while todo: |
| 113 | + name = todo.pop() |
| 114 | + if name in kind and name not in seen: |
| 115 | + seen.add(name) |
| 116 | + todo += re.findall(r"[\w-]+", deps.get(name, "")) |
| 117 | + print(" ".join(sorted(n for n in seen if kind[n] != "INTERFACE"))) |
| 118 | + EOF |
| 119 | + )" |
| 120 | + cmake --build build -j "$(nproc)" --target mlir-headers mlir-tblgen ${targets} |
| 121 | + CIBW_CONFIG_SETTINGS: >- |
| 122 | + cmake.define.TOSA_ENABLE_PROJECTS=serialization,reference_model,mlir_translator |
| 123 | + cmake.define.MLIR_TOSA_OPT=ON |
| 124 | + cmake.define.MLIR_DIR=/project/llvm-project/build/lib/cmake/mlir |
| 125 | + cmake.define.LLVM_DIR=/project/llvm-project/build/lib/cmake/llvm |
| 126 | + CIBW_ENVIRONMENT: >- |
| 127 | + SETUPTOOLS_SCM_PRETEND_VERSION_FOR_TOSA_TOOLS=${{ env.TOSA_TOOLS_VERSION }} |
| 128 | + SKBUILD_WHEEL_LICENSE_FILES="LICENSES/Apache-2.0.txt;LICENSE.*" |
| 129 | + PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ |
| 130 | + CIBW_TEST_COMMAND: 'python -c "import tosa_reference_model, tosa_serializer; print(tosa_reference_model.__file__); print(tosa_serializer.__file__)"' |
| 131 | + |
| 132 | + - name: Check wheel contents |
| 133 | + run: | |
| 134 | + python3 - wheelhouse/*.whl <<'EOF' |
| 135 | + import sys, zipfile |
| 136 | + assert len(sys.argv) == 4, sys.argv |
| 137 | + for whl in sys.argv[1:]: |
| 138 | + names = zipfile.ZipFile(whl).namelist() |
| 139 | + for tool in ("tosa-opt", "tosa_reference_model", "tosa_verify", "flatc"): |
| 140 | + assert f"bin/{tool}" in names, (whl, tool) |
| 141 | + licences = {n.split(".dist-info/licenses/", 1)[1] for n in names |
| 142 | + if ".dist-info/licenses/" in n and not n.endswith("/")} |
| 143 | + assert licences == {"LICENSES/Apache-2.0.txt", "LICENSE.cxxopts", "LICENSE.flatbuffers", |
| 144 | + "LICENSE.googletest", "LICENSE.llvm", "LICENSE.musl", |
| 145 | + "LICENSE.nlohmann-json", "LICENSE.pybind11"}, (whl, licences) |
| 146 | + EOF |
| 147 | +
|
| 148 | + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 |
| 149 | + with: |
| 150 | + name: tosa-tools-${{ env.TOSA_TOOLS_VERSION }}-cibw-wheels-manylinux_riscv64 |
| 151 | + path: wheelhouse/*.whl |
| 152 | + if-no-files-found: error |
| 153 | + |
| 154 | + test_wheels: |
| 155 | + needs: [setup, build_wheels] |
| 156 | + if: needs.setup.outputs.versions != '[]' |
| 157 | + name: Test tosa-tools ${{ matrix.version }} ${{ matrix.python }}-manylinux_riscv64 |
| 158 | + runs-on: ubuntu-24.04-riscv |
| 159 | + timeout-minutes: 120 |
| 160 | + strategy: |
| 161 | + fail-fast: false |
| 162 | + matrix: |
| 163 | + version: ${{ fromJSON(needs.setup.outputs.versions) }} |
| 164 | + python: ["3.12", "3.13", "3.14"] |
| 165 | + |
| 166 | + env: |
| 167 | + TOSA_TOOLS_VERSION: ${{ matrix.version }} |
| 168 | + PIP_EXTRA_INDEX_URL: https://pypi.riseproject.dev/simple/ |
| 169 | + |
| 170 | + steps: |
| 171 | + - id: tag |
| 172 | + run: | |
| 173 | + IFS=. read -r year month patch <<< "${TOSA_TOOLS_VERSION}" |
| 174 | + printf 'ref=v%s.%02d.%s\n' "${year}" "${month}" "${patch}" >> "$GITHUB_OUTPUT" |
| 175 | +
|
| 176 | + - name: Checkout tosa-tools ${{ steps.tag.outputs.ref }} |
| 177 | + run: git clone --depth 1 --branch "${{ steps.tag.outputs.ref }}" https://gitlab.arm.com/tosa/tosa-tools.git tosa-tools |
| 178 | + |
| 179 | + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 |
| 180 | + with: |
| 181 | + name: tosa-tools-${{ env.TOSA_TOOLS_VERSION }}-cibw-wheels-manylinux_riscv64 |
| 182 | + path: wheelhouse |
| 183 | + |
| 184 | + - uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 |
| 185 | + with: |
| 186 | + python-version: ${{ matrix.python }} |
| 187 | + activate-environment: true |
| 188 | + enable-cache: false |
| 189 | + |
| 190 | + - name: Out-of-box test |
| 191 | + run: | |
| 192 | + python tosa-tools/ci/python/tools/python_wheels_oobt.py \ |
| 193 | + --version "${TOSA_TOOLS_VERSION}" \ |
| 194 | + --wheel-dir wheelhouse \ |
| 195 | + --python-version "${{ matrix.python }}" \ |
| 196 | + --platform-label linux-riscv64 \ |
| 197 | + --output-dir oobt-results |
| 198 | +
|
| 199 | + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 |
| 200 | + if: always() |
| 201 | + with: |
| 202 | + name: tosa-tools-${{ env.TOSA_TOOLS_VERSION }}-${{ matrix.python }}-oobt-results |
| 203 | + path: oobt-results |
| 204 | + if-no-files-found: ignore |
| 205 | + |
| 206 | + publish: |
| 207 | + name: Publish tosa-tools ${{ matrix.version }} |
| 208 | + needs: [setup, build_wheels, test_wheels] |
| 209 | + if: needs.setup.outputs.versions != '[]' |
| 210 | + strategy: |
| 211 | + fail-fast: false |
| 212 | + matrix: |
| 213 | + version: ${{ fromJSON(needs.setup.outputs.versions) }} |
| 214 | + permissions: |
| 215 | + contents: write |
| 216 | + pull-requests: write |
| 217 | + uses: $/.github/workflows/_publish-wheel.yml |
| 218 | + secrets: |
| 219 | + app-private-key: ${{ secrets.RISEPROJECT_APP_PRIVATE_KEY }} |
| 220 | + with: |
| 221 | + artifact-pattern: tosa-tools-${{ matrix.version }}-*-manylinux_riscv64 |
0 commit comments