-
Notifications
You must be signed in to change notification settings - Fork 97
Home
Before you read on:
- If you want to know how to use a libint library in your code:
- 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.
- If you want to know how to generate a libint library using the libint compiler , first make sure you really need to do that:
- if all you want is a basic library that computes integrals necessary to compute energies, use the pre-generated library labeled "lmax=6 library (standard ints only)" from the latest release of Libint;
- many codes using libint, e.g. orca and mpqc, 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.
- Robust C++ compiler with "some" C++11 support;
- Recent boost library;
- Recent GMP library, including C++ support;
- (optional) Recent MPFR library for high-precision (>64bit) testing of the computed integrals;
- Standard GNU toolchain (make, tar, autoconf);
- doxygen and latex to make compiler documentation.
- 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
- enter the top source directory
- ./autogen.sh
- make a separate directory where you will build the compiler (WARNING: BUILD DIRECTORY CANNOT BE LOCATED WITHIN THE SOURCE TREE), and cd that directory
- run configure script with appropriate configure command-line options (see the next section for more info). All available options can be listed as such: [libint_srcdir]/configure --help. Some information can be passed to configure via standard environmental variables:
- CPPFLAGS can be used if the boost library is not in the default compiler search path, e.g. /path/to/libint/source/configure CPPFLAGS='-I/path/to/boost'.
- CXX can be used to specify the C++ compiler.
- CXXFLAGS can be used to specify the C++ compiler flags.
These are the most useful configure options:
- --enable-eri=N Use this option to enable support for N-th order derivatives of (4-center) electron repulsion integrals. To disable support for ERIs set N to 'no', or use the --disable-eri option. By default, N=0 (i.e. no derivatives are requested).
- --enable-eri3=N Same as --enable-eri, except for 3-center ERIs.
- --enable-eri2=N Same as --enable-eri, except for 2-center ERIs.
- --with-max-am=L Species the maximum angular momentum level for the Gaussian basis functions when computing electron repul- sion integrals. By default, integrals over g-type functions (L=4) are supported.
-
--with-cartgauss-ordering=ORDER Specifies the ordering of cartesian Gaussians in shells. The known values are:
- standard (default) -- the standard ordering (xxx, xxy, xxz, xyy, xyz, xzz, yyy, ...); this is ordering of the Common Component Architecture (CCA) standard for molecular integral data exchange described in “Components for Integral Evaluation in Quantum Chemistry”, J. P. Kenny, C. L. Janssen, E. F. Valeev, and T. L. Windus, J. Comp. Chem. 29, 562 (2008);
- intv3 -- the intv3 ordering (yyy, yyz, yzz, zzz, xyy, xyz, xzz, xxy, xxz, xxx) used the by IntV3, the default integral engine of MPQC; use this to make Libint and IntV3 engines in MPQC interoperable;
- gamess -- GAMESS ordering (xxx, yyy, zzz, xxy, xxz, yyx, yyz, zzx, zzy, xyz)
- orca -- ORCA ordering (hydrid between GAMESS and standard);
- bagel -- BAGEL ordering;
-
--with-shell-set=SET The library will support computation of shell sets sets subject to these restrictions:
- standard -- standard ordering (default). For (ab|cd): l(a) >= l(b), l(c) >= l(d), l(a)+l(b) <= l(c)+l(d). For (b|cd): l(c) >= l(d).
- orca -- ORCA ordering. For (ab|cd): l(a) <= l(b), l(c) <= l(d), l(a) < l(c) || (l(a) == l(c) && l(b) < l(d)). For (b|cd): l(c) <= l(d).
this will produce a tarball of libint library that is suitable for independent distribution (it will have its own configure, etc.):
make export
Version 2.5.0 and older of the exported libint library is built using GNU Autoconf and GNU Make. As of version 2.6.0 the Autoconf build is deprecated; the exported libint library should be configured with CMake and built with any CMake-supported generator, e.g. Ninja and GNU Make. Only CMake-based build will be discussed.
Prerequisites:
- 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!
- On MacOS the default
ar
program lacks support for response files (e.g., https://github.com/evaleev/libint/issues/135 and see https://gitlab.kitware.com/cmake/cmake/issues/16731). Thus you should install the GNUar
program (e.g., using HomeBrew:brew install binutils
) and tell CMake to use it (e.g., add-DCMAKE_AR=/usr/local/opt/binutils/bin/ar
to the CMake command line).
- (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
-DREQUIRE_CXX_API=OFF
to 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.y
- cmake . -DCMAKE_INSTALL_PREFIX=[installation prefix] -DCMAKE_CXX_COMPILER=[C++ compiler] -DCMAKE_CXX_FLAGS=[C++ compiler flags] ; out-of-source builds are also supported
- cmake --build .
- optional: cmake --build . --target check
- cmake --build . --target install
To enable Fortran bindings generation add -DENABLE_FORTRAN=ON
to the cmake
command line, and set the FC
environment variable to the Fortran compiler you want to use, or, alternatively, pass the compiler on the cmake
command line as -DCMAKE_Fortran_COMPILER=[/path/to/fortran/compiler]
.
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:
-
REQUIRE_CXX_API={ON,OFF} controls whether the C++ API is required or not; the default is
ON
. -
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.
- Apple clang++ and MacPorts g++ (4.8) both work with -std=c++11 flag
- MacPorts gmp package works fine
- standard configuration: '--enable-generic-code' '--with-max-am=6' '--with-opt-am=3' '--enable-eri3=0' '--enable-eri2=0' '--enable-eri3-pure-sh' '--enable-eri2-pure-sh' '--enable-fma' '--disable-1body-property-derivs'
- configuration prior to Jan. 8, 2015: '--enable-eri=0' '--with-max-am=7' '--with-opt-am=4' '--disable-unrolling' '--enable-generic-code' '--enable-contracted-ints'
- standard configuration: '--enable-eri=0' '--with-max-am=7' '--with-opt-am=4' '--disable-unrolling' '--enable-generic-code' '--enable-contracted-ints' '--with-cartgauss-ordering=gamess'
- a libint library (version 2.0.2) is embedded in ORCA
- standard configuration: '--enable-eri=2' '--enable-eri3=2' '--enable-eri2=2' '--with-max-am=7' '--with-opt-am=4' '--with-eri-max-am=7,4,3' '--with-eri-opt-am=4,3,2' '--disable-unrolling' '--enable-generic-code' '--enable-contracted-ints' '--with-cartgauss-ordering=orca' '--with-shell-set=orca' '--enable-eri3-pure-sh' '--enable-eri2-pure-sh'
- standard configuration: '--with-max-am=4' '--with-eri3-max-am=6' '--with-eri2-max-am=6' '--enable-eri3=1' '-enable-eri=1' '--enable-eri2=1' '--disable-unrolling' '--enable-generic-code' '--enable-contracted-ints' '--with-cartgauss-ordering=bagel'
- if you want to use spherical Gaussians only add: '--enable-eri3-pure-sh' '--enable-eri2-pure-sh' (some tests may fail)
- It appears that on a Mac Libint and BAGEL must be either both static or both shared (2/3/2014)