From 44a03f55519addb5d3ef4ccbb72bf25beee634de Mon Sep 17 00:00:00 2001 From: Anthony Scemama Date: Wed, 18 Oct 2023 15:25:57 +0200 Subject: [PATCH] Updated formatting --- README.md | 2 +- rust/trexio/Cargo.toml | 2 + rust/trexio/Makefile | 10 ++ rust/trexio/build.rs | 2 - rust/trexio/src/back_end.rs | 38 ++++--- rust/trexio/src/bitfield.rs | 89 ++++++++------- rust/trexio/src/exit_code.rs | 175 +++++++++++++++--------------- rust/trexio/src/lib.rs | 132 +++++++++++++---------- rust/trexio/tests/read_write.rs | 186 ++++++++++++++++++-------------- 9 files changed, 349 insertions(+), 287 deletions(-) create mode 100644 rust/trexio/Makefile diff --git a/README.md b/README.md index 4073fd8..5e16e3b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![build](https://github.com/TREX-CoE/trexio/actions/workflows/actions.yml/badge.svg)](https://github.com/TREX-CoE/trexio/actions/workflows/actions.yml) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/TREX-CoE/trexio) -TREXIO is an open-source file format and library developed for the storage and manipulation of data produced by quantum chemistry calculations. It is designed with the goal of providing a reliable and efficient method of storing and exchanging wave function parameters and matrix elements, making it an important tool for researchers in the field of quantum chemistry. In this work, we present an overview of the TREXIO file format and library. The library consists of a front-end implemented in the C programming language and two different back-ends: a text back-end and a binary back-end utilizing the HDF5 library which enables fast read and write operations. It is compatible with a variety of platforms and has interfaces for the Fortran, Python, and OCaml programming languages. In addition, a suite of tools has been developed to facilitate the use of the TREXIO format and library, including converters for popular quantum chemistry codes and utilities for validating and manipulating data stored in TREXIO files. The simplicity, versatility, and ease of use of TREXIO make it a valuable resource for researchers working with quantum chemistry data. +TREXIO is an open-source file format and library developed for the storage and manipulation of data produced by quantum chemistry calculations. It is designed with the goal of providing a reliable and efficient method of storing and exchanging wave function parameters and matrix elements, making it an important tool for researchers in the field of quantum chemistry. The library consists of a front-end implemented in the C programming language and two different back-ends: a text back-end and a binary back-end utilizing the HDF5 library which enables fast read and write operations. It is compatible with a variety of platforms and has interfaces for the Fortran, Python, OCaml and Rust programming languages. ## Minimal requirements (for users): diff --git a/rust/trexio/Cargo.toml b/rust/trexio/Cargo.toml index 483c15f..758c86f 100644 --- a/rust/trexio/Cargo.toml +++ b/rust/trexio/Cargo.toml @@ -2,6 +2,8 @@ name = "trexio" version = "2.4.0" edition = "2021" +license = "BSD-3-Clause" +description = "TREXIO is an open-source file format and library developed for the storage and manipulation of data produced by quantum chemistry calculations. It is designed with the goal of providing a reliable and efficient method of storing and exchanging wave function parameters and matrix elements." # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/rust/trexio/Makefile b/rust/trexio/Makefile new file mode 100644 index 0000000..cd8509b --- /dev/null +++ b/rust/trexio/Makefile @@ -0,0 +1,10 @@ +default: src/generated.rs + cargo build + cargo test + +generated.rs: build.py + python3 build.py + +test: default + - cargo test -- --show-output + diff --git a/rust/trexio/build.rs b/rust/trexio/build.rs index adf0e0b..52e604c 100644 --- a/rust/trexio/build.rs +++ b/rust/trexio/build.rs @@ -32,6 +32,4 @@ fn main() { bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings!"); - } - diff --git a/rust/trexio/src/back_end.rs b/rust/trexio/src/back_end.rs index e1e4ba4..6349b88 100644 --- a/rust/trexio/src/back_end.rs +++ b/rust/trexio/src/back_end.rs @@ -1,37 +1,35 @@ use crate::c; -#[derive(Debug)] -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum BackEnd { - /// The TREXIO "file" is a directory with text files for each group. - /// A fallback when HDF5 is not available. - Text, + /// The TREXIO "file" is a directory with text files for each group. + /// A fallback when HDF5 is not available. + Text, - /// Should be used for production. The TREXIO file is a single HDF5 file. - Hdf5, + /// Should be used for production. The TREXIO file is a single HDF5 file. + Hdf5, - /// Automatic discovery of the appropriate backend - Auto, + /// Automatic discovery of the appropriate backend + Auto, } impl BackEnd { - /// Creation from a C value - pub fn from(b : c::back_end_t) -> Self { - match b { - c::TREXIO_TEXT => Self::Text, - c::TREXIO_HDF5 => Self::Hdf5, - c::TREXIO_AUTO => Self::Auto, - _ => panic!("Invalid backend"), - } + pub fn from(b: c::back_end_t) -> Self { + match b { + c::TREXIO_TEXT => Self::Text, + c::TREXIO_HDF5 => Self::Hdf5, + c::TREXIO_AUTO => Self::Auto, + _ => panic!("Invalid backend"), + } } /// Conversion to a C value pub fn to_c(self) -> c::back_end_t { match self { - Self::Text => c::TREXIO_TEXT, - Self::Hdf5 => c::TREXIO_HDF5, - Self::Auto => c::TREXIO_AUTO, + Self::Text => c::TREXIO_TEXT, + Self::Hdf5 => c::TREXIO_HDF5, + Self::Auto => c::TREXIO_AUTO, } } } diff --git a/rust/trexio/src/bitfield.rs b/rust/trexio/src/bitfield.rs index 54ee6d3..de722f8 100644 --- a/rust/trexio/src/bitfield.rs +++ b/rust/trexio/src/bitfield.rs @@ -1,5 +1,4 @@ -#[derive(Debug)] -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub struct Bitfield { data: Vec, } @@ -8,21 +7,20 @@ use crate::c; use crate::ExitCode; impl Bitfield { - /// Creates a new bitfield , using a number of i64 elements consistent /// with the number of MOs in the TREXIO file. pub fn from(n_int: usize, orb_list: &[usize]) -> (Self, f64) { - let orb_list: Vec = orb_list.iter().map(|&x| x as i32).collect(); - let occ_num = orb_list.len().try_into().expect("try_into failed in Bitfield::from"); + let occ_num = orb_list + .len() + .try_into() + .expect("try_into failed in Bitfield::from"); let orb_list_ptr = orb_list.as_ptr() as *const i32; let n_int32: i32 = n_int.try_into().expect("try_into failed in Bitfield::from"); - let mut b = vec![0i64 ; n_int]; + let mut b = vec![0i64; n_int]; let bit_list = b.as_mut_ptr() as *mut c::bitfield_t; std::mem::forget(b); - let rc = unsafe { - c::trexio_to_bitfield_list(orb_list_ptr, occ_num, bit_list, n_int32) - }; + let rc = unsafe { c::trexio_to_bitfield_list(orb_list_ptr, occ_num, bit_list, n_int32) }; let data = unsafe { Vec::from_raw_parts(bit_list, n_int, n_int) }; @@ -30,8 +28,8 @@ impl Bitfield { match ExitCode::from(rc) { ExitCode::Success => (result, 1.0), - ExitCode::PhaseChange=> (result,-1.0), - x => panic!("TREXIO Error {}", x) + ExitCode::PhaseChange => (result, -1.0), + x => panic!("TREXIO Error {}", x), } } @@ -50,14 +48,18 @@ impl Bitfield { /// Returns the alpha part pub fn alpha(&self) -> Bitfield { - let n_int = self.data.len()/2; - Bitfield { data: (&self.data[0..n_int]).to_vec() } + let n_int = self.data.len() / 2; + Bitfield { + data: (&self.data[0..n_int]).to_vec(), + } } /// Returns the beta part pub fn beta(&self) -> Bitfield { - let n_int = self.data.len()/2; - Bitfield { data: (&self.data[n_int..2*n_int]).to_vec() } + let n_int = self.data.len() / 2; + Bitfield { + data: (&self.data[n_int..2 * n_int]).to_vec(), + } } /// Converts to a format usable in the C library @@ -76,20 +78,23 @@ impl Bitfield { /// Converts the bitfield into a list of orbital indices (0-based) pub fn to_orbital_list(&self) -> Vec { - - let n_int : i32 = self.data.len().try_into().expect("try_into failed in to_orbital_list"); + let n_int: i32 = self + .data + .len() + .try_into() + .expect("try_into failed in to_orbital_list"); let d1 = self.as_ptr(); let cap = self.data.len() * 64; - let mut list = vec![ 0i32 ; cap ]; + let mut list = vec![0i32; cap]; let list_c = list.as_mut_ptr() as *mut i32; std::mem::forget(list); - let mut occ_num : i32 = 0; + let mut occ_num: i32 = 0; let rc = unsafe { c::trexio_to_orbital_list(n_int, d1, list_c, &mut occ_num) }; match ExitCode::from(rc) { ExitCode::Success => (), - x => panic!("TREXIO Error {}", x) + x => panic!("TREXIO Error {}", x), }; let occ_num = occ_num as usize; @@ -97,7 +102,7 @@ impl Bitfield { let mut result: Vec = Vec::with_capacity(occ_num); for i in list.iter() { - result.push( *i as usize ); + result.push(*i as usize); } result } @@ -109,24 +114,34 @@ impl Bitfield { /// Converts the determinant into a list of orbital indices (0-based) pub fn to_orbital_list_up_dn(&self) -> (Vec, Vec) { - - let n_int : i32 = (self.data.len()/2).try_into().expect("try_into failed in to_orbital_list"); + let n_int: i32 = (self.data.len() / 2) + .try_into() + .expect("try_into failed in to_orbital_list"); let d1 = self.as_ptr(); - let cap = self.data.len()/2 * 64; - let mut b = vec![ 0i32 ; cap ]; + let cap = self.data.len() / 2 * 64; + let mut b = vec![0i32; cap]; let list_up_c = b.as_mut_ptr() as *mut i32; std::mem::forget(b); - let mut b = vec![ 0i32 ; cap ]; + let mut b = vec![0i32; cap]; let list_dn_c = b.as_mut_ptr() as *mut i32; std::mem::forget(b); - let mut occ_num_up : i32 = 0; - let mut occ_num_dn : i32 = 0; + let mut occ_num_up: i32 = 0; + let mut occ_num_dn: i32 = 0; - let rc = unsafe { c::trexio_to_orbital_list_up_dn(n_int, d1, list_up_c, list_dn_c, &mut occ_num_up, &mut occ_num_dn) }; + let rc = unsafe { + c::trexio_to_orbital_list_up_dn( + n_int, + d1, + list_up_c, + list_dn_c, + &mut occ_num_up, + &mut occ_num_dn, + ) + }; match ExitCode::from(rc) { ExitCode::Success => (), - x => panic!("TREXIO Error {}", x) + x => panic!("TREXIO Error {}", x), }; let occ_num_up = occ_num_up as usize; @@ -136,26 +151,23 @@ impl Bitfield { let mut result_up: Vec = Vec::with_capacity(occ_num_up); for i in list_up.iter() { - result_up.push( *i as usize ); + result_up.push(*i as usize); } let mut result_dn: Vec = Vec::with_capacity(occ_num_dn); for i in list_dn.iter() { - result_dn.push( *i as usize ); + result_dn.push(*i as usize); } (result_up, result_dn) } - } - #[cfg(test)] mod tests { use super::*; #[test] fn creation_from_list() { - let list0 = vec![0, 1, 2, 3, 4]; let list1 = vec![0, 1, 2, 4, 3]; let list2 = vec![0, 1, 4, 2, 3]; @@ -173,16 +185,15 @@ mod tests { let list = alpha2.to_orbital_list(); assert_eq!(list, list0); assert_eq!(phase2, phase0); - } #[test] fn creation_alpha_beta() { let (alpha, _) = Bitfield::from(2, &[0, 1, 2, 3, 4]); - let (beta , _) = Bitfield::from(2, &[0, 1, 2, 4, 5]); + let (beta, _) = Bitfield::from(2, &[0, 1, 2, 4, 5]); let det = Bitfield::from_alpha_beta(&alpha, &beta); let list = det.to_orbital_list(); - assert_eq!(list, [0,1,2,3,4,128,129,130,132,133]); + assert_eq!(list, [0, 1, 2, 3, 4, 128, 129, 130, 132, 133]); assert_eq!(det.alpha(), alpha); assert_eq!(det.beta(), beta); } @@ -191,7 +202,7 @@ mod tests { #[should_panic] fn creation_alpha_beta_with_different_nint() { let (alpha, _) = Bitfield::from(1, &[0, 1, 2, 3, 4]); - let (beta , _) = Bitfield::from(2, &[0, 1, 2, 4, 5]); + let (beta, _) = Bitfield::from(2, &[0, 1, 2, 4, 5]); let _ = Bitfield::from_alpha_beta(&alpha, &beta); } } diff --git a/rust/trexio/src/exit_code.rs b/rust/trexio/src/exit_code.rs index 60a7240..dce0467 100644 --- a/rust/trexio/src/exit_code.rs +++ b/rust/trexio/src/exit_code.rs @@ -1,7 +1,6 @@ use crate::c; -#[derive(Debug)] -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] pub enum ExitCode { /// Unknown failure Failure, @@ -98,115 +97,113 @@ pub enum ExitCode { /// The function succeeded with a change of sign PhaseChange, - } impl ExitCode { - /// Creation from a C value - pub fn from(rc : c::trexio_exit_code) -> Self { + pub fn from(rc: c::trexio_exit_code) -> Self { match rc { - c::TREXIO_FAILURE => Self::Failure, - c::TREXIO_SUCCESS => Self::Success, - c::TREXIO_INVALID_ARG_1 => Self::InvalidArg(1), - c::TREXIO_INVALID_ARG_2 => Self::InvalidArg(2), - c::TREXIO_INVALID_ARG_3 => Self::InvalidArg(3), - c::TREXIO_INVALID_ARG_4 => Self::InvalidArg(4), - c::TREXIO_INVALID_ARG_5 => Self::InvalidArg(5), - c::TREXIO_END => Self::End, - c::TREXIO_READONLY => Self::ReadOnly, - c::TREXIO_ERRNO => Self::Errno, - c::TREXIO_INVALID_ID => Self::InvalidId, - c::TREXIO_ALLOCATION_FAILED => Self::AllocationFailed, - c::TREXIO_HAS_NOT => Self::HasNot, - c::TREXIO_INVALID_NUM => Self::InvalidNum, - c::TREXIO_ATTR_ALREADY_EXISTS => Self::AttrAlreadyExists, - c::TREXIO_DSET_ALREADY_EXISTS => Self::DsetAlreadyExists, - c::TREXIO_OPEN_ERROR => Self::OpenError, - c::TREXIO_LOCK_ERROR => Self::LockError, - c::TREXIO_UNLOCK_ERROR => Self::UnlockError, - c::TREXIO_FILE_ERROR => Self::FileError, - c::TREXIO_GROUP_READ_ERROR => Self::GroupReadError, - c::TREXIO_GROUP_WRITE_ERROR => Self::GroupWriteError, - c::TREXIO_ELEM_READ_ERROR => Self::ElemReadError, - c::TREXIO_ELEM_WRITE_ERROR => Self::ElemWriteError, - c::TREXIO_UNSAFE_ARRAY_DIM => Self::UnsafeArrayDim, - c::TREXIO_ATTR_MISSING => Self::AttrMissing, - c::TREXIO_DSET_MISSING => Self::DsetMissing, - c::TREXIO_BACK_END_MISSING => Self::BackEndMissing, - c::TREXIO_INVALID_ARG_6 => Self::InvalidArg(6), - c::TREXIO_INVALID_ARG_7 => Self::InvalidArg(7), - c::TREXIO_INVALID_ARG_8 => Self::InvalidArg(8), - c::TREXIO_INVALID_STR_LEN => Self::InvalidStrLen, - c::TREXIO_INT_SIZE_OVERFLOW => Self::IntSizeOverflow, - c::TREXIO_SAFE_MODE => Self::SafeMode, - c::TREXIO_INVALID_ELECTRON_NUM => Self::InvalidElectronNum, - c::TREXIO_INVALID_DETERMINANT_NUM => Self::InvalidDeterminantNum, - c::TREXIO_INVALID_STATE => Self::InvalidState, - c::TREXIO_VERSION_PARSING_ISSUE => Self::VersionParsingIssue, - c::TREXIO_PHASE_CHANGE => Self::PhaseChange, - _ => panic!("Unknown exit code"), + c::TREXIO_FAILURE => Self::Failure, + c::TREXIO_SUCCESS => Self::Success, + c::TREXIO_INVALID_ARG_1 => Self::InvalidArg(1), + c::TREXIO_INVALID_ARG_2 => Self::InvalidArg(2), + c::TREXIO_INVALID_ARG_3 => Self::InvalidArg(3), + c::TREXIO_INVALID_ARG_4 => Self::InvalidArg(4), + c::TREXIO_INVALID_ARG_5 => Self::InvalidArg(5), + c::TREXIO_END => Self::End, + c::TREXIO_READONLY => Self::ReadOnly, + c::TREXIO_ERRNO => Self::Errno, + c::TREXIO_INVALID_ID => Self::InvalidId, + c::TREXIO_ALLOCATION_FAILED => Self::AllocationFailed, + c::TREXIO_HAS_NOT => Self::HasNot, + c::TREXIO_INVALID_NUM => Self::InvalidNum, + c::TREXIO_ATTR_ALREADY_EXISTS => Self::AttrAlreadyExists, + c::TREXIO_DSET_ALREADY_EXISTS => Self::DsetAlreadyExists, + c::TREXIO_OPEN_ERROR => Self::OpenError, + c::TREXIO_LOCK_ERROR => Self::LockError, + c::TREXIO_UNLOCK_ERROR => Self::UnlockError, + c::TREXIO_FILE_ERROR => Self::FileError, + c::TREXIO_GROUP_READ_ERROR => Self::GroupReadError, + c::TREXIO_GROUP_WRITE_ERROR => Self::GroupWriteError, + c::TREXIO_ELEM_READ_ERROR => Self::ElemReadError, + c::TREXIO_ELEM_WRITE_ERROR => Self::ElemWriteError, + c::TREXIO_UNSAFE_ARRAY_DIM => Self::UnsafeArrayDim, + c::TREXIO_ATTR_MISSING => Self::AttrMissing, + c::TREXIO_DSET_MISSING => Self::DsetMissing, + c::TREXIO_BACK_END_MISSING => Self::BackEndMissing, + c::TREXIO_INVALID_ARG_6 => Self::InvalidArg(6), + c::TREXIO_INVALID_ARG_7 => Self::InvalidArg(7), + c::TREXIO_INVALID_ARG_8 => Self::InvalidArg(8), + c::TREXIO_INVALID_STR_LEN => Self::InvalidStrLen, + c::TREXIO_INT_SIZE_OVERFLOW => Self::IntSizeOverflow, + c::TREXIO_SAFE_MODE => Self::SafeMode, + c::TREXIO_INVALID_ELECTRON_NUM => Self::InvalidElectronNum, + c::TREXIO_INVALID_DETERMINANT_NUM => Self::InvalidDeterminantNum, + c::TREXIO_INVALID_STATE => Self::InvalidState, + c::TREXIO_VERSION_PARSING_ISSUE => Self::VersionParsingIssue, + c::TREXIO_PHASE_CHANGE => Self::PhaseChange, + _ => panic!("Unknown exit code"), } } /// Conversion to a C value - pub fn to_c(&self) -> c::trexio_exit_code { + pub fn to_c(&self) -> c::trexio_exit_code { match self { - Self::Failure => c::TREXIO_FAILURE, - Self::Success => c::TREXIO_SUCCESS, - Self::InvalidArg(1) => c::TREXIO_INVALID_ARG_1, - Self::InvalidArg(2) => c::TREXIO_INVALID_ARG_2, - Self::InvalidArg(3) => c::TREXIO_INVALID_ARG_3, - Self::InvalidArg(4) => c::TREXIO_INVALID_ARG_4, - Self::InvalidArg(5) => c::TREXIO_INVALID_ARG_5, - Self::End => c::TREXIO_END, - Self::ReadOnly => c::TREXIO_READONLY, - Self::Errno => c::TREXIO_ERRNO, - Self::InvalidId => c::TREXIO_INVALID_ID, - Self::AllocationFailed => c::TREXIO_ALLOCATION_FAILED, - Self::HasNot => c::TREXIO_HAS_NOT, - Self::InvalidNum => c::TREXIO_INVALID_NUM, - Self::AttrAlreadyExists => c::TREXIO_ATTR_ALREADY_EXISTS, - Self::DsetAlreadyExists => c::TREXIO_DSET_ALREADY_EXISTS, - Self::OpenError => c::TREXIO_OPEN_ERROR, - Self::LockError => c::TREXIO_LOCK_ERROR, - Self::UnlockError => c::TREXIO_UNLOCK_ERROR, - Self::FileError => c::TREXIO_FILE_ERROR, - Self::GroupReadError => c::TREXIO_GROUP_READ_ERROR, - Self::GroupWriteError => c::TREXIO_GROUP_WRITE_ERROR, - Self::ElemReadError => c::TREXIO_ELEM_READ_ERROR, - Self::ElemWriteError => c::TREXIO_ELEM_WRITE_ERROR, - Self::UnsafeArrayDim => c::TREXIO_UNSAFE_ARRAY_DIM, - Self::AttrMissing => c::TREXIO_ATTR_MISSING, - Self::DsetMissing => c::TREXIO_DSET_MISSING, - Self::BackEndMissing => c::TREXIO_BACK_END_MISSING, - Self::InvalidArg(6) => c::TREXIO_INVALID_ARG_6, - Self::InvalidArg(7) => c::TREXIO_INVALID_ARG_7, - Self::InvalidArg(8) => c::TREXIO_INVALID_ARG_8, - Self::InvalidStrLen => c::TREXIO_INVALID_STR_LEN, - Self::IntSizeOverflow => c::TREXIO_INT_SIZE_OVERFLOW, - Self::SafeMode => c::TREXIO_SAFE_MODE, - Self::InvalidElectronNum => c::TREXIO_INVALID_ELECTRON_NUM, - Self::InvalidDeterminantNum => c::TREXIO_INVALID_DETERMINANT_NUM, - Self::InvalidState => c::TREXIO_INVALID_STATE, - Self::VersionParsingIssue => c::TREXIO_VERSION_PARSING_ISSUE, - Self::PhaseChange => c::TREXIO_PHASE_CHANGE, - _ => panic!("Unknown exit code"), + Self::Failure => c::TREXIO_FAILURE, + Self::Success => c::TREXIO_SUCCESS, + Self::InvalidArg(1) => c::TREXIO_INVALID_ARG_1, + Self::InvalidArg(2) => c::TREXIO_INVALID_ARG_2, + Self::InvalidArg(3) => c::TREXIO_INVALID_ARG_3, + Self::InvalidArg(4) => c::TREXIO_INVALID_ARG_4, + Self::InvalidArg(5) => c::TREXIO_INVALID_ARG_5, + Self::End => c::TREXIO_END, + Self::ReadOnly => c::TREXIO_READONLY, + Self::Errno => c::TREXIO_ERRNO, + Self::InvalidId => c::TREXIO_INVALID_ID, + Self::AllocationFailed => c::TREXIO_ALLOCATION_FAILED, + Self::HasNot => c::TREXIO_HAS_NOT, + Self::InvalidNum => c::TREXIO_INVALID_NUM, + Self::AttrAlreadyExists => c::TREXIO_ATTR_ALREADY_EXISTS, + Self::DsetAlreadyExists => c::TREXIO_DSET_ALREADY_EXISTS, + Self::OpenError => c::TREXIO_OPEN_ERROR, + Self::LockError => c::TREXIO_LOCK_ERROR, + Self::UnlockError => c::TREXIO_UNLOCK_ERROR, + Self::FileError => c::TREXIO_FILE_ERROR, + Self::GroupReadError => c::TREXIO_GROUP_READ_ERROR, + Self::GroupWriteError => c::TREXIO_GROUP_WRITE_ERROR, + Self::ElemReadError => c::TREXIO_ELEM_READ_ERROR, + Self::ElemWriteError => c::TREXIO_ELEM_WRITE_ERROR, + Self::UnsafeArrayDim => c::TREXIO_UNSAFE_ARRAY_DIM, + Self::AttrMissing => c::TREXIO_ATTR_MISSING, + Self::DsetMissing => c::TREXIO_DSET_MISSING, + Self::BackEndMissing => c::TREXIO_BACK_END_MISSING, + Self::InvalidArg(6) => c::TREXIO_INVALID_ARG_6, + Self::InvalidArg(7) => c::TREXIO_INVALID_ARG_7, + Self::InvalidArg(8) => c::TREXIO_INVALID_ARG_8, + Self::InvalidStrLen => c::TREXIO_INVALID_STR_LEN, + Self::IntSizeOverflow => c::TREXIO_INT_SIZE_OVERFLOW, + Self::SafeMode => c::TREXIO_SAFE_MODE, + Self::InvalidElectronNum => c::TREXIO_INVALID_ELECTRON_NUM, + Self::InvalidDeterminantNum => c::TREXIO_INVALID_DETERMINANT_NUM, + Self::InvalidState => c::TREXIO_INVALID_STATE, + Self::VersionParsingIssue => c::TREXIO_VERSION_PARSING_ISSUE, + Self::PhaseChange => c::TREXIO_PHASE_CHANGE, + _ => panic!("Unknown exit code"), } } pub fn to_str(&self) -> Result<&'static str, Utf8Error> { let c_error = self.to_c(); - let c_buf: *const c_char = unsafe { c::trexio_string_of_error( c_error ) }; + let c_buf: *const c_char = unsafe { c::trexio_string_of_error(c_error) }; let c_str: &CStr = unsafe { CStr::from_ptr(c_buf) }; c_str.to_str() } } -use std::fmt; use std::error::Error; -use std::ffi::CStr; use std::ffi::c_char; +use std::ffi::CStr; +use std::fmt; use std::str::Utf8Error; impl fmt::Display for ExitCode { diff --git a/rust/trexio/src/lib.rs b/rust/trexio/src/lib.rs index 298a802..492aa3a 100644 --- a/rust/trexio/src/lib.rs +++ b/rust/trexio/src/lib.rs @@ -1,12 +1,12 @@ -/// TREXIO is an open-source file format and library developed for the storage and manipulation of -/// data produced by quantum chemistry calculations. It was designed with the goal of providing a -/// reliable and efficient method of storing and exchanging wave function parameters and matrix -/// elements. -/// -/// For comprehensive documentation, consult: [TREXIO Documentation](https://trex-coe.github.io/trexio/) -/// -/// The C library source code is available on GitHub: [TREXIO GitHub Repository](https://github.com/trex-coe/trexio) -/// +//! TREXIO is an open-source file format and library developed for the storage and manipulation of +//! data produced by quantum chemistry calculations. It was designed with the goal of providing a +//! reliable and efficient method of storing and exchanging wave function parameters and matrix +//! elements. +//! +//! For comprehensive documentation, consult: [TREXIO Documentation](https://trex-coe.github.io/trexio/) +//! +//! The C library source code is available on GitHub: [TREXIO GitHub Repository](https://github.com/trex-coe/trexio) +//! use ::std::os::raw::c_char; @@ -16,6 +16,7 @@ mod c; /// These error codes are mapped to those defined in the original C TREXIO library. pub mod exit_code; pub use exit_code::ExitCode; +use exit_code::ExitCode::InvalidArg; /// Enum representing the different backends that TREXIO can employ for data storage. pub mod back_end; @@ -26,14 +27,15 @@ pub mod bitfield; pub use bitfield::Bitfield; /// A constant string representing the package version of the linked C TREXIO library. -pub const PACKAGE_VERSION : &str = unsafe { std::str::from_utf8_unchecked(c::TREXIO_PACKAGE_VERSION) }; +pub const PACKAGE_VERSION: &str = + unsafe { std::str::from_utf8_unchecked(c::TREXIO_PACKAGE_VERSION) }; /// Utility function to convert Rust results into TREXIO exit codes. -fn rc_return(result: T, rc : c::trexio_exit_code) -> Result { +fn rc_return(result: T, rc: c::trexio_exit_code) -> Result { let rc = ExitCode::from(rc); match rc { ExitCode::Success => Ok(result), - x => Err(x) + x => Err(x), } } @@ -42,22 +44,18 @@ fn string_to_c(s: &str) -> std::ffi::CString { std::ffi::CString::new(s).unwrap() } - /// Function to print out diagnostic information about the linked C TREXIO library. -pub fn info() -> Result<(),ExitCode> { +pub fn info() -> Result<(), ExitCode> { let rc = unsafe { c::trexio_info() }; rc_return((), rc) } - /// Type representing a TREXIO file. Wraps a pointer to the underlying C structure. pub struct File { ptr: *mut c::trexio_t, } - impl File { - /// Opens a TREXIO file. Returns a `File` instance that can be used for subsequent I/O operations. /// /// # Parameters @@ -88,7 +86,6 @@ impl File { rc_return((), rc) } - /// Inquires if a file with the specified name exists. /// /// # Parameters @@ -107,7 +104,7 @@ impl File { match ExitCode::from(rc) { ExitCode::Failure => Ok(false), ExitCode::Success => Ok(true), - x => Err(x), + x => Err(x), } } @@ -157,11 +154,9 @@ impl File { /// otherwise returns `Err(ExitCode)`. pub fn get_int64_num(&self) -> Result { let mut num = 0i32; - let rc = unsafe { - c::trexio_get_int64_num(self.ptr, &mut num) - }; - let num:usize = num.try_into().expect("try_into failed in get_int64_num"); - rc_return(num, rc) + let rc = unsafe { c::trexio_get_int64_num(self.ptr, &mut num) }; + let num: usize = num.try_into().expect("try_into failed in get_int64_num"); + rc_return(num, rc) } /// Writes a vector of determinants, represented as [Bitfield] objects. @@ -175,27 +170,36 @@ impl File { /// /// * `Result<(), ExitCode>` - Returns `Ok(())` if the operation is successful, /// otherwise returns `Err(ExitCode)`. - pub fn write_determinant_list(&self, offset: usize, determinants: &[Bitfield]) -> Result<(), ExitCode> { + pub fn write_determinant_list( + &self, + offset: usize, + determinants: &[Bitfield], + ) -> Result<(), ExitCode> { let n_int = self.get_int64_num()?; match determinants.len() { 0 => return Ok(()), - _ => if determinants[0].as_vec().len() != 2*n_int { - return Err(exit_code::Invalid_Arg(3)) + _ => { + if determinants[0].as_vec().len() != 2 * n_int { + return Err(InvalidArg(3)); + } } }; - let offset: i64 = offset.try_into().expect("try_into failed in write_determinant_list"); - let buffer_size: i64 = determinants.len().try_into().expect("try_into failed in write_determinant_list"); + let offset: i64 = offset + .try_into() + .expect("try_into failed in write_determinant_list"); + let buffer_size: i64 = determinants + .len() + .try_into() + .expect("try_into failed in write_determinant_list"); let mut one_d_array: Vec = Vec::with_capacity(determinants.len() * n_int); for det in determinants.iter() { - for i in det.as_vec().iter() { - one_d_array.push(i.clone()); - } + for i in det.as_vec().iter() { + one_d_array.push(i.clone()); + } } let dset: *const i64 = one_d_array.as_ptr() as *const i64; - let rc = unsafe { - c::trexio_write_determinant_list(self.ptr, offset, buffer_size, dset) - }; - rc_return((), rc) + let rc = unsafe { c::trexio_write_determinant_list(self.ptr, offset, buffer_size, dset) }; + rc_return((), rc) } /// Reads a vector of determinants, represented as [Bitfield] objects. @@ -207,34 +211,50 @@ impl File { /// /// # Returns /// - /// * `Result, ExitCode>` - Returns the read determinants as `Ok(Vec)` + /// * `Result, ExitCode>` - Returns the read determinants as `Ok(Vec)` /// if the operation is successful, otherwise returns `Err(ExitCode)`. - pub fn read_determinant_list(&self, offset: usize, buffer_size: usize) -> Result, ExitCode> { + pub fn read_determinant_list( + &self, + offset: usize, + buffer_size: usize, + ) -> Result, ExitCode> { let n_int = self.get_int64_num()?; - let mut one_d_array: Vec = Vec::with_capacity(buffer_size * 2* n_int); + let mut one_d_array: Vec = Vec::with_capacity(buffer_size * 2 * n_int); let one_d_array_ptr = one_d_array.as_ptr() as *mut i64; let rc = unsafe { - let offset: i64 = offset.try_into().expect("try_into failed in read_determinant_list (offset)"); - let mut buffer_size_read: i64 = buffer_size.try_into().expect("try_into failed in read_determinant_list (buffer_size)"); - let rc = c::trexio_read_determinant_list(self.ptr, offset, &mut buffer_size_read, one_d_array_ptr); - let buffer_size_read: usize = buffer_size_read.try_into().expect("try_into failed in read_determinant_list (buffer_size)"); - one_d_array.set_len(n_int*2usize*buffer_size_read); + let offset: i64 = offset + .try_into() + .expect("try_into failed in read_determinant_list (offset)"); + let mut buffer_size_read: i64 = buffer_size + .try_into() + .expect("try_into failed in read_determinant_list (buffer_size)"); + let rc = c::trexio_read_determinant_list( + self.ptr, + offset, + &mut buffer_size_read, + one_d_array_ptr, + ); + let buffer_size_read: usize = buffer_size_read + .try_into() + .expect("try_into failed in read_determinant_list (buffer_size)"); + one_d_array.set_len(n_int * 2usize * buffer_size_read); match ExitCode::from(rc) { - ExitCode::End => ExitCode::to_c(&ExitCode::Success), - ExitCode::Success => { assert_eq!(buffer_size_read, buffer_size); rc } - _ => rc + ExitCode::End => ExitCode::to_c(&ExitCode::Success), + ExitCode::Success => { + assert_eq!(buffer_size_read, buffer_size); + rc + } + _ => rc, } }; - let result: Vec:: = one_d_array.chunks(2*n_int) - .collect::>() - .iter() - .map(|x| (Bitfield::from_vec(&x))) - .collect::>(); - rc_return(result, rc) + let result: Vec = one_d_array + .chunks(2 * n_int) + .collect::>() + .iter() + .map(|x| (Bitfield::from_vec(&x))) + .collect::>(); + rc_return(result, rc) } - } include!("generated.rs"); - - diff --git a/rust/trexio/tests/read_write.rs b/rust/trexio/tests/read_write.rs index fead812..ebdd88f 100644 --- a/rust/trexio/tests/read_write.rs +++ b/rust/trexio/tests/read_write.rs @@ -1,49 +1,49 @@ use trexio::back_end::BackEnd; use trexio::bitfield::Bitfield; - fn write(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> { - // Prepare data to be written let nucleus_num = 12; let state_id = 2; let charge = vec![6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1.0f64]; - let coord = vec![ [ 0.00000000f64, 1.39250319 , 0.00 ], - [ -1.20594314, 0.69625160 , 0.00 ], - [ -1.20594314, -0.69625160 , 0.00 ], - [ 0.00000000, -1.39250319 , 0.00 ], - [ 1.20594314, -0.69625160 , 0.00 ], - [ 1.20594314, 0.69625160 , 0.00 ], - [ -2.14171677, 1.23652075 , 0.00 ], - [ -2.14171677, -1.23652075 , 0.00 ], - [ 0.00000000, -2.47304151 , 0.00 ], - [ 2.14171677, -1.23652075 , 0.00 ], - [ 2.14171677, 1.23652075 , 0.00 ], - [ 0.00000000, 2.47304151 , 0.00 ]]; + let coord = vec![ + [0.00000000f64, 1.39250319, 0.00], + [-1.20594314, 0.69625160, 0.00], + [-1.20594314, -0.69625160, 0.00], + [0.00000000, -1.39250319, 0.00], + [1.20594314, -0.69625160, 0.00], + [1.20594314, 0.69625160, 0.00], + [-2.14171677, 1.23652075, 0.00], + [-2.14171677, -1.23652075, 0.00], + [0.00000000, -2.47304151, 0.00], + [2.14171677, -1.23652075, 0.00], + [2.14171677, 1.23652075, 0.00], + [0.00000000, 2.47304151, 0.00], + ]; let flat_coord = coord.into_iter().flatten().collect::>(); let mo_num = 150; let ao_num = 1000; let basis_shell_num = 24; let basis_nucleus_index: Vec = (0..24).collect(); - let label = vec![ "C", "Na", "C", "C 66", "C", - "C", "H 99", "Ru", "H", "H", "H", "H" ]; + let label = vec![ + "C", "Na", "C", "C 66", "C", "C", "H 99", "Ru", "H", "H", "H", "H", + ]; let sym_str = "B3U with some comments"; - println!("Write {}", file_name); - assert!( ! trexio::File::inquire(file_name)? ); + assert!(!trexio::File::inquire(file_name)?); let trex_file = trexio::File::open(file_name, 'w', back_end)?; - assert!( ! trex_file.has_nucleus()? ); - assert!( ! trex_file.has_nucleus_num()? ); - assert!( ! trex_file.has_nucleus_charge()? ); - assert!( ! trex_file.has_ao_2e_int()? ); - assert!( ! trex_file.has_ao_2e_int_eri()? ); - assert!( ! trex_file.has_determinant_list()? ); + assert!(!trex_file.has_nucleus()?); + assert!(!trex_file.has_nucleus_num()?); + assert!(!trex_file.has_nucleus_charge()?); + assert!(!trex_file.has_ao_2e_int()?); + assert!(!trex_file.has_ao_2e_int_eri()?); + assert!(!trex_file.has_determinant_list()?); trex_file.write_nucleus_num(nucleus_num)?; trex_file.write_nucleus_charge(&charge)?; @@ -54,84 +54,80 @@ fn write(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> { trex_file.write_basis_nucleus_index(&basis_nucleus_index)?; trex_file.write_state_id(state_id)?; - if ! trex_file.has_ao_num()? { + if !trex_file.has_ao_num()? { trex_file.write_ao_num(ao_num)?; } - if ! trex_file.has_mo_num()? { + if !trex_file.has_mo_num()? { trex_file.write_mo_num(mo_num)?; } let mut energy = Vec::with_capacity(mo_num); for i in 0..mo_num { - let e: f64 = i as f64 -100.0f64; + let e: f64 = i as f64 - 100.0f64; energy.push(e); } trex_file.write_mo_energy(&energy)?; - let mut spin = vec![0 ; mo_num]; - for i in mo_num/2..mo_num { + let mut spin = vec![0; mo_num]; + for i in mo_num / 2..mo_num { spin[i] = 1; } trex_file.write_mo_spin(&spin)?; // Integrals let nmax = 100; - let mut ao_2e_int_eri = Vec::<(usize,usize,usize,usize,f64)>::with_capacity(nmax); + let mut ao_2e_int_eri = Vec::<(usize, usize, usize, usize, f64)>::with_capacity(nmax); let n_buffers = 5; - let bufsize = nmax/n_buffers; + let bufsize = nmax / n_buffers; for i in 0..100 { // Quadruplet of indices + value - let data = (4*i, 4*i+1, 4*i+2, 4*i+3, 3.14 + (i as f64)); + let data = (4 * i, 4 * i + 1, 4 * i + 2, 4 * i + 3, 3.14 + (i as f64)); ao_2e_int_eri.push(data); } let mut offset = 0; for _ in 0..n_buffers { - trex_file.write_ao_2e_int_eri(offset, &ao_2e_int_eri[offset..offset+bufsize])?; + trex_file.write_ao_2e_int_eri(offset, &ao_2e_int_eri[offset..offset + bufsize])?; offset += bufsize; } - // Determinants let det_num = 50; let mut det_list = Vec::with_capacity(det_num); for i in 0..det_num { - let mut d = [0i64 ; 6 ]; + let mut d = [0i64; 6]; for j in 0..6 { - d[j] = 6*(i as i64)+(j as i64); + d[j] = 6 * (i as i64) + (j as i64); } - det_list.push( Bitfield::from_vec(&d) ); + det_list.push(Bitfield::from_vec(&d)); } let n_buffers = 5; - let bufsize = 50/n_buffers; + let bufsize = 50 / n_buffers; let mut offset = 0; for _ in 0..n_buffers { - trex_file.write_determinant_list(offset, &det_list[offset..offset+bufsize])?; + trex_file.write_determinant_list(offset, &det_list[offset..offset + bufsize])?; offset += bufsize; } - trex_file.close() - } fn read(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> { - println!("Read {}", file_name); - assert!( trexio::File::inquire(file_name)? ); + assert!(trexio::File::inquire(file_name)?); let trex_file = trexio::File::open(file_name, 'r', back_end)?; - assert!( trex_file.has_nucleus()? ); - assert!( trex_file.has_nucleus_num()? ); - assert!( trex_file.has_nucleus_charge()? ); - assert!( trex_file.has_ao_2e_int()? ); - assert!( trex_file.has_ao_2e_int_eri()? ); - assert!( trex_file.has_determinant_list()? ); + assert!(trex_file.has_nucleus()?); + assert!(trex_file.has_nucleus_num()?); + assert!(trex_file.has_nucleus_charge()?); + assert!(trex_file.has_ao_2e_int()?); + assert!(trex_file.has_ao_2e_int_eri()?); + assert!(trex_file.has_determinant_list()?); let nucleus_num = trex_file.read_nucleus_num()?; assert_eq!(nucleus_num, 12); @@ -140,31 +136,65 @@ fn read(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> { assert_eq!(sym_str, "B3U with some comments"); let charge = trex_file.read_nucleus_charge()?; - assert_eq!(charge, vec![6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1.0f64]); + assert_eq!( + charge, + vec![6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1.0f64] + ); let coord = trex_file.read_nucleus_coord()?; - assert_eq!(coord, vec![ 0.00000000f64, 1.39250319 , 0.00, - -1.20594314, 0.69625160 , 0.00, - -1.20594314, -0.69625160 , 0.00, - 0.00000000, -1.39250319 , 0.00, - 1.20594314, -0.69625160 , 0.00, - 1.20594314, 0.69625160 , 0.00, - -2.14171677, 1.23652075 , 0.00, - -2.14171677, -1.23652075 , 0.00, - 0.00000000, -2.47304151 , 0.00, - 2.14171677, -1.23652075 , 0.00, - 2.14171677, 1.23652075 , 0.00, - 0.00000000, 2.47304151 , 0.00 ]); + assert_eq!( + coord, + vec![ + 0.00000000f64, + 1.39250319, + 0.00, + -1.20594314, + 0.69625160, + 0.00, + -1.20594314, + -0.69625160, + 0.00, + 0.00000000, + -1.39250319, + 0.00, + 1.20594314, + -0.69625160, + 0.00, + 1.20594314, + 0.69625160, + 0.00, + -2.14171677, + 1.23652075, + 0.00, + -2.14171677, + -1.23652075, + 0.00, + 0.00000000, + -2.47304151, + 0.00, + 2.14171677, + -1.23652075, + 0.00, + 2.14171677, + 1.23652075, + 0.00, + 0.00000000, + 2.47304151, + 0.00 + ] + ); let label = trex_file.read_nucleus_label(6)?; - assert_eq!(label, vec![ "C", "Na", "C", "C 66", "C", - "C", "H 99", "Ru", "H", "H", "H", "H" ]); + assert_eq!( + label, + vec!["C", "Na", "C", "C 66", "C", "C", "H 99", "Ru", "H", "H", "H", "H"] + ); let basis_shell_num = trex_file.read_basis_shell_num()?; assert_eq!(basis_shell_num, 24); let basis_nucleus_index = trex_file.read_basis_nucleus_index()?; - let ref_val : Vec = (0..24).collect(); + let ref_val: Vec = (0..24).collect(); assert_eq!(basis_nucleus_index, ref_val); let state_id = trex_file.read_state_id()?; @@ -178,14 +208,14 @@ fn read(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> { let mut energy_ref = Vec::with_capacity(mo_num); for i in 0..mo_num { - let e: f64 = i as f64 -100.0f64; + let e: f64 = i as f64 - 100.0f64; energy_ref.push(e); } let energy = trex_file.read_mo_energy()?; assert_eq!(energy, energy_ref); - let mut spin_ref = vec![0 ; mo_num]; - for i in mo_num/2..mo_num { + let mut spin_ref = vec![0; mo_num]; + for i in mo_num / 2..mo_num { spin_ref[i] = 1; } let spin = trex_file.read_mo_spin()?; @@ -193,19 +223,19 @@ fn read(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> { // Integrals let nmax = 100; - let mut ao_2e_int_eri_ref = Vec::<(usize,usize,usize,usize,f64)>::with_capacity(nmax); + let mut ao_2e_int_eri_ref = Vec::<(usize, usize, usize, usize, f64)>::with_capacity(nmax); let n_buffers = 8; - let bufsize = nmax/n_buffers+10; + let bufsize = nmax / n_buffers + 10; for i in 0..100 { // Quadruplet of indices + value - let data = (4*i, 4*i+1, 4*i+2, 4*i+3, 3.14 + (i as f64)); + let data = (4 * i, 4 * i + 1, 4 * i + 2, 4 * i + 3, 3.14 + (i as f64)); ao_2e_int_eri_ref.push(data); } let mut offset = 0; - let mut ao_2e_int_eri = Vec::<(usize,usize,usize,usize,f64)>::with_capacity(nmax); + let mut ao_2e_int_eri = Vec::<(usize, usize, usize, usize, f64)>::with_capacity(nmax); for _ in 0..n_buffers { let buffer = trex_file.read_ao_2e_int_eri(offset, bufsize)?; offset += buffer.len(); @@ -213,22 +243,21 @@ fn read(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> { } assert_eq!(ao_2e_int_eri_ref, ao_2e_int_eri); - // Determinants let det_num = trex_file.read_determinant_num()?; assert_eq!(det_num, 50); let mut det_list_ref = Vec::with_capacity(det_num); for i in 0..det_num { - let mut d = [0i64 ; 6 ]; + let mut d = [0i64; 6]; for j in 0..6 { - d[j] = 6*(i as i64)+(j as i64); + d[j] = 6 * (i as i64) + (j as i64); } - det_list_ref.push( Bitfield::from_vec(&d) ); + det_list_ref.push(Bitfield::from_vec(&d)); } let n_buffers = 8; - let bufsize = det_num/n_buffers + 20; + let bufsize = det_num / n_buffers + 20; let mut offset = 0; let mut det_list: Vec = Vec::with_capacity(det_num); for _ in 0..n_buffers { @@ -239,7 +268,6 @@ fn read(file_name: &str, back_end: BackEnd) -> Result<(), trexio::ExitCode> { assert_eq!(det_list_ref, det_list); trex_file.close() - } #[test] @@ -247,7 +275,6 @@ pub fn info() { let _ = trexio::info(); } - use std::fs; #[test] @@ -263,4 +290,3 @@ pub fn hdf5_backend() { let _ = read("tmp/test_write.hdf5", trexio::BackEnd::Hdf5).unwrap(); fs::remove_file("tmp/test_write.hdf5").unwrap() } -