Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
7b5eaf1
PRE-RELEASE: grace/fs support
Sep 12, 2024
144bf6c
Merge pull request #81 from ICAMS/master
yury-lysogorskiy Nov 7, 2024
38306b9
update pace_select for GRACE/FS
Nov 14, 2024
79ff2d4
Merge remote-tracking branch 'origin/feature/grace_fs' into feature/g…
Nov 14, 2024
39cd17f
bugfix: Replace `pkg_resources` with `importlib.resources` for resour…
yury-lysogorskiy Feb 23, 2026
1e69eeb
remove test_calculator.py::test_PyACECalculator_active_set_dump_extr…
yury-lysogorskiy Feb 23, 2026
a7e19fa
bump version to numpy>=2.0.0
yury-lysogorskiy Feb 23, 2026
b350213
replace `.set_calculator` with `.calc`
yury-lysogorskiy Feb 23, 2026
d0f7a0b
adjust numpy<2.2.0 with tensorflow 2.19.1
yury-lysogorskiy Feb 23, 2026
b4629f0
Merge origin/master into feature/grace_fs
Sep 4, 2026
df3350d
build: restore debuggable Debug builds
Sep 4, 2026
70a620f
build: compile shared ACE sources once via OBJECT libraries
Sep 4, 2026
b64e60e
build: single CMake tree, safer job count, ccache; vendor fp64 maxvol
Sep 4, 2026
d996100
build: drop vendored maxvolpy, require python>=3.9, clamp jobs explic…
Sep 4, 2026
0366094
build: move metadata to pyproject.toml, drop versioneer, unpin numpy …
Sep 4, 2026
17aba14
build: expose CLI as console entry points, cap python at <3.14
Sep 4, 2026
8dbc3d1
build: drop python upper bound, matching grace-tensorpotential
Sep 4, 2026
89b9ca4
build: clear the warnings a verbose build was emitting
Sep 4, 2026
e4f25c1
Merge origin/master into feature/build-speedup
Sep 4, 2026
7148751
build: upgrade vendored pybind11 2.11.0.dev1 -> 3.1.0
Sep 4, 2026
cb62309
build: ship the C++ tree in the sdist
Sep 4, 2026
7ada8e4
build: distribute as python-ace, keep importing as pyace
Sep 4, 2026
c5f6df3
build: add PYACE_PORTABLE_MATH so wheels can reach manylinux_2_17
Sep 4, 2026
a45bfb4
CI: build manylinux wheels; make every publish manual
Sep 4, 2026
0c228fb
CI: build wheels on manylinux_2_28, not manylinux2014
Sep 4, 2026
5beead7
CI: bump actions to their current majors
Sep 4, 2026
b71416c
CI: allow the full python matrix from a branch push [full-matrix]
Sep 4, 2026
60a0e35
build: keep C++ sources out of the installed wheel
Sep 4, 2026
3fb0993
ci: rebuild all wheels after package-data fix [full-matrix]
Sep 4, 2026
9a614c2
ci: rebuild all wheels after the package-data fix [full-matrix]
Sep 4, 2026
a30785e
build: 0.4.0rc1 for a pre-release to PyPI [full-matrix]
Sep 4, 2026
b8cd66a
Refresh Python and TensorFlow compatibility and documentation
Oct 29, 2026
f12a1b1
Pin compatibility CI to merged TensorPotential fix
Oct 29, 2026
bf94cb3
Merge pull request #106 from ICAMS/refresh/python-tensorflow
yury-lysogorskiy Oct 30, 2026
f0f2a4e
Document released GRACE backend installation from PyPI
Oct 31, 2026
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
78 changes: 45 additions & 33 deletions .github/workflows/publish-to-test-pypi.yml
Original file line number Diff line number Diff line change
@@ -1,36 +1,48 @@
name: Publish to TestPyPI
on: push
name: Publish sdist to TestPyPI

# Manual only. An index filename can be uploaded exactly once -- deleting or
# yanking does not free it -- so this must never fire by itself. It used to run
# `on: push`, which would have burned a version number on every commit.
on: workflow_dispatch

