diff --git a/.github/workflows/build-wheels.yml b/.github/workflows/build-wheels.yml index 93f534c94..25b5f1658 100644 --- a/.github/workflows/build-wheels.yml +++ b/.github/workflows/build-wheels.yml @@ -99,7 +99,7 @@ jobs: name: ${{ matrix.name }} (torch v${{ matrix.torch-version }}) strategy: matrix: - torch-version: ['2.1', '2.2', '2.3', '2.4', '2.5', '2.6', '2.7'] + torch-version: ['2.1', '2.2', '2.3', '2.4', '2.5', '2.6', '2.7', '2.8'] arch: ['arm64', 'x86_64'] os: ['ubuntu-22.04', 'ubuntu-22.04-arm', 'macos-13', 'macos-14', 'windows-2022'] exclude: @@ -115,6 +115,7 @@ jobs: - {os: macos-13, arch: x86_64, torch-version: '2.5'} - {os: macos-13, arch: x86_64, torch-version: '2.6'} - {os: macos-13, arch: x86_64, torch-version: '2.7'} + - {os: macos-13, arch: x86_64, torch-version: '2.8'} include: # add `cibw-arch` and `rust-target` to the different configurations - name: x86_64 Linux @@ -149,6 +150,8 @@ jobs: - {torch-version: '2.4', cibw-python: 'cp312-*'} - {torch-version: '2.5', cibw-python: 'cp312-*'} - {torch-version: '2.6', cibw-python: 'cp312-*'} + - {torch-version: '2.7', cibw-python: 'cp312-*'} + - {torch-version: '2.8', cibw-python: 'cp312-*'} steps: - uses: actions/checkout@v4 with: diff --git a/.github/workflows/torch-tests.yml b/.github/workflows/torch-tests.yml index 4ca96032a..f319b9243 100644 --- a/.github/workflows/torch-tests.yml +++ b/.github/workflows/torch-tests.yml @@ -24,7 +24,7 @@ jobs: cargo-test-flags: --release - os: ubuntu-22.04 - torch-version: "2.7" + torch-version: "2.8" python-version: "3.13" cargo-test-flags: --release do-valgrind: true @@ -32,18 +32,18 @@ jobs: - os: ubuntu-22.04 container: ubuntu:20.04 extra-name: ", cmake 3.16" - torch-version: "2.7" + torch-version: "2.8" python-version: "3.13" cargo-test-flags: "" cxx-flags: -fsanitize=undefined -fsanitize=address -fno-omit-frame-pointer -g - os: macos-14 - torch-version: "2.7" + torch-version: "2.8" python-version: "3.13" cargo-test-flags: --release - os: windows-2022 - torch-version: "2.7" + torch-version: "2.8" python-version: "3.13" cargo-test-flags: --release diff --git a/docs/featomic-json-schema/Cargo.toml b/docs/featomic-json-schema/Cargo.toml index 8d69b5deb..523ad13e7 100644 --- a/docs/featomic-json-schema/Cargo.toml +++ b/docs/featomic-json-schema/Cargo.toml @@ -14,5 +14,5 @@ test = false [dependencies] featomic = {path = "../../featomic"} -schemars = "=1.0.0-alpha.17" +schemars = "1" serde_json = "1" diff --git a/docs/requirements.txt b/docs/requirements.txt index d7f081aeb..b3cac1460 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -11,8 +11,8 @@ myst-parser # markdown => rst translation, used in extensions/featomic_json_ # dependencies for the tutorials --extra-index-url https://download.pytorch.org/whl/cpu metatensor-operations >=0.3.3,<0.4 -metatensor-torch >= 0.7.6,<0.8 -metatomic-torch >= 0.1.1,<0.2 +metatensor-torch >=0.8.0,<0.9 +metatomic-torch >= 0.1.4,<0.2 torch chemfiles matplotlib diff --git a/featomic-torch/CMakeLists.txt b/featomic-torch/CMakeLists.txt index 79ae5d08b..448de13e0 100644 --- a/featomic-torch/CMakeLists.txt +++ b/featomic-torch/CMakeLists.txt @@ -122,8 +122,8 @@ find_package(Torch 2.1 REQUIRED) # # When updating METATENSOR_TORCH_FETCH_VERSION, you will also have to update the # SHA256 sum of the file in `FetchContent_Declare`. -set(METATENSOR_TORCH_FETCH_VERSION "0.7.6") -set(REQUIRED_METATENSOR_TORCH_VERSION "0.7") +set(METATENSOR_TORCH_FETCH_VERSION "0.8.0") +set(REQUIRED_METATENSOR_TORCH_VERSION "0.8") if (FEATOMIC_FETCH_METATENSOR_TORCH) message(STATUS "Fetching metatensor-torch from github") @@ -132,7 +132,7 @@ if (FEATOMIC_FETCH_METATENSOR_TORCH) FetchContent_Declare( metatensor_torch URL ${URL_ROOT}/metatensor-torch-v${METATENSOR_TORCH_FETCH_VERSION}/metatensor-torch-cxx-${METATENSOR_TORCH_FETCH_VERSION}.tar.gz - URL_HASH SHA256=8dcc07c86094034facba09ebcc6b52f41847c2413737c8f9c88ae0a2990f8d41 + URL_HASH SHA256=61d383ce958deafe0e3916088185527680c9118588722b17ec5c39cfbaa6da55 ) FetchContent_MakeAvailable(metatensor_torch) @@ -150,19 +150,17 @@ endif() # # When updating METATOMIC_TORCH_FETCH_VERSION, you will also have to update the # SHA256 sum of the file in `FetchContent_Declare`. -set(METATOMIC_TORCH_FETCH_VERSION "0.1.1") +set(METATOMIC_TORCH_FETCH_VERSION "0.1.4") set(REQUIRED_METATOMIC_TORCH_VERSION "0.1") if (FEATOMIC_FETCH_METATENSOR_TORCH) message(STATUS "Fetching metatomic-torch from github") - find_package(Patch REQUIRED) set(URL_ROOT "https://github.com/metatensor/metatomic/releases/download") include(FetchContent) FetchContent_Declare( metatomic_torch URL ${URL_ROOT}/metatomic-torch-v${METATOMIC_TORCH_FETCH_VERSION}/metatomic-torch-cxx-${METATOMIC_TORCH_FETCH_VERSION}.tar.gz - URL_HASH SHA256=2dc0a0213b7f5df3ac519516f1b17801baa6973d96b339f0b39cadea310fefe1 - PATCH_COMMAND ${Patch_EXECUTABLE} -p2 < ${CMAKE_CURRENT_SOURCE_DIR}/cmake/metatomic-cmake.patch + URL_HASH SHA256=385ec8b8515d674b6a9f093f724792b2469e7ea2365ca596f574b64e38494f94 ) FetchContent_MakeAvailable(metatomic_torch) diff --git a/featomic-torch/Cargo.toml b/featomic-torch/Cargo.toml index 24954fefc..1f8dea45f 100644 --- a/featomic-torch/Cargo.toml +++ b/featomic-torch/Cargo.toml @@ -10,7 +10,7 @@ test = false doctest = false [dev-dependencies] -which = "7" +which = "8" [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin)'] } diff --git a/featomic-torch/cmake/metatomic-cmake.patch b/featomic-torch/cmake/metatomic-cmake.patch deleted file mode 100644 index 25984eaf1..000000000 --- a/featomic-torch/cmake/metatomic-cmake.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff --git a/metatomic-torch/CMakeLists.txt b/metatomic-torch/CMakeLists.txt -index d54f7634..93a0c0e5 100644 ---- a/metatomic-torch/CMakeLists.txt -+++ b/metatomic-torch/CMakeLists.txt -@@ -85,8 +85,6 @@ if (TARGET metatensor_torch) - check_compatible_versions(${METATENSOR_TORCH_BUILD_VERSION} ${REQUIRED_METATENSOR_TORCH_VERSION}) - else() - find_package(metatensor_torch ${REQUIRED_METATENSOR_TORCH_VERSION} CONFIG REQUIRED) -- # No version specification here, we'll use whatever `metatensor_torch` uses -- find_package(metatensor CONFIG REQUIRED) - endif() - - # FindCUDNN.cmake distributed with PyTorch is a bit broken, so we have a -@@ -118,7 +116,7 @@ set_target_properties(metatomic_torch PROPERTIES - BUILD_VERSION ${METATOMIC_TORCH_FULL_VERSION} - ) - --target_link_libraries(metatomic_torch PUBLIC torch metatensor_torch metatensor ${CMAKE_DL_LIBS}) -+target_link_libraries(metatomic_torch PUBLIC torch metatensor_torch ${CMAKE_DL_LIBS}) - target_compile_features(metatomic_torch PUBLIC cxx_std_17) - target_include_directories(metatomic_torch PUBLIC - $ -@@ -195,15 +193,7 @@ FetchContent_Declare(nlohmann_json - URL https://github.com/nlohmann/json/releases/download/v3.11.3/json.tar.xz - URL_HASH SHA256=d6c65aca6b1ed68e7a182f4757257b107ae403032760ed6ef121c9d55e81757d - ) --if (CMAKE_VERSION VERSION_GREATER 3.18) -- FetchContent_MakeAvailable(nlohmann_json) --else() -- if (NOT nlohmann_json_POPULATED) -- FetchContent_Populate(nlohmann_json) -- endif() -- -- add_subdirectory(${nlohmann_json_SOURCE_DIR} ${nlohmann_json_BINARY_DIR}) --endif() -+FetchContent_MakeAvailable(nlohmann_json) - - target_link_libraries(metatomic_torch PRIVATE nlohmann_json::nlohmann_json) - diff --git a/featomic-torch/include/featomic/torch/autograd.hpp b/featomic-torch/include/featomic/torch/autograd.hpp index 14673d16a..b4d822584 100644 --- a/featomic-torch/include/featomic/torch/autograd.hpp +++ b/featomic-torch/include/featomic/torch/autograd.hpp @@ -41,7 +41,7 @@ class FEATOMIC_TORCH_EXPORT FeatomicAutograd: public torch::autograd::Function systems, TorchCalculatorOptions options = {} ); @@ -123,9 +123,9 @@ class FEATOMIC_TORCH_EXPORT CalculatorHolder: public torch::CustomClassHolder { /// contain `"cell"` gradients. /// /// `forward_gradients` controls which gradients are left inside the TensorMap. -metatensor_torch::TorchTensorMap FEATOMIC_TORCH_EXPORT register_autograd( +metatensor_torch::TensorMap FEATOMIC_TORCH_EXPORT register_autograd( std::vector systems, - metatensor_torch::TorchTensorMap precomputed, + metatensor_torch::TensorMap precomputed, std::vector forward_gradients ); diff --git a/featomic-torch/src/autograd.cpp b/featomic-torch/src/autograd.cpp index 2ab1a75dc..2dbef0fa8 100644 --- a/featomic-torch/src/autograd.cpp +++ b/featomic-torch/src/autograd.cpp @@ -5,7 +5,6 @@ #include "./openmp.hpp" -using namespace metatensor_torch; using namespace featomic_torch; // # NOTATION @@ -29,7 +28,7 @@ struct PositionsGrad: torch::autograd::Function> { torch::autograd::AutogradContext *ctx, torch::Tensor all_positions, torch::Tensor dA_dX, - TorchTensorBlock dX_dr, + metatensor_torch::TensorBlock dX_dr, torch::IValue systems_start ); @@ -46,7 +45,7 @@ struct CellGrad: torch::autograd::Function> { torch::autograd::AutogradContext *ctx, torch::Tensor all_cells, torch::Tensor dA_dX, - TorchTensorBlock dX_dH, + metatensor_torch::TensorBlock dX_dH, torch::Tensor systems ); @@ -72,16 +71,16 @@ struct CellGrad: torch::autograd::Function> { } \ } while (false) -static std::vector extract_gradient_blocks( - const TorchTensorMap& tensor, +static std::vector extract_gradient_blocks( + const metatensor_torch::TensorMap& tensor, const std::string& parameter ) { - auto gradients = std::vector(); + auto gradients = std::vector(); for (int64_t i=0; ikeys()->count(); i++) { - auto block = TensorMapHolder::block_by_id(tensor, i); - auto gradient = TensorBlockHolder::gradient(block, parameter); + auto block = metatensor_torch::TensorMapHolder::block_by_id(tensor, i); + auto gradient = metatensor_torch::TensorBlockHolder::gradient(block, parameter); - gradients.push_back(torch::make_intrusive( + gradients.push_back(torch::make_intrusive( gradient->values(), gradient->samples(), gradient->components(), @@ -101,15 +100,15 @@ std::vector FeatomicAutograd::forward( torch::Tensor all_positions, torch::Tensor all_cells, torch::IValue systems_start, - metatensor_torch::TorchTensorBlock block + metatensor_torch::TensorBlock block ) { ctx->save_for_backward({all_positions, all_cells}); if (all_positions.requires_grad()) { ctx->saved_data.emplace("systems_start", systems_start); - auto gradient = TensorBlockHolder::gradient(block, "positions"); - ctx->saved_data["positions_gradients"] = torch::make_intrusive( + auto gradient = metatensor_torch::TensorBlockHolder::gradient(block, "positions"); + ctx->saved_data["positions_gradients"] = torch::make_intrusive( gradient->values(), gradient->samples(), gradient->components(), @@ -120,8 +119,8 @@ std::vector FeatomicAutograd::forward( if (all_cells.requires_grad()) { ctx->saved_data["samples"] = block->samples(); - auto gradient = TensorBlockHolder::gradient(block, "cell"); - ctx->saved_data["cell_gradients"] = torch::make_intrusive( + auto gradient = metatensor_torch::TensorBlockHolder::gradient(block, "cell"); + ctx->saved_data["cell_gradients"] = torch::make_intrusive( gradient->values(), gradient->samples(), gradient->components(), @@ -151,7 +150,7 @@ std::vector FeatomicAutograd::backward( // ===================== gradient w.r.t. positions ====================== // if (all_positions.requires_grad()) { - auto forward_gradient = ctx->saved_data["positions_gradients"].toCustomClass(); + auto forward_gradient = ctx->saved_data["positions_gradients"].toCustomClass(); auto systems_start = ctx->saved_data["systems_start"]; if (all_positions.scalar_type() == torch::kFloat32) { @@ -179,8 +178,8 @@ std::vector FeatomicAutograd::backward( // ======================= gradient w.r.t. cell ========================= // if (all_cells.requires_grad()) { - auto forward_gradient = ctx->saved_data["cell_gradients"].toCustomClass(); - auto block_samples = ctx->saved_data["samples"].toCustomClass(); + auto forward_gradient = ctx->saved_data["cell_gradients"].toCustomClass(); + auto block_samples = ctx->saved_data["samples"].toCustomClass(); // find the index of the "system" dimension in the samples const auto& sample_names = block_samples->names(); @@ -238,7 +237,7 @@ std::vector PositionsGrad::forward( torch::autograd::AutogradContext *ctx, torch::Tensor all_positions, torch::Tensor dA_dX, - TorchTensorBlock dX_dr, + metatensor_torch::TensorBlock dX_dr, torch::IValue systems_start_ivalue ) { // ====================== input parameters checks ======================= // @@ -323,10 +322,10 @@ std::vector PositionsGrad::backward( ) { // ====================== input parameters checks ======================= // auto saved_variables = ctx->get_saved_variables(); - auto all_positions = saved_variables[0]; - auto dA_dX = saved_variables[1]; + const auto& all_positions = saved_variables[0]; + const auto& dA_dX = saved_variables[1]; - auto dX_dr = ctx->saved_data["positions_gradients"].toCustomClass(); + auto dX_dr = ctx->saved_data["positions_gradients"].toCustomClass(); auto systems_start = ctx->saved_data["systems_start"].toIntList(); auto dB_d_dA_dr = grad_outputs[0]; // gradient of B w.r.t. dA/dr (output of forward) @@ -430,7 +429,7 @@ std::vector CellGrad::forward( torch::autograd::AutogradContext *ctx, torch::Tensor all_cells, torch::Tensor dA_dX, - TorchTensorBlock dX_dH, + metatensor_torch::TensorBlock dX_dH, torch::Tensor systems ) { // ====================== input parameters checks ======================= // @@ -509,11 +508,11 @@ std::vector CellGrad::backward( ) { // ====================== input parameters checks ======================= // auto saved_variables = ctx->get_saved_variables(); - auto all_cells = saved_variables[0]; - auto dA_dX = saved_variables[1]; - auto systems = saved_variables[2]; + const auto& all_cells = saved_variables[0]; + const auto& dA_dX = saved_variables[1]; + const auto& systems = saved_variables[2]; - auto dX_dH = ctx->saved_data["cell_gradients"].toCustomClass(); + auto dX_dH = ctx->saved_data["cell_gradients"].toCustomClass(); auto dB_d_dA_dH = grad_outputs[0]; // gradient of B w.r.t. dA/dH (output of forward) diff --git a/featomic-torch/src/calculator.cpp b/featomic-torch/src/calculator.cpp index 0dc6c1e20..e97294bf1 100644 --- a/featomic-torch/src/calculator.cpp +++ b/featomic-torch/src/calculator.cpp @@ -7,7 +7,6 @@ #include "featomic/torch/autograd.hpp" #include "featomic/torch/system.hpp" -using namespace metatensor_torch; using namespace featomic_torch; class DisableFeatomicCellGradientWarning { @@ -40,7 +39,7 @@ class DisableFeatomicCellGradientWarning { }; // move a block created by featomic to torch -static TorchTensorBlock block_to_torch( +static metatensor_torch::TensorBlock block_to_torch( std::shared_ptr tensor, metatensor::TensorBlock block ) { @@ -64,17 +63,17 @@ static TorchTensorBlock block_to_torch( torch::TensorOptions().dtype(torch::kF64).device(torch::kCPU) ); - auto components = std::vector(); + auto components = std::vector(); components.reserve(block.components().size()); for (auto component: block.components()) { - components.emplace_back(torch::make_intrusive(std::move(component))); + components.emplace_back(torch::make_intrusive(std::move(component))); } - auto new_block = torch::make_intrusive( + auto new_block = torch::make_intrusive( torch_values, - torch::make_intrusive(block.samples()), + torch::make_intrusive(block.samples()), std::move(components), - torch::make_intrusive(block.properties()) + torch::make_intrusive(block.properties()) ); for (const auto& parameter: block.gradients_list()) { @@ -121,14 +120,14 @@ static bool all_systems_use_native(const std::vector& systems) { return result; } -static TorchTensorMap remove_other_gradients( - TorchTensorMap tensor, +static metatensor_torch::TensorMap remove_other_gradients( + metatensor_torch::TensorMap tensor, const std::vector& gradients_to_keep ) { - auto new_blocks = std::vector(); + auto new_blocks = std::vector(); for (int64_t i=0; ikeys()->count(); i++) { - auto block = TensorMapHolder::block_by_id(tensor, i); - auto new_block = torch::make_intrusive( + auto block = metatensor_torch::TensorMapHolder::block_by_id(tensor, i); + auto new_block = torch::make_intrusive( block->values(), block->samples(), block->components(), @@ -136,14 +135,14 @@ static TorchTensorMap remove_other_gradients( ); for (const auto& parameter: gradients_to_keep) { - auto gradient = TensorBlockHolder::gradient(block, parameter); + auto gradient = metatensor_torch::TensorBlockHolder::gradient(block, parameter); new_block->add_gradient(parameter, gradient); } new_blocks.push_back(std::move(new_block)); } - return torch::make_intrusive( + return torch::make_intrusive( tensor->keys(), std::move(new_blocks) ); @@ -190,7 +189,7 @@ static torch::Device systems_device(const std::vector& systems) { } } -metatensor_torch::TorchTensorMap CalculatorHolder::compute( +metatensor_torch::TensorMap CalculatorHolder::compute( std::vector systems, TorchCalculatorOptions torch_options ) { @@ -261,7 +260,9 @@ metatensor_torch::TorchTensorMap CalculatorHolder::compute( options.use_native_system = all_systems_use_native(featomic_systems); if (torch_options->selected_keys().isCustomClass()) { - options.selected_keys = torch_options->selected_keys().toCustomClass()->as_metatensor(); + options.selected_keys = torch_options->selected_keys() + .toCustomClass() + ->as_metatensor(); } options.selected_samples = torch_options->selected_samples_featomic(); options.selected_properties = torch_options->selected_properties_featomic(); @@ -278,14 +279,14 @@ metatensor_torch::TorchTensorMap CalculatorHolder::compute( } // move all data to torch - auto blocks = std::vector(); + auto blocks = std::vector(); blocks.reserve(raw_descriptor->keys().count()); for (size_t block_i=0; block_ikeys().count(); block_i++) { blocks.emplace_back(block_to_torch(raw_descriptor, raw_descriptor->block_by_id(block_i))); } auto torch_descriptor = torch::make_intrusive( - torch::make_intrusive(raw_descriptor->keys()), + torch::make_intrusive(raw_descriptor->keys()), std::move(blocks) ); @@ -295,7 +296,7 @@ metatensor_torch::TorchTensorMap CalculatorHolder::compute( // ============ register the autograd nodes for each block ============== // for (int64_t block_i=0; block_ikeys()->count(); block_i++) { - auto block = TensorMapHolder::block_by_id(torch_descriptor, block_i); + auto block = metatensor_torch::TensorMapHolder::block_by_id(torch_descriptor, block_i); // see `FeatomicAutograd::forward` for an explanation of what's happening auto _ = FeatomicAutograd::apply( all_positions, @@ -314,9 +315,9 @@ metatensor_torch::TorchTensorMap CalculatorHolder::compute( } -metatensor_torch::TorchTensorMap featomic_torch::register_autograd( +metatensor_torch::TensorMap featomic_torch::register_autograd( std::vector systems, - metatensor_torch::TorchTensorMap precomputed, + metatensor_torch::TensorMap precomputed, std::vector forward_gradients ) { if (precomputed->keys()->count() == 0) { @@ -327,7 +328,7 @@ metatensor_torch::TorchTensorMap featomic_torch::register_autograd( auto all_cells = stack_all_cells(systems); auto systems_start_ivalue = torch::IValue(); - auto precomputed_gradients = TensorMapHolder::block_by_id(precomputed, 0)->gradients_list(); + auto precomputed_gradients = metatensor_torch::TensorMapHolder::block_by_id(precomputed, 0)->gradients_list(); if (all_positions.requires_grad()) { if (!contains(precomputed_gradients, "positions")) { @@ -370,7 +371,7 @@ metatensor_torch::TorchTensorMap featomic_torch::register_autograd( } for (int64_t block_i=0; block_ikeys()->count(); block_i++) { - auto block = TensorMapHolder::block_by_id(precomputed, block_i); + auto block = metatensor_torch::TensorMapHolder::block_by_id(precomputed, block_i); auto _ = FeatomicAutograd::apply( all_positions, all_cells, diff --git a/featomic-torch/tests/utils/mod.rs b/featomic-torch/tests/utils/mod.rs index c240ec331..f620e53aa 100644 --- a/featomic-torch/tests/utils/mod.rs +++ b/featomic-torch/tests/utils/mod.rs @@ -84,7 +84,7 @@ pub fn setup_pytorch(build_dir: PathBuf) -> PathBuf { .expect("failed to run python"); assert!(status.success(), "failed to run `python -m pip install --upgrade pip`"); - let torch_version = std::env::var("FEATOMIC_TORCH_TEST_VERSION").unwrap_or("2.7.*".into()); + let torch_version = std::env::var("FEATOMIC_TORCH_TEST_VERSION").unwrap_or("2.8.*".into()); let status = Command::new(&python) .arg("-m") .arg("pip") diff --git a/featomic/CMakeLists.txt b/featomic/CMakeLists.txt index cb761a501..8d20e24e6 100644 --- a/featomic/CMakeLists.txt +++ b/featomic/CMakeLists.txt @@ -245,7 +245,7 @@ endif() # # When updating METATENSOR_FETCH_VERSION, you will also have to update the # SHA256 sum of the file in `FetchContent_Declare`. -set(METATENSOR_FETCH_VERSION "0.1.14") +set(METATENSOR_FETCH_VERSION "0.1.17") set(METATENSOR_REQUIRED_VERSION "0.1") if (FEATOMIC_FETCH_METATENSOR) message(STATUS "Fetching metatensor-core from github") @@ -255,7 +255,7 @@ if (FEATOMIC_FETCH_METATENSOR) FetchContent_Declare( metatensor URL ${URL_ROOT}/metatensor-core-v${METATENSOR_FETCH_VERSION}/metatensor-core-cxx-${METATENSOR_FETCH_VERSION}.tar.gz - URL_HASH SHA256=dc6cdd9cf0113e2f012ecf68b81cc7cfc71bef3d2020b41574de8fa403dba646 + URL_HASH SHA256=42119e11908239915ccc187d7ca65449b461f1d4b5af4d6df1fb613d687da76a ) if (CMAKE_VERSION VERSION_GREATER 3.18) diff --git a/featomic/Cargo.toml b/featomic/Cargo.toml index c147f9b10..2d7a57a2f 100644 --- a/featomic/Cargo.toml +++ b/featomic/Cargo.toml @@ -25,11 +25,13 @@ metatensor-static = ["metatensor/static"] all-features = true [dependencies] -metatensor = {version = "0.2", features = ["rayon"]} +metatensor = {version = "0.2.2", features = ["rayon"]} ndarray = {version = "0.16", features = ["rayon", "serde", "approx"]} num-traits = "0.2" rayon = "1.5" +# pin for compatibility with rustc 1.74 +rayon-core = "=1.12" log = "0.4" once_cell = "1" @@ -39,20 +41,20 @@ time-graph = "0.3.0" serde = { version = "1", features = ["derive"] } serde_json = "1" -schemars = "=1.0.0-alpha.17" +schemars = "1" -chemfiles = {version = "0.10", optional = true} +chemfiles = { version = "0.10", optional = true } approx = "0.5" [build-dependencies] -cbindgen = { version = "0.28", default-features = false } +cbindgen = { version = "0.29", default-features = false } fs_extra = "1" metatensor = "0.2" [dev-dependencies] criterion = "0.5" -which = "7" +which = "8" glob = "0.3" ndarray-npy = "0.9" flate2 = "1.0.20" diff --git a/featomic/src/calculator.rs b/featomic/src/calculator.rs index 1acfc9932..121fdf92b 100644 --- a/featomic/src/calculator.rs +++ b/featomic/src/calculator.rs @@ -103,7 +103,10 @@ impl LabelsSelection<'_> { for entry in matches { builder.add(&labels[entry as usize]); } - results.push(builder.finish()); + + // the labels entries are unique because they are a + // sub-selection of existing labels + results.push(builder.finish_assume_unique()); } return Ok(results); @@ -301,7 +304,7 @@ impl Calculator { for entry in matches { builder.add(&default_keys[entry as usize]); } - builder.finish() + builder.finish_assume_unique() } } None => default_keys, @@ -363,7 +366,7 @@ impl Calculator { for sample_i in 0..samples.count() { builder.add(&[sample_i]); } - cell_gradient_samples.push(builder.finish()); + cell_gradient_samples.push(builder.finish_assume_unique()); } Some(cell_gradient_samples) } else { @@ -384,7 +387,7 @@ impl Calculator { for sample_i in 0..samples.count() { builder.add(&[sample_i]); } - strain_gradient_samples.push(builder.finish()); + strain_gradient_samples.push(builder.finish_assume_unique()); } Some(strain_gradient_samples) } else { diff --git a/featomic/src/calculators/atomic_composition.rs b/featomic/src/calculators/atomic_composition.rs index 41be866dd..e4207110a 100644 --- a/featomic/src/calculators/atomic_composition.rs +++ b/featomic/src/calculators/atomic_composition.rs @@ -67,7 +67,7 @@ impl CalculatorBase for AtomicComposition { } } } - samples.push(builder.finish()); + samples.push(builder.finish_assume_unique()); } return Ok(samples); diff --git a/featomic/src/calculators/lode/spherical_expansion.rs b/featomic/src/calculators/lode/spherical_expansion.rs index c5932ca4f..ead483f86 100644 --- a/featomic/src/calculators/lode/spherical_expansion.rs +++ b/featomic/src/calculators/lode/spherical_expansion.rs @@ -473,7 +473,7 @@ impl CalculatorBase for LodeSphericalExpansion { } } - return Ok(builder.finish()); + return Ok(builder.finish_assume_unique()); } fn sample_names(&self) -> Vec<&str> { @@ -553,7 +553,7 @@ impl CalculatorBase for LodeSphericalExpansion { component.add(&[LabelValue::new(m)]); } - let components = vec![component.finish()]; + let components = vec![component.finish_assume_unique()]; component_by_l.insert(*o3_lambda, components); } @@ -579,7 +579,7 @@ impl CalculatorBase for LodeSphericalExpansion { properties.add(&[n]); } - return vec![properties.finish(); keys.count()]; + return vec![properties.finish_assume_unique(); keys.count()]; } SphericalExpansionBasis::Explicit(ref basis) => { let mut result = Vec::new(); @@ -591,7 +591,7 @@ impl CalculatorBase for LodeSphericalExpansion { properties.add(&[n]); } - result.push(properties.finish()); + result.push(properties.finish_assume_unique()); } return result; } diff --git a/featomic/src/calculators/neighbor_list.rs b/featomic/src/calculators/neighbor_list.rs index 668d96424..f1fb5c998 100644 --- a/featomic/src/calculators/neighbor_list.rs +++ b/featomic/src/calculators/neighbor_list.rs @@ -123,7 +123,7 @@ impl CalculatorBase for NeighborList { builder.add(&[sample_i.into(), system_i, second]); } - results.push(builder.finish()); + results.push(builder.finish_assume_unique()); } return Ok(results); @@ -140,7 +140,7 @@ impl CalculatorBase for NeighborList { fn properties(&self, keys: &Labels) -> Vec { let mut properties = LabelsBuilder::new(self.property_names()); - properties.add(&[LabelValue::new(1)]); + properties.add(&[LabelValue::new(0)]); let properties = properties.finish(); return vec![properties; keys.count()]; @@ -196,7 +196,7 @@ impl HalfNeighborList { keys.add(&[first, second]); } - return Ok(keys.finish()); + return Ok(keys.finish_assume_unique()); } fn samples(&self, keys: &Labels, systems: &mut [Box]) -> Result, Error> { @@ -261,7 +261,7 @@ impl HalfNeighborList { } } - results.push(builder.finish()); + results.push(builder.finish_assume_unique()); } return Ok(results); @@ -322,7 +322,7 @@ impl HalfNeighborList { if let Some(sample_i) = sample_i { let array = block_data.values.to_array_mut(); for (property_i, &[distance]) in block_data.properties.iter_fixed_size().enumerate() { - if distance == 1 { + if distance == 0 { array[[sample_i, 0, property_i]] = pair_vector[0]; array[[sample_i, 1, property_i]] = pair_vector[1]; array[[sample_i, 2, property_i]] = pair_vector[2]; @@ -342,7 +342,7 @@ impl HalfNeighborList { let array = gradient.values.to_array_mut(); for (property_i, &[distance]) in gradient.properties.iter_fixed_size().enumerate() { - if distance == 1 { + if distance == 0 { array[[first_grad_sample_i, 0, 0, property_i]] = -1.0; array[[first_grad_sample_i, 1, 1, property_i]] = -1.0; array[[first_grad_sample_i, 2, 2, property_i]] = -1.0; @@ -397,7 +397,7 @@ impl FullNeighborList { keys.add(&[first, second]); } - return Ok(keys.finish()); + return Ok(keys.finish_assume_unique()); } pub(crate) fn samples(&self, keys: &Labels, systems: &mut [Box]) -> Result, Error> { @@ -485,7 +485,7 @@ impl FullNeighborList { } } - results.push(builder.finish()); + results.push(builder.finish_assume_unique()); } return Ok(results); @@ -533,7 +533,7 @@ impl FullNeighborList { let array = block_data.values.to_array_mut(); for (property_i, &[distance]) in block_data.properties.iter_fixed_size().enumerate() { - if distance == 1 { + if distance == 0 { array[[sample_i, 0, property_i]] = pair.vector[0]; array[[sample_i, 1, property_i]] = pair.vector[1]; array[[sample_i, 2, property_i]] = pair.vector[2]; @@ -553,7 +553,7 @@ impl FullNeighborList { let array = gradient.values.to_array_mut(); for (property_i, &[distance]) in gradient.properties.iter_fixed_size().enumerate() { - if distance == 1 { + if distance == 0 { array[[first_grad_sample_i, 0, 0, property_i]] = -1.0; array[[first_grad_sample_i, 1, 1, property_i]] = -1.0; array[[first_grad_sample_i, 2, 2, property_i]] = -1.0; @@ -584,7 +584,7 @@ impl FullNeighborList { if let Some(sample_i) = sample_i { let array = block_data.values.to_array_mut(); for (property_i, &[distance]) in block_data.properties.iter_fixed_size().enumerate() { - if distance == 1 { + if distance == 0 { array[[sample_i, 0, property_i]] = -pair.vector[0]; array[[sample_i, 1, property_i]] = -pair.vector[1]; array[[sample_i, 2, property_i]] = -pair.vector[2]; @@ -604,7 +604,7 @@ impl FullNeighborList { let array = gradient.values.to_array_mut(); for (property_i, &[distance]) in gradient.properties.iter_fixed_size().enumerate() { - if distance == 1 { + if distance == 0 { array[[first_grad_sample_i, 0, 0, property_i]] = -1.0; array[[first_grad_sample_i, 1, 1, property_i]] = -1.0; array[[first_grad_sample_i, 2, 2, property_i]] = -1.0; @@ -655,7 +655,7 @@ mod tests { // O-H block let block = descriptor.block_by_id(0); - assert_eq!(block.properties(), Labels::new(["distance"], &[[1]])); + assert_eq!(block.properties(), Labels::new(["distance"], &[[0]])); assert_eq!(block.components().len(), 1); assert_eq!(block.components()[0], Labels::new(["pair_xyz"], &[[0], [1], [2]])); @@ -709,7 +709,7 @@ mod tests { // O-H block let block = descriptor.block_by_id(0); - assert_eq!(block.properties(), Labels::new(["distance"], &[[1]])); + assert_eq!(block.properties(), Labels::new(["distance"], &[[0]])); assert_eq!(block.components().len(), 1); assert_eq!(block.components()[0], Labels::new(["pair_xyz"], &[[0], [1], [2]])); @@ -729,7 +729,7 @@ mod tests { // H-O block let block = descriptor.block_by_id(1); - assert_eq!(block.properties(), Labels::new(["distance"], &[[1]])); + assert_eq!(block.properties(), Labels::new(["distance"], &[[0]])); assert_eq!(block.components().len(), 1); assert_eq!(block.components()[0], Labels::new(["pair_xyz"], &[[0], [1], [2]])); @@ -880,7 +880,7 @@ mod tests { let properties = Labels::new( ["distance"], - &[[1]], + &[[0]], ); let keys = Labels::new( diff --git a/featomic/src/calculators/shared/descriptors_by_systems.rs b/featomic/src/calculators/shared/descriptors_by_systems.rs index 043ac2e5e..32bbc7ae8 100644 --- a/featomic/src/calculators/shared/descriptors_by_systems.rs +++ b/featomic/src/calculators/shared/descriptors_by_systems.rs @@ -153,7 +153,7 @@ pub fn split_tensor_map_by_system(descriptor: &mut TensorMap, n_systems: usize) let mut shape = Vec::new(); - let samples = samples.finish(); + let samples = samples.finish_assume_unique(); shape.push(samples.count()); for component in &*block_data.components { @@ -217,7 +217,7 @@ pub fn split_tensor_map_by_system(descriptor: &mut TensorMap, n_systems: usize) let mut shape = Vec::new(); - let samples = samples.finish(); + let samples = samples.finish_assume_unique(); shape.push(samples.count()); for component in &*gradient.components { diff --git a/featomic/src/calculators/soap/power_spectrum.rs b/featomic/src/calculators/soap/power_spectrum.rs index 3bec446ec..34c9cfd4d 100644 --- a/featomic/src/calculators/soap/power_spectrum.rs +++ b/featomic/src/calculators/soap/power_spectrum.rs @@ -148,13 +148,13 @@ impl SoapPowerSpectrum { for entry in samples { samples_builder.add(&entry); } - let samples = samples_builder.finish(); + let samples = samples_builder.finish_assume_unique(); let mut properties_builder = LabelsBuilder::new(vec!["n"]); for entry in properties { properties_builder.add(&entry); } - let properties = properties_builder.finish(); + let properties = properties_builder.finish_assume_unique(); blocks.push(TensorBlock::new( EmptyArray::new(vec![samples.count(), properties.count()]), @@ -507,7 +507,7 @@ impl CalculatorBase for SoapPowerSpectrum { } } - return vec![properties.finish(); keys.count()]; + return vec![properties.finish_assume_unique(); keys.count()]; } SphericalExpansionBasis::Explicit(ref basis) => { let mut properties = LabelsBuilder::new(self.property_names()); diff --git a/featomic/src/calculators/soap/radial_spectrum.rs b/featomic/src/calculators/soap/radial_spectrum.rs index 7414dc0c8..4d174c248 100644 --- a/featomic/src/calculators/soap/radial_spectrum.rs +++ b/featomic/src/calculators/soap/radial_spectrum.rs @@ -129,7 +129,7 @@ impl SoapRadialSpectrum { ); } - return TensorMap::new(keys_builder.finish(), blocks).expect("invalid TensorMap"); + return TensorMap::new(keys_builder.finish_assume_unique(), blocks).expect("invalid TensorMap"); } } @@ -218,7 +218,7 @@ impl CalculatorBase for SoapRadialSpectrum { for n in 0..self.parameters.basis.radial.size() { properties.add(&[n]); } - let properties = properties.finish(); + let properties = properties.finish_assume_unique(); return vec![properties; keys.count()]; } diff --git a/featomic/src/calculators/soap/spherical_expansion.rs b/featomic/src/calculators/soap/spherical_expansion.rs index e36685e91..78113f8be 100644 --- a/featomic/src/calculators/soap/spherical_expansion.rs +++ b/featomic/src/calculators/soap/spherical_expansion.rs @@ -673,7 +673,7 @@ impl CalculatorBase for SphericalExpansion { } } - return Ok(builder.finish()); + return Ok(builder.finish_assume_unique()); } fn sample_names(&self) -> Vec<&str> { @@ -757,7 +757,7 @@ impl CalculatorBase for SphericalExpansion { component.add(&[LabelValue::new(m)]); } - let components = vec![component.finish()]; + let components = vec![component.finish_assume_unique()]; component_by_l.insert(*o3_lambda, components); } @@ -783,7 +783,7 @@ impl CalculatorBase for SphericalExpansion { properties.add(&[n]); } - return vec![properties.finish(); keys.count()]; + return vec![properties.finish_assume_unique(); keys.count()]; } SphericalExpansionBasis::Explicit(ref basis) => { let mut result = Vec::new(); @@ -795,7 +795,7 @@ impl CalculatorBase for SphericalExpansion { properties.add(&[n]); } - result.push(properties.finish()); + result.push(properties.finish_assume_unique()); } return result; } @@ -1040,7 +1040,7 @@ mod tests { } } } - let select_all_samples = TensorMap::new(keys.finish(), blocks).unwrap(); + let select_all_samples = TensorMap::new(keys.finish_assume_unique(), blocks).unwrap(); let options = CalculationOptions { selected_samples: LabelsSelection::Predefined(&select_all_samples), diff --git a/featomic/src/calculators/soap/spherical_expansion_pair.rs b/featomic/src/calculators/soap/spherical_expansion_pair.rs index 8c71ec0be..c1f7c078e 100644 --- a/featomic/src/calculators/soap/spherical_expansion_pair.rs +++ b/featomic/src/calculators/soap/spherical_expansion_pair.rs @@ -578,7 +578,7 @@ impl CalculatorBase for SphericalExpansionByPair { } } - return Ok(keys.finish()); + return Ok(keys.finish_assume_unique()); } fn sample_names(&self) -> Vec<&str> { @@ -595,7 +595,7 @@ impl CalculatorBase for SphericalExpansionByPair { for (first_type, second_type) in types_keys { builder.add(&[first_type, second_type]); } - let types_keys = builder.finish(); + let types_keys = builder.finish_assume_unique(); // for l=0, we want to include self pairs in the samples let mut samples_by_types_l0: BTreeMap<_, Labels> = BTreeMap::new(); @@ -661,7 +661,7 @@ impl CalculatorBase for SphericalExpansionByPair { } } - results.push(builder.finish()); + results.push(builder.finish_assume_unique()); } return Ok(results); @@ -684,7 +684,7 @@ impl CalculatorBase for SphericalExpansionByPair { component.add(&[LabelValue::new(m)]); } - let components = vec![component.finish()]; + let components = vec![component.finish_assume_unique()]; entry.insert(components).clone() } }; @@ -709,7 +709,7 @@ impl CalculatorBase for SphericalExpansionByPair { properties.add(&[n]); } - return vec![properties.finish(); keys.count()]; + return vec![properties.finish_assume_unique(); keys.count()]; } SphericalExpansionBasis::Explicit(ref basis) => { let mut result = Vec::new(); @@ -721,7 +721,7 @@ impl CalculatorBase for SphericalExpansionByPair { properties.add(&[n]); } - result.push(properties.finish()); + result.push(properties.finish_assume_unique()); } return result; } diff --git a/featomic/src/labels/keys.rs b/featomic/src/labels/keys.rs index aae620af5..54c4bc8ab 100644 --- a/featomic/src/labels/keys.rs +++ b/featomic/src/labels/keys.rs @@ -27,7 +27,7 @@ impl KeysBuilder for CenterTypesKeys { for atomic_type in all_types { keys.add(&[atomic_type]); } - return Ok(keys.finish()); + return Ok(keys.finish_assume_unique()); } } @@ -52,7 +52,7 @@ impl KeysBuilder for AllTypesPairsKeys { keys.add(&[center, neighbor]); } - return Ok(keys.finish()); + return Ok(keys.finish_assume_unique()); } } @@ -91,7 +91,7 @@ impl KeysBuilder for CenterSingleNeighborsTypesKeys { keys.add(&[center, neighbor]); } - return Ok(keys.finish()); + return Ok(keys.finish_assume_unique()); } } @@ -154,6 +154,6 @@ impl KeysBuilder for CenterTwoNeighborsTypesKeys { keys_builder.add(&[center_type, neighbor_1_type, neighbor_2_type]); } - return Ok(keys_builder.finish()); + return Ok(keys_builder.finish_assume_unique()); } } diff --git a/featomic/src/labels/samples/atom_centered.rs b/featomic/src/labels/samples/atom_centered.rs index 96592c733..b9974a95b 100644 --- a/featomic/src/labels/samples/atom_centered.rs +++ b/featomic/src/labels/samples/atom_centered.rs @@ -97,7 +97,7 @@ impl SamplesBuilder for AtomCenteredSamples { } } - return Ok(builder.finish()); + return Ok(builder.finish_assume_unique()); } fn gradients_for(&self, systems: &mut [Box], samples: &Labels) -> Result { @@ -145,7 +145,7 @@ impl SamplesBuilder for AtomCenteredSamples { } } - return Ok(builder.finish()); + return Ok(builder.finish_assume_unique()); } } diff --git a/featomic/src/labels/samples/long_range.rs b/featomic/src/labels/samples/long_range.rs index c4ac4c4a4..cd56d807f 100644 --- a/featomic/src/labels/samples/long_range.rs +++ b/featomic/src/labels/samples/long_range.rs @@ -49,7 +49,7 @@ impl SamplesBuilder for LongRangeSamplesPerAtom { } } - return Ok(builder.finish()); + return Ok(builder.finish_assume_unique()); } fn gradients_for(&self, systems: &mut [Box], samples: &Labels) -> Result { @@ -67,7 +67,7 @@ impl SamplesBuilder for LongRangeSamplesPerAtom { } } - return Ok(builder.finish()); + return Ok(builder.finish_assume_unique()); } } diff --git a/python/Cargo.toml b/python/Cargo.toml index 2db48a4dd..b05956db0 100644 --- a/python/Cargo.toml +++ b/python/Cargo.toml @@ -10,7 +10,7 @@ test = false doctest = false [dev-dependencies] -which = "7" +which = "8" [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin)'] } diff --git a/python/featomic_torch/build-backend/backend.py b/python/featomic_torch/build-backend/backend.py index f893d6112..4bfe0fbcf 100644 --- a/python/featomic_torch/build-backend/backend.py +++ b/python/featomic_torch/build-backend/backend.py @@ -42,7 +42,7 @@ def get_requires_for_build_wheel(config_settings=None): return defaults + [ "cmake", TORCH_DEP, - "metatensor-torch >=0.7.6,<0.8", - "metatomic-torch >=0.1.1,<0.2", + "metatensor-torch >=0.8.0,<0.9", + "metatomic-torch >=0.1.4,<0.2", FEATOMIC_DEP, ] diff --git a/python/featomic_torch/setup.py b/python/featomic_torch/setup.py index 932660486..ce4c6f861 100644 --- a/python/featomic_torch/setup.py +++ b/python/featomic_torch/setup.py @@ -346,8 +346,8 @@ def create_version_number(version): install_requires = [ f"torch {torch_version}", - "metatensor-torch >=0.7.6,<0.8", - "metatomic-torch >=0.1.1,<0.2", + "metatensor-torch >=0.8.0,<0.9", + "metatomic-torch >=0.1.4,<0.2", ] # when packaging a sdist for release, we should never use local dependencies diff --git a/tox.ini b/tox.ini index db5c4ae76..80b8b8496 100644 --- a/tox.ini +++ b/tox.ini @@ -21,11 +21,11 @@ lint-folders = "{toxinidir}/python" "{toxinidir}/setup.py" # we need to manually install dependencies for featomic, since tox will install # the fresh wheel with `--no-deps` after building it. metatensor-core-requirement = - metatensor-core >=0.1.14,<0.2 + metatensor-core >=0.1.15,<0.2 metatensor-torch-requirement = - metatensor-torch >=0.7.6,<0.8 - metatomic-torch >=0.1.1,<0.2 + metatensor-torch >=0.8.0,<0.9 + metatomic-torch >=0.1.4,<0.2 build-single-wheel = --no-deps --no-build-isolation --check-build-dependencies warning_options =