diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml index 0f44e477..8d86daba 100644 --- a/.github/workflows/build-wheels.yml +++ b/.github/workflows/build-wheels.yml @@ -83,7 +83,7 @@ jobs: name: ${{ matrix.name }} (torch v${{ matrix.torch-version }}) strategy: matrix: - torch-version: ['2.3', '2.4', '2.5', '2.6', '2.7', '2.8', '2.9', '2.10', '2.11', '2.12'] + torch-version: ['2.3', '2.4', '2.5', '2.6', '2.7', '2.8', '2.9', '2.10', '2.11', '2.12', '2.13'] arch: ['arm64', 'x86_64'] os: ['ubuntu-24.04', 'ubuntu-24.04-arm', 'macos-15', 'windows-2022'] exclude: @@ -121,6 +121,7 @@ jobs: - {torch-version: '2.10', python-version: '3.14', cibw-python: 'cp314-*'} - {torch-version: '2.11', python-version: '3.14', cibw-python: 'cp314-*'} - {torch-version: '2.12', python-version: '3.14', cibw-python: 'cp314-*'} + - {torch-version: '2.13', python-version: '3.14', cibw-python: 'cp314-*'} steps: - uses: actions/checkout@v6 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index fdcd5e3b..001f3d15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ changelog](https://keepachangelog.com/en/1.1.0/) format. This project follows ### Removed --> +### Added + +- Added support for PyTorch v2.13 in the `vesin-torch` wheels on PyPI + ### Changed - Importing from `vesin.torch` is deprecated, users should now import from diff --git a/fortran/src/cdef.f90 b/fortran/src/cdef.f90 index 0c67bfd9..68d29e3d 100644 --- a/fortran/src/cdef.f90 +++ b/fortran/src/cdef.f90 @@ -63,6 +63,11 @@ module vesin_c !> Which algorithm to use for the calculation integer(c_int) :: algorithm = VesinAutoAlgorithm + !> Skin size for Verlet caching. A positive value enables caching the + !! neighbor list until any atom moves farther than `skin/2` from its + !! reference coordinates. + real(c_double) :: skin = 0.0_c_double + !> Number of CPU threads to use. Must be zero or positive. If zero, !! Vesin uses `OMP_NUM_THREADS` when set to a positive integer, and !! otherwise defaults to the number of available CPU cores. @@ -76,10 +81,6 @@ module vesin_c !> Should the returned `VesinNeighborList` contain `vector`? logical(c_bool) :: return_vectors = .false. - - !> Skin size for Verlet caching. - real(c_double) :: skin = 0.0_c_double - end type VesinOptions !> Used as return type from `vesin_neighbors()`. diff --git a/python/vesin/vesin/_c_api.py b/python/vesin/vesin/_c_api.py index 7713f02a..bb63e7b3 100644 --- a/python/vesin/vesin/_c_api.py +++ b/python/vesin/vesin/_c_api.py @@ -26,11 +26,11 @@ class VesinOptions(ctypes.Structure): ("full", ctypes.c_bool), ("sorted", ctypes.c_bool), ("algorithm", VesinAlgorithm), + ("skin", ctypes.c_double), ("n_threads", ctypes.c_int32), ("return_shifts", ctypes.c_bool), ("return_distances", ctypes.c_bool), ("return_vectors", ctypes.c_bool), - ("skin", ctypes.c_double), ] diff --git a/python/vesin/vesin/_neighbors.py b/python/vesin/vesin/_neighbors.py index bc09f0bd..2086787e 100644 --- a/python/vesin/vesin/_neighbors.py +++ b/python/vesin/vesin/_neighbors.py @@ -72,6 +72,7 @@ class NeighborList: def __init__( self, + *, cutoff: float, full_list: bool, sorted: bool = False, diff --git a/python/vesin_torch/tests/test_neighbors.py b/python/vesin_torch/tests/test_neighbors.py index aede2aae..07634e2e 100644 --- a/python/vesin_torch/tests/test_neighbors.py +++ b/python/vesin_torch/tests/test_neighbors.py @@ -94,8 +94,23 @@ def test_all_alone_no_neighbors(quantities, dtype): class NeighborListWrap: - def __init__(self, cutoff: float, full_list: bool, sorted: bool): - self._c = NeighborList(cutoff=cutoff, full_list=full_list, sorted=sorted) + def __init__( + self, + cutoff: float, + full_list: bool, + sorted: bool, + algorithm: str, + skin: float, + n_threads: int, + ): + self._c = NeighborList( + cutoff=cutoff, + full_list=full_list, + sorted=sorted, + algorithm=algorithm, + skin=skin, + n_threads=n_threads, + ) def compute( self, diff --git a/python/vesin_torch/vesin_torch/_neighbors.py b/python/vesin_torch/vesin_torch/_neighbors.py index a77ac761..342cbad3 100644 --- a/python/vesin_torch/vesin_torch/_neighbors.py +++ b/python/vesin_torch/vesin_torch/_neighbors.py @@ -12,6 +12,7 @@ def __init__( full_list: bool, sorted: bool = False, algorithm: str = "auto", + skin: float = 0.0, n_threads: int = 0, ): """ @@ -23,6 +24,9 @@ def __init__( second point index (``j``) and shifts in the list of pairs is unspecified. :param algorithm: algorithm to use when computing the neighbor list. One of ``"auto"``, ``"brute_force"``, or ``"cell_list"``. + :param skin: skin size for Verlet caching. A positive value enables + caching the neighbor list until any atom moves farther than + ``skin/2`` from its reference coordinates. :param n_threads: number of CPU threads to use. Must be 0 or a positive integer. If set to 0, Vesin uses ``OMP_NUM_THREADS`` when set to a positive integer, and otherwise the number of available CPU cores. @@ -36,6 +40,7 @@ def __init__( full_list=full_list, sorted=sorted, algorithm=algorithm, + skin=skin, n_threads=n_threads, ) diff --git a/tox.ini b/tox.ini index d83a9401..5d055796 100644 --- a/tox.ini +++ b/tox.ini @@ -18,6 +18,8 @@ lint-folders = python setup.py package = external package_env = build-vesin +build_single_wheel = --no-deps --force-reinstall --no-build-isolation --check-build-dependencies + # this warning fires when collecting tests and seemingly can not be # supressed by the code in pyproject.toml, so we add it as a CLI flag test_args = -W "ignore:`torch.jit.script` is not supported in Python 3.14+ and may break:DeprecationWarning" @@ -28,14 +30,14 @@ packaging_deps = optional_deps = ase metatomic-torch >=0.1,<0.2 - torch + torch=={env:VESIN_TESTS_TORCH_VERSION:2.12}.* [testenv:check-cuda-available] description = Tests that CUDA is available in PyTorch and CuPy package = skip passenv = * deps = - torch + torch=={env:VESIN_TESTS_TORCH_VERSION:2.12}.* allowlist_externals = bash commands = bash ./scripts/install-cupy.sh @@ -99,7 +101,7 @@ deps = changedir = python/vesin_torch commands = - pip install . --no-deps --no-build-isolation --check-build-dependencies + pip install {[testenv]build_single_wheel} . # Make torch.autograd.gradcheck works with pytest python {toxinidir}/scripts/pytest-dont-rewrite-torch.py @@ -118,7 +120,8 @@ deps = {[testenv]optional_deps} commands = - pip install .[torch] + pip install {[testenv]build_single_wheel} python/vesin + pip install {[testenv]build_single_wheel} python/vesin_torch pytest {[testenv]test_args} --suppress-no-test-exit-code --doctest-modules --pyargs vesin pytest {[testenv]test_args} --suppress-no-test-exit-code --doctest-modules --pyargs vesin_torch @@ -199,13 +202,13 @@ deps = ford == 7.0.* - torch + torch=={env:VESIN_TESTS_TORCH_VERSION:2.12}.* metatomic-torch >=0.1,<0.2 cmake setuptools >= 77 wheel >= 0.41 commands = - pip install python/vesin_torch --no-deps --force-reinstall --no-build-isolation --check-build-dependencies + pip install {[testenv]build_single_wheel} python/vesin_torch sphinx-build -d docs/build/doctrees -W -b html docs/src docs/build/html ford fortran/docs.md --output_dir=../docs/build/html/fortran/ diff --git a/vesin-torch/CMakeLists.txt b/vesin-torch/CMakeLists.txt index 1d39a758..c594fdd8 100644 --- a/vesin-torch/CMakeLists.txt +++ b/vesin-torch/CMakeLists.txt @@ -44,7 +44,12 @@ target_include_directories(vesin_torch PUBLIC $ ) -target_compile_features(vesin_torch PUBLIC cxx_std_17) +if (${Torch_VERSION} VERSION_GREATER_EQUAL 2.13) + # Torch 2.13+ requires C++20 + target_compile_features(vesin_torch PUBLIC cxx_std_20) +else() + target_compile_features(vesin_torch PUBLIC cxx_std_17) +endif() target_compile_definitions(vesin_torch PRIVATE VESIN_TORCH_EXPORTS) set_target_properties(vesin_torch PROPERTIES diff --git a/vesin-torch/include/vesin_torch.hpp b/vesin-torch/include/vesin_torch.hpp index 80bf9fe4..18c425d3 100644 --- a/vesin-torch/include/vesin_torch.hpp +++ b/vesin-torch/include/vesin_torch.hpp @@ -45,6 +45,9 @@ class VESIN_TORCH_API NeighborListHolder: public torch::CustomClassHolder { // shifts in the list of pairs is unspecified. /// @param algorithm the algorithm to use for neighbor list calculation. One /// of `"auto"`, `"brute_force"`, or `"cell_list"`. + /// @param skin skin size for Verlet caching. A positive value enables + /// caching the neighbor list until any atom moves farther than + /// ``skin/2`` from its reference coordinates. /// @param n_threads number of CPU threads to use. Must be zero or positive. /// A value of 0 lets Vesin choose from `OMP_NUM_THREADS` or CPU cores. NeighborListHolder( @@ -52,6 +55,7 @@ class VESIN_TORCH_API NeighborListHolder: public torch::CustomClassHolder { bool full_list, bool sorted = false, std::string algorithm = "auto", + double skin = 0.0, int64_t n_threads = 0 ); ~NeighborListHolder(); @@ -103,6 +107,7 @@ class VESIN_TORCH_API NeighborListHolder: public torch::CustomClassHolder { bool full_list_; bool sorted_; std::string algorithm_; + double skin_; int64_t n_threads_; VesinNeighborList* data_; }; diff --git a/vesin-torch/src/vesin_torch.cpp b/vesin-torch/src/vesin_torch.cpp index 8b52ef54..4ef900f2 100644 --- a/vesin-torch/src/vesin_torch.cpp +++ b/vesin-torch/src/vesin_torch.cpp @@ -54,12 +54,14 @@ NeighborListHolder::NeighborListHolder( bool full_list, bool sorted, std::string algorithm, + double skin, int64_t n_threads ): cutoff_(cutoff), full_list_(full_list), sorted_(sorted), algorithm_(std::move(algorithm)), + skin_(skin), n_threads_(n_threads), data_(nullptr) { if (n_threads_ < 0) { @@ -180,6 +182,7 @@ std::vector NeighborListHolder::compute( /*full=*/this->full_list_, /*sorted=*/this->sorted_, /*algorithm=*/algorithm, + /*skin=*/this->skin_, /*n_threads=*/n_threads, /*return_shifts=*/return_shifts, /*return_distances=*/return_distances, @@ -322,11 +325,12 @@ TORCH_LIBRARY(vesin, m) { // clang-format off m.class_("_NeighborList") .def( - torch::init(), DOCSTRING, { + torch::init(), DOCSTRING, { torch::arg("cutoff"), torch::arg("full_list"), torch::arg("sorted") = false, torch::arg("algorithm") = "auto", + torch::arg("skin") = 0.0, torch::arg("n_threads") = 0, } ) diff --git a/vesin/include/vesin.h b/vesin/include/vesin.h index 36ca9f31..dcef9ab4 100644 --- a/vesin/include/vesin.h +++ b/vesin/include/vesin.h @@ -58,6 +58,10 @@ struct VesinOptions { bool sorted; /// Which algorithm to use for the calculation VesinAlgorithm algorithm; + /// Skin size for Verlet caching. A positive value enables caching: vesin + /// builds the cached topology with `cutoff + skin` and reuses it until an + /// atom moves more than `skin / 2` from the cached reference positions. + double skin; /// Number of CPU threads to use. This must be zero or positive. A value of /// zero means using the `OMP_NUM_THREADS` environment variable when set to a /// positive value, or otherwise defaulting to the number of available CPU @@ -70,11 +74,6 @@ struct VesinOptions { bool return_distances; /// Should the returned `VesinNeighborList` contain `vector`? bool return_vectors; - - /// Skin size for Verlet caching. A positive value enables caching: vesin - /// builds the cached topology with `cutoff + skin` and reuses it until an - /// atom moves more than `skin / 2` from the cached reference positions. - double skin; }; /// Device on which the data can be