jobs:
build-n-publish:
name: Build and publish Python distributions to TestPyPI
runs-on: ubuntu-18.04
name: Build and publish the source distribution to TestPyPI
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Set up Python 3.8
uses: actions/setup-python@v1
with:
python-version: 3.8
- name: Install pypa/build
run: >-
python -m
pip install
build
--user
- name: Build a binary wheel and a source tarball
run: >-
python -m
build
--sdist
--wheel
--outdir dist/
.
- name: Publish distribution to Test PyPI
uses: pypa/gh-action-pypi-publish@master
with:
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository_url: https://test.pypi.org/legacy/
# - name: Publish distribution 📦 to PyPI
# if: startsWith(github.ref, 'refs/tags')
# uses: pypa/gh-action-pypi-publish@master
# with:
# password: ${{ secrets.PYPI_API_TOKEN }}
- uses: actions/checkout@v7

- name: Set up Python
uses: actions/setup-python@v7
with:
python-version: "3.12"

# sdist only, deliberately. `build --wheel` on a bare runner emits a
# linux_x86_64 tag, which PyPI and TestPyPI both reject -- portable wheels
# have to be built inside a manylinux container, which is what
# wheels.yml does with cibuildwheel. Publishing wheels from here is not a
# matter of adding a flag; it cannot work.
- name: Build the source distribution
run: pipx run build --sdist

