Building Siesta with CMake

Siesta requires CMake >= 3.20, and (if used) the ninja (>=1.10) backend. Both cmake and ninja can be installed easily in most systems, in particular with conda or pip.

This document provides the basic instructions for building, but the details depend on the way the software stack is organized in the target machine. We provide more information about what to do in various cases in the build-tools repository.

Siesta’s CMake scripts have borrowed ideas from the DFTB+, SIRIUS, and other open-source projects, and we fully acknowledge their contributions and efforts towards streamlining the build-system experience.

Quick and go

The most basic compilation of Siesta can be done simply by:

cmake -S. -B_build -DCMAKE_INSTALL_PREFIX=/path/to/installation  #<MORE_OPTIONS>
cmake --build _build -j 4
cmake --install _build

If your system is relatively standard and all required dependencies are found this will result in the /path/to/installation/bin directory being populated with executables for siesta, tbtrans, and all the Siesta utilties.

Most likely, you will have to work a bit more to provide the <MORE_OPTIONS> part of the above command. Follow the instructions below, and note the sections below on toolchains for some examples.

Dependencies

Siesta relies on a number of libraries, some required and some optional. The CMake approach facilitates the handling of these dependencies, and several modes of operation are available:

  • You can pre-install (some of) the libraries and provide CMake with hints about where to find them. This can be done by setting the CMAKE_PREFIX_PATH environment variable to the paths of the installed packages. For example:

    export CMAKE_PREFIX_PATH=/path/libxc/share/cmake:/path/libgridxc/share/cmake
    cmake ...
    

    CMake to look for the required packages in the directories specified in CMAKE_PREFIX_PATH.

    Alternatively, you can set CMAKE_PREFIX_PATH as a CMake variable when running the cmake command. For example:

    cmake ... -DCMAKE_PREFIX_PATH=/path/libxc/share/cmake;/path/libgridxc/share/cmake
    

    Please note the different delimiters used: “:” for Unix OS and “;” for CMake list separator, and remember to replace /path/... with the actual path to the installed libraries on your system.

  • The source for (some of) the external libraries can be made available in the External/ subdirectories by activating git submodules within the Siesta distribution:

    git submodule update --init --recursive
    

    This option requires versions of git 2.13 and above, and is only available for versions of Siesta that have been accessed via git  clone. Release and source code packages obtained through direct downloads from Gitlab do not feature this capability. If CMake detects source code is those directories, it can compile it on-the-fly.

  • The source for (some of) the external libraries can be downloaded automatically and compiled on-the-fly

    If users do not have internet access on the compiling machine one must send the sources by other means. To aid this procedure one may use the stage_submodules.sh script to gather all sources for later uploading. (More on this in the build-tools repo)

Here is the list of dependencies together with their options, with notes on whether they can be compiled on-the-fly or not.

System software

These are functionalities that should be already installed in most systems devoted to scientific computing. Please check your site’s documentation about available versions.

Note that this “system software stack” should be consistent, and the libraries (e.g. LAPACK, ScaLAPACK, etc) should have versions that match the compiler and MPI system used. Software-stack support can get complicated pretty quickly, and most sites use package managers such as Spack or EasyBuild, offering users the possibility to load environment modules to select the appropriate software stack. Depending on the installation, either the libraries are installed in “well-known” places or environment modules set their variables in a CMake-friendly way, so CMake will detect the appropriate libraries and no further action is needed on the part of the user. If not, the CMake search can be helped by setting “hint” variables, as explained below. We suggest that CMake is run first without any extra libraries, and the log inspected to see if the appropriate libraries have been found.

BLAS (required)

  • BLAS_LIBRARY=<name of library>|NONE specifies the library name for linking.

    The NONE setting should can be used when BLAS is implicitly linked through other libraries (for example, when OpenBLAS provides LAPACK), or by the compiler itself (e.g. the Cray compiler )

  • BLAS_LIBRARY_DIR=<path to library> place where to find the library BLAS_LIBRARY

  • BLAS_LINKER_FLAG flags to use when linking

