cp2k/tools/toolchain/install_cp2k_toolchain.sh
Stefano Battaglia ad1d558f05
refactor: Remove OneDFT branding from GauXC interface (#5563)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-10 09:05:04 +02:00

1609 lines
61 KiB
Bash
Executable file

#!/bin/bash -e
# Disabled shellcheck items: SC1091 for external scripts, SC2034 for unused
# variables, SC2124 for concatenating toolchain options with $@, SC2129 for
# individual redirects ">>".
# shellcheck disable=SC1091,SC2034,SC2124,SC2129
[ "${BASH_SOURCE[0]}" ] && SCRIPT_NAME="${BASH_SOURCE[0]}" || SCRIPT_NAME=$0
SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_NAME")" && pwd -P)"
# +---------------------------------------------------------------------------+
# | CP2K: A general program to perform molecular dynamics simulations |
# | Copyright 2000-2022 CP2K developers group <https://cp2k.org> |
# | |
# | SPDX-License-Identifier: GPL-2.0-or-later |
# +---------------------------------------------------------------------------+
#
#
# *****************************************************************************
#> \brief This script will compile and install or link existing tools and
#> libraries CP2K depends on and generate a set of ARCH files which
#> can be used to compile CP2K
#> \history Created on Friday, 2016/02/05
# Update for Intel (17.01.2022, MK)
#> \author Lianheng Tong (ltong) lianheng.tong@kcl.ac.uk
# *****************************************************************************
# ------------------------------------------------------------------------
# Work directories and used files
# ------------------------------------------------------------------------
export ROOTDIR="${PWD}"
export SCRIPTDIR="${ROOTDIR}/scripts"
export BUILDDIR="${ROOTDIR}/build"
export INSTALLDIR="${ROOTDIR}/install"
export TOOLKIT_SCRIPT="${SCRIPTDIR}/tool_kit.sh"
# ------------------------------------------------------------------------
# Make a copy of all options for $SETUPFILE
# ------------------------------------------------------------------------
TOOLCHAIN_OPTIONS="$@"
# ------------------------------------------------------------------------
# Exit this script if it is not called from the ./tools/toolchain directory
# ------------------------------------------------------------------------
if [ "${ROOTDIR}" != "${SCRIPT_DIR}" ]; then
cat << EOF
ERROR: (${SCRIPT_NAME}, line ${LINENO}) Incorrect execution location.
The absolute path of the main toolchain script is at:
${SCRIPT_DIR}
Actual working directory where it is currently called:
${ROOTDIR}
Please enter the absolute path above before executing the main toolchain script
so that subsequent scripts can be found and files can be placed correctly.
EOF
exit 1
fi
# ------------------------------------------------------------------------
# Load common variables and tools
# ------------------------------------------------------------------------
source "${SCRIPTDIR}"/common_vars.sh
source "${SCRIPTDIR}"/tool_kit.sh
# ------------------------------------------------------------------------
# Documentation
# ------------------------------------------------------------------------
show_help() {
cat << EOF
This script will help you prepare the toolchain for compiling and using CP2K.
There are a number of dependency packages for CP2K, which may be downloaded
from internet and freshly installed, or detected from system path and linked.
Once these dependencies are ready, the CMake options for compiling CP2K and
further instructions will be printed at the end of this script's execution.
See README.md under the toolchain directory for more information.
USAGE:
$(basename "$SCRIPT_NAME") [options]
OPTIONS:
-h, --help Show this message and exit.
--help-hpc Show additional hints for HPC users and exit.
-j <n> Number of processors for parallel compiling.
If omitted, the script will automatically try to
determine the number of available processors and use
all of them by default.
--install-dir Set the directory you want to installed toolchain
dependencies to. Default is the "install" directory
in current path.
--no-check-certificate Bypass verification of server's certificate while
downloading anything from internet via wget command.
In case wget errors about "certificate verification"
or "common name doesn't match requested host name"
occur while downloading tarballs, the recommended
solution is to install the latest wget release;
alternatively, this script can be rerun with this
option in command line.
Security wise this should still be okay as sha256
checksums are validated after every tarball
download. Nevertheless, use this option at your own
risk.
--install-all Set value of all --with-PKG options to "install"
(except --with-intel, --with-intelmpi, --with-amd).
By default, GNU compiler and MPICH are installed.
AFTER this option on the command line, you can set
specific --with-PKG options to another value again
for selective fine controls (see below).
--mpi-mode Select which MPI flavour to use. Available options
are: mpich, openmpi, intelmpi, and no.
If omitted, the script will automatically try to
determine the flavour based on the MPI library
available in system path; alternatively, if any of
--with-mpich, --with-openmpi or --with-intelmpi
options (see below) is explicitly set to values
other than no, the script will follow.
For CRAY (CLE) systems and the case that you use
"--with-mpi" but no MPI installation is detected,
the default flavour is mpich.
By selecting "no", MPI is unsupported and disabled.
--math-mode Select which core math library to use. Available
options are: acml, cray, mkl, and openblas.
If omitted, for non-CRAY systems, mkl is the default
when environment variable \$MKLROOT exists, otherwise
openblas is the drefault; for CRAY (CLE) systems,
cray is the default, corresponding to cray libsci.
Alternatively, if any of --with-acml, --with-mkl,
or --with-openblas options (see below) is explicitly
set to values other than no, the script will follow.
--target-cpu Select the target CPU architecture for compiling.
This option determines the value of -mtune flag in
CFLAGS for compilers. If omitted or set to "native",
compiling will be tuned/optimized for the native
host system, and some instruction sets will be
detected including AVX, AVX2, AVX512,etc.
Alternatively this option can be set depending on
actual target CPU microarchitecture, e.g. "haswell",
"skylake", or just "generic".
Default = native
--gpu-ver Select the target GPU architecture for compiling.
Available options are: K20X, K40, K80, P100, V100,
A100, H100, GB10, A40, Mi50, Mi100, Mi250, and no.
This option determines the value of nvcc -arch flag.
Default = no
--libint-lmax Maximum supported angular momentum by libint if the
"--with-libint" option is set to "install".
Available options are: 4, 5, 6, 7. Higher value will
result in more build time and larger library size.
Default = 5
--log-lines The number of final lines from the log file in the
corresponding directory that will be dumped to the
command line in case a package build returns a non-
zero exit code. Due to limited length, this snippet
may not contain the very first warning or error
message.
Default = 200
--dry-run After writing toolchain config and env files to the
install directory, just print a list of effective
settings after resolving known conflicts, then exit
without actually downloading tarballs or building
packages.
The --enable-FEATURE options follow the rules:
--enable-FEATURE=yes Enable this particular feature.
--enable-FEATURE=no Disable this particular feature.
--enable-FEATURE The option keyword alone is equivalent to
--enable-FEATURE=yes
Specific options of --enable-FEATURE:
--enable-tsan Turn on Thread Sanitizer (TSAN) for GNU compiler.
Default = no
--enable-cuda Turn on GPU (CUDA) support.
Can be combined with --enable-opencl.
Default = no
--enable-gauxc-cutlass Turn on CUTLASS local work driver support when
installing GauXC. Requires --with-gauxc=install,
--enable-cuda=yes, and CUDA compute capability >= 8.0.
Default = no
--enable-hip Turn on GPU (HIP) support.
Default = no
--enable-opencl Turn on OpenCL (GPU) support. Requires the OpenCL
development packages and runtime. If combined with
--enable-cuda, OpenCL alongside of CUDA is used.
Default = no
--enable-cray Turn on CRAY Linux Environment (CLE) support.
If omitted, the script will automatically try to
determine if your system is CLE by detecting
environment variable \$CRAY_LD_LIBRARY_PATH and
provide support accordingly.
The --with-PKG options follow the rules:
--with-PKG=no Do not use the package.
--with-PKG=install Download and decompress the package in \$PWD/build,
and install the library package in \$PWD/install.
--with-PKG=system Find the required libraries of the package from the
system path variables such as PATH, LD_LIBRARY_PATH
and CPATH etc.
--with-PKG=<path> The package will be assumed to be installed in
the given <path>, and be linked accordingly.
--with-PKG The option keyword alone will be equivalent to
--with-PKG=install
Specific options of --with-PKG:
--with-gcc Use the GNU compilers (gcc, g++, gfortran) to build
newly installed dependencies and CP2K.
Only one of --with-gcc, --with-intel and --with-amd
should be used.
Default = system
--with-intel Use the Intel compilers (icx, icpx, ifort) to build
newly installed dependencies and CP2K.
Default = system
--with-ifx If yes, use the new Intel Fortran compiler ifx
instead of ifort to compile CP2K.
Default = no
--with-amd Use the AMD compilers (clang, clang++, flang) to
build newly installed dependencies and CP2K.
Default = system
--with-cmake CMake utilities.
Default = install
--with-ninja Ninja utilities.
Default = install
--with-openmpi Use OpenMPI library for parallel versions of
newly installed dependencies and CP2K.
Only one of --with-openmpi, --with-mpich and
--with-intelmpi should be used, and --mpi-mode option
(see above) should be consistent.
Default = system
--with-mpich Use MPICH library for parallel versions of
newly installed dependencies and CP2K.
Default = system
--with-mpich-device Select the MPICH device, implying use of MPICH.
Default = ch4
--with-intelmpi Use Intel MPI library for parallel versions of
newly installed dependencies and CP2K.
Default = system
--with-openblas Use OpenBLAS, which provides LAPACK and BLAS library,
and is also used to get arch information.
--math-mode option (see above) should be consistent.
Default = install
--with-mkl Use Intel Math Kernel Library (MKL), which provides
LAPACK and BLAS library.
If MKL's FFTW3 interface is suitable (no FFTW-MPI
support), it replaces the FFTW library.
If the ScaLAPACK component is found, it replaces the
one specified by --with-scalapack.
Default = system
--with-acml Use AMD core maths library (ACML), which provides
LAPACK and BLAS library.
Default = system
--with-gmp Enable GMP library, optional dependency of GreenX.
Default = no
--with-fftw Enable FFTW3 library for fast fourier transform.
Default = install
--with-libxc Enable libxc for exchange-correlation in QuickStep
DFT (pure and hybrid functionals) calculations.
Default = install
--with-gauxc Enable GauXC for external exchange-correlation
integration. Installing GauXC with Skala
support also enables libtorch and installs Skala-1.1.
Default = no
--with-eigen Enable Eigen3; required by libint and SIRIUS.
Default = no
--with-libint Enable libint for two-body molecular integrals in
Hartree-Fock and hybrid functional calculations.
Default = install
--with-greenx Enable GreenX library for Minimax grids and Padé
analytic continuation in RT-BSE.
This package requires CMake, BLAS and LAPACK.
Default = no
--with-cosma Enable COSMA as a replacement for ScaLAPACK in matrix
multiplication. If set to "install", COSTA and TileMM
will also be installed; if CUDA and/or HIP support is
enabled too, respective versions will all be built.
Default = install
--with-libxsmm Enable LIBXSMM to provide kernels for LIBXS.
Installing is supported on arch x86_64 or arm64.
Default = install
--with-libxs Enable LIBXS as a small matrix multiplication
library and for other low-level operations.
Default = install
--with-libxstream Enable LIBXSTREAM as an OpenCL-based accelerator
backend (requires LIBXS).
Default = install
--with-scalapack Enable ScaLAPACK for parallel linear algebra
calculations.
Default = install
--with-elpa Enable ELPA library as eigenvalue solver for large
parallel jobs.
Default = install
--with-ace Enable interface to ML-pace library.
Default = no
--with-deepmd Enable interface to DeePMD-kit library.
This does not include other DeepModeling utilities
like DP-GEN or dpdata.
Default = no
--with-gsl Enable the GNU scientific library (GSL).
This package is required for PLUMED and SIRIUS.
Default = install
--with-fmt Enable the formatting C/C++ library.
This package is required for SIRIUS.
Default = no
--with-libtorch Enable libtorch as a machine learning framework.
This package is required for NequIP and Allegro, and
also for installing DeePMD-kit.
Default = no
--with-plumed Enable interface to the PLUMED library for enhanced
sampling methods.
This package requires MPI, GSL and FFTW.
Default = no
--with-hdf5 Enable the hdf5 library for file format support.
This package is used by sirius and trexio.
Default = no
--with-libsmeagol Enable interface to SMEAGOL NEGF library.
This package requires MPI.
Default = no
--with-libvdwxc Enable libvdwxc library for support of Van der Waals
interactions in SIRIUS.
This library is optinal to SIRIUS.
Default = no
--with-libvori Enable libvori for the Voronoi integration and the
BQB compressed trajectory format.
Default = install
--with-spglib Enable the spg library for symmetry groups detection.
This package depends on CMake.
Default = install
--with-dftd4 Enable the standalone DFTD4 package by Grimme for the
DFT-D4 dispersion correction method.
This package requires CMake.
Default = no
--with-tblite Enable the tblite package by Grimme for GFN-xtb and
DFT-D4 methods, bundled with multicharge, mctc-lib,
mstore, s-dftd3, and toml-f libraries as backends.
If tblite is used, standalone DFTD4 package specified
by --with-dftd4 will not be used.
This package requires CMake.
Default = install
--with-sirius Enable interface to the plane wave SIRIUS library.
This package requires Libxc, ScaLAPACK, ELPA, GSL,
libspg, HDF5, pugixml, and libvdwxc.
Default = no
--with-pugixml Enable pugixml library for XML parsing.
This library is required by SIRIUS.
Default = no
--with-spla Enable the Specialized Parallel Linear Algebra (SPLA)
library.
This library is required by SIRIUS and is optional
for GPU support.
Default = no
--with-spfft Enable SpFFT for sparse Fourier Transform.
This library is required by SIRIUS.
Default = no
--with-trexio Enable the trexio library for TREXIO file format.
Default = no
--with-libfci Enable the libfci active-space solver library.
Default = no
--with-mcl Install MCL library for MiMiC with toolchain.
Default = no
--with-dbcsr Install DBCSR library with toolchain.
Default = install
--with-cusolvermp NVIDIA cusolverMp: CUDA library for distributed dense
linear algebra.
Default = no
--with-libgint Enable the use of libGint for the calculation of the Hartree-Fock exchange on (nvidia) GPUs
Default = no
FURTHER INSTRUCTIONS
Before running the script, please ensure that several prerequisites including
(but not limited to) wget, bzip2 and make are present, which should be provided
by the system package manager (such as dnf and apt). The install_requirements.sh
script in the toolchain directory can help collect them.
All packages to be installed locally will be downloaded and built inside
./build, and then installed into package specific directories inside ./install.
The directory ./build is safe to delete, as it contains only the files and
directories that are downloaded via this script to install these packages.
However, once the packages are installed and you compiled CP2K then you must
keep ./install in exactly the same location as it was first created, as it
contains tools and libraries your version of CP2K binary will depend on.
It should be safe to terminate running of this script in the middle of a build
process. The script will know if a package has been successfully installed and
will just carry on and recompile and install the last package it is working on.
This is true even if you lose the content of the entire ./build directory.
Some packages are sensitive to the environment variables of their dependencies.
Therefore, if you use --with-PKG_A=system but encounter an error indicating that
PKG_A cannot be found when installing PKG_B, please first check whether the
environment variables set for PKG_A are correctly and fully imported (especially
LIBRARY_PATH and CPATH, which are often overlooked).
For HPC users who wish to install toolchain dependencies and CP2K on public
supercomputer clusters for oneself, it would be helpful to use "--help-hpc"
option to show some hints and observations.
+----------------------------------------------------------------+
| YOU SHOULD ALWAYS SOURCE ./install/setup BEFORE YOU RUN CP2K |
| COMPILED WITH THIS TOOLCHAIN |
+----------------------------------------------------------------+
EOF
}
show_help_hpc() {
cat << EOF
For HPC users who wish to install toolchain dependencies and CP2K on public
supercomputer clusters for oneself:
As this is a complicated process, it is strongly advised to contact local
system administrators or managers for timely, specific assistance. Here are
some hints and observations that may be useful:
(1) Please don't forget to use "-h" or "--help" option to see detailed usage of
the toolchain script!
(2) Generally root or sudo power is not necessary, and a convenient directory
with read and write permission as well as sufficient disk space should be
okay when installing toolchain and CP2K for a single user.
(3) The server is very likely to have multiple compilers, MPI libraries, math
libraries and other packages that are managed by module systems, such as
LMod and Environment Modules. Users can load or unload modules to control
active environment variables and paths in runtime without conflicts. It is
recommended to check for available modules (with "module avail", "module
show" or similar commands) beforehand, and activate desired packages when
running the toolchain script with "--with-PKG=system" options so as to
avoid repeated labour. That said, actual compatibility between modules and
CP2K to be built may still take rounds of trial-and-error to confirm, and
resorting to "--with-PKG=install" can sometimes resolve problems if modules
turn out to be outdated, or compiled inconsistently, or not registering
complete variables and paths, or not built with GPU support on GPU machine,
etc. Please forward complaints about faulty modules to whoever responsible
for the server first before submitting any bug report to program developer.
(4) If no internet connection is available for downloading packages from public
resources on the server, an offline installation of toolchain and CP2K may
be carried out by downloading all packages elsewhere, transferring them to
server and placing them under the ./build directory. The toolchain script
will not attempt to download packages if they are already present in the
build directory, with filenames and sha256sum strings matching the records.
(5) An important common feature of clusters is the distinction of node types:
"login node", where users log in and perform tasks with low workload; and
"compute node", where resource-intensive computation jobs are carried out.
They may be hosted on separate machines, and their hardware specifications
(CPU, RAM, disk space, etc.) may be similar or different. Therefore, care
must be taken especially for the latter case. For instance, discrepancies
in CPU architectures and supported instruction sets may cause poor program
performance or illegal instruction errors if toolchain script is executed
on login node with "--target-cpu=native" (which is default too if omitted)
but CP2K is executed on compute node(s) afterwards. In this case, an option
"--target-cpu=generic" with best portability for compiling programs at the
cost of reduced (non-optimized) performance may be necessary.
(6) Again, be careful about the environment if CP2K is to be executed with job
submission scripts to the job queue system handling resource allocation.
Active environment variables and paths on the login node seen by user (by
loading modules, sourcing scripts, editing ~/.bashrc or /etc/profile files,
or entering commands interactively in general) may NOT be effective on the
compute node where CP2K actually runs, unless all appropriate commands are
written explicitly in the batch job submission script. For example, a
frequently encountered scenario with corrupted, interleaved output messages
stems from incorrect MPI library configuration launching multiple instances
of CP2K simultaneously instead of multi-process parallel execution of one
single instance; some possible culprits are that the ./install/setup file
is not sourced or the wrong module for MPI library is loaded at runtime.
EOF
}
# ------------------------------------------------------------------------
# PACKAGE LIST: register all new dependent tools and libs here. Order
# is important, the first in the list gets installed first
# ------------------------------------------------------------------------
tool_list="gcc intel amd cmake ninja"
mpi_list="mpich openmpi intelmpi"
math_list="mkl acml openblas"
lib_list="fftw eigen libint libxc gauxc libxsmm libxs libxstream cosma scalapack
elpa dbcsr cusolvermp plumed spfft spla gsl spglib hdf5 libvdwxc sirius
libvori libtorch deepmd ace dftd4 tblite pugixml libsmeagol fmt trexio
libfci greenx gmp mcl libgint"
package_list="${tool_list} ${mpi_list} ${math_list} ${lib_list}"
# ------------------------------------------------------------------------
# first set everything to __DONTUSE__
for ii in ${package_list}; do
eval "with_${ii}=__DONTUSE__"
done
# ------------------------------------------------------------------------
# Work out default settings
# ------------------------------------------------------------------------
# tools to turn on by default:
with_gcc="__SYSTEM__"
# libs to turn on by default:
with_dbcsr="__INSTALL__"
with_fftw="__INSTALL__"
with_eigen="__DONTUSE__"
with_libint="__INSTALL__"
with_libxsmm="__INSTALL__"
with_libxs="__INSTALL__"
with_libxstream="__DONTUSE__"
with_libxc="__INSTALL__"
with_gauxc="__DONTUSE__"
with_scalapack="__INSTALL__"
with_sirius="__DONTUSE__"
with_gsl="__DONTUSE__"
with_fmt="__DONTUSE__"
with_spglib="__INSTALL__"
with_hdf5="__DONTUSE__"
with_trexio="__DONTUSE__"
with_libfci="__DONTUSE__"
with_elpa="__INSTALL__"
with_cusolvermp="__DONTUSE__"
with_libvdwxc="__DONTUSE__"
with_spfft="__DONTUSE__"
with_spla="__DONTUSE__"
with_cosma="__INSTALL__"
with_libvori="__INSTALL__"
with_libtorch="__DONTUSE__"
with_ninja="__DONTUSE__"
with_dftd4="__DONTUSE__"
with_tblite="__INSTALL__"
with_libsmeagol="__DONTUSE__"
with_mcl="__DONTUSE__"
with_libgint="__DONTUSE__"
# the math and mpi libraries are chosen by their respective modes.
# default math library settings, MATH_MODE picks the math library
# to use, and with_* defines the default method of installation if it
# is picked. For non-CRAY systems defaults to mkl if $MKLROOT is
# available, otherwise defaults to openblas
if [ -n "${MKLROOT}" ]; then
export MATH_MODE="mkl"
with_mkl="__SYSTEM__"
else
export MATH_MODE="openblas"
fi
with_acml="__SYSTEM__"
with_openblas="__INSTALL__"
# for MPI, we try to detect system MPI variant
if (command -v mpiexec > /dev/null 2>&1); then
# check if we are dealing with openmpi, mpich or intelmpi
if (mpiexec --version 2>&1 | grep -s -q "HYDRA"); then
echo "MPI is detected and it appears to be MPICH"
export MPI_MODE="mpich"
with_mpich="__SYSTEM__"
elif (mpiexec --version 2>&1 | grep -s -q "OpenRTE"); then
echo "MPI is detected and it appears to be OpenMPI 4 (or older)"
export MPI_MODE="openmpi"
with_openmpi="__SYSTEM__"
elif (mpiexec --version 2>&1 | grep -s -q "Open MPI"); then
echo "MPI is detected and it appears to be OpenMPI 5"
export MPI_MODE="openmpi"
with_openmpi="__SYSTEM__"
elif (mpiexec --version 2>&1 | grep -s -q "Intel"); then
echo "MPI is detected and it appears to be Intel MPI"
with_gcc="__DONTUSE__"
with_amd="__DONTUSE__"
with_intel="__SYSTEM__"
with_intelmpi="__SYSTEM__"
export MPI_MODE="intelmpi"
else # default to mpich
echo "MPI is detected and defaults to MPICH"
export MPI_MODE="mpich"
with_mpich="__SYSTEM__"
fi
else
if [ -n "${CRAY_LD_LIBRARY_PATH}" ]; then
echo "Cray Linux Environment (CLE) is detected with no MPI"
else
echo "No MPI installation detected. (Ignore this message if
a fresh MPI installation is requested.)"
fi
export MPI_MODE="no"
fi
# default enable options
dry_run="__FALSE__"
enable_tsan="__FALSE__"
enable_opencl="__FALSE__"
enable_cuda="__FALSE__"
enable_gauxc_cutlass="__FALSE__"
enable_hip="__FALSE__"
export with_ifx="no"
export GPUVER="no"
export MPICH_DEVICE="ch4"
export TARGET_CPU="native"
NPROCS_OVERWRITE="$(get_nprocs)"
export NPROCS_OVERWRITE
# default for libint
export LIBINT_LMAX="5"
# default for log file dump size
export LOG_LINES="200"
# defaults for CRAY Linux Environment
if [ -n "${CRAY_LD_LIBRARY_PATH}" ]; then
enable_cray="__TRUE__"
export MATH_MODE="cray"
# Default MPI used by CLE is assumed to be MPICH, in any case
# do not use the installers for the MPI libraries
with_mpich="__DONTUSE__"
with_openmpi="__DONTUSE__"
with_intelmpi="__DONTUSE__"
export MPI_MODE="mpich"
# set default value for some installers appropriate for CLE
with_gcc="__DONTUSE__"
with_amd="__DONTUSE__"
with_intel="__DONTUSE__"
with_fftw="__SYSTEM__"
with_scalapack="__DONTUSE__"
else
enable_cray="__FALSE__"
fi
# ------------------------------------------------------------------------
# Parse user options
# ------------------------------------------------------------------------
echo "Toolchain script received the following options:"
echo " ${TOOLCHAIN_OPTIONS}"
echo "Parsing options and resolving conflicts..."
while [ $# -ge 1 ]; do
case ${1} in
-j)
case "${2}" in
-*)
NPROCS_OVERWRITE="$(get_nprocs)"
export NPROCS_OVERWRITE
;;
[0-9]*)
shift
export NPROCS_OVERWRITE="${1}"
;;
*)
report_error ${LINENO} "Non-integer argument ${2} for -j flag found."
;;
esac
;;
-j[0-9]*)
export NPROCS_OVERWRITE="${1#-j}"
;;
--install-dir=*)
if [[ "${1#--install-dir=}" != /* ]]; then
report_error "The path for --install-dir must be an absolute path."
fi
export INSTALLDIR="${1#--install-dir=}"
;;
--no-check-certificate)
export DOWNLOADER_FLAGS="--no-check-certificate"
;;
--install-all)
# set all package to the default installation status
for ii in ${package_list}; do
if [ "${ii}" != "intel" ] &&
[ "${ii}" != "intelmpi" ] &&
[ "${ii}" != "amd" ] &&
[ "${ii}" != "mkl" ] &&
[ "${ii}" != "acml" ] &&
[ "${ii}" != "cusolvermp" ]; then
eval "with_${ii}=__INSTALL__"
fi
done
# Use MPICH as default
export MPI_MODE="mpich"
;;
--mpi-mode=*)
user_input="${1#*=}"
case "$user_input" in
mpich)
export MPI_MODE="mpich"
;;
openmpi)
export MPI_MODE="openmpi"
;;
intelmpi)
export MPI_MODE="intelmpi"
;;
no)
export MPI_MODE="no"
;;
*)
echo "ERROR: Invalid value for --mpi-mode found."
echo "Currently only one of the following options is supported:
openmpi, mpich, intelmpi.
Otherwise use option no."
exit 1
;;
esac
;;
--math-mode=*)
user_input="${1#*=}"
case "$user_input" in
cray)
export MATH_MODE="cray"
;;
mkl)
export MATH_MODE="mkl"
;;
acml)
export MATH_MODE="acml"
;;
openblas)
export MATH_MODE="openblas"
;;
*)
echo "ERROR: Invalid value for --math-mode found."
echo "Currently only one of the following options is supported:
mkl, acml, openblas, cray."
exit 1
;;
esac
;;
--gpu-ver=*)
user_input="${1#*=}"
case "${user_input}" in
K20X | K40 | K80 | P100 | V100 | A100 | H100 | GB10 | A40 | Mi50 | Mi100 | Mi250 | no)
export GPUVER="${user_input}"
;;
*)
echo "ERROR: Invalid value for --gpu-ver found."
echo "Currently only one of the following options is supported:
K20X, K40, K80, P100, V100, A100, H100, GB10, A40, Mi50, Mi100, Mi250.
Otherwise use option no."
exit 1
;;
esac
;;
--target-cpu=*)
user_input="${1#*=}"
export TARGET_CPU="${user_input}"
;;
--log-lines=*)
user_input="${1#*=}"
case "${user_input}" in
[0-9]*)
export LOG_LINES="${user_input}"
;;
*)
report_error ${LINENO} "Non-integer ${user_input} for --log-lines."
;;
esac
;;
--libint-lmax=*)
user_input="${1#*=}"
export LIBINT_LMAX="${user_input}"
;;
--dry-run)
dry_run="__TRUE__"
;;
--enable-tsan*)
enable_tsan=$(read_enable "${1}")
if [ "${enable_tsan}" = "__INVALID__" ]; then
report_error "invalid value for --enable-tsan, please use yes or no"
fi
;;
--enable-cuda*)
enable_cuda=$(read_enable "${1}")
if [ "${enable_cuda}" = "__INVALID__" ]; then
report_error "invalid value for --enable-cuda, please use yes or no"
fi
;;
--enable-gauxc-cutlass*)
enable_gauxc_cutlass=$(read_enable "${1}")
if [ "${enable_gauxc_cutlass}" = "__INVALID__" ]; then
report_error "invalid value for --enable-gauxc-cutlass, please use yes or no"
fi
;;
--enable-hip*)
enable_hip=$(read_enable "${1}")
if [ "${enable_hip}" = "__INVALID__" ]; then
report_error "invalid value for --enable-hip, please use yes or no"
fi
;;
--enable-opencl*)
enable_opencl=$(read_enable "${1}")
if [ "${enable_opencl}" = "__INVALID__" ]; then
report_error "invalid value for --enable-opencl, please use yes or no"
fi
;;
--enable-cray*)
enable_cray=$(read_enable "${1}")
if [ "${enable_cray}" = "__INVALID__" ]; then
report_error "invalid value for --enable-cray, please use yes or no"
fi
;;
--with-gcc*)
with_gcc=$(read_with "${1}")
;;
--with-cmake*)
with_cmake=$(read_with "${1}")
;;
--with-ninja*)
with_ninja=$(read_with "${1}")
;;
--with-mpich-device=*)
user_input="${1#*=}"
export MPICH_DEVICE="${user_input}"
export MPI_MODE="mpich"
;;
--with-mpich*)
with_mpich=$(read_with "${1}")
if [ "${with_mpich}" != "__DONTUSE__" ]; then
export MPI_MODE="mpich"
fi
;;
--with-openmpi*)
with_openmpi=$(read_with "${1}")
if [ "${with_openmpi}" != "__DONTUSE__" ]; then
export MPI_MODE="openmpi"
fi
;;
--with-intelmpi*)
with_intelmpi=$(read_with "${1}" "__SYSTEM__")
if [ "${with_intelmpi}" != "__DONTUSE__" ]; then
export MPI_MODE="intelmpi"
fi
;;
--with-amd*)
with_amd=$(read_with "${1}" "__SYSTEM__")
;;
--with-ifx*)
with_ifx=$(read_with "${1}" "yes")
;;
--with-intel*)
with_intel=$(read_with "${1}" "__SYSTEM__")
;;
--with-libint*)
with_libint=$(read_with "${1}")
;;
--with-libxc*)
with_libxc=$(read_with "${1}")
;;
--with-gauxc*)
with_gauxc=$(read_with "${1}")
;;
--with-fftw*)
with_fftw=$(read_with "${1}")
;;
--with-eigen*)
with_eigen=$(read_with "${1}")
;;
--with-mkl*)
with_mkl=$(read_with "${1}" "__SYSTEM__")
if [ "${with_mkl}" != "__DONTUSE__" ]; then
export MATH_MODE="mkl"
fi
;;
--with-acml*)
with_acml=$(read_with "${1}")
if [ "${with_acml}" != "__DONTUSE__" ]; then
export MATH_MODE="acml"
fi
;;
--with-openblas*)
with_openblas=$(read_with "${1}")
if [ "${with_openblas}" != "__DONTUSE__" ]; then
export MATH_MODE="openblas"
fi
;;
--with-scalapack*)
with_scalapack=$(read_with "${1}")
;;
--with-libxsmm*)
with_libxsmm=$(read_with "${1}")
;;
--with-libxstream*)
with_libxstream=$(read_with "${1}")
;;
--with-libxs*)
with_libxs=$(read_with "${1}")
;;
--with-elpa*)
with_elpa=$(read_with "${1}")
;;
--with-cusolvermp*)
with_cusolvermp=$(read_with "${1}" "__SYSTEM__")
;;
--with-deepmd*)
with_deepmd=$(read_with "${1}")
;;
--with-ace*)
with_ace=$(read_with "${1}")
;;
--with-plumed*)
with_plumed=$(read_with "${1}")
;;
--with-sirius*)
with_sirius=$(read_with "${1}")
;;
--with-pugixml*)
with_pugixml=$(read_with "${1}")
;;
--with-gsl*)
with_gsl=$(read_with "${1}")
;;
--with-libgint*)
with_libgint=$(read_with "${1}")
;;
--with-fmt*)
with_fmt=$(read_with "${1}")
;;
--with-spglib*)
with_spglib=$(read_with "${1}")
;;
--with-hdf5*)
with_hdf5=$(read_with "${1}")
;;
--with-libvdwxc*)
with_libvdwxc=$(read_with "${1}")
;;
--with-spfft*)
with_spfft=$(read_with "${1}")
;;
--with-cosma*)
with_cosma=$(read_with "${1}")
;;
--with-libvori*)
with_libvori=$(read_with "${1}")
;;
--with-libtorch*)
with_libtorch=$(read_with "${1}")
;;
--with-spla*)
with_spla=$(read_with "${1}")
;;
--with-dftd4*)
with_dftd4=$(read_with "${1}")
;;
--with-tblite*)
with_tblite=$(read_with "${1}")
;;
--with-libsmeagol*)
with_libsmeagol=$(read_with "${1}")
;;
--with-trexio*)
with_trexio=$(read_with "${1}")
;;
--with-libfci*)
with_libfci=$(read_with "${1}")
;;
--with-greenx*)
with_greenx=$(read_with "${1}")
;;
--with-gmp*)
with_gmp=$(read_with "${1}")
;;
--with-dbcsr*)
with_dbcsr=$(read_with "${1}")
;;
--with-mcl*)
with_mcl=$(read_with "${1}")
;;
--help)
show_help
exit 0
;;
-h)
show_help
exit 0
;;
--help-hpc)
show_help_hpc
exit 0
;;
*)
report_error ${LINENO} "Unknown flag: ${1}
See help message of this script produced by --help option for supported ones."
;;
esac
shift
done
# consolidate settings after user input
export ENABLE_TSAN="${enable_tsan}"
export ENABLE_CUDA="${enable_cuda}"
export ENABLE_GAUXC_CUTLASS="${enable_gauxc_cutlass}"
export ENABLE_HIP="${enable_hip}"
export ENABLE_OPENCL="${enable_opencl}"
export ENABLE_CRAY="${enable_cray}"
# ------------------------------------------------------------------------
# Check and solve known conflicts before installations proceed
# ------------------------------------------------------------------------
# Compiler conflicts
if [ "${with_gcc}" = "__INSTALL__" ]; then
if [ "${with_intel}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "With Intel compiler, do not install GNU compiler."
with_gcc="__SYSTEM__"
elif [ "${with_amd}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "With AMD compiler, do not install GNU compiler."
with_gcc="__SYSTEM__"
fi
fi
if [ "${with_amd}" != "__DONTUSE__" ]; then
if [ "${with_intel}" != "__DONTUSE__" ]; then
report_error ${LINENO} "The AMD and Intel compilers can't be used together."
fi
fi
# MPI library conflicts
if [ "${MPI_MODE}" = "no" ]; then
if [ "${with_scalapack}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "Not using MPI, so ScaLAPACK is disabled."
with_scalapack="__DONTUSE__"
fi
if [ "${with_elpa}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "Not using MPI, so ELPA is disabled."
with_elpa="__DONTUSE__"
fi
if [ "${with_plumed}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "Not using MPI, so PLUMED is disabled."
with_plumed="__DONTUSE__"
fi
if [ "${with_libsmeagol}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "Not using MPI, so libsmeagol is disabled."
with_libsmeagol="__DONTUSE__"
fi
if [ "${with_sirius}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "Not using MPI, so SIRIUS is disabled."
with_sirius="__DONTUSE__"
fi
if [ "${with_spfft}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "Not using MPI, so SpFFT is disabled."
with_spfft="__DONTUSE__"
fi
if [ "${with_spla}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "Not using MPI, so SpLA is disabled."
with_spla="__DONTUSE__"
fi
if [ "${with_cosma}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "Not using MPI, so COSMA is disabled."
with_cosma="__DONTUSE__"
fi
if [ "${with_mcl}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "Not using MPI, so MCL is disabled."
with_mcl="__DONTUSE__"
fi
else
# if gcc is installed, then mpi needs to be installed too.
if [ "${with_gcc}" = "__INSTALL__" ]; then
report_warning ${LINENO} "When installing GNU compiler, Intel compiler and
Intel MPI are disabled, and MPI library is freshly installed."
with_intel="__DONTUSE__"
with_intelmpi="__DONTUSE__"
case ${MPI_MODE} in
mpich)
with_mpich="__INSTALL__"
with_openmpi="__DONTUSE__"
;;
openmpi)
with_mpich="__DONTUSE__"
with_openmpi="__INSTALL__"
;;
intelmpi)
report_error ${LINENO} "Incompatible --mpi-mode=intelmpi found."
;;
esac
fi
# Enable only one MPI implementation.
case ${MPI_MODE} in
mpich)
with_openmpi="__DONTUSE__"
with_intelmpi="__DONTUSE__"
if [ "${with_mpich}" = "__DONTUSE__" ]; then
with_mpich="__INSTALL__"
fi
;;
openmpi)
with_mpich="__DONTUSE__"
with_intelmpi="__DONTUSE__"
if [ "${with_openmpi}" = "__DONTUSE__" ]; then
with_openmpi="__INSTALL__"
fi
;;
intelmpi)
with_mpich="__DONTUSE__"
with_openmpi="__DONTUSE__"
if [ "${with_intelmpi}" = "__DONTUSE__" ]; then
report_error ${LINENO} "While --mpi-mode=intelmpi is set, no Intel MPI
could be found or linked in the system, and installation by toolchain is not
supported. Please install manually and check executable path before rerunning."
fi
;;
esac
fi
# If CUDA or HIP are enabled, make sure the GPU version has been defined.
if [ "${ENABLE_CUDA}" = "__TRUE__" ] || [ "${ENABLE_HIP}" = "__TRUE__" ]; then
if [ "${GPUVER}" = "no" ]; then
report_error ${LINENO} "Either CUDA or HIP is enabled, but --gpu-ver is not
set to one of the known architectures. See help message of this script produced
by --help option for supported ones."
fi
fi
if [ "${ENABLE_GAUXC_CUTLASS}" = "__TRUE__" ]; then
if [ "${ENABLE_CUDA}" != "__TRUE__" ]; then
report_error ${LINENO} "--enable-gauxc-cutlass requires --enable-cuda=yes."
fi
case "${GPUVER}" in
A100 | A40 | H100 | GB10) ;;
*)
report_error ${LINENO} "--enable-gauxc-cutlass requires CUDA compute capability >= 8.0."
;;
esac
if [ "${with_gauxc}" = "__DONTUSE__" ]; then
report_warning ${LINENO} "--enable-gauxc-cutlass requires GauXC, enabling --with-gauxc=install."
with_gauxc="__INSTALL__"
elif [ "${with_gauxc}" != "__INSTALL__" ]; then
report_error ${LINENO} "--enable-gauxc-cutlass is only supported with --with-gauxc=install."
fi
fi
# If OpenCL is enabled, ensure LIBXS and LIBXSTREAM are available.
if [ "${ENABLE_OPENCL}" = "__TRUE__" ]; then
if [ "${with_libxs}" = "__DONTUSE__" ]; then
report_warning ${LINENO} "When enabling OpenCL, LIBXS is needed."
with_libxs="__INSTALL__"
fi
if [ "${with_libxstream}" = "__DONTUSE__" ]; then
report_warning ${LINENO} "When enabling OpenCL, LIBXSTREAM is needed."
with_libxstream="__INSTALL__"
fi
else
if [ "${with_libxstream}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "LIBXSTREAM is only used by the OpenCL backend; disabling it because OpenCL is not enabled."
with_libxstream="__DONTUSE__"
fi
fi
# LIBXSTREAM depends on LIBXS
if [ "${with_libxstream}" != "__DONTUSE__" ]; then
if [ "${with_libxs}" = "__DONTUSE__" ]; then
report_warning ${LINENO} "LIBXSTREAM requires LIBXS, enabling LIBXS."
with_libxs="__INSTALL__"
fi
fi
# LIBXSMM kernels are delivered through LIBXS
if [ "${with_libxsmm}" != "__DONTUSE__" ] && [ "${with_libxs}" = "__DONTUSE__" ]; then
report_warning ${LINENO} "LIBXSMM requires LIBXS, disabling LIBXSMM."
with_libxsmm="__DONTUSE__"
fi
if [ "${with_gauxc}" != "__DONTUSE__" ] &&
[ "${with_libxc}" = "__DONTUSE__" ]; then
report_warning ${LINENO} "GauXC requires Libxc through ExchCXX, so Libxc is enabled."
with_libxc="__INSTALL__"
fi
# Since tblite includes dftd4, a separate dftd4 is not needed.
if [ "${with_tblite}" != "__DONTUSE__" ]; then
if [ "${with_dftd4}" != "__DONTUSE__" ]; then
report_warning ${LINENO} "Since tblite includes dft-d4, a standalone dft-d4
package will not be used separately."
with_dftd4="__DONTUSE__"
fi
fi
# Require cmake as hard dependency.
if [ "${with_cmake}" = "__DONTUSE__" ]; then
report_warning ${LINENO} "Installing dependencies and CP2K requires CMake but
CMake is not enabled, so a new copy of CMake will be installed first."
with_cmake="__INSTALL__"
fi
#libGint installation requires cuda enabled
if [ "${with_libgint}" != "__DONTUSE__" ] && [ "${enable_cuda}" != "__TRUE__" ]; then
report_warning ${LINENO} "libGint requires the use of cuda. Disabling libGint"
with_libgint="__DONTUSE__"
fi
# SIRIUS dependencies
if [ "${with_sirius}" = "__INSTALL__" ]; then
[ "${with_spfft}" = "__DONTUSE__" ] && with_spfft="__INSTALL__"
[ "${with_spla}" = "__DONTUSE__" ] && with_spla="__INSTALL__"
[ "${with_gsl}" = "__DONTUSE__" ] && with_gsl="__INSTALL__"
[ "${with_eigen}" = "__DONTUSE__" ] && with_eigen="__INSTALL__"
[ "${with_fmt}" = "__DONTUSE__" ] && with_fmt="__INSTALL__"
[ "${with_libxc}" = "__DONTUSE__" ] && with_libxc="__INSTALL__"
[ "${with_fftw}" = "__DONTUSE__" ] && with_fftw="__INSTALL__"
[ "${with_scalapack}" = "__DONTUSE__" ] && with_scalapack="__INSTALL__"
[ "${with_spglib}" = "__DONTUSE__" ] && with_spglib="__INSTALL__"
[ "${with_hdf5}" = "__DONTUSE__" ] && with_hdf5="__INSTALL__"
[ "${with_libvdwxc}" = "__DONTUSE__" ] && with_libvdwxc="__INSTALL__"
[ "${with_cosma}" = "__DONTUSE__" ] && with_cosma="__INSTALL__"
[ "${with_pugixml}" = "__DONTUSE__" ] && with_pugixml="__INSTALL__"
elif [ "${with_sirius}" = "__DONTUSE__" ]; then
with_pugixml="__DONTUSE__"
with_spfft="__DONTUSE__"
with_libvdwxc="__DONTUSE__"
with_fmt="__DONTUSE__"
[ "${GPUVER}" = "no" ] && with_spla="__DONTUSE__"
fi
if [ "${with_libint}" = "__INSTALL__" ]; then
[ "${with_eigen}" = "__DONTUSE__" ] && with_eigen="__INSTALL__"
fi
if [ "${with_trexio}" = "__INSTALL__" ]; then
[ "${with_hdf5}" = "__DONTUSE__" ] && with_hdf5="__INSTALL__"
fi
if [ "${with_plumed}" = "__INSTALL__" ]; then
[ "${with_gsl}" = "__DONTUSE__" ] && with_gsl="__INSTALL__"
[ "${with_fftw}" = "__DONTUSE__" ] && with_fftw="__INSTALL__"
fi
if [ "${with_deepmd}" = "__INSTALL__" ]; then
[ "${with_libtorch}" = "__DONTUSE__" ] && with_libtorch="__INSTALL__"
fi
if [ "${with_gauxc}" = "__INSTALL__" ]; then
[ "${with_libtorch}" = "__DONTUSE__" ] && with_libtorch="__INSTALL__"
fi
# MKL may provide the FFTW3 interface and ScaLAPACK/BLACS. Resolve these
# choices here so the package plan, toolchain.conf and summary stay in sync.
if [ "${MATH_MODE}" = "mkl" ]; then
# Use standalone FFTW when FFTW-MPI wrappers are needed. Otherwise, use
# MKL's FFTW3 interface and do not install a separate FFTW package.
if [ "${with_libvdwxc}" != "__DONTUSE__" ] && [ "${MPI_MODE}" != "no" ]; then
report_warning ${LINENO} "libvdwxc with MPI needs FFTW-MPI wrappers; enabling standalone FFTW."
if [ "${with_fftw}" = "__DONTUSE__" ]; then
with_fftw="__INSTALL__"
fi
export MKL_FFTW="no"
else
echo "Using MKL-vendored FFTW"
with_fftw="__DONTUSE__"
export MKL_FFTW="yes"
fi
# Use MKL-provided ScaLAPACK/BLACS for MPI builds.
if [ "${MPI_MODE}" != "no" ]; then
echo "Using MKL-vendored ScaLAPACK"
with_scalapack="__DONTUSE__"
export MKL_SCALAPACK="yes"
fi
# Block libtorch installation bacause of compatibility issue
if [ "${with_libtorch}" = "__INSTALL__" ]; then
report_error ${LINENO} \
"Installing prebuilt libtorch is disabled for oneMKL builds due to known conflicts between bundled and externally linked oneMKL libraries. Please provide a compatible libtorch installation via --with-libtorch=system or --with-libtorch=<path>."
fi
fi
# ------------------------------------------------------------------------
# Preliminaries
# ------------------------------------------------------------------------
mkdir -p "${INSTALLDIR}"
export SETUPFILE="${INSTALLDIR}/setup"
if [ "${INSTALLDIR}" != "${ROOTDIR}/install" ]; then
cp "${SCRIPTDIR}"/tool_kit.sh "${INSTALLDIR}"/
export TOOLKIT_SCRIPT="${INSTALLDIR}/tool_kit.sh"
fi
# Select the correct compute number based on the GPU architecture
case ${GPUVER} in
K20X)
export ARCH_NUM="35"
;;
K40)
export ARCH_NUM="35"
;;
K80)
export ARCH_NUM="37"
;;
P100)
export ARCH_NUM="60"
;;
V100)
export ARCH_NUM="70"
;;
A100)
export ARCH_NUM="80"
;;
A40)
export ARCH_NUM="86"
;;
H100)
export ARCH_NUM="90"
;;
GB10)
export ARCH_NUM="121"
;;
Mi50)
# TODO: export ARCH_NUM=
;;
Mi100)
# TODO: export ARCH_NUM=
;;
Mi250)
# TODO: export ARCH_NUM=
;;
no)
export ARCH_NUM="no"
;;
*)
echo "ERROR: Invalid value for --gpu-ver found."
echo "Currently only one of the following options is supported:
K20X, K40, K80, P100, V100, A100, H100, A40, Mi50, Mi100, Mi250.
Otherwise use option no."
exit 1
;;
esac
# variables used for generating cp2k ARCH file
export CP_DFLAGS=""
export CP_LIBS=""
export CP_CFLAGS=""
export CP_LDFLAGS="-Wl,--enable-new-dtags"
# ------------------------------------------------------------------------
# Special settings for CRAY Linux Environment (CLE)
# TODO: CLE should be handle like gcc or Intel using a with_cray flag and
# this section should be moved to a separate file install_cray.
# ------------------------------------------------------------------------
if [ "${ENABLE_CRAY}" = "__TRUE__" ]; then
echo "------------------------------------------------------------------------"
echo "CRAY Linux Environment (CLE) is detected"
echo "------------------------------------------------------------------------"
# add cray paths to system search path
export LIB_PATHS="CRAY_LD_LIBRARY_PATH ${LIB_PATHS}"
# set compilers to CLE wrappers
check_command cc
check_command ftn
check_command CC
export CC="cc"
export CXX="CC"
export FC="ftn"
export F90="${FC}"
export F77="${FC}"
export MPICC="${CC}"
export MPICXX="${CXX}"
export MPIFC="${FC}"
export MPIFORT="${MPIFC}"
export MPIF77="${MPIFC}"
if [ "$with_intelmpi" = "__DONTUSE__" ]; then
with_gcc="__DONTUSE__"
with_intel="__SYSTEM__"
fi
check_lib -lz
check_lib -ldl
export CRAY_EXTRA_LIBS="-lz -ldl"
# the space is intentional, so that the variable is non-empty and
# can pass require_env checks
export SCALAPACK_LDFLAGS=" "
export SCALAPACK_LIBS=" "
fi
# ------------------------------------------------------------------------
# Installing tools required for building CP2K and associated libraries
# ------------------------------------------------------------------------
# Write toolchain configurations
cat << EOF > "${ROOTDIR}/toolchain_settings"
#!/bin/bash
export TOOLCHAIN_INSTALL_DIR="${INSTALLDIR}"
export CP2K_TOOLCHAIN_OPTIONS="${TOOLCHAIN_OPTIONS}"
EOF
# Write head of setup file
cat << EOF > "$SETUPFILE"
#!/bin/bash
source "${TOOLKIT_SCRIPT}"
EOF
# Write toolchain environment
write_toolchain_env "${INSTALLDIR}"
# Write toolchain config
echo "tool_list=\"${tool_list}\"" > "${INSTALLDIR}"/toolchain.conf
echo "mpi_mode=\"${MPI_MODE}\"" >> "${INSTALLDIR}"/toolchain.conf
echo "math_mode=\"${MATH_MODE}\"" >> "${INSTALLDIR}"/toolchain.conf
if [ "${MATH_MODE}" = "mkl" ]; then
echo "MKL_FFTW=\"${MKL_FFTW}\"" >> "${INSTALLDIR}"/toolchain.conf
echo "MKL_SCALAPACK=\"${MKL_SCALAPACK}\"" >> "${INSTALLDIR}"/toolchain.conf
fi
echo "ENABLE_CUDA=\"${ENABLE_CUDA}\"" >> "${INSTALLDIR}"/toolchain.conf
echo "ENABLE_GAUXC_CUTLASS=\"${ENABLE_GAUXC_CUTLASS}\"" >> "${INSTALLDIR}"/toolchain.conf
echo "ENABLE_HIP=\"${ENABLE_HIP}\"" >> "${INSTALLDIR}"/toolchain.conf
echo "ENABLE_OPENCL=\"${ENABLE_OPENCL}\"" >> "${INSTALLDIR}"/toolchain.conf
if [ "${ENABLE_CUDA}" == "__TRUE__" ] || [ "${ENABLE_HIP}" == "__TRUE__" ]; then
echo "GPU_VER=\"${GPUVER}\"" >> "${INSTALLDIR}"/toolchain.conf
fi
for ii in ${package_list}; do
install_mode=$(eval "echo \${with_${ii}}")
echo "with_${ii}=\"${install_mode}\"" >> "${INSTALLDIR}"/toolchain.conf
done
# ------------------------------------------------------------------------
# Print the resolved toolchain configuration in a user-friendly form. The
# raw with_* variables are written to toolchain.conf, while this report
# groups packages by what the toolchain will actually do with them.
# ------------------------------------------------------------------------
get_effective_package_mode() {
local pkg="$1"
local var_name="with_${pkg}"
local mode="${!var_name}"
# Only the selected math backend is active. Some non-selected math
# variables may keep their default value, but they are not used by
# stage2/install_mathlibs.sh.
case "${pkg}" in
mkl | acml | openblas)
if [ "${MATH_MODE}" != "${pkg}" ]; then
mode="__DONTUSE__"
fi
;;
esac
# Likewise, only the selected MPI implementation is active.
case "${pkg}" in
mpich | openmpi | intelmpi)
if [ "${MPI_MODE}" = "no" ] || [ "${MPI_MODE}" != "${pkg}" ]; then
mode="__DONTUSE__"
fi
;;
esac
printf '%s' "${mode}"
}
append_report_line() {
local var_name="$1"
local line="$2"
local current="${!var_name}"
if [ -z "${current}" ]; then
printf -v "${var_name}" '%s' "${line}"
else
printf -v "${var_name}" '%s\n%s' "${current}" "${line}"
fi
}
print_report_group() {
local title="$1"
local body="$2"
local width="${TOOLCHAIN_REPORT_WIDTH:-80}"
local indent=" "
local max_cols=5
local min_col_width=15
local item line padded
local n=0 max_len=0 col_width cols rows row col idx
local items=()
printf '%s\n' "${title}"
if [ -z "${body}" ]; then
printf ' (none)\n'
return
fi
while IFS= read -r item; do
[ -z "${item}" ] && continue
item="${item# }"
items[n]="${item}"
[ "${#item}" -gt "${max_len}" ] && max_len="${#item}"
n=$((n + 1))
done << EOF
${body}
EOF
[ "${n}" -eq 0 ] && printf ' (none)\n' && return
col_width=$((max_len + 2))
[ "${col_width}" -lt "${min_col_width}" ] && col_width="${min_col_width}"
cols=$(((width - ${#indent}) / col_width))
[ "${cols}" -gt "${max_cols}" ] && cols="${max_cols}"
[ "${cols}" -lt 1 ] && cols=1
[ "${cols}" -gt "${n}" ] && cols="${n}"
rows=$(((n + cols - 1) / cols))
row=0
while [ "${row}" -lt "${rows}" ]; do
line="${indent}"
col=0
while [ "${col}" -lt "${cols}" ]; do
idx=$((row * cols + col))
if [ "${idx}" -lt "${n}" ]; then
item="${items[idx]}"
if [ "${col}" -lt $((cols - 1)) ]; then
printf -v padded '%-*s' "${col_width}" "${item}"
line="${line}${padded}"
else
line="${line}${item}"
fi
fi
col=$((col + 1))
done
while [ "${line% }" != "${line}" ]; do
line="${line% }"
done
printf '%s\n' "${line}"
row=$((row + 1))
done
}
format_bool() {
case "$1" in
__TRUE__)
printf 'yes'
;;
__FALSE__)
printf 'no'
;;
*)
printf '%s' "$1"
;;
esac
}
print_toolchain_summary() {
local pkg mode
local install_packages=""
local system_packages=""
local path_packages=""
local disabled_packages=""
for pkg in ${package_list}; do
mode=$(get_effective_package_mode "${pkg}")
case "${mode}" in
__INSTALL__)
append_report_line install_packages " - ${pkg}"
;;
__SYSTEM__)
append_report_line system_packages " - ${pkg}"
;;
__DONTUSE__)
append_report_line disabled_packages " - ${pkg}"
;;
*)
append_report_line path_packages " - ${pkg}: ${mode}"
;;
esac
done
printf '\nToolchain configuration summary\n'
printf '%s\n' '-------------------------------'
printf 'System specifications:\n'
printf ' -%-20s = %s\n' "j" "${NPROCS_OVERWRITE}"
printf ' --%-20s = %s\n' "target-cpu" "${TARGET_CPU}"
printf ' --%-20s = %s\n' "gpu-ver" "${GPUVER}"
printf ' --%-20s = %s\n' "mpi-mode" "${MPI_MODE}"
printf ' --%-20s = %s\n' "math-mode" "${MATH_MODE}"
printf '\nEnabled features:\n'
printf ' --%-20s = %s\n' "enable-tsan" "$(format_bool "${enable_tsan}")"
printf ' --%-20s = %s\n' "enable-cuda" "$(format_bool "${enable_cuda}")"
printf ' --%-20s = %s\n' "enable-gauxc-cutlass" "$(format_bool "${enable_gauxc_cutlass}")"
printf ' --%-20s = %s\n' "enable-hip" "$(format_bool "${enable_hip}")"
printf ' --%-20s = %s\n' "enable-opencl" "$(format_bool "${enable_opencl}")"
printf ' --%-20s = %s\n' "enable-cray" "$(format_bool "${enable_cray}")"
printf '\n'
print_report_group "Packages to be installed:" "${install_packages}"
printf '\n'
print_report_group "Packages to be detected from system:" "${system_packages}"
if [ -n "${path_packages}" ]; then
printf '\n'
print_report_group "Packages linked from user paths:" "${path_packages}"
fi
printf '\n'
print_report_group "Packages not used:" "${disabled_packages}"
printf '\n'
}
# ------------------------------------------------------------------------
# Build packages unless dry-run mode is enabled.
# ------------------------------------------------------------------------
if [ "${dry_run}" = "__TRUE__" ]; then
print_toolchain_summary
printf "With --dry-run option, this script concludes with above report.\n"
printf "The setup, toolchain env and conf files are written to %s.\n" "${INSTALLDIR}"
else
echo "Options have been parsed successfully."
print_toolchain_summary
echo "Compiling with ${NPROCS_OVERWRITE} processes for target ${TARGET_CPU}."
echo "# Leak suppressions" > "${INSTALLDIR}"/lsan.supp
"${SCRIPTDIR}"/stage0/install_stage0.sh
"${SCRIPTDIR}"/stage1/install_stage1.sh
"${SCRIPTDIR}"/stage2/install_stage2.sh
"${SCRIPTDIR}"/stage3/install_stage3.sh
"${SCRIPTDIR}"/stage4/install_stage4.sh
"${SCRIPTDIR}"/stage5/install_stage5.sh
"${SCRIPTDIR}"/stage6/install_stage6.sh
"${SCRIPTDIR}"/stage7/install_stage7.sh
"${SCRIPTDIR}"/stage8/install_stage8.sh
"${SCRIPTDIR}"/stage9/install_stage9.sh
echo
cat << EOF
========================== Epilogue =========================
Done! To build CP2K with dependencies you installed via toolchain, simply run
this script:
./build_cp2k.sh -j $(get_nprocs)
It will source the file "install/setup", generate proper CMake flags based on
toolchain options, and then build and install CP2K. For available options
with the script, run "./build_cp2k.sh -h".
EOF
fi
#EOF