Skip to main content

readcon_core/
lib.rs

1// glibc's allocator serialises the per-frame shells of a parallel parse
2// on one arena lock. mimalloc keeps a serial read at the same speed and
3// lets those shells allocate on the thread that parses them.
4// `asan_run` is set only for `-Zsanitizer=address`. mimalloc's `mi_free`
5// ignores the size Rust passes, so that run uses the system allocator.
6// Miri cannot execute mimalloc either, so it uses the system allocator too.
7#![allow(unexpected_cfgs)]
8#[cfg(not(any(asan_run, miri)))]
9#[global_allocator]
10static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
11
12#[cfg(test)]
13mod allocator_link_tests {
14    unsafe extern "C" {
15        fn mi_usable_size(ptr: *const std::ffi::c_void) -> usize;
16    }
17
18    /// Rust, C, and Python builds all link this crate, so they all use
19    /// this allocator. `mi_usable_size` is only meaningful for mimalloc.
20    #[cfg(not(any(asan_run, miri)))]
21    #[test]
22    fn the_shipped_allocator_is_mimalloc() {
23        let boxed = Box::new([0u8; 32]);
24        let usable = unsafe { mi_usable_size(boxed.as_ptr() as *const std::ffi::c_void) };
25        assert!(
26            usable >= 32,
27            "global allocator is not mimalloc (usable size {usable})"
28        );
29    }
30}
31
32pub mod array;
33mod columns;
34pub mod compression;
35pub mod conbin;
36pub mod correspondence;
37#[cfg(feature = "cuda")]
38pub mod cuda_array;
39pub mod distrib;
40#[cfg(feature = "mpi")]
41pub mod distrib_read;
42#[cfg(feature = "mpi")]
43pub mod distrib_write;
44pub mod error;
45pub mod extxyz_scan;
46mod fast_dec;
47pub mod ffi;
48pub mod frame_index;
49#[cfg(feature = "grammar")]
50pub mod grammar;
51pub mod helpers;
52pub mod hostlabel;
53/// Campaign screening scalars / CON ingest contracts for corpus stores (`readcon-db`).
54pub mod index_proj;
55pub mod iterators;
56pub mod parser;
57pub mod pdb_scan;
58/// RCSO/RCSB cooked numerics for a caller-side broadcast. No MPI in this crate.
59pub mod rcso;
60pub mod storage_dtype;
61pub mod stream;
62pub mod trajectory;
63pub mod types;
64pub mod units;
65pub mod writer;
66
67/// Foreign path / CON → CON write for stack migration (CLI + library).
68pub mod convert;
69
70#[cfg(feature = "metatensor")]
71pub mod metatensor_export;
72
73/// Chemfiles multi-format import (real impl behind `chemfiles` feature; stubs otherwise).
74pub mod chemfiles_import;
75
76/// Chemfiles selection grammar on CON frames (real impl behind `chemfiles` feature; stubs otherwise).
77pub mod chemfiles_selection;
78
79#[cfg(feature = "rpc")]
80pub mod rpc;
81
82// Re-export for generated capnp code which references crate::ReadCon_capnp
83#[cfg(feature = "rpc")]
84pub use rpc::read_con_capnp as ReadCon_capnp;
85
86#[cfg(feature = "python")]
87pub mod python;
88
89/// CON/convel format spec version implemented by this build.
90///
91/// - Version 1: column 5 present but semantics undefined. Readers MAY
92///   ignore it. No JSON metadata line.
93/// - Version 2: column 5 is the original atom index before type-based
94///   grouping; JSON line 2 with at least `{"con_spec_version": 2}`.
95/// - Version 3: same as v2 plus **required** `units` object on JSON **line 2**
96///   with non-empty `length` and `energy`. Writers emit canonical names
97///   (`angstrom`, `eV`). A velocities section on minor 1 also requires
98///   `units.time`. See `units::canonicalize_unit_expression`.
99///
100/// See `docs/orgmode/spec.org` for the full specification.
101pub const CON_SPEC_VERSION: u32 = 3;
102
103/// Minor implemented by this reader. Newer minors of major 3 are accepted.
104/// An unknown section is skipped only when the frame minor is greater than
105/// this value and `section_arity` gives the value-field count
106/// (CON-section.8, CON-section.12, D14).
107pub const CON_SPEC_MINOR: u32 = 1;
108
109/// Library version string, taken from the package version at compile time.
110/// `build.rs` checks that it matches the `VERSION` file.
111pub const VERSION: &str = env!("CARGO_PKG_VERSION");
112
113pub use correspondence::{
114    CorrespondenceError, IdentityCheck, atom_id_permutation, check_atom_id_consistency,
115    minimum_image_delta, minimum_image_displacements, reorder_like,
116};
117
118#[cfg(test)]
119mod tests {
120    use super::*;
121
122    #[test]
123    fn test_spec_version_is_current() {
124        assert_eq!(CON_SPEC_VERSION, 3);
125        assert_eq!(ffi::RKR_CON_SPEC_VERSION, CON_SPEC_VERSION);
126    }
127
128    #[test]
129    fn test_version_matches_source() {
130        let path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("VERSION");
131        let text = std::fs::read_to_string(&path).unwrap();
132        assert_eq!(text, format!("{VERSION}\n"));
133    }
134}