-
Notifications
You must be signed in to change notification settings - Fork 0
workflows: add build-apache-tvm-ffi.yml for riscv64 manywheel builds #289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,192 @@ | ||
| # SPDX-FileCopyrightText: 2026 The RISE Project | ||
| # SPDX-License-Identifier: MIT | ||
| --- | ||
| # This workflow is based on upstream's own wheel build/publish setup: | ||
| # https://github.com/apache/tvm-ffi/blob/v0.1.12/.github/workflows/publish_wheel.yml | ||
| # https://github.com/apache/tvm-ffi/blob/v0.1.12/.github/actions/build-wheel-for-publish/action.yml | ||
| name: Build apache-tvm-ffi wheels (riscv64) | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| version: | ||
| description: 'apache-tvm-ffi version to build (git tag without leading v, e.g. 0.1.12)' | ||
| required: true | ||
| default: '0.1.12' | ||
| pull_request: | ||
| paths: | ||
| - '.github/workflows/build-apache-tvm-ffi.yml' | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ inputs.version || '0.1.12' }}-${{ github.head_ref || github.run_id }} | ||
| cancel-in-progress: true | ||
|
|
||
| permissions: | ||
| contents: read # to fetch code (actions/checkout) | ||
|
|
||
| env: | ||
| # `inputs.version` is empty on pull_request events; default to 0.1.12 there. | ||
| TVM_FFI_VERSION: ${{ inputs.version || '0.1.12' }} | ||
| UV_EXTRA_INDEX_URL: https://pypi.riseproject.dev/simple/ | ||
| UV_INDEX_STRATEGY: unsafe-best-match | ||
| UV_ONLY_BINARY: ':all:' | ||
| MANYLINUX_RISCV64_IMAGE: quay.io/pypa/manylinux_2_39_riscv64 | ||
|
|
||
| jobs: | ||
| build_sdist: | ||
| # The sdist is architecture-independent: it just packages the source tree, | ||
| # the vendored submodules (dlpack, libbacktrace) and a setuptools-scm-derived | ||
| # _version.py. Build it once on x86 instead of burning a scarce riscv runner | ||
| # (see CLAUDE.md gotcha 4). The resulting sdist is self-contained, so the | ||
| # riscv wheel job below needs neither git history nor submodules. | ||
| name: Build apache-tvm-ffi ${{ inputs.version || '0.1.12' }} sdist | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: read | ||
| outputs: | ||
| sdist_name: ${{ steps.sdist.outputs.sdist_name }} | ||
| steps: | ||
| - name: Checkout tvm-ffi v${{ env.TVM_FFI_VERSION }} | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | ||
| with: | ||
| repository: apache/tvm-ffi | ||
| ref: v${{ env.TVM_FFI_VERSION }} | ||
| # submodules must be present so pyproject's sdist.include /3rdparty/** | ||
| # globs actually bundle dlpack + libbacktrace; setuptools-scm needs the | ||
| # full history + tags to derive the version from the checked-out tag. | ||
| submodules: recursive | ||
| fetch-depth: 0 | ||
| fetch-tags: true | ||
| persist-credentials: false | ||
|
|
||
| - name: Install Python | ||
| uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 | ||
| with: | ||
| python-version: '3.12' | ||
| activate-environment: true | ||
| enable-cache: false | ||
|
|
||
| - name: Build sdist | ||
| id: sdist | ||
| run: | | ||
| uv pip install build twine | ||
| python -m build --sdist | ||
| twine check dist/* | ||
| sdists=(dist/*.tar.gz) | ||
| echo "sdist_name=$(basename "${sdists[0]}")" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Upload sdist artifact | ||
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | ||
| with: | ||
| name: apache-tvm-ffi-${{ env.TVM_FFI_VERSION }}-sdist | ||
| path: dist/*.tar.gz | ||
| if-no-files-found: error | ||
|
|
||
| build_wheels: | ||
| needs: build_sdist | ||
| name: Build apache-tvm-ffi ${{ inputs.version || '0.1.12' }} ${{ matrix.python }}-manylinux_riscv64 | ||
| runs-on: ubuntu-24.04-riscv | ||
| permissions: | ||
| contents: read | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| # Wheels are abi3 (pyproject sets wheel.py-api = "cp312"), so the single | ||
| # cp312 build is loadable on 3.12/3.13/3.14; only the free-threaded | ||
| # cp314t build needs its own wheel. This is upstream's cibuildwheel | ||
| # `build` list (cp38..cp312 + cp314t) collapsed to the two that differ. | ||
| python: [cp312, cp314t] | ||
| steps: | ||
| - name: Download sdist | ||
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | ||
| with: | ||
| name: apache-tvm-ffi-${{ env.TVM_FFI_VERSION }}-sdist | ||
| path: dist/ | ||
|
|
||
| - name: Build wheels | ||
| uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0 | ||
| with: | ||
| # cibuildwheel accepts an sdist tarball directly: it extracts it and | ||
| # builds from the self-contained tree (no submodules/git needed here). | ||
| package-dir: dist/${{ needs.build_sdist.outputs.sdist_name }} | ||
| env: | ||
| CIBW_BUILD: ${{ matrix.python }}-* | ||
| # pyproject pins [tool.cibuildwheel.linux] archs to x86_64+aarch64; | ||
| # override so this native riscv runner builds the riscv64 wheel. | ||
| CIBW_ARCHS: riscv64 | ||
| CIBW_SKIP: '*-musllinux_*' | ||
| CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }} | ||
| # Override upstream's build-frontend = "build[uv]". cibuildwheel's audit | ||
| # step creates a venv on the *host* runner (not in the container) and, | ||
| # when the frontend is build[uv], insists on a host `uv` binary | ||
| # (venv.py: `assert uv_path is not None`). The self-hosted riscv runner | ||
| # has no host uv, so the abi3 wheel builds fine but the run crashes in | ||
| # "Auditing wheel...". Plain `build` uses pip/virtualenv on the host | ||
| # instead - the way our local container build was validated. | ||
| CIBW_BUILD_FRONTEND: build | ||
| # The test-command (pytest {package}/tests/python) and test-groups | ||
| # (["test"] pulls in torch/numpy/ml_dtypes/pytest/ninja) are inherited | ||
| # from the sdist's pyproject.toml, so we build and test exactly the way | ||
| # upstream does. | ||
| # | ||
| # CIBW_ENVIRONMENT applies to BOTH the build and test phases. We only | ||
| # point pip/uv at our registry here (needed so test deps resolve, and | ||
| # harmless at build time). We deliberately do NOT set ONLY_BINARY here: | ||
| # the build backend needs cython>=3.0, which has no riscv64 wheel on | ||
| # any index and must be compiled from its sdist inside the container. | ||
| CIBW_ENVIRONMENT: >- | ||
| PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ | ||
| UV_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/ | ||
| UV_INDEX_STRATEGY=unsafe-best-match | ||
| # Test phase only: force wheels-only so a missing riscv64 wheel for a | ||
| # heavy test dep (torch/numpy/ml_dtypes) fails fast instead of silently | ||
| # kicking off a multi-hour source build under the runner. GPU-only tests | ||
| # self-skip via torch.cuda.is_available(). | ||
| CIBW_TEST_ENVIRONMENT: >- | ||
| PIP_ONLY_BINARY=:all: | ||
| UV_ONLY_BINARY=:all: | ||
| # Mirror upstream's test-command (pytest {package}/tests/python -vvs) | ||
| # but drop two tests that fail only because of this riscv64 runner's | ||
| # environment, not the wheel (2300+ others pass; cp314t, which pulls no | ||
| # torch, is fully green): | ||
| # * test_libinfo.py - every test there shells out to `tvm-ffi-config` | ||
| # and asserts the subprocess's stderr is empty. Importing tvm_ffi | ||
| # pulls in torch, whose bundled libcpuinfo can't parse this runner's | ||
| # /sys CPU topology (core_id reads "-1") and prints | ||
| # "Error in cpuinfo: failed to parse ... core_id" to stderr. The | ||
| # noise is nondeterministic across the module's subprocess tests, so | ||
| # the whole file is dropped via --ignore (an absolute path, so it's | ||
| # unambiguous regardless of pytest's rootdir). | ||
| # * test_filelock.py::test_concurrent_access - spawns 16 concurrent | ||
| # torch-importing workers under a hard 60s wait; the slower riscv64 | ||
| # runner blows the timeout. Dropped with -k by its (unique) name - | ||
| # rootdir-independent, unlike a path-based --deselect (which silently | ||
| # no-ops when the nodeid prefix doesn't match pytest's rootdir). | ||
| CIBW_TEST_COMMAND: >- | ||
| pytest {package}/tests/python -vvs | ||
| --ignore {package}/tests/python/test_libinfo.py | ||
| -k "not test_concurrent_access" | ||
|
|
||
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | ||
| with: | ||
| name: apache-tvm-ffi-${{ env.TVM_FFI_VERSION }}-${{ matrix.python }}-manylinux_riscv64 | ||
| path: ./wheelhouse/*.whl | ||
| if-no-files-found: error | ||
|
|
||
| publish: | ||
| name: Publish apache-tvm-ffi ${{ inputs.version || '0.1.12' }} to GitLab | ||
| needs: [build_wheels] | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
|
|
||
| steps: | ||
| - name: Publish wheels and open docs PR | ||
| uses: riseproject-dev/python-wheels/actions/publish-wheels@main | ||
| with: | ||
| artifact-pattern: apache-tvm-ffi-${{ env.TVM_FFI_VERSION }}-*-manylinux_riscv64 | ||
| gitlab-username: ${{ vars.GITLAB_DEPLOY_USER }} | ||
| gitlab-token: ${{ secrets.GITLAB_DEPLOY_TOKEN }} | ||
| gitlab-project-id: ${{ vars.GITLAB_PROJECT_ID }} | ||
| gh-token: ${{ secrets.GITHUB_TOKEN }} | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.