Example:

cmake ... -DBLAS_LIBRARY=blis \
          -DBLAS_LIBRARY_DIR=/opt/blis/lib

LAPACK (required)

  • LAPACK_LIBRARY=<name of library>|NONE specifies the library name for linking. If NONE LAPACK is implicitly linked through other libraries/flags or the compiler itself (e.g. Cray).

  • LAPACK_LIBRARY_DIR=<path to library> place where to find the library LAPACK_LIBRARY

  • LAPACK_LINKER_FLAG flags to use when linking

Example:

cmake ... -DLAPACK_LIBRARY=openblas \
          -DLAPACK_LIBRARY_DIR=/opt/openblas/lib \
          -DBLAS_LIBRARY=NONE

ScaLAPACK (required for MPI support)

  • SCALAPACK_LIBRARY=<name of library>|NONE specifies the library name for linking. If NONE ScaLAPACK is implicitly linked through other libraries/flags or the compiler itself.

  • SCALAPACK_LIBRARY_DIR=<path to library> place where to find the library SCALAPACK_LIBRARY

  • SCALAPACK_LINKER_FLAG flags to use when linking

Example:

cmake ... -DSCALAPACK_LIBRARY="-lmkl=cluster" \
          -DBLAS_LIBRARY=NONE -DLAPACK_LIBRARY=NONE

For certain versions of unix-based Scalapack installations, this flag needs to be set explicitly to -DSCALAPACK_LIBRARY="-lscalapack-openmpi" (or the variant you want to use). If not, CMake will fail to find it.

OpenMP

Enable threading support using OpenMP.

Both TranSiesta/TBtrans may benefict from OpenMP when running large systems which may result in performance gains plus memory reductions. The rest of Siesta will not benefit as much.

  • SIESTA_WITH_OPENMP=OFF|ON to disable, enable support respectively. By default it is OFF.

Users are recommended to test whether it makes sense for them to use the threading support.

Be aware of OMP_NUM_THREADS and OMP_PROC_BIND variables which may highly influence the performance gains.

Required domain-specific libraries

These libraries were formerly part of the Siesta distribution, but now they are packaged separately and made available to third parties. They are part of the offerings of the Electronic Structure Library (ESL), and they feature as modules in the MaX (“Materials at the eXascale”) Center of Excellence.

