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
142 changes: 142 additions & 0 deletions .github/workflows/build-vesin-torch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# SPDX-FileCopyrightText: 2026 The RISE Project
# SPDX-License-Identifier: MIT
---
# This workflow is based on the `build-torch-wheels` job of
# https://github.com/Luthaf/vesin/blob/v0.6.1/.github/workflows/build-wheels.yml
name: Build vesin-torch wheels (riscv64)

on:
workflow_dispatch:
inputs:
version:
description: 'Version glob to (re)build; empty builds every version of docs/packages/vesin-torch.yaml not released yet'
required: false
default: ''
pull_request:
branches: [main]
paths:
- '.github/workflows/build-vesin-torch.yml'
- 'docs/packages/vesin-torch.yaml'
push:
branches: [main]
paths:
- '.github/workflows/build-vesin-torch.yml'
- 'docs/packages/vesin-torch.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
GPULITE_COMMIT: 6c221167aeca7e113ea6f27e9a2e12391bdb189a # mts-v1.3.0, pinned in vesin/CMakeLists.txt
# Our registry only has the torch release the ladybug/torchaudio ports already built.
TORCH_VERSION: '2.13'

jobs:
setup:
uses: $/.github/workflows/_setup.yml
with:
package: vesin-torch
version: ${{ inputs.version }}

build_wheels:
needs: [setup]
if: needs.setup.outputs.versions != '[]'
strategy:
fail-fast: false
matrix:
version: ${{ fromJSON(needs.setup.outputs.versions) }}
name: Build vesin-torch ${{ matrix.version }} py3-none-manylinux_riscv64
runs-on: ubuntu-24.04-riscv
timeout-minutes: 90

env:
VESIN_TORCH_VERSION: ${{ matrix.version }}

steps:
- name: Checkout vesin v${{ env.VESIN_TORCH_VERSION }}
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
repository: Luthaf/vesin
ref: v${{ env.VESIN_TORCH_VERSION }}
persist-credentials: false

# setup.py's `universal_wheel` forces py3-none, so one build serves every
# interpreter. The wheel statically links gpulite (fetched by CMake) and
# dynamically links torch; none of their licences reach
# python/vesin_torch's pyproject.toml glob root, so upstream ships none.
- name: Stage the vesin and gpulite licences
run: |
cp LICENSE python/vesin_torch/LICENSE
curl -fsSL --retry 5 "https://raw.githubusercontent.com/metatensor/gpu-lite/${{ env.GPULITE_COMMIT }}/LICENSE" -o python/vesin_torch/LICENSE.gpulite

- uses: pypa/cibuildwheel@1828c10ab37f080699c7b81cea34097c684a7074 # v4.2.0
with:
package-dir: python/vesin_torch
output-dir: wheelhouse/
only: cp312-manylinux_riscv64
env:
CIBW_MANYLINUX_RISCV64_IMAGE: ${{ env.MANYLINUX_RISCV64_IMAGE }}
CIBW_BUILD_FRONTEND: build
# The build backend (python/vesin_torch/build-backend/backend.py) adds
# cmake + torch==<VESIN_TORCH_BUILD_WITH_TORCH_VERSION>.* as dynamic
# build-time requirements, resolved from our registry like upstream
# resolves them from download.pytorch.org.
VESIN_TORCH_BUILD_WITH_TORCH_VERSION: ${{ env.TORCH_VERSION }}
CIBW_ENVIRONMENT: >-
PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple/
PIP_ONLY_BINARY=cmake,torch,numpy
VESIN_TORCH_BUILD_WITH_TORCH_VERSION=${{ env.TORCH_VERSION }}.*
# vesin_torch links libtorch/libc10 (provided by the torch wheel at
# runtime, loaded RTLD_GLOBAL before vesin_torch is), same as our
# torchaudio port; excluding them keeps auditwheel from vendoring them.
CIBW_REPAIR_WHEEL_COMMAND_LINUX: >-
auditwheel repair -w {dest_dir} {wheel}
--exclude libtorch.so
--exclude libtorch_cpu.so
--exclude libtorch_python.so
--exclude libtorch_global_deps.so
--exclude libc10.so
--exclude libgomp.so.1
# numpy is not a vesin-torch test dependency, but without it `import
# torch` warns "Failed to initialize NumPy", which the tests'
# `filterwarnings = ["error"]` turns into a collection error.
# Upstream gets numpy transitively through ase (tox optional_deps).
CIBW_TEST_REQUIRES: pytest numpy torch==${{ env.TORCH_VERSION }}.*
# {project} is the checkout root, not package-dir, since
# python/vesin_torch's CMakeLists.txt needs the sibling top-level
# vesin/ and vesin-torch/ (C++ library) directories.
# test_metatomic.py needs metatensor-torch/metatomic-torch, neither
# of which this registry carries; deselect it rather than the whole file.
CIBW_TEST_COMMAND: >-
python -c "import importlib.metadata as md;
assert {p.name for p in md.files('vesin_torch') if 'licenses' in str(p)} == {'LICENSE', 'LICENSE.gpulite'}" &&
python {project}/scripts/pytest-dont-rewrite-torch.py &&
pytest {project}/python/vesin_torch/tests --ignore={project}/python/vesin_torch/tests/test_metatomic.py

- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: vesin-torch-${{ env.VESIN_TORCH_VERSION }}-py3-none-manylinux_riscv64
path: wheelhouse/*.whl
if-no-files-found: error

publish:
name: Publish vesin-torch ${{ 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: vesin-torch-${{ matrix.version }}-*-manylinux_riscv64
5 changes: 5 additions & 0 deletions docs/packages/vesin-torch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package-name: vesin-torch
source-code: https://github.com/Luthaf/vesin/
license: BSD-3-Clause
versions:
- version: 0.6.1
Loading