Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 150 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,58 +19,159 @@ Integrals

[![Nightly Workflow](https://github.com/NWChemEx/Integrals/actions/workflows/nightly.yaml/badge.svg)](https://github.com/NWChemEx/Integrals/actions/workflows/nightly.yaml)

Repository for the generic integral API and implementations for specific integral libraries.
Repository for the generic integral API and implementations for specific
integral libraries. Integrals is a PluginPlay plugin; its modules are written
in C++ and are also usable from Python.

Building Integrals
------------------
Installing a Pre-Built Wheel
----------------------------

Integrals is built using
[CPP](https://github.com/CMakePackagingProject/CMakePackagingProject.git).
Assuming you have already installed CPP, that you are on a sane Unix-like
computer, and you are willing to let Integrals build all dependencies, then
the following will suffice to build Integrals:
If you just want to use Integrals from Python, install the published wheel.
The wheels are built for Python 3.12:

```.sh
python3.12 -m venv venv
source venv/bin/activate
pip install nwchemex-integrals
```

The rest of this file describes building Integrals from source.

Prerequisites
-------------

- A C++20 compiler. CI uses GCC 14 or Clang 18 on Linux and AppleClang on
macOS. On macOS do **not** use GCC: the published wheels of Integrals'
dependencies are built with AppleClang (libc++), and GCC (libstdc++) cannot
link against them. The build stops with an error if you try.
- CMake 3.14 or newer. Ninja is optional but recommended.
- Python 3 with its development headers, and pip. Use Python 3.12 if you want
the build to reuse the published wheels of the dependencies (see
[How dependencies are found](#how-dependencies-are-found)).
- MPI, Boost (headers only) and Eigen3. The build can not obtain these for you.

On Ubuntu:

```.sh
sudo apt-get install g++-14 cmake ninja-build libopenmpi-dev openmpi-bin \
libboost-dev libeigen3-dev
```

On macOS, with Homebrew:

```.sh
brew install cmake ninja open-mpi boost eigen
```

How dependencies are found
--------------------------

Integrals depends on [SimDE](https://github.com/NWChemEx/SimDE) (and through it
the rest of the NWChemEx stack: PluginPlay, Chemist, TensorWrapper,
ParallelZone, Utilities, ...) and on [Libint](https://github.com/evaleev/libint).
The build system comes from [NWXCMake](https://github.com/NWChemEx/NWXCMake).
You do not need to install any of these yourself:

- **NWXCMake** is taken from the `nwchemex-nwxcmake` pip package if it is
installed in the Python CMake finds; otherwise it is downloaded from GitHub.
- **NWChemEx dependencies** (SimDE and everything below it) are taken from
their `nwchemex-*` wheels if they are installed in the active Python
environment. Otherwise they are downloaded from the `master` branch on GitHub
and built as part of this build, which takes considerably longer.
- **Libint** is taken from an existing installation if CMake can find one
(`find_package(Libint2)`, e.g., via `CMAKE_PREFIX_PATH`). Otherwise the
v2.11.0 release is downloaded and built, which takes a while.

The quickest builds come from a Python 3.12 virtual environment that has the
dependency wheels installed, which is what the instructions below set up.

Building with pip
-----------------

This builds Integrals and installs it, including the Python module, into the
active virtual environment:

```.sh
git clone https://github.com/NWChemEx/Integrals.git
cd Integrals
python3.12 -m venv venv
source venv/bin/activate
pip install scikit-build-core setuptools-scm nwchemex-nwxcmake nwchemex-simde
pip install . --no-build-isolation
```

The third `pip install` puts Integrals' build requirements (listed under
`[build-system]` in `pyproject.toml`) into the environment. Together with
`--no-build-isolation`, this makes Integrals link against the dependency wheels
that stay installed, rather than copies in a temporary build environment that
pip deletes afterwards.

For development, do an editable install instead:

```.sh
pip install -e ".[dev]" --no-build-isolation
```

This turns on `DEVELOPER_SETUP` (see the table below), so it also builds the
tests, uses a Debug build and installs the pre-commit hooks. The build tree is
`build/`.

Building with CMake
-------------------

Integrals can also be built with CMake directly. Activating the virtual
environment from the previous section first is optional, but if the dependency
wheels are installed there, CMake reuses them:

```.sh
git clone https://github.com/NWChemEx/Integrals.git
cd SDE
cmake -H. -Bbuild -DCPP_GITHUB_TOKEN=<your super-secret token> \
-DMPI_ROOT=<path/to/your/mpi/installation> \
-DCMAKE_PREFIX_PATH=<where/you/installed/CPP> \
-DCMAKE_INSTALL_PREFIX=<where/you/want/to/install/Integrals>
cd build
cmake --build .
#May need to run as an admin depending on where you are installing
cmake --build . --target install
cd Integrals
cmake -B build -G Ninja \
-DPython_EXECUTABLE="$(command -v python3)" \
-DBUILD_TESTING=ON \
-DCMAKE_INSTALL_PREFIX=<where/you/want/to/install/Integrals>
cmake --build build --parallel
cmake --install build
```
The build process is not capable of building MPI so you will have to provide a
path to a known installation via the `MPI_ROOT` variable. The GitHub token is
necessary because, at the moment, Chemist, TAMM, SDE, and Utilities are
private repositories (instructions for generating a token are
[here](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/)).

For finer-grained control over the build we direct the reader to the more
thorough CPP build instructions located
[here](https://cmakepackagingproject.readthedocs.io/en/latest/end_user/quick_start.html)

and note that Integrals depends on several other projects:

- [utilities](https://github.com/NWChemEx/Utilities)
- [SDE](https://github.com/NWChemEx/SDE)
- [bphash](https://github.com/bennybp/BPHash)
- [pybind11](https://github.com/pybind/pybind11)
- Requires a development version of Python
- [cereal](https://github.com/USCiLab/cereal)
- [Chemist](https://github.com/NWChemEx/Chemist)
- [TAMM](https://github.com/NWChemEx/TAMM)
- [HPTT](https://github.com/ajaypanyala/hptt)
- [MSGSL](https://github.com/Microsoft/GSL)
- [LAPACKE](http://www.netlib.org/lapack/)
- [Eigen3](https://github.com/eigenteam/eigen-git-mirror)
- [GlobalArrays](https://github.com/GlobalArrays/ga)
- MPI
- [LibInt](https://github.com/evaleev/libint)
- (For testing only)[Catch2](https://github.com/catchorg/Catch2)

We recommend building Libint separately for the moment because a proper
autotools build (the only autotools variant supported by CPP) builds the
generator and many more integrals than are necessary.

Setting `Python_EXECUTABLE` makes sure CMake uses the Python of your active
environment (and therefore its wheels) rather than some other Python it finds
first. Commonly used options are:

| Option | Default | Description |
|--------------------------------------|---------|-----------------------------------------------------------------------------------------------------|
| `BUILD_TESTING` | `OFF` | Build the C++ unit tests and register the Python tests with CTest. |
| `BUILD_PYBIND11_BINDINGS` | `ON` | Build the `integrals` Python module. |
| `ENABLE_SIGMA` | `OFF` | Use [Sigma](https://github.com/QCUncertainty/sigma) for uncertainty quantification (UQ modules). |
| `INTEGRALS_ENABLE_OPENMP` | `OFF` | Thread the integral evaluation with OpenMP. On macOS, install `libomp` and add its prefix to `CMAKE_PREFIX_PATH`. |
| `DEVELOPER_SETUP` | `OFF` | Debug build, turns on `BUILD_TESTING`, and installs the pre-commit hooks. |
| `ENABLE_XHOST` | `ON` | Tune dependencies for this machine's CPU. Turn off if the build must run on other machines. |
| `NWX_ECOSYSTEM_FROM_SOURCE` | `OFF` | Ignore installed `nwchemex-*` wheels and build every NWChemEx dependency from GitHub. |
| `FETCHCONTENT_SOURCE_DIR_<NAME>` | unset | Use a local checkout of dependency `<NAME>` (e.g. `FETCHCONTENT_SOURCE_DIR_SIMDE=/path/to/SimDE`). |

If you change which Python or which dependency wheels the build should use,
delete `build/` and configure again; earlier choices are cached.

Running the tests
-----------------

After a CMake build with `-DBUILD_TESTING=ON` (or an editable pip install),
run the C++ and Python tests with:

```.sh
ctest --test-dir build --output-on-failure
```

After a pip install, the Python tests can also be run directly:

```.sh
pip install pytest
pytest tests/python
```

Examples
--------

The [examples](examples) directory contains small programs showing how to use
Integrals. `examples/primitive_error_models` is built along with the tests;
the Python examples have their own `README.md`.
83 changes: 83 additions & 0 deletions examples/eri_error_explorer/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<!--
~ Copyright 2026 NWChemEx-Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->

ERI Error Explorer
==================

`eri_error_explorer.py` explores how the basis set parameters, the separation
between centers, and the screening tolerance affect the error in the
four-center electron repulsion integrals (ERIs). See the docstring at the top
of the script for details.

Setting up
----------

1. Build Integrals, with its Python bindings, as described in the
[top-level README](../../README.md). Building with pip in a Python 3.12
virtual environment is the simplest option.
2. In the same environment, install ChemCache (the script takes its STO-3G
basis set from ChemCache) and NumPy:

```.sh
pip install nwchemex-chemcache numpy
```

ChemCache and Integrals must share one copy of SimDE and the libraries
below it. That is the case if Integrals was built against the dependency
wheels installed in this environment, which the top-level README's
instructions do. If you built Integrals with `NWX_ECOSYSTEM_FROM_SOURCE=ON`,
or in an environment without the wheels, build ChemCache from source the
same way instead of installing its wheel.
3. If you built Integrals with CMake and did not install it into the
environment, add the build directory to `PYTHONPATH` so Python can find the
`integrals` module:

```.sh
export PYTHONPATH=/path/to/Integrals/build:$PYTHONPATH
```

This step is not needed after a pip install.

Running
-------

From the root of the Integrals repository:

```.sh
python examples/eri_error_explorer/eri_error_explorer.py
```

With the default settings this takes a few seconds. The script prints the
sampled shells, one line per shell quartet and tolerance, and a summary per
separation and tolerance.

Changing what is explored
-------------------------

The parameters are hard-coded near the top of the script. Edit them and run
the script again:

| Parameter | Default | Meaning |
|-------------------------|--------------------|-----------------------------------------------------------------------------------|
| `SHELL_SAMPLES` | `[(1, 0), (8, 2)]` | `(Z, i)` pairs: shell `i` of the STO-3G basis set for atomic number `Z` (H 1s, O 2p). |
| `R_MIN`, `R_MAX` | `1.0`, `5.0` | Range of center separations, in bohr. |
| `N_SEPARATIONS` | `3` | Number of evenly spaced separations in that range. |
| `TOLERANCES` | `[1e-6, 1e-8]` | Screening tolerances to study. |
| `REFERENCE_TOLERANCE` | `1e-25` | Tolerance used to compute the reference ("exact") ERIs. |

Each sampled shell is placed on all four corners of a regular tetrahedron
whose edge length is the separation, so the number of shells, and therefore of
shell quartets, grows quickly with the number of samples.
Loading
Loading