Skip to content

Commit 9592bd6

Browse files
authored
Merge pull request #63 from ewanwm/feature_pypi_distribution
Add a workflow to upload python module to pypi
2 parents 975f567 + 8e08fe6 commit 9592bd6

15 files changed

+342
-25
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
on:
2+
workflow_call:
3+
inputs:
4+
build_type:
5+
required: true
6+
type: string
7+
platform:
8+
required: true
9+
type: string
10+
11+
jobs:
12+
build:
13+
14+
name: Build ${{ inputs.platform }} ${{ inputs.build_type }} distribution 📦
15+
runs-on: ${{ inputs.platform }}
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
## runner will run out of space if we don't clear some up by removing some unused tools
21+
- name: Clear space
22+
run: >-
23+
sudo rm -rf /usr/share/dotnet
24+
sudo rm -rf /opt/ghc
25+
sudo rm -rf "/usr/local/share/boost"
26+
sudo rm -rf "$AGENT_TOOLSDIRECTORY"
27+
28+
#- name: cuda-toolkit
29+
# if: ${{ startsWith( inputs.build_type, 'cuda' ) }}
30+
# uses: Jimver/cuda-toolkit@v0.2.17
31+
32+
#- name: Set up Python
33+
# uses: actions/setup-python@v5
34+
# with:
35+
# python-version: "3.11"
36+
37+
#- name: Install Protoc
38+
# run: sudo apt install protobuf-compiler
39+
40+
#- name: Install Python dependencies
41+
# uses: py-actions/py-dependency-install@v4
42+
# with:
43+
# path: "PyTorch_requirements.txt"
44+
45+
#- name: Install cibuildwheel
46+
# run: python -m pip install cibuildwheel==2.21.1
47+
48+
- uses: yezz123/setup-uv@v4
49+
50+
- uses: pypa/cibuildwheel@v2.21
51+
if: runner.os == 'Linux'
52+
env:
53+
CIBW_BUILD_VERBOSITY: 1
54+
CIBW_ARCHS_LINUX: "x86_64"
55+
CIBW_SKIP: "*musl*"
56+
CIBW_BEFORE_ALL: >
57+
yum-config-manager --add-repo https://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/cuda-rhel7.repo &&
58+
yum clean all &&
59+
yum -y install cuda-toolkit &&
60+
ls -al /usr/local &&
61+
nvcc --version &&
62+
echo nvcc location: &&
63+
which nvcc &&
64+
export CUDACXX="$(which nvcc)" &&
65+
echo $CUDACXX &&
66+
echo gcc version: &&
67+
gcc --version &&
68+
export BUILD_WITH_CUDA=1 &&
69+
export TORCH_CUDA_ARCH_LIST="8.0 8.6 8.9 9.0"
70+
CIBW_ENVIRONMENT: >
71+
PATH=$PATH:/usr/local/cuda/bin LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(python -c 'import sys; print(sys.prefix + "/lib/python" + sys.version[:3] + "/site-packages")')/torch/lib/
72+
CIBW_BEFORE_BUILD: >
73+
python -m site &&
74+
python -c 'import sys; print(sys.prefix + "/lib/python" + sys.version[:3] + "/site-packages")' &&
75+
echo $LD_LIBRARY_PATH &&
76+
ls $(python -c 'import sys; print(sys.prefix + "/lib/python" + sys.version[:3] + "/site-packages")')
77+
78+
79+
#- name: Build wheels
80+
# run: python -m cibuildwheel --output-dir dist
81+
# env:
82+
# CIBW_BEFORE_BUILD: pip install scikit-build-core
83+
84+
- name: Store the distribution packages
85+
uses: actions/upload-artifact@v4
86+
with:
87+
name: python-package-distributions
88+
path: dist/
89+
90+
91+
publish-to-testpypi:
92+
name: Publish Python 🐍 distribution 📦 to TestPyPI
93+
needs:
94+
- build
95+
runs-on: ${{ inputs.platform }}
96+
97+
environment:
98+
name: testPyPi-distribution
99+
url: https://test.pypi.org/p/nuTens
100+
101+
permissions:
102+
id-token: write # IMPORTANT: mandatory for trusted publishing
103+
104+
steps:
105+
- name: Download all the dists
106+
uses: actions/download-artifact@v4
107+
with:
108+
name: python-package-distributions
109+
path: dist/
110+
- name: Publish distribution 📦 to TestPyPI
111+
uses: pypa/gh-action-pypi-publish@release/v1
112+
with:
113+
repository-url: https://test.pypi.org/legacy/
114+
115+
publish-to-pypi:
116+
name: >-
117+
Publish Python 🐍 distribution 📦 to PyPI
118+
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
119+
needs:
120+
- build
121+
runs-on: ${{ inputs.platform }}
122+
environment:
123+
name: PyPi-distribution
124+
url: https://pypi.org/p/nuTens # Replace <package-name> with your PyPI project name
125+
permissions:
126+
id-token: write # IMPORTANT: mandatory for trusted publishing
127+
128+
steps:
129+
- name: Download all the dists
130+
uses: actions/download-artifact@v4
131+
with:
132+
name: python-package-distributions
133+
path: dist/
134+
- name: Publish distribution 📦 to PyPI
135+
uses: pypa/gh-action-pypi-publish@release/v1
136+
137+
github-release:
138+
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
139+
name: >-
140+
Sign the Python 🐍 distribution 📦 with Sigstore
141+
and upload them to GitHub Release
142+
needs:
143+
- publish-to-pypi
144+
runs-on: ${{ inputs.platform }}
145+
146+
permissions:
147+
contents: write # IMPORTANT: mandatory for making GitHub Releases
148+
id-token: write # IMPORTANT: mandatory for sigstore
149+
150+
steps:
151+
- name: Download all the dists
152+
uses: actions/download-artifact@v4
153+
with:
154+
name: python-package-distributions
155+
path: dist/
156+
- name: Sign the dists with Sigstore
157+
uses: sigstore/gh-action-sigstore-python@v2.1.1
158+
with:
159+
inputs: >-
160+
./dist/*.tar.gz
161+
./dist/*.whl
162+
- name: Create GitHub Release
163+
env:
164+
GITHUB_TOKEN: ${{ github.token }}
165+
run: >-
166+
gh release create
167+
'${{ github.ref_name }}'
168+
--repo '${{ github.repository }}'
169+
--notes ""
170+
- name: Upload artifact signatures to GitHub Release
171+
env:
172+
GITHUB_TOKEN: ${{ github.token }}
173+
# Upload to GitHub Release using the `gh` CLI.
174+
# `dist/` contains the built packages, and the
175+
# sigstore-produced signatures and certificates.
176+
run: >-
177+
gh release upload
178+
'${{ github.ref_name }}' dist/**
179+
--repo '${{ github.repository }}'
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
name: Publish to PyPi
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
8+
jobs:
9+
10+
build:
11+
name: Make SDist
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 0 # Optional, use if you use setuptools_scm
17+
submodules: true # Optional, use if you have submodules
18+
19+
- name: Build SDist
20+
run: pipx run build --sdist
21+
22+
- uses: actions/upload-artifact@v4
23+
with:
24+
name: python-package-distributions
25+
path: dist/*.tar.gz
26+
27+
publish-to-testpypi:
28+
name: Publish Python 🐍 distribution 📦 to TestPyPI
29+
needs:
30+
- build
31+
runs-on: ubuntu-latest
32+
33+
environment:
34+
name: testPyPi-distribution
35+
url: https://test.pypi.org/p/nuTens
36+
37+
permissions:
38+
id-token: write # IMPORTANT: mandatory for trusted publishing
39+
40+
steps:
41+
- name: Download all the dists
42+
uses: actions/download-artifact@v4
43+
with:
44+
name: python-package-distributions
45+
path: dist/
46+
- name: Publish distribution 📦 to TestPyPI
47+
uses: pypa/gh-action-pypi-publish@release/v1
48+
with:
49+
repository-url: https://test.pypi.org/legacy/
50+
51+
publish-to-pypi:
52+
name: >-
53+
Publish Python 🐍 distribution 📦 to PyPI
54+
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
55+
needs:
56+
- build
57+
runs-on: ubuntu-latest
58+
environment:
59+
name: PyPi-distribution
60+
url: https://pypi.org/p/nuTens # Replace <package-name> with your PyPI project name
61+
permissions:
62+
id-token: write # IMPORTANT: mandatory for trusted publishing
63+
64+
steps:
65+
- name: Download all the dists
66+
uses: actions/download-artifact@v4
67+
with:
68+
name: python-package-distributions
69+
path: dist/
70+
- name: Publish distribution 📦 to PyPI
71+
uses: pypa/gh-action-pypi-publish@release/v1
72+
73+
74+
## one day we will buld wheels and upload them to pypi... but it is not this day
75+
## when that day comes, the below might be useful
76+
77+
##pypi_distribution:
78+
79+
##permissions:
80+
## contents: write
81+
## id-token: write # IMPORTANT: mandatory for trusted publishing
82+
83+
## secrets: inherit
84+
85+
##strategy:
86+
## fail-fast: false
87+
## matrix:
88+
## include:
89+
## - build_type: cpu
90+
## platform: ubuntu-latest
91+
92+
## - build_type: cuda
93+
## platform: ubuntu-latest
94+
95+
## ./ At start of reusable workflow indicates to use the one in current repo i.e. the from the current branch
96+
## uses: ./.github/workflows/pypi-distribution-reusable.yaml
97+
## with:
98+
## platform: ${{ matrix.platform }}
99+
## build_type: ${{ matrix.build_type }}
100+

CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
22
set(CMAKE_CXX_STANDARD 17)
3+
set(CUDA_STANDARD 14)
4+
set( CMAKE_CUDA_COMPILER "nvcc" )
5+
6+
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
7+
set(CMAKE_CUDA_ARCHITECTURES 75)
8+
endif()
39

410
project(nuTens)
511

pyproject.toml

+33-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,41 @@
1-
[build-system]
2-
requires = ["scikit-build-core", "pybind11", "torch"]
3-
build-backend = "scikit_build_core.build"
41

52
[project]
6-
name = "pyNuTens"
7-
version = "0.0.1"
3+
name = "nuTens"
4+
version = "0.0.3"
85
description="Library to calculate neutrino oscillation probabilities using tensors"
96
readme = "README.md"
107
authors = [
118
{ name = "Ewan Miller", email = "emiller@ifae.es" },
129
]
10+
requires-python = ">=3.9"
11+
license = {file="LICENSE"}
12+
keywords = ["neutrino", "oscillations", "physics", "particle", "tensor", "experiment", "autograd", "differentiable programming"]
13+
classifiers = [
14+
"Development Status :: 2 - Pre-Alpha",
15+
"Environment :: GPU",
16+
"Programming Language :: C++",
17+
"Programming Language :: Python :: 3",
18+
"Programming Language :: Python :: 3.9",
19+
"Programming Language :: Python :: 3.10",
20+
"Programming Language :: Python :: 3.11",
21+
"Topic :: Scientific/Engineering :: Physics",
22+
"Intended Audience :: Science/Research"
23+
]
24+
dependencies = [
25+
"torch"
26+
]
27+
28+
[project.urls]
29+
Repository = "https://github.com/ewanwm/nuTens"
30+
Issues = "https://github.com/ewanwm/nuTens/issues"
31+
Documentation = "https://ewanwm.github.io/nuTens/"
32+
33+
[build-system]
34+
requires = ["scikit-build-core>=0.3.3", "pybind11", "torch"]
35+
build-backend = "scikit_build_core.build"
36+
37+
[tool.cibuildwheel]
38+
build-frontend = "build[uv]"
1339

14-
[tool.scikit-build]
15-
cmake.args = ["-DNT_ENABLE_PYTHON=ON"]
40+
[tool.scikit-build.cmake]
41+
args = ["-DNT_ENABLE_PYTHON=ON"]

python/CMakeLists.txt

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11

22
pybind11_add_module(
3-
pyNuTens MODULE
3+
_pyNuTens MODULE
44
binding.cpp
55
)
66

77
if(NT_USE_PCH)
8-
target_precompile_headers( pyNuTens REUSE_FROM nuTens-pch )
8+
target_precompile_headers( _pyNuTens REUSE_FROM nuTens-pch )
99
endif()
10-
target_link_libraries( pyNuTens PUBLIC nuTens )
10+
target_link_libraries( _pyNuTens PUBLIC nuTens )
1111

1212
# This is passing in the version as a define just as an example
13-
target_compile_definitions( pyNuTens PRIVATE VERSION_INFO=${PROJECT_VERSION} )
13+
target_compile_definitions( _pyNuTens PRIVATE VERSION_INFO=${PROJECT_VERSION} )
1414

15-
install( TARGETS pyNuTens DESTINATION pyNuTens/ )
15+
install( TARGETS _pyNuTens DESTINATION nuTens/ )

python/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## Python Interface
2+
3+
nuTens provides a python interface that can be installed manually or via [pyPi](https://pypi.org/). [binding.cpp](binding.cpp) defines the python bindings of many of the nuTens c++ objects, which are then compiled into a python module using [pybind11](https://github.com/pybind/pybind11) (see [CMakeLists.txt](CMakeLists.txt)).
4+
5+
The [nuTens](nuTens) folder defines the python module and any pure python extension code for nuTens should go in there.

python/binding.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ void initTensor(py::module & /*m*/);
1818
void initPropagator(py::module & /*m*/);
1919
void initDtypes(py::module & /*m*/);
2020

21-
// initialise the top level module "pyNuTens"
21+
// initialise the top level module "_pyNuTens"
2222
// NOLINTNEXTLINE
23-
PYBIND11_MODULE(pyNuTens, m)
23+
PYBIND11_MODULE(_pyNuTens, m)
2424
{
2525
m.doc() = "Library to calculate neutrino oscillations";
2626
initTensor(m);

python/nuTens/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from ._pyNuTens import __doc__, __version__, tensor, propagator, dtype
2+
3+
__all__ = ["__doc__", "__version__", "tensor", "propagator", "dtype"]

python/nuTens/dtype.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from ._pyNuTens import dtype
2+
from ._pyNuTens.dtype import *

python/nuTens/propagator.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from ._pyNuTens import propagator
2+
from ._pyNuTens.propagator import *

0 commit comments

Comments
 (0)