High-performance molecular integral library for quantum chemistry.
A standalone Rust library for evaluating one-electron and two-electron molecular integrals over Gaussian-type orbitals. Designed to outperform libcint — the de facto standard C library (~60,500 lines) used by PySCF, Q-Chem, and dozens of quantum chemistry codes — through SIMD batching, const-generic specialization, and unified derivative computation. Compiles to both native and WebAssembly from the same source.
| Capability | libcint | rustint |
|---|---|---|
| SIMD | Auto-vectorization only | Explicit AVX2/AVX-512/NEON/WASM SIMD128 via trait abstraction |
| Batching | One quartet at a time | N quartets per SIMD operation (Structure-of-Arrays) |
| Derivatives | 3 separate code paths (6,000+ lines) | Unified fused Rys: single pass for base + all derivative orders |
| Specialization | Common Lisp code generation (570 functions) | Rust const generics: compiler monomorphization |
| WebAssembly | Not supported | Native wasm32 target, same source |
| Memory safety | Manual C pointers | Rust ownership + arena allocators, zero undefined behavior |
| Screening | Binary Schwarz threshold | Multi-level: Schwarz + density-weighted + distance-based |
| Threading | External (caller must parallelize) | Built-in Rayon with WASM-aware fallback |
rustint v0.1 is the production integral engine of IQCP, a browser-based quantum chemistry application (RHF/LDA/B3LYP energies, analytic gradients and Hessians, harmonic frequencies, IR/Raman intensities) validated against PySCF 2.11.0. The library provides:
- One-electron integrals: overlap, kinetic, nuclear attraction — values, first derivatives, and second derivatives (Cartesian and spherical)
- Two-electron integrals: ERIs via Rys quadrature with const-generic specialization, first derivatives (fused Rys), and second derivatives
- Direct Fock builds: J/K matrices with 8-fold permutational symmetry, multi-level screening, and built-in Rayon threading
- GTO evaluation on grids: values and gradients for DFT quadrature
- Dipole and electric-field perturbation integrals (length gauge)
- SIMD backends: AVX2, AVX-512, NEON, WASM SIMD128, scalar — selected by feature flag, with lane-wise bit-identity tests across backends
- WebAssembly: the same source compiles to wasm32 (including a deterministic relaxed-FMA build used by IQCP in production)
Element coverage H–Ar, angular momentum through g functions (L ≤ 4 via const-generic fast paths, higher L via runtime fallback).
crates/
rustint/ Core library — public API, all integral algorithms
rustint-ffi/ C-ABI wrapper for non-Rust callers
-
Const-generic angular momentum specialization — The compiler monomorphizes
shell_eri_kernel<LA, LB, LC, LD>into specialized functions with stack-allocated VRR tables and compile-time loop bounds. A static dispatch table maps runtime angular momentum values to these specialized kernels, replacing libcint's Common Lisp code generator. -
SIMD batching — Structure-of-Arrays layout processes N shell quartets simultaneously per SIMD operation (4 for AVX2, 8 for AVX-512, 2 for WASM SIMD128). Abstracted behind a
SimdF64trait for portability across platforms. -
Fused Rys derivatives — Single VRR pass at extended angular momentum (L + 2*DERIV_ORDER) produces base integrals and all derivative orders simultaneously. Replaces libcint's 3 separate passes for base/gradient/Hessian integrals.
-
Multi-level screening — Schwarz bounds (always) + density-weighted screening (during SCF) + distance-based Gaussian decay (extended systems). Reduces redundant integral computation by 30-60%.
-
Arena allocator — Thread-local bump allocator for scratch space in hot paths. O(1) allocation and reset, zero system allocator calls during integral evaluation.
| Module | Purpose |
|---|---|
boys.rs |
Boys function F_m(T): series, recurrence, asymptotic regimes |
rys.rs |
Rys quadrature roots and weights via Chebyshev/Stieltjes algorithm |
basis.rs |
Shell, Nucleus, BasisSet types |
one_electron/ |
Overlap, kinetic, nuclear attraction (Obara-Saika), 1e derivatives |
two_electron/ |
ERIs, const-generic kernels, batched SIMD, VRR, HTR, fused Rys |
simd/ |
SimdF64 trait + backends (AVX2, AVX-512, NEON, WASM, scalar) |
screening.rs |
Multi-level integral screening engine |
arena.rs |
Thread-local bump allocator |
use rustint::{Shell, Nucleus, BasisSet, n_cart};
// Compute overlap integrals for a shell pair
shell_overlap(&shell_i, &shell_j, &mut out);
// Compute electron repulsion integrals for a shell quartet
shell_eri(&shell_a, &shell_b, &shell_c, &shell_d, &mut out);
// Compute ERI gradients (fused Rys — single pass)
shell_eri_grad(&shell_a, &shell_b, &shell_c, &shell_d, &mut grad_out);// Full overlap matrix for a basis set
let s_matrix = overlap_matrix(&basis);
// Full ERI tensor with screening and parallelism
let eri = eri_tensor(&basis, &config);cargo add rustint-qcThe crates.io package is named rustint-qc (the bare rustint name is held
by an unrelated project), but the library target is rustint — so code
imports are unchanged:
use rustint::{Shell, shell_eri};Note: the PySCF golden-test data (~55 MB) ships in this GitHub repository but is excluded from the crates.io package to respect the registry size limit; see Golden test data.
use rustint::{Shell, Nucleus, BasisSet, n_cart, n_sph};
// Define a hydrogen 1s shell (STO-3G)
let h1s = Shell {
l: 0,
center: [0.0, 0.0, 0.0],
exponents: vec![3.42525091, 0.62391373, 0.16885540],
coefficients: vec![0.15432897, 0.53532814, 0.44463454],
atom_idx: 0,
};
// Angular momentum component counts
assert_eq!(n_cart(0), 1); // s-shell: 1 Cartesian component
assert_eq!(n_cart(1), 3); // p-shell: 3 (px, py, pz)
assert_eq!(n_cart(2), 6); // d-shell: 6 (xx, xy, xz, yy, yz, zz)
// Build a basis set (auto-computes n_basis)
let basis = BasisSet::new(vec![h1s], vec![Nucleus {
charge: 1.0,
position: [0.0, 0.0, 0.0],
}]);
assert_eq!(basis.n_basis, 1);Validated against PySCF 2.11.0 and mpmath reference values with strict, non-negotiable tolerances. Worst measured deviations:
| Quantity | Tolerance | Measured (worst case) |
|---|---|---|
| Boys function F_m(T) | 1e-15 relative | 5.1e-15 (m=50), 2.2e-15 typical |
| Rys quadrature moments (n=1-20) | 1e-14 / 1e-13 | ~1e-16 (machine eps) |
| Overlap integrals | 1e-14 absolute | 2.2e-16 |
| Kinetic integrals | 1e-14 absolute | 3.6e-15 |
| Nuclear attraction (Rys) | 1e-13 absolute | 1.1e-13 (CH4/cc-pVDZ, at the PySCF precision floor) |
| Two-electron ERIs | 1e-12 absolute | 1.3e-13 ((dd |
| 1st-derivative integrals (S, T, V, ERI) | 1e-10 absolute | <= 5.7e-15 |
| 2nd-derivative 1e integrals (S'', T'', V'') | 1e-12 absolute | 16/17 PySCF golden cells strict-pass; 1 cell at the measured f64 architectural floor (2.1e-11, C6H6/cc-pVDZ V'' — propagates to <= 0.5 cm^-1 in frequencies) |
| 2nd-derivative ERIs | 1e-12 absolute | full archetype matrix vs PySCF |
| Dipole integrals | 1e-12 absolute | 5.7e-15 (C6H6/cc-pVDZ) |
| Field perturbation +E.r | 1e-12 absolute | 2.8e-17 |
| GTO grid evaluation (value/gradient) | 1e-12 absolute | 8.9e-16 / 3.6e-15 |
| SIMD backend bit-identity | 0 ULP lane-wise | 0 deviations (Scalar vs AVX2 vs AVX-512, ~10^5 lane checks) |
Cross-backend reductions (reduce_sum) differ by tree shape as mathematically
required; everything upstream of the first cross-lane operation is bit-identical
across backends by test.
Measured against libcint (the reference C library used by PySCF) on Xeon Silver 4314: rustint's cached scalar ERI path is competitive to faster per shell class, the fused-Rys derivative kernels avoid libcint's multiple passes, and the threaded Fock builder reaches parallel efficiency η(8) ≈ 0.87–0.93 on H₂O/C₆H₆ cc-pVDZ. In-browser (WASM), rustint powers interactive SCF at sizes up to caffeine/6-31++G** (312 basis functions) via integral-direct Fock builds. Detailed, reproducible benchmark methodology ships with the IQCP publication material.
cargo test passes out of the box: reference data (PySCF 2.11.0 golden
files) ships in crates/rustint/tests/golden/ for all but 11 large files
(>10 MB each) that are excluded to keep the repository lean. Tests that
need an absent large golden print a SKIP line and pass gracefully; the
files can be regenerated with the PySCF scripts in scripts/ (see
crates/rustint/tests/golden/README.md).
[features]
default = ["simd-auto"]
simd-auto = [] # Compile-time SIMD detection (default)
avx2 = [] # Force AVX2 (f64x4, 4 lanes)
avx512 = [] # Force AVX-512 (f64x8, 8 lanes)
neon = [] # Force ARM NEON (f64x2, 2 lanes)
wasm-simd = [] # Force WASM SIMD128 (f64x2, 2 lanes)
wasm-simd-relaxed = [] # WASM relaxed-SIMD FMA build (deterministic; used by IQCP)
max-l-4 = [] # Limit to L<=4 (81 dispatch entries, smaller binary)
max-l-6 = [] # Limit to L<=6 (2,401 dispatch entries)
# Default: MAX_L=8 (6,561 dispatch entries)
parallel = [] # Enable Rayon multi-threading
serde = [] # Enable Shell/BasisSet serialization
no_std = [] # no_std + alloc compatibility
dev-fast = [] # (dev only) Shrink const-generic ERI dispatch from L<=4 (625 kernels)
# to L<=2 (81 kernels) to cut cold release compile time
# from ≥102 min to 20 s (≥308× speedup). Incompatible with
# max-l-4 and max-l-6. DO NOT ship release artifacts with this.| Platform | SIMD Backend | Threading |
|---|---|---|
| Linux x86_64 | AVX2 / AVX-512 | Rayon |
| macOS x86_64 | AVX2 | Rayon |
| macOS ARM64 (Apple Silicon) | NEON | Rayon |
| Windows x86_64 | AVX2 / AVX-512 | Rayon |
| WebAssembly | SIMD128 / scalar | Single-threaded |
# Native build
cargo build --workspace
# WASM target
cargo build -p rustint-qc --target wasm32-unknown-unknown
# With features
cargo build -p rustint-qc --features "parallel,serde"
# Run tests
cargo test --workspace
# Run benchmarks (when available)
cargo bench --workspaceThe default wasm build is single-threaded and builds on stable. Browser
multi-threading (the _parallel drivers, e.g. fock_hessian_contract_parallel)
is backed by wasm-bindgen-rayon (Web
Workers + SharedArrayBuffer). It requires nightly + atomics + build-std
and a cross-origin-isolated host page (COOP: same-origin,
COEP: require-corp):
RUSTFLAGS="-C target-feature=+atomics,+bulk-memory,+mutable-globals,+simd128" \
rustup run nightly \
wasm-pack build crates/rustint --release --target web \
--features "parallel,wasm-simd" -- -Z build-std=panic_abort,stdCall await initThreadPool(n) once from JS before any _parallel driver runs.
Full recipe (build flags, JS init, COOP/COEP headers, headless test):
docs/wasm-threading.md.
Minimal by design:
| Dependency | Purpose | Required |
|---|---|---|
wide |
Portable SIMD (f64x4, f64x2) | Yes |
libm |
Pure-Rust math (exp, erf, sqrt) for no_std/WASM | Yes |
thiserror |
Error derive macros | Yes |
rayon |
Multi-threading | Optional (parallel feature) |
wasm-bindgen-rayon |
Browser threading (Web Workers + SharedArrayBuffer) | Optional (parallel feature, wasm32-only) |
serde |
Serialization | Optional (serde feature) |
No nalgebra, no ndarray — callers provide flat &[f64] slices.
| Paper | Topic |
|---|---|
| Shavitt (1963) | Boys function evaluation |
| Dupuis, Rys & King (1976) | Rys quadrature for molecular integrals |
| Obara & Saika (1986) | Recurrence relations for 1e integrals |
| Head-Gordon & Pople (1988) | HGP algorithm for 2e integrals |
| McMurchie & Davidson (1978) | Alternative recurrence scheme |
Algorithms are cross-validated against established open reference implementations, including libcint (C), SIMINT (C), libint2 (C++), GauXC (C++), gbasis (Python), libgtoint (C/Fortran), and Intception (C), with numerical reference values from PySCF and mpmath.
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
at your option.
rustint is currently developed as a solo project by ExaPsi. Contributions may be accepted after the v0.1.0 release.