There might be pre-installed versions of (some of) these libraries. If not, they can be fetched and compiled on-the-fly if there is an internet connection. Alternatively, the source code can be made available by instantiation of a git submodule (it will be placed in the External/ folder, or by manual deposit (in that one or in a custom source directory). All these options are controlled by the setting of the <PACKAGE>_FIND_METHOD CMake variable, where <PACKAGE> stands for the uppercase form of any of the package names below. By default, its value is:

<PACKAGE>_FIND_METHOD="cmake;pkgconf;source;fetch"

allowing all available kinds of library-search strategies, which will be tried in this order:

  • cmake will search using CMake’s find_package

  • pkgconf will search using the pkg-config wrappers within CMake.

    cmake and pkgconf are generically implemented using package finders shipped with CMake. Ensure CMAKE_PREFIX_PATH and PKG_CONFIG_PATH are (prepended)/appended with the directories that should be searched.

  • source will compile the sources if found in <PACKAGE>_SOURCE_DIR, which typically defaults to External/<package>. The sources can be checked out via git submodule instantiation, manually cloned, unpacked from a release archive, etc.

  • fetch will fetch the source , using the variables:

    • <PACKAGE>_GIT_REPOSITORY: the URL of the Git repository to clone the sources. It defaults to the original development site. Changing it may be useful for testing forks with different functionaties (mostly for developers or advanced users).

    • <PACKAGE>_GIT_TAG: points to the revision to be checked out (tag, branch, or commit hash).

NOTE: The value of the <PACKAGE>_FIND_METHOD variables defaults to that of SIESTA_FIND_METHOD, which in turn defaults to cmake;pkgconf;source;fetch.

libfdf (required)

(Submodule) sources in the External/libfdf folder.

libpsml (required)

Enables the reading of pseudopotential files in the PSML file format, such as those downloaded from www.pseudo-dojo.org.

(Submodule) sources in the External/libpsml folder.

xmlf90 (required)

It is used in Siesta as a dependency of libpsml, and also to produce XML output.

(Submodule) sources in the External/xmlf90 folder.

libgridxc (required)

Evaluates the XC energy and potentials on the grids where the density is calculated. It can leverage the libxc library, which is optional (see below) but highly recommended.

The libgridxc library used must be compatible with the MPI and grid-precision settings in SIESTA (e.g. those controlled by the SIESTA_WITH_MPI and SIESTA_WITH_GRID_SP variables). This is automatic if it is compiled on-the-fly. If if it pre-installed, CMake will verify the compatibility.

Extra variables:

  • LIBGRIDXC_MIN_VERSION can be used to allow the use of a (pre-compiled) lower minimum version (the default is “2.0.1”). Note that the use of older versions of libgridxc might cause some malfunctions. For example, the new default of reparametrizing the pseudopotential grids might not work well with vdw functionals. The absolute minimum version is 0.10.0.

(Submodule) sources in the External/libgridxc folder.

Optional libraries

simple-DFTD3 (optional)

Add support for DFTD3 dispersion corrections as suggested by Grimme et.al.

(Submodule) sources in the External/DFTD3/s-dftd3 folder.

  • SIESTA_WITH_DFTD3=ON|OFF to enable, disable support respectively. Defaults to ON if the External/DFTD3/ directory contains directories with the appropriate sources.

The variables controlling this package’s handling are prefixed by S-DFTD3 (e.g. S-DFTD3_FIND_METHOD). The package depends on a number of sub-packages that are handled automatically. Their names and their associated prefixes are:

  • mctc-lib (MCTC-LIB)

  • mstore (MSTORE)

  • test-drive (TEST-DRIVE)

  • toml-f (TOML-F)

PEXSI (native interface)

The Pole EXpansion and Selected Inversion (PEXSI) method evaluates certain selected elements of matrix functions, e.g., the Fermi-Dirac function of the KS Hamiltonian, yielding the density matrix. It can be used as a highly scalable and efficient alternative to diagonalization methods.

  • SIESTA_WITH_PEXSI=ON|OFF to enable, disable support respectively. Defaults to OFF.

This refers to the native interface to PEXSI in Siesta. PEXSI is also offered by the ELSI library of solvers, both as built-in and as ‘external library’. If ELSI is compiled with an external PEXSI, the same PEXSI library must be used.

The PEXSI library must be pre-compiled, and it can be found in several ways:

  • If an ELSI library (with PEXSI) is available, it will be used if CMAKE_PREFIX_PATH includes the path to the ELSI installation.

  • For (pre-release) PEXSI 2.1 (which uses a new scheme with subordinate libraries), the environment variable PEXSI_ROOT must point to the PEXSI installation directory.

  • For PEXSI v2.0, CMAKE_PREFIX_PATH must include the path to the PEXSI installation, and it will use the CMake config package.

The PEXSI libraries can be obtained from

See the file Config/cmake/search_for_native_PEXSI_provider.cmake for more details.

CheSS (experimental)

CheSS implements a linear-scaling Fermi-Operator-Expansion method with Chebyshev polynomials. It was developed by the BigDFT project.

  • SIESTA_WITH_CHESS=ON|OFF to enable, disable support respectively. Defaults to OFF.

See Config/cmake/Modules/FindCustomCHESS.cmake for details on how to link against CheSS. You might have to do some work to compile the needed dependencies from the BigDFT project, and tweak the finder module.

FFTW

The FFTW library is currently only used in the Util/STM/ol-stm utility.

  • SIESTA_WITH_FFTW=ON|OFF to enable, disable support respectively. Defaults to ON if found.

FLOOK

Flook implements an interface to access internal Siesta variables from a built-in Lua interpreter, enabling the creation of custom scripted functionality (e.g. control of molecular dynamics trajectories, novel geometry-relaxation methods) without recompiling the code.

  • SIESTA_WITH_FLOOK=ON|OFF to enable, disable support respectively. Defaults to ON if found.

(Submodule) sources in the External/Lua-Engine folder.

An installed version might be found if its root directory is contained in CMAKE_PREFIX_PATH or in the environment variable FLOOK_ROOT.

If not found in the default directory, the source can be fetched automatically from the flook development site, or from the URL contained in the environment variable FLOOK_PACKAGE.

If you already have an installation of lua that is compatible with flook, you can set the LUA_DIR environment variable to the directory containing lib/liblua.*. Then, flook will not compile its own version of lua and will use the provided one.

Wannier90 “wrapper-library” interface

A wrapper interface between Siesta and wannier90 (version 3.1.0) so that wannier90 can be called from Siesta on-the-fly.

  • SIESTA_WITH_WANNIER90=ON|OFF to enable, disable support respectively. Defaults to OFF.

Turn on the SIESTA_WITH_WANNIER90 option and use an environment variable WANNIER90_PACKAGE that points to a pristine wannier90-3.1.0.tar.gz file (a remote URL is also allowed). This file will be unpacked, patched, and compiled into a wrapper library that Siesta can use directly.

If SIESTA_WITH_WANNIER90 is set to ON and no package is found, SIESTA will attempt to automatically download Wannier90 3.1.0.

Other Siesta Options

Siesta provides other options to control some internal features. The generic Siesta executable should be sufficient for most, but some users may have different needs.

  • SIESTA_WITH_GRID_SP=OFF|ON use single-precision grid operations (Default OFF). It can reduce the memory requirements for large mesh-cutoffs and/or large unit-cells, at the expense of some precision. The default is to use double precision -DSIESTA_WITH_GRID_SP=OFF

If you enable this feature you might consider adding the variable SIESTA_SUFFIX=_grid_sp so that the Siesta executable and libraries are properly tagged in this case.

Profiling

Support for profiling is overloaded in the “timer” interface. The currently enabled profiling options are:

  • SIESTA_WITH_PROFILE_NVTX=ON|OFF (Defaults to OFF) If enabled, the variable SIESTA_PROFILE_NVTX_LIBRARY must contain the path to the libnvToolsExt library by nVidia.

The EXTRAE library by BSC can be used to generate MPI traces, but its configuration is not yet supported by the CMake build system. See the next section.

Use of options not supported directly by CMake

Some options are not yet supported directly by the CMake framework, but they can still be supported indirectly.

For example, if it is desired to use the MUMPS library in TranSiesta, the library needs to be pre-compiled, and the following CMake variable specified:

-DFortran_FLAGS="-DSIESTA__MUMPS <other flags>"
-DSIESTA_LINKER_FLAGS="-L/path/to/mumps/lib -lzmumps -lmumps_common <other libraries>"

where ‘<>’ are any libraries that MUMPS depends on, and ‘/path/to/mumps’ is the root of the MUMPS installation.

This mechanism is general, even if a bit coarse. It is expected that native CMake support for all options will be offered soon.

Settings for compiler flags and build types

Compilation flags

Compilation flags are generally managed through the environment variables (NOT CMake variables).

  • FC for specifying the fortran compiler

  • FFLAGS for specifying the compilation flags

An invocation might be:

FC=gfortran FFLAGS='-O3 -march=native' cmake ...

Alternatively, the flags can be supplied on the command line

cmake -DFortran_FLAGS=-Os -DC_FLAGS=-Os

This enables fine tuning of the compiler flags.

Customarily, CMake uses the CMAKE_<LANG>_FLAGS. These may also be used

Toolchains for compiler flags

Siesta’s build system supports the use of SIESTA_TOOLCHAIN files to gather compiler flags. (This is different from, although related to the functionality provided by the CMAKE_TOOLCHAIN_FILE variable; see below)

This feature can be used in several ways:

# Use default toolchain files located in Config/cmake/toolchains

  cmake ... -DSIESTA_TOOLCHAIN=gnu

# or a full path (for local edited files)

  cmake ... -DSIESTA_TOOLCHAIN=/path/to/toolchain/file/gnu.cmake

When using SIESTA_TOOLCHAIN one can use multiple toolchains. This can be valuable for overwriting or adding variables from various toolchains (mainly useful for developers). For example:

cmake -DSIESTA_TOOLCHAIN=gnu;local ...

to use ./Config/cmake/toolchains/gnu.cmake and ./local.cmake.

Currently the default toolchain to use will be decided internally as follows:

  • GNU compilers will use the Config/cmake/toolchains/gnu.cmake toolchain file.

  • Intel (and the newer Intel LLVM backend) compilers will use the Config/cmake/toolchains/intel.cmake toolchain file.

  • Otherwise a generic toolchain file will be used, which uses the default CMake variables.

To gain complete control of the compiler flags (without adding the toolchain ones) you will have to select the none toolchain and set the flags by hand:

cmake -DSIESTA_TOOLCHAIN=none -DFortran_FLAGS="-Os -DSOME__VAR"

Custom toolchain files and pre-loading of cache variables

A custom toolchain may contain any setting of variables. They can be thought of as an arch.make file with default parameters.

Toolchains for a few sample computer systems can be found in Config/cmake/toolchains, but note that it is impractical to cover all possibilities. Further examples and documentation for building can be found in this repository.

There are two ways to load a custom toolchain file:

# Use of the -C option to pre-load the (cache) variables contained in the file:

  cmake ... -C Config/cmake/toolchains/leonardo.cmake

# Use the form:

  cmake ... -DCMAKE_TOOLCHAIN_FILE=Config/cmake/toolchains/leonardo.cmake

The second form is somewhat of an abuse of the CMake functionality intended for cross-compilation. The first form loads the variables at the beginning of the CMake configuration run, before the project() call is executed, so custom toolchain files loaded with -C can contain settings for the build type (see next section).

Parameters that exists in a toolchain file can be overridden on the command-line with cmake -D<VAR>=<VALUE>.

Developers are suggested to create custom toolchain files with the appropriate variables. CMake’s presets functionality could also be used, although it is not officially supported by Siesta yet.

Build type

CMake uses a build-type to help determine the flags to be used. The default build type (Release) should be sufficient for most (if not all users), but other types can be enabled with, for example:

cmake -DCMAKE_BUILD_TYPE=Debug

Currently the default Siesta toolchain files support these build types:

  • Release: the default and recommended build type, it uses a high optimization level without sacrifycing accuracy.

  • Debug: used for debugging Siesta, or if there are runs that show problems. Bug reports should use this build

  • Check: used for debug + checking code execution runs, primarily useful for developers; equally good for bug-reports.

  • RelWithDebInfo: a release mode with debug symbols.

  • MinSizeRel: optimizes the executables for minimum size (-Os)

Compiler flags associated to the different build types can also be specified in the command line. For example:

cmake -DFortran_FLAGS="-Wall" -DFortran_FLAGS_DEBUG=-g -DCMAKE_BUILD_TYPE=Debug

will result in the internal variable CMAKE_Fortran_FLAGS evaluating to the string -Wall -g, because Fortran_FLAGS is sort of a global setting, while Fortran_FLAGS_DEBUG applies only to the Debug build type.

Custom build types can also be specified if needed for particular uses:

cmake  -DFortran_FLAGS_EXOTIC="-fcrazy-unroll -ffind-bugs"  -DCMAKE_BUILD_TYPE=Exotic

The currently supported build-types in the shipped toolchain files are:

  • Fortran_FLAGS

  • Fortran_FLAGS_RELEASE

  • Fortran_FLAGS_DEBUG

  • Fortran_FLAGS_CHECK

  • Fortran_FLAGS_RELWITHDEBINFO

  • Fortran_FLAGS_MINSIZEREL

Custom suffixes for executables and/or libraries

By default, Siesta executables and libraries are installed with plain names such as siesta, tbtrans, libsiesta.a, etc. A custom suffix can be added by using the variables

  • SIESTA_SUFFIX (for executables and libraries)

  • SIESTA_EXECUTABLE_SUFFIX

  • SIESTA_SHARED_LIBRARY_SUFFIX

  • SIESTA_STATIC_LIBRARY_SUFFIX

For instance, to change the suffixes for the executables:

cmake ... -DSIESTA_EXECUTABLE_SUFFIX=.x

will create siesta.x, and similarly for all other executables.

This can be used to have multiple executables in the same PATH using different backends. For example, a GPU enabled executable can be build with -DSIESTA_EXECUTABLE_SUFFIX=_gpu.

Inspecting the configuration log file

The first part of the CMake invocation:

cmake -S. -B_build -DCMAKE_INSTALL_PREFIX=/path/to/installation  #<MORE_OPTIONS>

will produce lenghty output related to the configuration steps, the variables used, packages found (or not found), etc. A final summary of all the options applied is also shown.

This output can appear overwhelming at first, but it pays to read it with some care, particularly if errors appear. It is also important to keep it in case a building issue has to be brought to the developers. In fact, in some cases even more output might be useful.

Using

cmake --log-level=debug ...

will show more internal steps.

Tests

Siesta’s build system integrates a testing framework, which is exercised by executing the ctest program under the build directory.

cd _build
ctest

If the required external libraries have been compiled as part of the current CMake invocation, installation tests for them will also be executed.

If you want to run only a minimal set of Siesta tests, you can select the simplest representative cases by choosing the label “simple”:

ctest -L simple <options>

One can test separately the execution of the examples and the verification of the numerical precision of the results (when compared to the provided reference outputs). The latter test involves the setting of appropriate tolerances, and its results might sometimes depend on the libraries used or on whether MPI is used or not. Further work is being done on the architecture of the verification process, to make it more robust and complete.

For output verification you will need a local Python installation with the ruamel.yaml package installed. To enable test verification, use the SIESTA_TESTS_VERIFY environment variable. For example:

SIESTA_TESTS_VERIFY=1 ctest # Runs and verifies all tests.

You can also run a single test using the -R option with the name of the test itself; for example:

ctest -R default_basis

Spack support

Spack is a package manager that can ease the task of maintaining and configuring the software stack.

We make available spack recipes and sample spack environment files for Siesta and relevant needed libraries in this auxiliary repo.

Deprecated options

Legacy form of the options

Most of the options above are prefixed by SIESTA_. The simpler forms without the prefix (e.g. WITH_MPI instead of SIESTA_WITH_MPI) are no longer accepted by default.

Units definitions

Since Siesta 5.0 the internal units in Siesta are based on CODATA-2018, so some numerical differences from older versions can be expected. In general these differences will be quite small, but sometimes the results might be appreciably different from older calculations, particularly for molecular dynamics runs.

One can select the units employed by using this cmake invocation:

# this will use the same units as in the 4 series and older
   cmake ... -DSIESTA_WITH_UNIT_CONVENTION=legacy
# this will use the new units (the default)
   cmake ... -DSIESTA_WITH_UNIT_CONVENTION=codata2018

It is NOT recommended to use the legacy scheme for anything but tests. The new units should always be preferred.