# Same guard as wheels.yml: CMakeExtension declares sources=[], so the
# C++ tree only reaches the sdist via MANIFEST.in. An sdist without it
# uploads happily and then fails for whoever builds from source.
- name: Verify the sdist can actually build
run: |
set -euo pipefail
tar tzf dist/*.tar.gz > files.txt
grep -qE 'CMakeLists\.txt$' files.txt || { echo "sdist has no CMakeLists.txt"; exit 1; }
grep -qE 'lib/pybind11/include/pybind11/pybind11\.h$' files.txt || { echo "sdist has no pybind11"; exit 1; }
cpp=$(grep -cE '\.cpp$' files.txt)
echo "sdist carries $cpp .cpp files"
[ "$cpp" -ge 60 ] || { echo "expected >=60 .cpp files, got $cpp"; exit 1; }

- name: Publish to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository-url: https://test.pypi.org/legacy/
# wheels.yml can also publish this same sdist to TestPyPI. Without
# this, whichever runs second fails on the duplicate filename.
skip-existing: true
48 changes: 25 additions & 23 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ name: Python package

on:
pull_request:
branches: [ "master" ]
branches: [ "master", "feature/build-speedup" ]

jobs:
build:
Expand All @@ -14,46 +14,48 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10"] # ver. 3.11 is not supported by TP
python-version: ["3.10", "3.11", "3.12", "3.13"]
tensorflow-version: ["2.20.0", "2.21.0"]
include:
- python-version: "3.9"
tensorflow-version: "2.20.0"

env:
CUDA_VISIBLE_DEVICES: "-1"
TF_USE_LEGACY_KERAS: "1"
CMAKE_BUILD_PARALLEL_LEVEL: "2"
OMP_NUM_THREADS: "2"
TF_NUM_INTRAOP_THREADS: "2"
TF_NUM_INTEROP_THREADS: "2"

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install general dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest
- name: Checkout tensorpotential
uses: actions/checkout@v2
- name: Checkout current tensorpotential with PACE compatibility
uses: actions/checkout@v4
with:
repository: ICAMS/TensorPotential
repository: ICAMS/grace-tensorpotential
# Includes the NumPy scalar fix and TensorFlow 2.21 bound from PR #43.
ref: 9ccb9090f53292a836cbbc3de4cadcae54c7ce1a
path: tensorpotential
- name: Install tensorpotential
run: |
cd tensorpotential
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
#python setup.py install
pip install .
python -m pip install "tensorflow==${{ matrix.tensorflow-version }}" "tf-keras~=${{ matrix.tensorflow-version }}" .
- name: Install python-ace
run: |
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
#python setup.py install
pip install .
- name: Install maxvolpy
# `pip install .` builds a wheel and never runs setup.py's custom
# InstallMaxVolPyLocalPackage(install) hook, so lib/maxvolpy is not
# installed and the active-learning tests fail to import. Build it
# explicitly; --no-build-isolation is required because
# lib/maxvolpy/setup.py imports Cython and numpy at module level
# without declaring them in a pyproject.toml build-system.
run: |
pip install Cython scipy
pip install --no-build-isolation ./lib/maxvolpy
python -m pip install .
- name: Test with python-ace with tensorpotential
run: |
python -m pip check
python -c 'import pyace, tensorpotential, tensorflow as tf, numpy as np; print("Versions:", pyace.__version__, tensorpotential.__version__, tf.__version__, np.__version__)'
python -m pytest tests/ --runtensorpot
- name: Integration test of CLI
run: |
Expand Down
169 changes: 169 additions & 0 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
name: Build wheels

# Publishing is deliberately never automatic. A PyPI filename can only be
# uploaded once -- deleting or yanking a release does NOT free the version
# number -- so a botched 0.4.0 would burn 0.4.0 permanently. Every trigger here
# only produces downloadable artifacts; uploading is a separate manual run with
# an explicit target, and the recommended first target is TestPyPI.
on:
# Branch pushes and pull requests both give a build without touching master.
# Note workflow_dispatch below only appears in the Actions UI once this file
# is on the default branch -- that is a GitHub restriction, not a choice
# here -- so until then, pushing to one of these branches is how you run it.
push:
branches:
- master
- "feature/**"
pull_request:
workflow_dispatch:
inputs:
publish:
description: "Upload the built distributions where?"
type: choice
default: none
options: [none, testpypi, pypi]

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

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

- run: pipx run build --sdist

# The sdist shipped no C++ at all from the initial release commit until
# MANIFEST.in was added: CMakeExtension declares sources=[], so setuptools
# cannot infer the build tree. It is invisible in a wheel-only world and
# only bites whoever falls back to building from source, so assert it here
# rather than find out from a bug report.
- name: Verify the sdist can actually build
run: |
set -euo pipefail
tar tzf dist/*.tar.gz > files.txt
for pattern in \
'CMakeLists\.txt$' \
'lib/pybind11/include/pybind11/pybind11\.h$' \
'lib/ace/ace-evaluator/CMakeLists\.txt$' \
'src/pyace/maxvol/_maxvol\.pyx$'
do
grep -qE "$pattern" files.txt || { echo "sdist is missing: $pattern"; exit 1; }
done
cpp=$(grep -cE '\.cpp$' files.txt)
echo "sdist carries $cpp .cpp files"
[ "$cpp" -ge 60 ] || { echo "expected >=60 .cpp files, got $cpp"; exit 1; }

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

wheels:
name: wheels (linux x86_64)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7

- name: Build wheels
uses: pypa/cibuildwheel@v4.2.0
env:
CIBW_ARCHS_LINUX: x86_64
# Routine commits build one interpreter; all five are built only when
# asked for, so a normal push costs one build rather than five. Ask
# either with a manual run, or -- since workflow_dispatch is invisible
# until this file reaches the default branch -- by putting
# [full-matrix] in the pushed commit's message.
#
# Upper bound is pybind11 3.1, which supports 3.9 through 3.14; the
# floor matches requires-python. head_commit is absent on
# pull_request events, where contains() is simply false.
CIBW_BUILD: >-
${{ (github.event_name == 'workflow_dispatch'
|| contains(github.event.head_commit.message, '[full-matrix]'))
&& 'cp39-manylinux_x86_64 cp310-manylinux_x86_64 cp311-manylinux_x86_64 cp312-manylinux_x86_64 cp313-manylinux_x86_64'
|| 'cp312-manylinux_x86_64' }}

# glibc 2.28 -- RHEL/Alma/Rocky 8+, Ubuntu 20.04+, Debian 10+. This is
# the floor the dependency set allows, not a compromise.
#
# An earlier revision tried manylinux2014 (glibc 2.17) on the theory
# that pip would resolve back to an older numpy/scipy that publishes
# 2_17 wheels. It does not: pip prefers the newest *version* and falls
# back to its sdist, so it downloaded numpy 2.5.2.tar.gz and died on
# "NumPy requires GCC >= 10.3". Pinning around that would not help
# either, because cibuildwheel installs the runtime dependencies in
# the same container to run the tests, and current pandas and
# scikit-learn publish x86_64 wheels only for 2_28 -- as would any
# actual glibc-2.17 user, who would get our wheel followed by a source
# build of pandas. There is no reach to be had below 2_28 while
# numpy, scipy, pandas and scikit-learn all stop there.
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28

# PYACE_PORTABLE_MATH is deliberately NOT set: 2_28 whitelists
# libmvec and permits GLIBC_2.22, so -Ofast costs nothing here. The
# option stays in CMakeLists.txt for whenever a lower floor is worth
# chasing again.

# Each of these has actually been broken in this project at some point,
# so the wheel is not accepted until all four hold.
# 1. importlib.metadata looks up the DISTRIBUTION name (python-ace),
# not the import package (pyace) -- "unknown" means that broke.
# 2. all seven pybind11 modules load (pybind11 2.11 -> 3.1 upgrade).
# 3. the compiled maxvol kernel is present, not the slow scipy
# fallback -- it silently vanished from wheels before.
# 4. a console entry point resolves, since bin/ scripts became
# [project.scripts].
CIBW_TEST_COMMAND: >-
python -c "import pyace; print('version:', pyace.__version__); assert pyace.__version__ != 'unknown', 'distribution-name lookup failed'"
&& python -c "import pyace.sharmonics, pyace.coupling, pyace.basis, pyace.evaluator, pyace.catomicenvironment, pyace.calculator, pyace.grace_fs; print('7 pybind11 modules ok')"
&& python -c "from pyace.maxvol import c_maxvol; import numpy as np; i, c = c_maxvol(np.random.rand(64, 8), 1.05, 100, -1, 0); print('compiled maxvol ok, selected', len(i), 'rows')"
&& pace_info --help > /dev/null && echo 'entry points ok'

# MANIFEST.in names the C++ sources so the sdist can build, and they sit
# inside the package tree -- so a lapse in include-package-data silently
# installs all of them into every wheel. It happened once already.
- name: Verify the wheels ship no source
run: |
set -euo pipefail
for whl in wheelhouse/*.whl; do
bad=$(unzip -Z1 "$whl" | grep -E '\.(cpp|h|pyx|c)$' || true)
if [ -n "$bad" ]; then
echo "$(basename "$whl") ships source files:"; echo "$bad"; exit 1
fi
n=$(unzip -Z1 "$whl" | grep -cE '\.so$')
echo "$(basename "$whl"): $n compiled modules, no source"
[ "$n" -eq 8 ] || { echo "expected 8 .so (7 pybind11 + _maxvol), got $n"; exit 1; }
done

- uses: actions/upload-artifact@v7
with:
name: wheels-linux-x86_64
path: wheelhouse/*.whl

publish:
name: publish to ${{ github.event.inputs.publish }}
needs: [sdist, wheels]
if: github.event_name == 'workflow_dispatch' && github.event.inputs.publish != 'none'
runs-on: ubuntu-latest
environment: ${{ github.event.inputs.publish }}
permissions:
id-token: write # trusted publishing; no API token in secrets
steps:
- uses: actions/download-artifact@v8
with:
path: dist
merge-multiple: true

- run: ls -l dist/

- name: Publish
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: >-
${{ github.event.inputs.publish == 'testpypi'
&& 'https://test.pypi.org/legacy/'
|| 'https://upload.pypi.org/legacy/' }}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,6 @@ cython_debug/
media
static

cmake-build-*/
cmake-build-*/
# generated by cython
src/pyace/maxvol/_maxvol.c
1 change: 1 addition & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ build:

mkdocs:
configuration: mkdocs.yml
fail_on_warning: true

# Optionally declare the Python requirements required to build your docs
python:
Expand Down
1 change: 0 additions & 1 deletion .version

This file was deleted.

Loading
Loading