-
Notifications
You must be signed in to change notification settings - Fork 105
Home
Before you read on:
- If you want to know how to use a libint library in your code:
- obtain a libint library:
- If you want a pre-built Libint library, packages may be available through your package manager
- Or build yourself from a pre-generated library tarball from the latest release
- skip to the compiling libint library section below.
- learn how to use the libint library:
- if you use C++11 or later (strongly recommended): read this instead.
- if you use pre-2011 C++, C, Fortran, or any other language, refer to the Libint Programmer's Manual.
- obtain a libint library:
- If you want to know how to generate a custom libint library using the libint compiler:
- many codes using libint, e.g. orca and psi4, already include an appropriately configured libint library and you do not need to generate it yourself;
- if you do need to make a custom library, read on.
The primary reason to use libint compiler is to generate custom Libint libraries. Most advanced customization, such as implementation of new integral types, recurrence relations, and computation strategies, will require making changes to the compiler. If you are interested in working on the compiler code please consider consulting with one of Libint authors, if possible, to avoid duplication of effort.
For building the libint compiler:
- C++ compiler that supports C++11 standard;
- CMake 3.19 or higher;
- Ninja build system (strongly recommended) or GNU Make;
- Boost library (1.57 or higher, header-only);
- GMP library, including C++ support (gmpxx);
- (optional) MPFR library for high-precision testing;
- Git client.
The only way to get the compiler source is from the Libint source code repository on GitHub. You can use a client, like GitHub app or (our favorite) SourceTree app from Atlassian. Or from the command line: git clone https://github.com/evaleev/libint.git
git clone https://github.com/evaleev/libint.git
cd libint
cmake -S. -Bbuild -GNinja [options]
cmake --build build --target build_libintThe compiler executable will be at build/src/bin/libint/build_libint.
Common CMake variables:
-
-DCMAKE_CXX_COMPILER=<compiler>- specify the C++ compiler -
-DCMAKE_CXX_FLAGS=<flags>- specify additional C++ compiler flags -
-DBOOST_ROOT=<path>- hint location of Boost if not in default search path -
-DMultiprecision_ROOT=<path>- hint location of GMP/MPFR
These are the most useful CMake options (pass via command-line as -D<OPTION>=<VALUE>):
- LIBINT2_ENABLE_ONEBODY=N - Support up to N-th derivatives of 1-body integrals. Use -1 for OFF. [Default=0]
- LIBINT2_ENABLE_ERI=N - Support up to N-th derivatives of 4-center ERIs. Use -1 for OFF. [Default=0]
- LIBINT2_ENABLE_ERI3=N - Support up to N-th derivatives of 3-center ERIs. Use -1 for OFF. [Default=-1]
- LIBINT2_ENABLE_ERI2=N - Support up to N-th derivatives of 2-center ERIs. Use -1 for OFF. [Default=-1]
-
LIBINT2_MAX_AM=L - Support Gaussians of angular momentum up to L. Can specify per-derivative level as semicolon-separated string, e.g.,
"6;5;4". [Default=4] - LIBINT2_OPT_AM=L - Optimize maximally for up to angular momentum L (L <= max-am). [Default=(max_am/2)+1]
-
LIBINT2_CARTGAUSS_ORDERING=ORDER - Ordering of cartesian Gaussians in shells. [Default=standard]
-
standard-- CCA standard ordering (xxx, xxy, xxz, xyy, xyz, xzz, yyy, ...) -
intv3-- intv3 ordering (yyy, yyz, yzz, zzz, xyy, xyz, xzz, xxy, xxz, xxx) -
gamess-- GAMESS ordering (xxx, yyy, zzz, xxy, xxz, yyx, yyz, zzx, zzy, xyz) -
orca-- ORCA ordering (hybrid between GAMESS and standard) -
bagel-- BAGEL ordering
-
-
LIBINT2_SHELL_SET=SET - Shell set ordering restrictions. [Default=standard]
-
standard-- For (ab|cd): l(a) >= l(b), l(c) >= l(d), l(a)+l(b) <= l(c)+l(d) -
orca-- ORCA ordering
-
See INSTALL.md for the complete list of options.
This will produce a tarball of libint library that is suitable for independent distribution (has its own CMakeLists.txt):
cmake --build build --target exportThe tarball will be at build/libint-<version>.tgz.
The exported libint library should be configured with CMake and built with any CMake-supported generator, e.g. Ninja and GNU Make.
- C++ compiler that supports the 2011 ISO C++ Standard (any recent compiler will do).
- CMake
- Ninja or GNU Make; the use of Ninja is strongly recommended!
- (optional) Eigen library is necessary to enable C++11 API; as of version 2.7.0-beta.3 the Eigen library will be required by default, add
-DLIBINT2_REQUIRE_CXX_API=OFFto the CMake configure line to disable the search for Eigen if you only need the C API. - (optional) Boost Preprocessor library; if not found and Eigen library has been found, libint will use (and install) a bundled copy of Boost.Preprocessor.
- (optional) a Fortran 2003 compiler to enable Fortran bindings generation
Compilation of the generated library is straightforward:
- Unpack the library:
tar -xvzf libint-2.x.y.tgz cd libint-2.x.ycmake -B build -DCMAKE_INSTALL_PREFIX=/path/to/installcmake --build build- optional:
cmake --build build --target check cmake --build build --target install
To enable Fortran bindings generation add -DLIBINT2_ENABLE_FORTRAN=ON to the cmake command line.
To obtain peak performance it is very important to use the C++ compiler and compiler options that are appropriate for the given platform. It is impossible to provide specific recommendations for specific platforms. We recommend to use a vendor compiler (e.g., Intel) before trying clang++ and g++. In some situations, however, clang++ and g++ are known to outperform the x86 vendor compiler, so we recommend trying several compilers.
Other important configure flags are described in the next section.
Besides the standard CMAKE_INSTALL_PREFIX, CMAKE_CXX_COMPILER, CMAKE_CXX_FLAGS variables, the following CMake variables may be necessary/useful:
-
LIBINT2_REQUIRE_CXX_API={ON,OFF} controls whether the C++ API is required or not; the default is
ON. -
LIBINT2_ENABLE_FORTRAN={ON,OFF} controls whether the Libint2 Fortran module is built; the default is
OFF. -
LIBINT2_BUILD_SHARED_AND_STATIC_LIBS={ON,OFF} controls whether both shared and static versions of the library will be built; the default is
OFF. -
LIBINT2_SHGAUSS_ORDERING={standard,gaussian} controls the ordering of solid harmonics Gaussians within shells when the C++ API is used; the default is
standard. -
LIBINT2_REALTYPE=TYPE specifies the floating-point data type used by the library. The default value for this option is
double(double-precision floating-point representation of a real number). By overriding the default it is possible to customize the library to use a lower-precision representation (which typically results in a performance boost) and/or to generate SIMD vectorized code. N.B. C++11 interface cannot be currently used with SIMD vectorized libraries! The following values are valid:-
float-- single-precision floating-point number; -
libint2::simd::VectorAVXDouble-- vector of 4 packed doubles that can be used with AVX instructions available on reasonably-modern x86 hardware (starting with Intel Sandy Bridge and AMD Bulldozer microarchitectures, available in processors since 2011); -
libint2::simd::VectorSSEDouble-- vector of 2 packed doubles that can be used with SSE2 instructions available on all x86 platforms, including those released before 2011; -
libint2::simd::VectorSSEFloat-- vector of 4 packed floats that can be used with SSE instructions available on all x86 platforms, including those released before 2011; -
libint2::simd::VectorQPXDouble-- vector of 4 packed doubles that can be used with QPX instructions available on recent PowerPC hardware (IBM Blue Gene/Q); -
libint2::simd::VectorFP2Double-- vector of 2 packed doubles that can be used with FP2 (Double Hummer) instructions available on older PowerPC hardware (IBM Blue Gene/P).
-
With the exception of float, these are vector types implemented in Libint using compiler intrinsics, functions that translate directly into vector instructions. To use these vector types you may need to provide additional compiler flags that will enable support for vector instructions. For example, to enable support for AVX in Clang use the -mavx compiler flag. With Intel compiler use flag -xHOST to enable all vector instruction sets supported by the processor on which you are compiling.
N.B. It is also possible to use real vector types of Agner Fog's vectorclass library, e.g. Vec4d and Vec8f for AVX. To use this library you need to add this to CPPFLAGS or CXXFLAGS: -Ipath_to_vectorclass -DLIBINT2_HAVE_AGNER_VECTORCLASS . On OS X we only succeeded in using this library with a recent GNU C++ compiler, not with Clang.
SIMD vectorization is the crucial contributor to performance of a modern processor core. Libint code can typically hit up to 70% of FLOP peak on a scalar core, hence on a SIMD core divide that number by the vector length (4 for AVX in double precision). The situation is only going to get worse (accelerators already use 8- and 16-wide vector units, and future mainstream processors are likely to use 8-wide units also). Hence if your method spends significant portion of its time computing integrals start rewriting your code now.
Vectorization of Libint is work in progress. However, by switching to AVX we see a factor of 2-2.5 speedup of the integrals kernels compared to scalar performance, thus we are optimistic that it will be possible to attain 50% of peak on AVX hardware. It is clear that significant reorganization of the manner in which integrals are computed and digested is involved, but these costs are unavoidable.
- if you use C++11 or later (strongly recommended): read this.
- if you use pre-2011 C++, C, pre-2003 Fortran, or any other language, refer to the Libint Programmer's Manual for (brief) information on how to use the library in your code.
none at the moment
cmake -GNinja \
-DLIBINT2_ENABLE_GENERIC_CODE=ON \
-DLIBINT2_MAX_AM="6;4;6" \
-DLIBINT2_OPT_AM="3;3;3" \
-DLIBINT2_ENABLE_ONEBODY=1 \
-DLIBINT2_ONEBODY_MAX_AM="6;4" \
-DLIBINT2_ENABLE_ERI=1 \
-DLIBINT2_ERI_MAX_AM="6;4" \
-DLIBINT2_ENABLE_ERI3=2 \
-DLIBINT2_ERI3_PURE_SH=ON \
-DLIBINT2_ERI3_MAX_AM="12;0;0" \
-DLIBINT2_ENABLE_ERI2=0 \
-DLIBINT2_ERI2_PURE_SH=ON \
-DLIBINT2_ERI2_MAX_AM=12 \
-DLIBINT2_GENERATE_FMA=ON \
-DLIBINT2_MULTIPOLE_MAX_ORDER=10
...
- a libint library (version 2.0.2) is embedded in ORCA
cmake -GNinja \
-DLIBINT2_ENABLE_ERI=2 -DLIBINT2_ENABLE_ERI3=2 -DLIBINT2_ENABLE_ERI2=2 \
-DLIBINT2_MAX_AM=7 -DLIBINT2_OPT_AM=4 \
-DLIBINT2_ERI_MAX_AM="7;4;3" -DLIBINT2_ERI_OPT_AM="4;3;2" \
-DLIBINT2_ENABLE_UNROLLING=0 \
-DLIBINT2_ENABLE_GENERIC_CODE=ON \
-DLIBINT2_CONTRACTED_INTS=ON \
-DLIBINT2_CARTGAUSS_ORDERING=orca \
-DLIBINT2_SHELL_SET=orca \
-DLIBINT2_ERI3_PURE_SH=ON -DLIBINT2_ERI2_PURE_SH=ON \
...
- Psi4 provisions a custom Libint2 library.