Skip to content

Commit 097352f

Browse files
committed
Implement C++ extension to have one-sided SVD calculations
1 parent 2e74436 commit 097352f

File tree

6 files changed

+670
-54
lines changed

6 files changed

+670
-54
lines changed

.github/workflows/release.yml

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,79 @@
66
# separate terms of service, privacy policy, and support
77
# documentation.
88

9-
name: Upload Python Package
9+
name: Build and upload Python Package
1010

1111
on:
12+
workflow_dispatch:
13+
pull_request:
14+
push:
15+
branches:
16+
- main
1217
release:
13-
types: [published]
18+
types:
19+
- published
1420

1521
permissions:
1622
contents: read
1723

1824
jobs:
19-
build:
20-
name: Build distribution
21-
runs-on: ubuntu-latest
25+
build_wheels:
26+
name: Build wheels for ${{ matrix.os }}
27+
runs-on: ${{ matrix.runs-on }}
28+
strategy:
29+
matrix:
30+
os: [ linux-intel, linux-arm, windows, macOS-intel, macOS-arm, iOS, pyodide ]
31+
include:
32+
- archs: auto
33+
platform: auto
34+
- os: linux-intel
35+
runs-on: ubuntu-latest
36+
- os: linux-arm
37+
runs-on: ubuntu-24.04-arm
38+
- os: windows
39+
runs-on: windows-latest
40+
- os: macos-intel
41+
# macos-13 was the last x86_64 runner
42+
runs-on: macos-13
43+
- os: macos-arm
44+
# macos-14+ (including latest) are ARM64 runners
45+
runs-on: macos-latest
46+
archs: auto,universal2
2247

2348
steps:
2449
- uses: actions/checkout@v4
25-
- name: Set up Python
26-
uses: actions/setup-python@v5
27-
with:
28-
python-version: "3.x"
29-
- name: Install pypa/build
30-
run: python3 -m pip install build --user
31-
- name: Build a binary wheel and a source tarball
32-
run: python3 -m build
33-
- name: Store the distribution packages
34-
uses: actions/upload-artifact@v4
35-
with:
36-
name: python-package-distributions
37-
path: dist/
50+
51+
- name: Build wheels
52+
uses: pypa/cibuildwheel@@v2.23.3
53+
env:
54+
CIBW_PLATFORM: ${{ matrix.platform }}
55+
CIBW_ARCHS: ${{ matrix.archs }}
56+
57+
- uses: actions/upload-artifact@v4
58+
with:
59+
name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }}
60+
path: ./wheelhouse/*.whl
61+
62+
build_sdist:
63+
name: Build source distribution
64+
runs-on: ubuntu-latest
65+
steps:
66+
- uses: actions/checkout@v4
67+
68+
- name: Build sdist
69+
run: pipx run build --sdist
70+
71+
- uses: actions/upload-artifact@v4
72+
with:
73+
name: cibw-sdist
74+
path: dist/*.tar.gz
3875

3976
publish-to-pypi:
4077
name: Publish Python distribution to PyPI
4178
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
4279
needs:
43-
- build
80+
- build_wheels
81+
- build_sdist
4482
runs-on: ubuntu-latest
4583
environment: release
4684
permissions:
@@ -49,7 +87,8 @@ jobs:
4987
- name: Download the dist file
5088
uses: actions/download-artifact@v4
5189
with:
52-
name: python-package-distributions
53-
path: dist/
90+
pattern: cibw-*
91+
path: dist
92+
merge-multiple: true
5493
- name: Publish distribution to PyPI
5594
uses: pypa/gh-action-pypi-publish@release/v1

CMakeLists.txt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Set the minimum CMake version and policies for highest tested version
2+
cmake_minimum_required(VERSION 3.15...3.27)
3+
4+
# Set default build type in CMake if skbuild is set
5+
message(STATUS "CMAKE_BUILD_TYPE set to '${CMAKE_BUILD_TYPE}'")
6+
7+
# Set up the project and ensure there is a working C++ compiler
8+
project(varipeps_extensions LANGUAGES CXX)
9+
10+
# Try to import all Python components potentially needed by nanobind
11+
find_package(Python 3.10
12+
REQUIRED COMPONENTS Interpreter Development.Module
13+
OPTIONAL_COMPONENTS Development.SABIModule)
14+
15+
# Import nanobind through CMake's find_package mechanism
16+
execute_process(
17+
COMMAND /usr/bin/env python3 -m nanobind --cmake_dir
18+
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE nanobind_ROOT)
19+
find_package(nanobind CONFIG REQUIRED)
20+
21+
# Find jaxlib include dir
22+
execute_process(
23+
COMMAND /usr/bin/env python3 -c "import inspect; import jaxlib; import pathlib; p = pathlib.Path(inspect.getfile(jaxlib)); print(p.parent / 'include')"
24+
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE jaxlib_INCLUDE_DIR)
25+
26+
# We are now ready to compile the actual extension module
27+
nanobind_add_module(
28+
# Name of the extension
29+
_svd_only_vt
30+
31+
# Target the stable ABI for Python 3.12+, which reduces
32+
# the number of binary wheels that must be built. This
33+
# does nothing on older Python versions
34+
STABLE_ABI
35+
36+
# Build libnanobind statically and merge it into the
37+
# extension (which itself remains a shared library)
38+
#
39+
# If your project builds multiple extensions, you can
40+
# replace this flag by NB_SHARED to conserve space by
41+
# reusing a shared libnanobind across libraries
42+
NB_STATIC
43+
44+
# Source code goes here
45+
varipeps/utils/extensions/svd_ffi.cpp
46+
)
47+
48+
target_include_directories(_svd_only_vt PRIVATE "${jaxlib_INCLUDE_DIR}")
49+
50+
target_link_libraries(_svd_only_vt PRIVATE lapack)
51+
52+
# Install directive for scikit-build-core
53+
install(TARGETS _svd_only_vt LIBRARY DESTINATION varipeps/utils/extensions)

pyproject.toml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,17 @@ dev = [
5050
]
5151

5252
[build-system]
53-
requires = ["hatchling"]
53+
requires = ["hatchling", "scikit-build-core>=0.11.0", "nanobind>=2.7.0", "jaxlib>=0.5.3"]
5454
build-backend = "hatchling.build"
55+
56+
[tool.scikit-build]
57+
# Protect the configuration against future changes in scikit-build-core
58+
minimum-version = "build-system.requires"
59+
# Setuptools-style build caching in a local directory
60+
build-dir = "build/{wheel_tag}"
61+
62+
[tool.scikit-build.cmake]
63+
build-type = "Release"
64+
65+
[tool.hatch.build.targets.wheel.hooks.scikit-build]
66+
experimental = true

0 commit comments

Comments
 (0)