Skip to content

Commit 4573e79

Browse files
luhenryclaude
andcommitted
workflows: add build-torch.yml for riscv64 manywheel builds
Add workflow to build torch manywheel wheels for riscv64 using pytorch's manylinux2_39_riscv64 builder image. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
1 parent 957bb6d commit 4573e79

3 files changed

Lines changed: 526 additions & 0 deletions

File tree

.github/workflows/build-torch.yml

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
# SPDX-FileCopyrightText: 2026 The RISE Project
2+
# SPDX-License-Identifier: MIT
3+
---
4+
# This workflow is based on: https://github.com/riseproject-dev/pytorch-ci/blob/main/.github/workflows/manywheel.yml
5+
name: Build torch wheels (riscv64)
6+
7+
on:
8+
workflow_dispatch:
9+
inputs:
10+
version:
11+
description: 'torch version to build (git tag without leading v, e.g. 2.13.0)'
12+
required: true
13+
default: '2.13.0'
14+
pull_request:
15+
paths:
16+
- '.github/workflows/build-torch.yml'
17+
- 'patches/torch/**'
18+
19+
run-name: build-torch - ${{ inputs.version || '2.13.0' }}
20+
21+
concurrency:
22+
group: ${{ github.workflow }}-${{ inputs.version || '2.13.0' }}-${{ github.head_ref || github.run_id }}
23+
cancel-in-progress: true
24+
25+
permissions:
26+
contents: read # to fetch code (actions/checkout)
27+
packages: read
28+
29+
defaults:
30+
run:
31+
shell: bash --noprofile --norc -exo pipefail {0}
32+
33+
env:
34+
TORCH_VERSION: ${{ inputs.version || '2.13.0' }}
35+
36+
jobs:
37+
docker-builds:
38+
runs-on: ubuntu-24.04
39+
timeout-minutes: 360 # 6h
40+
permissions:
41+
packages: write
42+
env:
43+
DOCKER_IMAGE_NAME: manylinux2_39_riscv64-builder:cpu-riscv64
44+
outputs:
45+
docker-image: ${{ steps.tag.outputs.docker-image }}
46+
47+
steps:
48+
- name: Checkout pytorch v${{ env.TORCH_VERSION }}
49+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
50+
with:
51+
repository: pytorch/pytorch
52+
ref: v${{ env.TORCH_VERSION }}
53+
path: pytorch
54+
submodules: false
55+
persist-credentials: false
56+
57+
- name: Checkout python-wheels
58+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
59+
with:
60+
path: python-wheels
61+
persist-credentials: false
62+
63+
- name: Patch pytorch source
64+
run: |
65+
git -C pytorch apply ../python-wheels/patches/torch/${{ env.TORCH_VERSION }}/00*.patch
66+
67+
- name: Login to GitHub Container Registry
68+
uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
69+
with:
70+
registry: ghcr.io
71+
username: ${{ github.actor }}
72+
password: ${{ secrets.GITHUB_TOKEN }}
73+
74+
- name: Set up QEMU
75+
uses: docker/setup-qemu-action@96fe6ef7f33517b61c61be40b68a1882f3264fb8 # v4.2.0
76+
77+
- name: Set up Docker Buildx
78+
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
79+
80+
- name: Compute image tag
81+
id: tag
82+
working-directory: pytorch
83+
run: |
84+
echo "docker-image=ghcr.io/${{ github.repository_owner }}/python-wheels/${DOCKER_IMAGE_NAME}-$(git rev-parse HEAD:.ci/docker)" >> "${GITHUB_OUTPUT}"
85+
86+
- name: Build and push to GitHub Container Registry
87+
env:
88+
REMOTE_BUILDKIT: "1"
89+
WITH_PUSH: "true"
90+
CI: "1"
91+
DOCKER_IMAGE: ${{ steps.tag.outputs.docker-image }}
92+
working-directory: pytorch
93+
run: |
94+
# Check if image already exists, if it does then skip building it
95+
if docker manifest inspect "${DOCKER_IMAGE}"; then
96+
exit 0
97+
fi
98+
99+
cd .ci/docker
100+
./manywheel/build.sh "${DOCKER_IMAGE_NAME}" -t "${DOCKER_IMAGE}"
101+
102+
build_wheels:
103+
name: Build torch ${{ inputs.version || '2.13.0' }} ${{ matrix.python-version }}-manylinux_riscv64
104+
runs-on: ubuntu-24.04-riscv
105+
timeout-minutes: 1440 # 24h
106+
needs:
107+
- docker-builds
108+
container:
109+
image: ${{ needs.docker-builds.outputs.docker-image }}
110+
strategy:
111+
fail-fast: false
112+
matrix:
113+
python-version: ["3.12", "3.13", "3.14", "3.14t"]
114+
env:
115+
BUILD_ENVIRONMENT: linux-riscv64-binary-manywheel
116+
PYTORCH_ROOT: ${{ github.workspace }}/pytorch
117+
BINARY_ENV_FILE: /tmp/env
118+
PACKAGE_TYPE: manywheel
119+
DESIRED_CUDA: cpu
120+
GPU_ARCH_VERSION: ""
121+
GPU_ARCH_TYPE: cpu-riscv64
122+
DOCKER_IMAGE: ${{ needs.docker-builds.outputs.docker-image }}
123+
SKIP_ALL_TESTS: 1
124+
DESIRED_PYTHONS: ${{ matrix.python-version }}
125+
BUILD_NAME_PREFIX: "manywheel-py"
126+
BUILD_NAME_SUFFIX: "-cpu-riscv64"
127+
128+
steps:
129+
- name: Checkout pytorch v${{ env.TORCH_VERSION }}
130+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
131+
with:
132+
repository: pytorch/pytorch
133+
ref: v${{ env.TORCH_VERSION }}
134+
submodules: recursive
135+
persist-credentials: false
136+
137+
- name: Checkout python-wheels
138+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
139+
with:
140+
path: python-wheels
141+
persist-credentials: false
142+
143+
- name: Patch pytorch source
144+
run: |
145+
git apply python-wheels/patches/torch/${{ env.TORCH_VERSION }}/00*.patch
146+
147+
- name: Populate binary env
148+
working-directory: pytorch
149+
run: |
150+
export MAX_JOBS=$(nproc)
151+
echo "MAX_JOBS=${MAX_JOBS}" >> "${GITHUB_ENV}"
152+
153+
export PYTORCH_FINAL_PACKAGE_DIR="${RUNNER_TEMP}/artifacts"
154+
mkdir -p "${PYTORCH_FINAL_PACKAGE_DIR}"
155+
echo "PYTORCH_FINAL_PACKAGE_DIR=${PYTORCH_FINAL_PACKAGE_DIR}" >> "${GITHUB_ENV}"
156+
157+
bash .ci/pytorch/binary_populate_env.sh
158+
159+
- name: Build
160+
id: build
161+
working-directory: pytorch
162+
run: |
163+
# shellcheck disable=SC1091
164+
source "${BINARY_ENV_FILE}"
165+
bash .ci/manywheel/build_all.sh
166+
167+
- name: Set manywheel artifact name
168+
id: artifact-name
169+
run: |
170+
echo "wheel=torch-${{ env.TORCH_VERSION }}-py$(echo ${{ matrix.python-version }} | tr '.' '_')-manylinux_riscv64" >> "${GITHUB_OUTPUT}"
171+
172+
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
173+
if: steps.build.outcome != 'skipped'
174+
with:
175+
name: ${{ steps.artifact-name.outputs.wheel }}
176+
if-no-files-found: error
177+
path: ${{ runner.temp }}/artifacts/${{ steps.artifact-name.outputs.wheel }}/*
178+
179+
publish:
180+
name: Publish torch ${{ inputs.version || '2.13.0' }} to GitLab
181+
needs: [build_wheels]
182+
runs-on: ubuntu-latest
183+
permissions:
184+
contents: write
185+
pull-requests: write
186+
187+
steps:
188+
- name: Publish wheels and open docs PR
189+
uses: riseproject-dev/python-wheels/actions/publish-wheels@main
190+
with:
191+
artifact-pattern: torch-${{ env.TORCH_VERSION }}-*-manylinux_riscv64
192+
gitlab-username: ${{ vars.GITLAB_DEPLOY_USER }}
193+
gitlab-token: ${{ secrets.GITLAB_DEPLOY_TOKEN }}
194+
gitlab-project-id: ${{ vars.GITLAB_PROJECT_ID }}
195+
gh-token: ${{ secrets.GITHUB_TOKEN }}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
From 0000000000000000000000000000000000000001 Mon Sep 17 00:00:00 2001
2+
From: RISE Project CI <ci@riseproject.dev>
3+
Date: Thu, 10 Jul 2026 00:00:00 +0000
4+
Subject: [PATCH 1/2] [CI] Add manywheel Dockerfile for riscv64
5+
6+
Add Dockerfile_2_39_riscv64 for building riscv64 manywheel images using
7+
quay.io/pypa/manylinux_2_39_riscv64 as base, and register the new
8+
manylinux2_39_riscv64-builder:cpu-riscv64 image in build.sh.
9+
10+
Upstream-Status: To upstream
11+
12+
Signed-off-by: RISE Project CI <ci@riseproject.dev>
13+
---
14+
.ci/docker/manywheel/Dockerfile_2_39_riscv64 | 66 +++++++++++++++++++++++++++++++++
15+
.ci/docker/manywheel/build.sh | 8 ++++
16+
2 files changed, 74 insertions(+)
17+
18+
diff --git a/.ci/docker/manywheel/Dockerfile_2_39_riscv64 b/.ci/docker/manywheel/Dockerfile_2_39_riscv64
19+
new file mode 100644
20+
index 0000000..24068dbd0c13ab1b1ddcd632a8b03f54233b3f3d
21+
--- /dev/null
22+
+++ b/.ci/docker/manywheel/Dockerfile_2_39_riscv64
23+
@@ -0,0 +1,66 @@
24+
+FROM quay.io/pypa/manylinux_2_39_riscv64 as base
25+
+
26+
+ARG GCCTOOLSET_VERSION=14
27+
+
28+
+# Language variables
29+
+ENV LC_ALL=en_US.UTF-8
30+
+ENV LANG=en_US.UTF-8
31+
+ENV LANGUAGE=en_US.UTF-8
32+
+
33+
+ARG PIP_EXTRA_INDEX_URL
34+
+ENV PIP_EXTRA_INDEX_URL=${PIP_EXTRA_INDEX_URL}
35+
+ARG PIP_PREFER_BINARY
36+
+ENV PIP_PREFER_BINARY=${PIP_PREFER_BINARY}
37+
+
38+
+# Installed needed OS packages. This is to support all
39+
+# the binary builds (torch, vision, audio, text, data)
40+
+RUN yum -y update
41+
+RUN yum install -y \
42+
+ autoconf \
43+
+ automake \
44+
+ bison \
45+
+ bzip2 \
46+
+ curl \
47+
+ diffutils \
48+
+ file \
49+
+ git \
50+
+ less \
51+
+ libffi-devel \
52+
+ libgomp \
53+
+ make \
54+
+ openssl-devel \
55+
+ patch \
56+
+ perl \
57+
+ unzip \
58+
+ util-linux \
59+
+ wget \
60+
+ which \
61+
+ xz \
62+
+ zstd \
63+
+ sudo \
64+
+ gcc \
65+
+ gcc-c++ \
66+
+ gcc-gfortran \
67+
+ gdb
68+
+RUN yum install -y ninja-build
69+
+
70+
+# git236+ would refuse to run git commands in repos owned by other users
71+
+# Which causes version check to fail, as pytorch repo is bind-mounted into the image
72+
+# Override this behaviour by treating every folder as safe
73+
+# For more details see https://github.com/pytorch/pytorch/issues/78659#issuecomment-1144107327
74+
+RUN git config --global --add safe.directory "*"
75+
+
76+
+# Build CPython 3.15.0 / 3.15.0t from source; quay.io/pypa does not ship them yet
77+
+COPY ./common/install_cpython.sh install_cpython.sh
78+
+RUN CPYTHON_VERSIONS="3.15.0 3.15.0t" bash ./install_cpython.sh && rm install_cpython.sh
79+
+
80+
+FROM base as openblas
81+
+# Install openblas
82+
+ARG OPENBLAS_VERSION
83+
+ADD ./common/install_openblas.sh install_openblas.sh
84+
+RUN bash ./install_openblas.sh && rm install_openblas.sh
85+
+
86+
+FROM base as final
87+
+
88+
+# remove unnecessary python versions
89+
+COPY --from=openblas /opt/OpenBLAS/ /opt/OpenBLAS/
90+
91+
diff --git a/.ci/docker/manywheel/build.sh b/.ci/docker/manywheel/build.sh
92+
index 087f4126cf78de6b696834b1e26d6c5ced42624a..89125c2947a83fa1a9cf657dbccbc1f75673b230 100755
93+
--- a/.ci/docker/manywheel/build.sh
94+
+++ b/.ci/docker/manywheel/build.sh
95+
@@ -43,6 +43,14 @@
96+
DOCKER_GPU_BUILD_ARG=" --build-arg DEVTOOLSET_VERSION=13"
97+
MANY_LINUX_VERSION="2_28_aarch64"
98+
;;
99+
+ manylinux2_39_riscv64-builder:cpu-riscv64)
100+
+ TARGET=final
101+
+ GPU_IMAGE=riscv64/almalinux:10-kitten
102+
+ # Use a custom PyPI index to get pre-built wheels for RISC-V
103+
+ # See https://riseproject-dev.github.io/python-wheels/
104+
+ DOCKER_GPU_BUILD_ARG=" --platform linux/riscv64 --build-arg DEVTOOLSET_VERSION=14 --build-arg PIP_EXTRA_INDEX_URL=https://pypi.riseproject.dev/simple --build-arg PIP_PREFER_BINARY=1"
105+
+ MANY_LINUX_VERSION="2_39_riscv64"
106+
+ ;;
107+
manylinuxs390x-builder:cpu-s390x)
108+
TARGET=final
109+
GPU_IMAGE=s390x/almalinux:8
110+
--
111+
2.39.0

0 commit comments

Comments
 (0)