diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index a91a4de8f..cef577899 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -44,9 +44,9 @@ jobs: run: sudo apt install -y lcov - name: Setup sccache - uses: mozilla-actions/sccache-action@v0.0.6 + uses: mozilla-actions/sccache-action@v0.0.9 with: - version: "v0.8.2" + version: "v0.10.0" - name: Setup sccache environnement variables run: | diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index ead0ba368..59f87da55 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -45,9 +45,9 @@ jobs: python -m pip install tox - name: Setup sccache - uses: mozilla-actions/sccache-action@v0.0.3 + uses: mozilla-actions/sccache-action@v0.0.9 with: - version: "v0.5.4" + version: "v0.10.0" - name: Setup sccache environnement variables run: | diff --git a/.github/workflows/rust-tests.yml b/.github/workflows/rust-tests.yml index 2b2f5eb9f..950fd6e45 100644 --- a/.github/workflows/rust-tests.yml +++ b/.github/workflows/rust-tests.yml @@ -105,9 +105,9 @@ jobs: sudo apt-get install -y valgrind - name: Setup sccache - uses: mozilla-actions/sccache-action@v0.0.3 + uses: mozilla-actions/sccache-action@v0.0.9 with: - version: "v0.5.4" + version: "v0.10.0" - name: Setup sccache environnement variables run: | @@ -143,9 +143,9 @@ jobs: toolchain: stable - name: Setup sccache - uses: mozilla-actions/sccache-action@v0.0.6 + uses: mozilla-actions/sccache-action@v0.0.9 with: - version: "v0.8.2" + version: "v0.10.0" - name: Setup sccache environnement variables run: | diff --git a/.github/workflows/torch-tests.yml b/.github/workflows/torch-tests.yml index 344dd2a0d..5902dcb31 100644 --- a/.github/workflows/torch-tests.yml +++ b/.github/workflows/torch-tests.yml @@ -13,7 +13,7 @@ concurrency: jobs: tests: runs-on: ${{ matrix.os }} - name: ${{ matrix.os }} / Torch ${{ matrix.torch-version }} + name: ${{ matrix.os }} / Torch ${{ matrix.torch-version }}${{ matrix.extra-name }} container: ${{ matrix.container }} strategy: matrix: @@ -29,7 +29,7 @@ jobs: cargo-test-flags: --release do-valgrind: true - - os: ubuntu-20.04 + - os: ubuntu-22.04 container: ubuntu:20.04 extra-name: ", cmake 3.16" torch-version: "2.6" @@ -53,7 +53,9 @@ jobs: run: | apt update apt install -y software-properties-common - apt install -y cmake make gcc g++ git curl + add-apt-repository ppa:deadsnakes/ppa + apt install -y cmake make gcc g++ git curl python3.10 python3.10-venv + update-alternatives --install /usr/local/bin/python python /usr/bin/python3.10 1 - uses: actions/checkout@v4 with: @@ -70,6 +72,7 @@ jobs: # we get torch from pip to run the C++ test - name: setup Python + if: matrix.container != 'ubuntu:20.04' uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} @@ -81,9 +84,9 @@ jobs: sudo apt-get install -y valgrind - name: Setup sccache - uses: mozilla-actions/sccache-action@v0.0.6 + uses: mozilla-actions/sccache-action@v0.0.9 with: - version: "v0.8.2" + version: "v0.10.0" - name: Setup sccache environnement variables run: | diff --git a/docs/featomic-json-schema/Cargo.toml b/docs/featomic-json-schema/Cargo.toml index f32619f79..8d69b5deb 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.15" +schemars = "=1.0.0-alpha.17" serde_json = "1" diff --git a/docs/src/get-started/installation.rst b/docs/src/get-started/installation.rst index 7ddb2b840..893287ee2 100644 --- a/docs/src/get-started/installation.rst +++ b/docs/src/get-started/installation.rst @@ -2,19 +2,30 @@ Installation ============ You can install featomic in different ways depending on which language you plan -to use it from. In all cases you will need a Rust compiler, which you can -install using `rustup `_ or your OS package manager. +to use it from. .. _install-python-lib: Installing the Python module ---------------------------- -For building and using the Python package, clone the repository using `git -`_ and install featomic using `pip -`_. +Pre-compiled wheels +^^^^^^^^^^^^^^^^^^^ -From source: +The easiest way to install featomic is to use `pip `_. + +.. code-block:: bash + + pip install --upgrade pip + pip install featomic + + +Building from source +^^^^^^^^^^^^^^^^^^^^ + +If you want to build the code from source, you'll need a Rust compiler, which +you can install using `rustup `_ or your OS package manager; +and `git `_. .. code-block:: bash @@ -29,15 +40,6 @@ From source: pip install git+https://github.com/metatensor/featomic -Featomic is also provided as prebuilt wheel which avoids the intermediate step -of building the package with a Rust compiler from the source code. - -.. code-block:: bash - - pip install --upgrade pip - pip install --extra-index-url https://luthaf.fr/nightly-wheels/ featomic - - .. _install-c-lib: Installing the C/C++ library @@ -101,17 +103,24 @@ Installing the TorchScript bindings For usage from Python ^^^^^^^^^^^^^^^^^^^^^ -Building from source: +You can install the code with ``pip``: + +.. code-block:: bash + + pip install --upgrade pip + pip install featomic[torch] + + +You can also build the code from source .. code-block:: bash + pip install --upgrade pip + git clone https://github.com/metatensor/featomic cd featomic/python/featomic_torch pip install . - # Make sure you are using the latest version of pip - pip install --upgrade pip - # alternatively, the same thing in a single command pip install git+https://github.com/metatensor/featomic#subdirectory=python/featomic_torch diff --git a/featomic-torch/Cargo.toml b/featomic-torch/Cargo.toml index 1a13d9b64..24954fefc 100644 --- a/featomic-torch/Cargo.toml +++ b/featomic-torch/Cargo.toml @@ -10,7 +10,7 @@ test = false doctest = false [dev-dependencies] -which = "5" +which = "7" [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin)'] } diff --git a/featomic/Cargo.toml b/featomic/Cargo.toml index ebc010d4b..6b9e11541 100644 --- a/featomic/Cargo.toml +++ b/featomic/Cargo.toml @@ -39,25 +39,28 @@ time-graph = "0.3.0" serde = { version = "1", features = ["derive"] } serde_json = "1" -schemars = "=1.0.0-alpha.15" +schemars = "=1.0.0-alpha.17" chemfiles = {version = "0.10", optional = true} approx = "0.5" [build-dependencies] -cbindgen = { version = "0.27", default-features = false } +cbindgen = { version = "0.28", default-features = false } fs_extra = "1" metatensor = "0.2" [dev-dependencies] criterion = "0.5" -which = "5" +which = "7" glob = "0.3" ndarray-npy = "0.9" flate2 = "1.0.20" time-graph = {version = "0.3.0", features = ["table", "json"]} +# Pin half to the last version supporting rustc 1.74 +half = "=2.4.1" + [[bench]] name = "spherical-harmonics" diff --git a/featomic/include/featomic.h b/featomic/include/featomic.h index 00f625861..202c786d0 100644 --- a/featomic/include/featomic.h +++ b/featomic/include/featomic.h @@ -146,7 +146,7 @@ typedef struct featomic_pair_t { * implement the rust `System` trait in C and other languages. Speaking in Rust * terms, `user_data` contains a pointer (analog to `Box`) to the struct * implementing the `System` trait; and then there is one function pointers - * (`Option`) for each function in the `System` trait. + * (`Option`) for each function in the `System` trait. * * The `featomic_status_t` return value for the function is used to communicate * error messages. It should be 0/`FEATOMIC_SUCCESS` in case of success, any diff --git a/featomic/src/c_api/calculator.rs b/featomic/src/c_api/calculator.rs index 8ad614310..b269bcc5e 100644 --- a/featomic/src/c_api/calculator.rs +++ b/featomic/src/c_api/calculator.rs @@ -51,7 +51,7 @@ impl DerefMut for featomic_calculator_t { /// to get the error message. #[no_mangle] #[allow(clippy::module_name_repetitions)] -pub unsafe extern fn featomic_calculator(name: *const c_char, parameters: *const c_char) -> *mut featomic_calculator_t { +pub unsafe extern "C" fn featomic_calculator(name: *const c_char, parameters: *const c_char) -> *mut featomic_calculator_t { let mut raw = std::ptr::null_mut(); let unwind_wrapper = std::panic::AssertUnwindSafe(&mut raw); let status = catch_unwind(move || { @@ -84,7 +84,7 @@ pub unsafe extern fn featomic_calculator(name: *const c_char, parameters: *const /// `FEATOMIC_SUCCESS`, you can use `featomic_last_error()` to get the /// full error message. #[no_mangle] -pub unsafe extern fn featomic_calculator_free(calculator: *mut featomic_calculator_t) -> featomic_status_t { +pub unsafe extern "C" fn featomic_calculator_free(calculator: *mut featomic_calculator_t) -> featomic_status_t { catch_unwind(|| { if !calculator.is_null() { let boxed = Box::from_raw(calculator); @@ -110,7 +110,7 @@ pub unsafe extern fn featomic_calculator_free(calculator: *mut featomic_calculat /// `FEATOMIC_SUCCESS`, you can use `featomic_last_error()` to get the full /// error message. #[no_mangle] -pub unsafe extern fn featomic_calculator_name( +pub unsafe extern "C" fn featomic_calculator_name( calculator: *const featomic_calculator_t, name: *mut c_char, bufflen: usize @@ -138,7 +138,7 @@ pub unsafe extern fn featomic_calculator_name( /// `FEATOMIC_SUCCESS`, you can use `featomic_last_error()` to get the full /// error message. #[no_mangle] -pub unsafe extern fn featomic_calculator_parameters( +pub unsafe extern "C" fn featomic_calculator_parameters( calculator: *const featomic_calculator_t, parameters: *mut c_char, bufflen: usize @@ -167,7 +167,7 @@ pub unsafe extern fn featomic_calculator_parameters( /// `FEATOMIC_SUCCESS`, you can use `featomic_last_error()` to get the full /// error message. #[no_mangle] -pub unsafe extern fn featomic_calculator_cutoffs( +pub unsafe extern "C" fn featomic_calculator_cutoffs( calculator: *const featomic_calculator_t, cutoffs: *mut *const f64, cutoffs_count: *mut usize @@ -389,7 +389,7 @@ pub struct featomic_calculation_options_t { /// `FEATOMIC_SUCCESS`, you can use `featomic_last_error()` to get the full /// error message. #[no_mangle] -pub unsafe extern fn featomic_calculator_compute( +pub unsafe extern "C" fn featomic_calculator_compute( calculator: *mut featomic_calculator_t, descriptor: *mut *mut mts_tensormap_t, systems: *mut featomic_system_t, diff --git a/featomic/src/c_api/logging.rs b/featomic/src/c_api/logging.rs index f2d0aac23..c7be8e3a4 100644 --- a/featomic/src/c_api/logging.rs +++ b/featomic/src/c_api/logging.rs @@ -36,7 +36,7 @@ pub const FEATOMIC_LOG_LEVEL_TRACE: i32 = 5; /// or `FEATOMIC_LOG_LEVEL_TRACE`. The second argument is a NULL-terminated string /// containing the message associated with the log event. #[allow(non_camel_case_types)] -pub type featomic_logging_callback_t = Option; +pub type featomic_logging_callback_t = Option; static GLOBAL_CALLBACK: Lazy> = Lazy::new(|| Mutex::new(None)); @@ -48,7 +48,7 @@ struct FeatomicLogger; /// function will be called on all log events. If a logging callback was already /// set, it is replaced by the new one. #[no_mangle] -pub unsafe extern fn featomic_set_logging_callback(callback: featomic_logging_callback_t) -> featomic_status_t { +pub unsafe extern "C" fn featomic_set_logging_callback(callback: featomic_logging_callback_t) -> featomic_status_t { catch_unwind(|| { *GLOBAL_CALLBACK.lock().expect("mutex was poisoned") = callback; // we allow multiple sets of logger, therefore the result will be ignored diff --git a/featomic/src/c_api/profiling.rs b/featomic/src/c_api/profiling.rs index 4bd9b3c7a..220567e54 100644 --- a/featomic/src/c_api/profiling.rs +++ b/featomic/src/c_api/profiling.rs @@ -14,7 +14,7 @@ use super::utils::copy_str_to_c; /// `FEATOMIC_SUCCESS`, you can use `featomic_last_error()` to get the full /// error message. #[no_mangle] -pub extern fn featomic_profiling_clear() -> featomic_status_t { +pub extern "C" fn featomic_profiling_clear() -> featomic_status_t { catch_unwind(|| { time_graph::clear_collected_data(); Ok(()) @@ -39,7 +39,7 @@ pub extern fn featomic_profiling_clear() -> featomic_status_t { /// `FEATOMIC_SUCCESS`, you can use `featomic_last_error()` to get the full /// error message. #[no_mangle] -pub extern fn featomic_profiling_enable(enabled: bool) -> featomic_status_t { +pub extern "C" fn featomic_profiling_enable(enabled: bool) -> featomic_status_t { catch_unwind(|| { time_graph::enable_data_collection(enabled); Ok(()) @@ -61,7 +61,7 @@ pub extern fn featomic_profiling_enable(enabled: bool) -> featomic_status_t { /// `FEATOMIC_SUCCESS`, you can use `featomic_last_error()` to get the full /// error message. #[no_mangle] -pub unsafe extern fn featomic_profiling_get( +pub unsafe extern "C" fn featomic_profiling_get( format: *const c_char, buffer: *mut c_char, bufflen: usize, diff --git a/featomic/src/c_api/status.rs b/featomic/src/c_api/status.rs index 7a1c318f0..5c65c8daf 100644 --- a/featomic/src/c_api/status.rs +++ b/featomic/src/c_api/status.rs @@ -109,7 +109,7 @@ macro_rules! check_pointers { /// /// @returns the last error message, as a NULL-terminated string #[no_mangle] -pub unsafe extern fn featomic_last_error() -> *const c_char { +pub unsafe extern "C" fn featomic_last_error() -> *const c_char { let mut result = std::ptr::null(); let unwind_wrapper = std::panic::AssertUnwindSafe(&mut result); let status = catch_unwind(move || { diff --git a/featomic/src/c_api/system.rs b/featomic/src/c_api/system.rs index 60f912d50..4d7d1fb3b 100644 --- a/featomic/src/c_api/system.rs +++ b/featomic/src/c_api/system.rs @@ -35,7 +35,7 @@ pub struct featomic_pair_t { /// implement the rust `System` trait in C and other languages. Speaking in Rust /// terms, `user_data` contains a pointer (analog to `Box`) to the struct /// implementing the `System` trait; and then there is one function pointers -/// (`Option`) for each function in the `System` trait. +/// (`Option`) for each function in the `System` trait. /// /// The `featomic_status_t` return value for the function is used to communicate /// error messages. It should be 0/`FEATOMIC_SUCCESS` in case of success, any @@ -53,7 +53,7 @@ pub struct featomic_pair_t { /// same time. The `featomic_system_t` itself might be moved from one thread to /// another. -// Function pointers have type `Option`, where `Option` +// Function pointers have type `Option`, where `Option` // ensure that the `impl System for featomic_system_t` is forced to deal with the // function pointer potentially being NULL. `unsafe` is required since these // function come from another language and are not checked by the Rust compiler. @@ -66,25 +66,25 @@ pub struct featomic_system_t { /// first parameter to all function pointers below. user_data: *mut c_void, /// This function should set `*size` to the number of atoms in this system - size: Option featomic_status_t>, + size: Option featomic_status_t>, /// This function should set `*types` to a pointer to the first element of /// a contiguous array containing the atomic types of each atom in the /// system. Different atomic types should be identified with a different /// value. These values are usually the atomic number, but don't have to be. /// The array should contain `featomic_system_t::size()` elements. - types: Option featomic_status_t>, + types: Option featomic_status_t>, /// This function should set `*positions` to a pointer to the first element /// of a contiguous array containing the atomic cartesian coordinates. /// `positions[0], positions[1], positions[2]` must contain the x, y, z /// cartesian coordinates of the first atom, and so on. - positions: Option featomic_status_t>, + positions: Option featomic_status_t>, /// This function should write the unit cell matrix in `cell`, which have /// space for 9 values. The cell should be written in row major order, i.e. /// `ax ay az bx by bz cx cy cz`, where a/b/c are the unit cell vectors. - cell: Option featomic_status_t>, + cell: Option featomic_status_t>, /// This function should compute the neighbor list with the given cutoff, /// and store it for later access using `pairs` or `pairs_containing`. - compute_neighbors: Option featomic_status_t>, + compute_neighbors: Option featomic_status_t>, /// This function should set `*pairs` to a pointer to the first element of a /// contiguous array containing all pairs in this system; and `*count` to /// the size of the array/the number of pairs. @@ -94,7 +94,7 @@ pub struct featomic_system_t { /// contains pairs where the distance between atoms is actually bellow the /// cutoff passed in the last call to `compute_neighbors`. This function is /// only valid to call after a call to `compute_neighbors`. - pairs: Option featomic_status_t>, + pairs: Option featomic_status_t>, /// This function should set `*pairs` to a pointer to the first element of a /// contiguous array containing all pairs in this system containing the atom /// with index `atom`; and `*count` to the size of the array/the number of @@ -104,7 +104,7 @@ pub struct featomic_system_t { /// applies, with the additional condition that the pair `i-j` should be /// included both in the return of `pairs_containing(i)` and /// `pairs_containing(j)`. - pairs_containing: Option featomic_status_t>, + pairs_containing: Option featomic_status_t>, } unsafe impl Send for featomic_system_t {} @@ -320,28 +320,28 @@ impl System for &mut featomic_system_t { /// Convert a Simple System to a `featomic_system_t` impl From for featomic_system_t { fn from(system: SimpleSystem) -> featomic_system_t { - unsafe extern fn size(this: *const c_void, size: *mut usize) -> featomic_status_t { + unsafe extern "C" fn size(this: *const c_void, size: *mut usize) -> featomic_status_t { catch_unwind(|| { *size = (*this.cast::()).size()?; Ok(()) }) } - unsafe extern fn types(this: *const c_void, types: *mut *const i32) -> featomic_status_t { + unsafe extern "C" fn types(this: *const c_void, types: *mut *const i32) -> featomic_status_t { catch_unwind(|| { *types = (*this.cast::()).types()?.as_ptr(); Ok(()) }) } - unsafe extern fn positions(this: *const c_void, positions: *mut *const f64) -> featomic_status_t { + unsafe extern "C" fn positions(this: *const c_void, positions: *mut *const f64) -> featomic_status_t { catch_unwind(|| { *positions = (*this.cast::()).positions()?.as_ptr().cast(); Ok(()) }) } - unsafe extern fn cell(this: *const c_void, cell: *mut f64) -> featomic_status_t { + unsafe extern "C" fn cell(this: *const c_void, cell: *mut f64) -> featomic_status_t { catch_unwind(|| { let matrix = (*this.cast::()).cell()?.matrix(); cell.add(0).write(matrix[0][0]); @@ -360,7 +360,7 @@ impl From for featomic_system_t { }) } - unsafe extern fn compute_neighbors(this: *mut c_void, cutoff: f64) -> featomic_status_t { + unsafe extern "C" fn compute_neighbors(this: *mut c_void, cutoff: f64) -> featomic_status_t { catch_unwind(|| { (*this.cast::()).compute_neighbors(cutoff)?; @@ -368,7 +368,7 @@ impl From for featomic_system_t { }) } - unsafe extern fn pairs( + unsafe extern "C" fn pairs( this: *const c_void, pairs: *mut *const featomic_pair_t, count: *mut usize, @@ -382,7 +382,7 @@ impl From for featomic_system_t { }) } - unsafe extern fn pairs_containing( + unsafe extern "C" fn pairs_containing( this: *const c_void, atom: usize, pairs: *mut *const featomic_pair_t, diff --git a/featomic/src/lib.rs b/featomic/src/lib.rs index 72e11435c..87bf6ee5d 100644 --- a/featomic/src/lib.rs +++ b/featomic/src/lib.rs @@ -11,6 +11,7 @@ #![allow(clippy::cast_possible_truncation, clippy::cast_precision_loss)] #![allow(clippy::cast_possible_wrap, clippy::cast_lossless, clippy::cast_sign_loss)] #![allow(clippy::default_trait_access, clippy::empty_line_after_doc_comments)] +#![allow(clippy::doc_overindented_list_items)] // Tests lints #![cfg_attr(test, allow(clippy::float_cmp))] diff --git a/featomic/src/math/hyp2f1.rs b/featomic/src/math/hyp2f1.rs index bedb1476e..17e61fcb8 100644 --- a/featomic/src/math/hyp2f1.rs +++ b/featomic/src/math/hyp2f1.rs @@ -238,7 +238,7 @@ pub fn hyp2f1(a: f64, b: f64, c: f64, mut x: f64) -> f64 { previous = result; } result += c0 + c1; - }; + } } else { let (a0, a, b, ) = if c > a && c < a * 2.0 && c > b && c < b * 2.0 { let a0 = (1.0 - x).powf(c - a - b); diff --git a/python/Cargo.toml b/python/Cargo.toml index b406d8912..2db48a4dd 100644 --- a/python/Cargo.toml +++ b/python/Cargo.toml @@ -10,7 +10,7 @@ test = false doctest = false [dev-dependencies] -which = "5" +which = "7" [lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tarpaulin)'] }