ri-kernels 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,221 @@
1
+ name: Wheels
2
+
3
+ # Builds the three distributions published from this repository:
4
+ #
5
+ # ri_kernels Python code + libri_kernels.so (CPU)
6
+ # ri_kernels_cuda12 libri_kernels_cuda.so built against CUDA 12
7
+ # ri_kernels_cuda13 libri_kernels_cuda.so built against CUDA 13
8
+ #
9
+ # The CUDA wheels are add-ons: they contain no Python code and depend on
10
+ # ri_kernels of the exact same version. ci/make_variant.py derives their build
11
+ # metadata from pyproject.toml. Wheels are built on every push and pull request;
12
+ # they are only uploaded to PyPI when a GitHub Release is published.
13
+
14
+ on:
15
+ push:
16
+ branches: [main]
17
+ tags: ["v*"]
18
+ pull_request:
19
+ workflow_dispatch:
20
+ release:
21
+ types: [published]
22
+
23
+ permissions:
24
+ contents: read
25
+
26
+ concurrency:
27
+ group: wheels-${{ github.ref }}
28
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
29
+
30
+ jobs:
31
+ sdist:
32
+ name: sdist (ri_kernels)
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+ - run: pipx run build --sdist
37
+ - uses: actions/upload-artifact@v4
38
+ with:
39
+ name: sdist-ri_kernels
40
+ path: dist/*.tar.gz
41
+
42
+ build_cpu:
43
+ name: ri_kernels (${{ matrix.arch }}, ${{ matrix.os }})
44
+ runs-on: ${{ matrix.os }}
45
+ strategy:
46
+ fail-fast: false
47
+ matrix:
48
+ include:
49
+ - { os: ubuntu-latest, arch: x86_64 }
50
+ - { os: ubuntu-24.04-arm, arch: aarch64 }
51
+ - { os: macos-14, arch: arm64 }
52
+ steps:
53
+ - uses: actions/checkout@v4
54
+
55
+ - uses: pypa/cibuildwheel@v4.2.0
56
+ env:
57
+ CIBW_BUILD_VERBOSITY: 1
58
+ CIBW_TEST_REQUIRES: pytest numpy
59
+ CIBW_TEST_SOURCES: tests
60
+ # The test module skips itself at module level when no library is
61
+ # found, so assert the library is present before running it -
62
+ # otherwise a wheel missing libri_kernels.so would pass vacuously.
63
+ CIBW_TEST_COMMAND: >
64
+ python -c "from ri_kernels.jax_api import rfi_vis_op as m; assert m._TAB_LIB is not None, 'libri_kernels.so missing from wheel'"
65
+ && pytest ./tests -q
66
+
67
+ - uses: actions/upload-artifact@v4
68
+ with:
69
+ name: wheels-ri_kernels-${{ matrix.os }}-${{ matrix.arch }}
70
+ path: wheelhouse/*.whl
71
+
72
+ build_cuda:
73
+ name: ri_kernels_cuda${{ matrix.cuda.major }} (${{ matrix.platform.arch }})
74
+ runs-on: ${{ matrix.platform.os }}
75
+ strategy:
76
+ fail-fast: false
77
+ matrix:
78
+ # `archs` overrides the CMAKE_CUDA_ARCHITECTURES default in
79
+ # CMakeLists.txt, which is kept to what any CUDA 12.x can build. The
80
+ # published wheels target one cubin per compute-capability *major*
81
+ # (plus 7.5, the CUDA 13 floor): cubins are binary compatible upward
82
+ # within a major, so 8.0 covers 8.6/8.7/8.9, 10.0 covers 10.3 (B300)
83
+ # and 12.0 covers 12.1 (GB10). 10.x and 12.x are separate families and
84
+ # need separate cubins. This is the set the jax CUDA plugin itself
85
+ # ships, minus 7.0, which only CUDA 12 can still build. The trailing
86
+ # `-virtual` embeds PTX once, as the JIT fallback for future GPUs.
87
+ cuda:
88
+ - major: "12"
89
+ pkg: "12-9"
90
+ home: "/usr/local/cuda-12.9"
91
+ archs: "60-real;70-real;75-real;80-real;90-real;100-real;120-real;120-virtual"
92
+ - major: "13"
93
+ pkg: "13-0"
94
+ home: "/usr/local/cuda-13.0"
95
+ # CUDA 13 dropped Maxwell/Pascal/Volta; Turing is the floor.
96
+ archs: "75-real;80-real;90-real;100-real;120-real;120-virtual"
97
+ platform:
98
+ - { os: ubuntu-latest, arch: x86_64, repo_arch: x86_64 }
99
+ - { os: ubuntu-24.04-arm, arch: aarch64, repo_arch: sbsa }
100
+ steps:
101
+ - uses: actions/checkout@v4
102
+
103
+ - name: Rewrite metadata for the CUDA ${{ matrix.cuda.major }} variant
104
+ run: |
105
+ python -m pip install --disable-pip-version-check tomlkit
106
+ python ci/make_variant.py --cuda ${{ matrix.cuda.major }}
107
+
108
+ - uses: pypa/cibuildwheel@v4.2.0
109
+ env:
110
+ CIBW_BUILD_VERBOSITY: 1
111
+ # nvcc, the CUDA runtime headers/static lib, and CUB, installed into
112
+ # the manylinux container. Use the cuda-toolkit-${{ matrix.cuda.pkg }}
113
+ # metapackage instead if these split packages ever stop resolving.
114
+ CIBW_BEFORE_ALL_LINUX: >
115
+ dnf -y install dnf-plugins-core &&
116
+ dnf config-manager --add-repo
117
+ https://developer.download.nvidia.com/compute/cuda/repos/rhel8/${{ matrix.platform.repo_arch }}/cuda-rhel8.repo &&
118
+ dnf -y install
119
+ cuda-nvcc-${{ matrix.cuda.pkg }}
120
+ cuda-cudart-devel-${{ matrix.cuda.pkg }}
121
+ cuda-cccl-${{ matrix.cuda.pkg }}
122
+ # CMAKE_ARGS is forwarded to the configure step by scikit-build-core.
123
+ # It has to carry the architectures rather than SKBUILD_CMAKE_DEFINE,
124
+ # which splits its own value on `;`. The quotes keep cibuildwheel's
125
+ # shell-style parser from reading the separators as command
126
+ # terminators.
127
+ CIBW_ENVIRONMENT_LINUX: >
128
+ CUDACXX=${{ matrix.cuda.home }}/bin/nvcc
129
+ PATH=${{ matrix.cuda.home }}/bin:$PATH
130
+ CMAKE_ARGS="-DCMAKE_CUDA_ARCHITECTURES=${{ matrix.cuda.archs }}"
131
+ # No test here: installing the wheel would pull ri_kernels==<version>
132
+ # from the index, which does not exist yet for an unreleased version. The
133
+ # library is smoke-tested below instead.
134
+ CIBW_TEST_COMMAND: ""
135
+
136
+ - name: Smoke-test the built library
137
+ run: python ci/check_library.py wheelhouse ri_kernels_cuda${{ matrix.cuda.major }}
138
+
139
+ - uses: actions/upload-artifact@v4
140
+ with:
141
+ name: wheels-ri_kernels_cuda${{ matrix.cuda.major }}-${{ matrix.platform.arch }}
142
+ path: wheelhouse/*.whl
143
+
144
+ check_release:
145
+ name: Check release tag
146
+ if: github.event_name == 'release'
147
+ runs-on: ubuntu-latest
148
+ steps:
149
+ - uses: actions/checkout@v4
150
+ - name: Tag must match the version in pyproject.toml
151
+ env:
152
+ TAG: ${{ github.event.release.tag_name }}
153
+ run: |
154
+ version=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
155
+ if [ "$TAG" != "v$version" ] && [ "$TAG" != "$version" ]; then
156
+ echo "::error::release tag '$TAG' does not match pyproject.toml version '$version'"
157
+ exit 1
158
+ fi
159
+ echo "Releasing version $version"
160
+
161
+ # One publish job per PyPI project: trusted publishing binds a project to
162
+ # a single workflow + environment, so they cannot share one.
163
+ publish_ri_kernels:
164
+ name: Publish ri_kernels
165
+ if: github.event_name == 'release'
166
+ needs: [check_release, sdist, build_cpu, build_cuda]
167
+ runs-on: ubuntu-latest
168
+ environment:
169
+ name: pypi-ri_kernels
170
+ url: https://pypi.org/p/ri_kernels
171
+ permissions:
172
+ id-token: write
173
+ steps:
174
+ - uses: actions/download-artifact@v4
175
+ with:
176
+ pattern: wheels-ri_kernels-*
177
+ path: dist
178
+ merge-multiple: true
179
+ - uses: actions/download-artifact@v4
180
+ with:
181
+ name: sdist-ri_kernels
182
+ path: dist
183
+ - uses: pypa/gh-action-pypi-publish@release/v1
184
+
185
+ # The CUDA packages pin ri_kernels==<version>, so the base package has to be
186
+ # on the index first.
187
+ publish_ri_kernels_cuda12:
188
+ name: Publish ri_kernels_cuda12
189
+ if: github.event_name == 'release'
190
+ needs: [publish_ri_kernels]
191
+ runs-on: ubuntu-latest
192
+ environment:
193
+ name: pypi-ri_kernels_cuda12
194
+ url: https://pypi.org/p/ri_kernels_cuda12
195
+ permissions:
196
+ id-token: write
197
+ steps:
198
+ - uses: actions/download-artifact@v4
199
+ with:
200
+ pattern: wheels-ri_kernels_cuda12-*
201
+ path: dist
202
+ merge-multiple: true
203
+ - uses: pypa/gh-action-pypi-publish@release/v1
204
+
205
+ publish_ri_kernels_cuda13:
206
+ name: Publish ri_kernels_cuda13
207
+ if: github.event_name == 'release'
208
+ needs: [publish_ri_kernels]
209
+ runs-on: ubuntu-latest
210
+ environment:
211
+ name: pypi-ri_kernels_cuda13
212
+ url: https://pypi.org/p/ri_kernels_cuda13
213
+ permissions:
214
+ id-token: write
215
+ steps:
216
+ - uses: actions/download-artifact@v4
217
+ with:
218
+ pattern: wheels-ri_kernels_cuda13-*
219
+ path: dist
220
+ merge-multiple: true
221
+ - uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,203 @@
1
+ cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
2
+
3
+ # Parse version from pyproject.toml
4
+ file(READ "${CMAKE_CURRENT_SOURCE_DIR}/pyproject.toml" PYPROJECT_TOML)
5
+ string(REGEX MATCH "\nversion = \"([^\"]+)\"" _ "${PYPROJECT_TOML}")
6
+ set(RI_KERNELS_VERSION "${CMAKE_MATCH_1}")
7
+
8
+ project(ri_kernels LANGUAGES CXX VERSION "${RI_KERNELS_VERSION}")
9
+ set(RI_KERNELS_SO_VERSION ${CMAKE_PROJECT_VERSION_MAJOR})
10
+
11
+
12
+ # set default build type to RELEASE
13
+ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
14
+ set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE)
15
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
16
+ "Debug" "Release" "MinSizeRel" "RelWithDebInfo"
17
+ )
18
+ endif()
19
+
20
+ # set language and standard
21
+ set(CMAKE_CXX_STANDARD 20)
22
+ set(CUDA_STANDARD 20)
23
+ set(CUDA_STANDARD_REQUIRED ON)
24
+
25
+ include(CMakeDependentOption)
26
+ include(FetchContent)
27
+ include(CheckLinkerFlag)
28
+
29
+ # --exclude-libs is a GNU ld / lld feature; Apple's linker rejects it.
30
+ check_linker_flag(CXX "-Wl,--exclude-libs,ALL" RI_KERNELS_HAVE_EXCLUDE_LIBS)
31
+
32
+ # Export only the FFI entry points annotated with RI_KERNELS_API (see
33
+ # src/visibility.h). Everything else, including symbols pulled in from static
34
+ # archives such as Highway or a statically linked CUDA runtime, stays out of
35
+ # the dynamic symbol table. Without this the CUDA runtime symbols would be
36
+ # exported and could be interposed by the runtime XLA already loaded into the
37
+ # process, since the dynamic loader searches the global scope before a dlopen'd
38
+ # object's own definitions.
39
+ function(ri_kernels_restrict_exports target)
40
+ set_target_properties(${target} PROPERTIES
41
+ C_VISIBILITY_PRESET hidden
42
+ CXX_VISIBILITY_PRESET hidden
43
+ CUDA_VISIBILITY_PRESET hidden
44
+ HIP_VISIBILITY_PRESET hidden
45
+ VISIBILITY_INLINES_HIDDEN ON
46
+ )
47
+ if(RI_KERNELS_HAVE_EXCLUDE_LIBS)
48
+ target_link_options(${target} PRIVATE "-Wl,--exclude-libs,ALL")
49
+ endif()
50
+ endfunction()
51
+
52
+ if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0")
53
+ cmake_policy(SET CMP0135 NEW)
54
+ endif()
55
+
56
+ # Options
57
+ option(RI_KERNELS_CPU "Build CPU extension" ON)
58
+ option(RI_KERNELS_CUDA "Build CUDA extension" OFF)
59
+ option(RI_KERNELS_ROCM "Build ROCm extension" OFF)
60
+
61
+ option(RI_KERNELS_BUNDLED_LIBS "Use all bundled libraries" ON)
62
+ cmake_dependent_option(RI_KERNELS_BUNDLED_HIGHWAY "Use bundled highway lib" ON "RI_KERNELS_BUNDLED_LIBS" OFF)
63
+ option(RI_KERNELS_MULTI_ARCH "Build kernels for multiple CPU architectues with dynamic dispatch. When disabled, arch flags should be set through CMAKE_CXX_FLAGS." ON)
64
+
65
+ # Directory inside the wheel the GPU libraries are installed into. The CPU
66
+ # library always ships in the ri_kernels package, but the GPU libraries are
67
+ # published as separate add-on distributions (ri_kernels_cuda12,
68
+ # ri_kernels_cuda13) that own a top-level package directory of their own.
69
+ set(RI_KERNELS_GPU_INSTALL_DIR "ri_kernels" CACHE STRING
70
+ "Directory inside the wheel that the GPU libraries are installed into")
71
+
72
+ set(CMAKE_CUDA_ARCHITECTURES "75-real;80-real;90-real;90-virtual" CACHE STRING "CUDA Architectures")
73
+ set(CMAKE_HIP_ARCHITECTURES "gfx90a;gfx942;gfx1030;gfx1100" CACHE STRING "HIP Architectures")
74
+
75
+ set(Python_EXECUTABLE "python3" CACHE STRING "The python interpreter")
76
+
77
+ # Detect jaxlib include directory (override with -DJAXLIB_HOME=...)
78
+ if(NOT DEFINED JAXLIB_HOME)
79
+ execute_process(
80
+ COMMAND ${Python_EXECUTABLE} -c
81
+ "import jaxlib, os; print(os.path.dirname(jaxlib.__file__))"
82
+ OUTPUT_VARIABLE JAXLIB_HOME
83
+ OUTPUT_STRIP_TRAILING_WHITESPACE
84
+ RESULT_VARIABLE _jaxlib_result
85
+ )
86
+ if(NOT _jaxlib_result EQUAL 0)
87
+ message(FATAL_ERROR "Failed to locate jaxlib via python3. "
88
+ "Install jaxlib or pass -DJAXLIB_HOME=<path>.")
89
+ endif()
90
+ endif()
91
+ message(STATUS "Using JAXLIB_HOME: ${JAXLIB_HOME}")
92
+
93
+
94
+ set(RI_KERNELS_CPU_SOURCES
95
+ ./src/rfi_kernel.cpp
96
+ ./src/rfi_jvp_kernel.cpp
97
+ ./src/rfi_transpose_kernel.cpp
98
+ )
99
+
100
+ set(RI_KERNELS_GPU_SOURCES
101
+ ./src/rfi_kernel_gpu.cu
102
+ ./src/rfi_jvp_kernel_gpu.cu
103
+ ./src/rfi_transpose_kernel_gpu.cu
104
+ ./src/util_gpu.cu
105
+ )
106
+
107
+ if(RI_KERNELS_CPU)
108
+ add_library(ri_kernels SHARED ${RI_KERNELS_CPU_SOURCES})
109
+ target_include_directories(ri_kernels PRIVATE ${JAXLIB_HOME}/include ./src)
110
+
111
+ target_compile_options(ri_kernels PRIVATE
112
+ $<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-return-type>
113
+ $<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wno-attributes>
114
+ )
115
+
116
+ if(RI_KERNELS_BUNDLED_HIGHWAY)
117
+ # add google highway
118
+ set(HWY_ENABLE_CONTRIB ON CACHE BOOL "")
119
+ set(HWY_ENABLE_EXAMPLES OFF CACHE BOOL "")
120
+ set(HWY_ENABLE_INSTALL OFF CACHE BOOL "")
121
+ set(HWY_ENABLE_TESTS OFF CACHE BOOL "")
122
+ set(HWY_FORCE_STATIC_LIBS ON CACHE BOOL "")
123
+ set(HWY_ENABLE_CONTRIB ON CACHE BOOL "")
124
+ FetchContent_Declare(
125
+ hwy
126
+ URL https://github.com/google/highway/archive/refs/tags/1.4.0.tar.gz
127
+ URL_MD5 9d335797777e17f827c7980b8313a34b
128
+ )
129
+ FetchContent_MakeAvailable(hwy)
130
+ if(NOT TARGET hwy::hwy)
131
+ add_library(hwy::hwy ALIAS hwy)
132
+ endif()
133
+ else()
134
+ find_package(hwy CONFIG REQUIRED)
135
+ endif()
136
+ target_link_libraries(ri_kernels PRIVATE hwy::hwy)
137
+
138
+ if(RI_KERNELS_MULTI_ARCH)
139
+ target_compile_definitions(ri_kernels PUBLIC -DRI_KERNELS_MULTI_ARCH)
140
+ endif()
141
+ endif()
142
+
143
+ if(RI_KERNELS_CUDA)
144
+ enable_language(CUDA)
145
+ # find toolkit after language is enabled to ensure version matching
146
+ find_package(CUDAToolkit REQUIRED)
147
+
148
+ set_source_files_properties(${RI_KERNELS_GPU_SOURCES} PROPERTIES LANGUAGE CUDA)
149
+
150
+ add_library(ri_kernels_cuda SHARED ${RI_KERNELS_GPU_SOURCES})
151
+ # set_target_properties(ri_kernels_cuda PROPERTIES OUTPUT_NAME "ri_kernels_cuda_${CUDAToolkit_VERSION_MAJOR}")
152
+ target_include_directories(ri_kernels_cuda PRIVATE ${JAXLIB_HOME}/include ./src)
153
+ target_link_libraries(ri_kernels_cuda PRIVATE CUDA::cudart_static)
154
+ target_compile_options(ri_kernels_cuda PRIVATE
155
+ $<$<COMPILE_LANGUAGE:CUDA>:--diag-suppress=940>
156
+ $<$<COMPILE_LANGUAGE:CUDA>:--diag-suppress=2473>
157
+ )
158
+ endif()
159
+
160
+ if(RI_KERNELS_ROCM)
161
+ enable_language(HIP)
162
+ find_package(hip CONFIG REQUIRED)
163
+
164
+ set_source_files_properties(${RI_KERNELS_GPU_SOURCES} PROPERTIES LANGUAGE HIP)
165
+
166
+ add_library(ri_kernels_hip SHARED ${RI_KERNELS_GPU_SOURCES})
167
+ target_include_directories(ri_kernels_hip PRIVATE ${JAXLIB_HOME}/include ./src)
168
+ target_link_libraries(ri_kernels_hip PRIVATE hip::host)
169
+ endif()
170
+
171
+ # Normalize shared-library suffix across platforms so Python loader finds
172
+ # libri_kernels*.so on macOS as well as Linux, and restrict the exported
173
+ # symbols to the annotated FFI entry points.
174
+ if(TARGET ri_kernels)
175
+ set_target_properties(ri_kernels PROPERTIES SUFFIX ".so")
176
+ ri_kernels_restrict_exports(ri_kernels)
177
+ endif()
178
+ if(TARGET ri_kernels_cuda)
179
+ set_target_properties(ri_kernels_cuda PROPERTIES SUFFIX ".so")
180
+ ri_kernels_restrict_exports(ri_kernels_cuda)
181
+ endif()
182
+ if(TARGET ri_kernels_hip)
183
+ set_target_properties(ri_kernels_hip PROPERTIES SUFFIX ".so")
184
+ ri_kernels_restrict_exports(ri_kernels_hip)
185
+ endif()
186
+
187
+ # Install rules so scikit-build-core stages libraries into the wheel at the
188
+ # location where ri_kernels/rfi_vis_op.py loads them from.
189
+ if(TARGET ri_kernels)
190
+ install(TARGETS ri_kernels
191
+ LIBRARY DESTINATION ri_kernels
192
+ RUNTIME DESTINATION ri_kernels)
193
+ endif()
194
+ if(TARGET ri_kernels_cuda)
195
+ install(TARGETS ri_kernels_cuda
196
+ LIBRARY DESTINATION ${RI_KERNELS_GPU_INSTALL_DIR}
197
+ RUNTIME DESTINATION ${RI_KERNELS_GPU_INSTALL_DIR})
198
+ endif()
199
+ if(TARGET ri_kernels_hip)
200
+ install(TARGETS ri_kernels_hip
201
+ LIBRARY DESTINATION ${RI_KERNELS_GPU_INSTALL_DIR}
202
+ RUNTIME DESTINATION ${RI_KERNELS_GPU_INSTALL_DIR})
203
+ endif()