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
137 changes: 137 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
name: Release

# Builds abi3 wheels (one per platform, any Python >= 3.9) and an sdist, tests each
# wheel, and publishes to PyPI when a version tag is pushed.
#
# - pull requests touching packaging: build + test only, nothing is published
# - workflow_dispatch: same, on demand
# - tag vX.Y.Z (must match the version in Cargo.toml): build, test, publish

on:
push:
tags: ["v*"]
pull_request:
paths:
- .github/workflows/release.yml
- pyproject.toml
- Cargo.toml
- Cargo.lock
workflow_dispatch:

permissions:
contents: read

jobs:
wheels:
name: wheel ${{ matrix.platform.name }}
runs-on: ${{ matrix.platform.runner }}
strategy:
fail-fast: false
matrix:
platform:
- { name: linux-x86_64, runner: ubuntu-latest, target: x86_64, manylinux: "2_28", test: true }
- { name: linux-aarch64, runner: ubuntu-24.04-arm, target: aarch64, manylinux: "2_28", test: true }
- { name: macos-arm64, runner: macos-14, target: aarch64-apple-darwin, test: true }
# cross-compiled on the arm64 runner, so it can't be run here
- { name: macos-x86_64, runner: macos-14, target: x86_64-apple-darwin, test: false }
- { name: windows-x86_64, runner: windows-latest, target: x64, test: true }
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Build wheel
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
manylinux: ${{ matrix.platform.manylinux || 'auto' }}
args: --release --locked --out dist

# the abi3 wheel is tested on the oldest and newest supported Pythons
- uses: actions/setup-python@v5
id: py-oldest
if: matrix.platform.test
with:
python-version: "3.9"

- uses: actions/setup-python@v5
id: py-newest
if: matrix.platform.test
with:
python-version: "3.13"

# runs from outside the repo so the installed wheel is imported, not the source tree
- name: Test wheel
if: matrix.platform.test
shell: bash
env:
PYTHONS: ${{ steps.py-oldest.outputs.python-path }};${{ steps.py-newest.outputs.python-path }}
run: |
IFS=';' read -ra pythons <<< "$PYTHONS"
for py in "${pythons[@]}"; do
echo "::group::$py"
venv="$RUNNER_TEMP/venv-$("$py" -c 'import sys; print("%d%d" % sys.version_info[:2])')"
"$py" -m venv "$venv"
bin="$venv/bin"; [ "$RUNNER_OS" = "Windows" ] && bin="$venv/Scripts"
"$bin/python" -m pip install -q dist/*.whl onnx onnxruntime
cd "$RUNNER_TEMP"
"$bin/python" -c "import sys, burn_python as b; print(sys.version, b.__version__, b.available_backends())"
"$bin/python" "$GITHUB_WORKSPACE/tests/test_ops.py"
cd "$GITHUB_WORKSPACE"
echo "::endgroup::"
done

- uses: actions/upload-artifact@v4
with:
name: wheel-${{ matrix.platform.name }}
path: dist/*.whl

sdist:
name: sdist
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist

- uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz

publish:
name: publish to PyPI
if: startsWith(github.ref, 'refs/tags/v')
needs: [wheels, sdist]
runs-on: ubuntu-latest
# PyPI trusted publishing: no API token, PyPI trusts this workflow + environment
environment:
name: pypi
url: https://pypi.org/p/burn-python
permissions:
id-token: write
steps:
- uses: actions/checkout@v4

- name: Check tag matches Cargo.toml version
run: |
version=$(grep -m1 '^version' Cargo.toml | cut -d'"' -f2)
if [ "v$version" != "$GITHUB_REF_NAME" ]; then
echo "::error::tag $GITHUB_REF_NAME does not match Cargo.toml version $version"
exit 1
fi

- uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true

- run: ls -la dist

- uses: pypa/gh-action-pypi-publish@release/v1
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ dist/
*.egg-info/
__pycache__/
.venv/
Cargo.lock
.claude/
tests/*.onnx
tests/*.npy
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- PyPI packaging: `.github/workflows/release.yml` builds abi3 wheels (one per platform,
Python ≥ 3.9) for Linux x86_64/aarch64, macOS arm64/x86_64 and Windows x86_64, tests
them on Python 3.9 and 3.13, and publishes to PyPI via trusted publishing on a `vX.Y.Z` tag.
- GPU inference: `load_onnx(path, backend="wgpu")`, compiled to Metal on macOS and
Vulkan on Linux / Windows. ResNet-18 on an Apple M-series GPU: 6.1 ms at batch 1,
35.6 ms at batch 8 (~3x faster than ONNX Runtime on CPU). `available_backends()`
Expand All @@ -30,6 +33,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Initial maturin/pyo3 project scaffold, `burn-flex` + `onnx-ir` dependencies.

### Changed
- License files now match the declared license: dual MIT / Apache-2.0
(`LICENSE-MIT`, `LICENSE-APACHE`), replacing a GPL-3.0 `LICENSE` file that contradicted it.
- `Cargo.lock` is committed and release builds use `--locked`.
- Package version comes from `Cargo.toml` only.
- All ops now run on burn-dispatch's `Dispatch` backend; the device is chosen per model.
The unused `burn` umbrella dependency was replaced by `burn-dispatch`.
- Backend failures that happen on a worker thread (e.g. no GPU adapter) now report the
Expand Down
Loading
Loading