cp2k/make_cp2k.sh
2026-07-11 16:53:23 +02:00

1655 lines
61 KiB
Bash
Executable file

#!/usr/bin/env bash
# Purpose: Build CP2K using Spack and CMake locally within the folder CP2K_ROOT
# which defaults to the current working directory. This should be a
# "cp2k/" folder containing the CP2K source tree which can be download with
#
# > git clone https://github.com/cp2k/cp2k.git cp2k
#
# and after
#
# > cd cp2k
#
# this script can be run in subshell using the default options with
#
# > ./make_cp2k.sh
#
# The flags -h or --help print the available options.
#
# The first run will take longer as it will build all CP2K dependencies
# with Spack. The Spack installation is kept fully local in the subfolder
# cp2k/spack which corresponds to the tools/toolchain/install folder
# created by the CP2K toolchain.
#
# Subsequent runs of the script will use the software stack from that
# cp2k/spack/ folder.
#
# A rebuild of all CP2K dependencies can be enforced simply by removing
# or renaming the folder cp2k/spack. The latter allows for keeping different
# software stacks (see also -bd and -bd_only flags).
#
# It is recommended to store already compiled packages in a cache (default).
# This will accelerate the (re)build of the CP2K dependencies with Spack
# significantly (see -uc flag).
#
# After the CP2K dependencies are built with Spack, CP2K itself is built
# and installed using CMake in the subfolders cp2k/build and cp2k/install,
# respectively.
#
# Subsequent runs of the script will use the CMake configuration in the
# subfolder cp2k/build. A rebuild of CP2K from scratch can be enforced
# by removing or renaming that subfolder.
#
# A CP2K regression run can be launched automatically by adding the flag
# -t "" (or --test ""). This flag expects a string with the TESTOPTS, e.g.
#
# > ./make_cp2k.sh -t "--maxtasks 8 --restrictdir QS/regtest-gpw-1"
#
# Alternatively, the script cp2k/install/bin/run_tests can be launched
# after a successful CP2K build. Usage examples are printed at the end.
# Authors: Matthias Krack (MK)
# Version: 2.0
# Facilitate the deugging of this script
set -uo pipefail
# Retrieve script name
SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
# Check if the script is sourced or run in a subshell
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
echo "${SCRIPT_NAME}: Running script in sourcing mode"
echo "${SCRIPT_NAME}: All changes from this script will become effective within the current shell"
EXIT_CMD="return"
else
echo "${SCRIPT_NAME}: Running script in subshell mode"
echo "${SCRIPT_NAME}: Changes from this script in the shell environment are lost after completion"
EXIT_CMD="exit"
fi
# Check platform
if [[ "$(uname -s)" == "Darwin" ]]; then
echo "ERROR: A build for Apple macOS (Darwin, Homebrew) is not supported yet,"
echo " but CP2K can be built within a container using podman."
echo " Check the Dockerfiles in the folder cp2k/tools/docker like"
echo " Dockerfile.test_spack_openmpi-psmp and the usage description in their header"
${EXIT_CMD} 1
fi
# Help finding ldconfig
if ! command -v ldconfig &> /dev/null; then
PATH="${PATH}:/sbin"
fi
# Check if all mandatory packages are installed in the environment
for package in awk bzip2 find g++ gcc gfortran git gzip ldconfig make patch python3 tar wget xz; do
if ! command -v "${package}" &> /dev/null; then
echo "ERROR: The package \"${package}\" is mandatory to build CP2K with Spack/CMake"
echo " Install the missing package and re-run the script"
${EXIT_CMD} 1
fi
done
# Disable python bytecode generation to suppress __pycache__ folder creation
export PYTHONDONTWRITEBYTECODE=1
# Print OS info if available
if [[ -f /etc/os-release ]]; then
echo ""
cat /etc/os-release
fi
# Check bash version
if ((BASH_VERSINFO < 4)); then
echo ""
echo "ERROR: The employed bash version ${BASH_VERSION} is too old (from 2004)"
echo " Install a newer bash version"
if [[ "$(uname -s)" == "Darwin" ]]; then
echo "HINT: Use the bash command provided by Homebrew with Apple"
echo " /opt/homebrew/bin should precede /bin/bash in the PATH"
echo " In sourcing mode, run /opt/homebrew/bin/bash first before sourcing this script"
fi
${EXIT_CMD} 1
elif ((BASH_VERSINFO < 5)); then
echo -e "\nWARNING: The employed bash version ${BASH_VERSION} is quite old (from 2009)"
else
echo -e "\nINFO: Using bash version ${BASH_VERSION}"
fi
# Check if the python3 version is new enough for spack
if ! python3 -c 'import sys; sys.exit(not(sys.version_info >= (3, 10)))'; then
echo ""
echo "ERROR: Python version is NOT >= 3.10 (needed for Spack)"
echo " Found only $(python3 -V)"
${EXIT_CMD} 1
else
echo -e "\nINFO: Found $(python3 -V)"
fi
# Default values
BUILD_DEPS="if_needed"
BUILD_DEPS_ONLY="no"
BUILD_SHARED_LIBS="${BUILD_SHARED_LIBS:-ON}"
CP2K_BUILD_TYPE="${CP2K_BUILD_TYPE:-Release}"
DEPS_BUILD_TYPE="${DEPS_BUILD_TYPE:-Release}"
CMAKE_FEATURE_FLAG_ALL="-DCP2K_USE_EVERYTHING=ON" # all features are activated by default
CMAKE_FEATURE_FLAGS="-DCP2K_BLAS_VENDOR=OpenBLAS" # LAPACK/BLAS from OpenBLAS by default
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_FFTW3=ON" # FFTW3 is always activated unless explicitly disabled
CMAKE_FEATURE_FLAG_MPI="-DCP2K_USE_MPI=ON" # MPI is switched on by default
CMAKE_FEATURE_FLAGS_GPU="-DCP2K_USE_SPLA_GEMM_OFFLOADING=ON"
CRAY="no"
CUDA_SM_CODE=0
GCC_VERSION="auto"
GPU_MODEL="none"
HELP="no"
INSTALL_MESSAGE="NEVER"
MPI_MODE="mpich"
if command -v nproc &> /dev/null; then
MAX_PROCS=$(nproc)
NUM_PROCS=${NUM_PROCS:-${MAX_PROCS}}
else
MAX_PROCS=-1
NUM_PROCS=${NUM_PROCS:-8}
fi
NUM_PACKAGES=2
NVCC_VERSION=0
REBUILD_CP2K="no"
RUN_TEST="no"
SED_PATTERN_LIST=""
TESTOPTS=""
USE_CACHE="folder"
USE_EXTERNALS="no"
USE_OPENCL="no"
VERBOSE=0
VERBOSE_FLAG="--quiet"
VERBOSE_MAKEFILE="OFF"
VERBOSE_SPACK=""
export CP2K_ENV="cp2k_env"
export CP2K_ROOT=${CP2K_ROOT:-${PWD}}
export CP2K_VERSION="${CP2K_VERSION:-psmp}"
export BUILD_PATH="${BUILD_PATH:-${CP2K_ROOT}}"
export INSTALL_PREFIX="${INSTALL_PREFIX:-${CP2K_ROOT}/install}"
# Parse flags
while [[ $# -gt 0 ]]; do
case "$1" in
-bd | --build_deps | --build_dependencies)
BUILD_DEPS="always"
shift 1
;;
-bd_only | --build_deps_only | --build_dependencies_only)
BUILD_DEPS="always"
BUILD_DEPS_ONLY="yes"
shift 1
;;
-bp | --build_path)
if (($# > 1)); then
BUILD_PATH="$(realpath "${2}")"
else
echo "ERROR: No build path argument found for flag \"${1}\""
${EXIT_CMD} 1
fi
shift 2
;;
-bsl | --build_static_libcp2k)
BUILD_SHARED_LIBS="OFF"
shift 1
;;
-bt | --build_type)
CP2K_BUILD_TYPE="${2}"
case "${CP2K_BUILD_TYPE}" in
Debug)
CP2K_VERSION="${CP2K_VERSION/smp/dbg}"
;;
Release | RelWithDebInfo)
CP2K_VERSION="${CP2K_VERSION/dbg/smp}"
;;
esac
shift 2
;;
-cray)
CRAY="yes"
shift 1
;;
-cv | --cp2k_version)
if (($# > 1)); then
case "${2,,}" in
pdbg | psmp | sdbg | ssmp | ssmp-static)
CP2K_VERSION="${2,,}"
# Set build type
case "${CP2K_VERSION}" in
pdbg | sdbg)
CP2K_BUILD_TYPE="Debug"
DEPS_BUILD_TYPE="RelWithDebInfo"
;;
psmp | ssmp | ssmp-static)
CP2K_BUILD_TYPE="Release"
DEPS_BUILD_TYPE="Release"
;;
esac
# Disable MPI for a serial CP2K binary
case "${CP2K_VERSION}" in
sdbg | ssmp | ssmp-static)
MPI_MODE="no"
CMAKE_FEATURE_FLAG_MPI="-DCP2K_USE_MPI=OFF"
;;
esac
# Apply specific package selection for statically linked binaries
case "${CP2K_VERSION}" in
ssmp-static)
CMAKE_FEATURE_FLAG_ALL="-DCP2K_USE_EVERYTHING=ON"
for package in libfci libint2 libxc libxs spglib vori tblite; do
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_${package^^}=ON"
done
for package in ace deepmd gauxc greenx hdf5 libgint libtorch pexsi trexio; do
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_${package^^}=OFF"
done
;;
esac
;;
*)
echo "ERROR: Invalid CP2K version \"${2}\" specified (choose pdbg, psmp, sdbg, ssmp, or ssmp-static)"
${EXIT_CMD} 1
;;
esac
else
echo "ERROR: No argument found for flag \"${1}\" (choose pdbg, psmp, sdbg, ssmp, or ssmp-static)"
${EXIT_CMD} 1
fi
shift 2
;;
-df | --disable | --disable_feature | -ef | --enable | --enable_feature)
if (($# > 1)); then
case "${1}" in
-df | --disable | --disable_feature)
ON_OFF="OFF"
SUBST="s/^ /#/'"
;;
-ef | --enable | --enable_feature)
ON_OFF="ON"
SUBST="s/#/ /'"
;;
esac
case "${2,,}" in
all)
# Enable or disable all features
CMAKE_FEATURE_FLAG_ALL="-DCP2K_USE_EVERYTHING=${ON_OFF}"
for package in adios2 cosma deepmdkit dla-future dla-future-fortran elpa \
gauxc greenx hdf5 libfabric libfci libint libvdwxc libsmeagol libvori \
libxc libxs libxsmm mimic-mcl openpmd-api pace pexsi plumed py-torch sirius \
spfft spglib spla tblite trexio; do
SED_PATTERN_LIST+=" -e '/\s*-\s+\"${package}@/ ${SUBST}"
done
# dbcsr must use blas as fallback when libxs/libxsmm is disabled
if [[ "${ON_OFF}" == "OFF" ]]; then
SED_PATTERN_LIST+=" -e '/\s*-\s+\"smm=libxs\"/ s/libxs/blas/'"
fi
;;
ace | cosma | deepmd | dftd4 | dlaf | elpa | fftw3 | gauxc | greenx | hdf5 | libfci | \
libgint | libint2 | libsmeagol | libtorch | libxc | libxs | mimic | openpmd | pexsi | \
plumed | spglib | tblite | trexio | vori)
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_${2^^}=${ON_OFF}"
# Translate package selection to sed pattern
case "${2,,}" in
ace)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"p${2,,}@/ ${SUBST}"
;;
cosma | elpa | greenx | hdf5 | libfci | libsmeagol | libxc | pexsi | plumed | \
spglib | trexio)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"${2,,}@/ ${SUBST}"
;;
deepmd)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"${2,,}kit@/ ${SUBST}"
if [[ "${ON_OFF}" == "ON" ]]; then
# DeePMD-kit requires libtorch
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_LIBTORCH=${ON_OFF}"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"py-torch@/ ${SUBST}"
fi
;;
dftd4)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"${2,,}@/ ${SUBST}"
if [[ "${ON_OFF}" == "ON" ]]; then
echo "INFO: tblite is disabled to avoid conflicts when dftd4 is used"
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_TBLITE=OFF"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"tblite@/ s/^ /#/'"
fi
;;
dlaf)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"dla-future.*@/ ${SUBST}"
if [[ "${ON_OFF}" == "ON" ]]; then
SED_PATTERN_LIST+=" -e 's/\~dlaf/\+dlaf/'"
else
SED_PATTERN_LIST+=" -e 's/\+dlaf/\~dlaf/'"
fi
;;
fftw3)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"fftw@/ ${SUBST}"
;;
gauxc)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"${2,,}@/ ${SUBST}"
if [[ "${ON_OFF}" == "ON" ]]; then
# GauXC requires libtorch
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_LIBTORCH=${ON_OFF}"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"py-torch@/ ${SUBST}"
fi
;;
libint2)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"libint@/ ${SUBST}"
;;
libtorch)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"py-torch@/ ${SUBST}"
if [[ "${ON_OFF}" == "OFF" ]]; then
# DeePMD-kit and GauXC require libtorch
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_DEEPMD=${ON_OFF}"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"deepmdkit@/ ${SUBST}"
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_GAUXC=${ON_OFF}"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"gauxc@/ ${SUBST}"
fi
;;
libxs)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"libxs@/ ${SUBST}"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"libxsmm@/ ${SUBST}"
if [[ "${ON_OFF}" == "OFF" ]]; then
SED_PATTERN_LIST+=" -e '/\s*-\s+\"smm=${2,,}\"/ s/${2,,}/blas/'"
fi
;;
mimic)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"mimic-mcl@/ ${SUBST}"
;;
openpmd | adios2)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"adios2@/ ${SUBST}"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"openpmd-api@/ ${SUBST}"
;;
tblite)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"${2,,}@/ ${SUBST}"
if [[ "${ON_OFF}" == "ON" ]]; then
echo "INFO: dftd4 is disabled to avoid conflicts when tblite is used"
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_DFTD4=OFF"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"dftd4@/ s/^ /#/'"
fi
;;
vori)
SED_PATTERN_LIST+=" -e '/\s*-\s+\"lib${2,,}@/ ${SUBST}"
;;
esac
;;
libvdwxc | spfft | spla | sirius)
echo "WARNING: You have enabled or disabled one of the packages libvdwxc, spfft, spla, sirius"
echo " which means that the other packages will also be enabled or disabled"
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_LIBVDWXC=${ON_OFF} -DCP2K_USE_SpFFT=${ON_OFF}"
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_SPLA=${ON_OFF} -DCP2K_USE_SIRIUS=${ON_OFF}"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"libvdwxc@/ ${SUBST}"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"spfft@/ ${SUBST}"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"spla@/ ${SUBST}"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"sirius@/ ${SUBST}"
;;
cray_pm_accel_energy | cusolver_mp | spla_gemm_offloading | unified_memory)
CMAKE_FEATURE_FLAGS_GPU+=" -DCP2K_USE_${2^^}=${ON_OFF}"
;;
dbm_gpu | elpa_gpu | grid_gpu | pw_gpu)
CMAKE_FEATURE_FLAGS_GPU+=" -DCP2K_ENABLE_${2^^}=${ON_OFF}"
;;
none)
# do nothing
;;
*)
echo "ERROR: Unknown CP2K feature \"${2}\" specified"
${EXIT_CMD} 1
;;
esac
else
echo "ERROR: No feature found for flag \"${1}\""
${EXIT_CMD} 1
fi
shift 2
;;
-gv | --gcc_version)
if (($# > 1)); then
case "${2}" in
1[0-6])
GCC_VERSION="${2}"
;;
*)
echo "ERROR: Invalid GCC version \"${2}\" specified (choose from 10 to 16)"
${EXIT_CMD} 1
;;
esac
else
echo "ERROR: No argument found for flag \"${1}\" (choose a GCC version)"
${EXIT_CMD} 1
fi
shift 2
;;
-gm | -gpu | --gpu_model)
if (($# > 1)); then
case "${2^^}" in
P100 | V100 | T400 | A100 | A40 | H100 | H200 | GH200)
GPU_MODEL="${2^^}"
case "${GPU_MODEL}" in
P100)
CUDA_SM_CODE=60
;;
V100)
CUDA_SM_CODE=70
;;
T400)
CUDA_SM_CODE=75
;;
A100)
CUDA_SM_CODE=80
;;
A40)
CUDA_SM_CODE=86
;;
H100 | H200 | GH200)
CUDA_SM_CODE=90
;;
esac
;;
60 | 70 | 75 | 80 | 86 | 87 | 89 | 90 | 120 | 121)
CUDA_SM_CODE=${2}
;;
NONE)
GPU_MODEL="${2,,}"
;;
*)
echo -e "\nERROR: Unknown GPU model \"${2}\" specified (choose <CUDA SM code>, P100, V100, T400, A100, A40, H100, H200, GH200 or none)\n"
${EXIT_CMD} 1
;;
esac
else
echo -e "\nERROR: No argument found for flag \"${1}\" (choose <CUDA SM code>, P100, V100, T400, A100, A40, H100, H200, GH200 or none)\n"
${EXIT_CMD} 1
fi
shift 2
;;
-h | --help)
HELP="yes"
shift 1
;;
-ip | --install_path | --install_prefix)
if (($# > 1)); then
INSTALL_PREFIX="$(realpath "${2}")"
else
echo "ERROR: No install path argument found for flag \"${1}\""
${EXIT_CMD} 1
fi
shift 2
;;
-j)
if (($# > 1)); then
case "${2}" in
-*)
shift 1
;;
[0-9]*)
NUM_PROCS="${2}"
shift 2
;;
*)
echo "ERROR: The -j flag can only be followed by an integer number, found \"${2}\""
${EXIT_CMD} 1
;;
esac
else
shift 1
fi
;;
-j[0-9]*)
NUM_PROCS="${1#-j}"
shift 1
;;
-mpi | --mpi_mode)
if (($# > 1)); then
case "${2,,}" in
mpich | openmpi)
CMAKE_FEATURE_FLAG_MPI="-DCP2K_USE_MPI=ON"
MPI_MODE="${2,,}"
;;
no | none | off)
CMAKE_FEATURE_FLAG_MPI="-DCP2K_USE_MPI=OFF"
MPI_MODE="no"
;;
*)
echo "ERROR: Unknown MPI mode \"${2}\" specified (choose mpich, openmpi, or no)"
${EXIT_CMD} 1
;;
esac
else
echo "ERROR: No argument found for flag \"${1}\""
echo " The MPI mode is required (choose mpich, openmpi, or no)"
${EXIT_CMD} 1
fi
shift 2
;;
-np | --num_packages)
if (($# > 1)); then
case "${2}" in
-*)
shift 1
;;
[0-9]*)
NUM_PACKAGES="${2}"
shift 2
;;
*)
echo "ERROR: The -np flag can only be followed by an integer number, found \"${2}\""
${EXIT_CMD} 1
;;
esac
else
shift 1
fi
;;
-opencl)
USE_OPENCL="yes"
shift 1
;;
-rc | --rebuild_cp2k)
REBUILD_CP2K="yes"
shift 1
;;
-t | --test)
RUN_TEST="yes"
if (($# > 1)); then
TESTOPTS="${2}"
else
echo "ERROR: No argument found for flag \"${1}\""
echo " A string argument with the TESTOPTS (even an empty one \"\") is required"
${EXIT_CMD} 1
fi
shift 2
;;
-uc | --use_cache)
if (($# > 1)); then
case "${2,,}" in
folder | minio | no | none)
USE_CACHE="${2,,}"
;;
*)
echo "ERROR: Invalid cache mode \"${2}\" specified (choose folder, minio or no)"
${EXIT_CMD} 1
;;
esac
else
echo "ERROR: No argument found for flag \"${1}\" (choose folder, minio or no)"
${EXIT_CMD} 1
fi
shift 2
;;
-ue | --use_externals)
USE_EXTERNALS="yes"
shift 1
;;
-v | --verbose)
VERBOSE=1
INSTALL_MESSAGE="LAZY"
VERBOSE_FLAG="--verbose"
VERBOSE_MAKEFILE="ON"
VERBOSE_SPACK="--verbose"
shift 1
;;
--)
shift 1
break
;;
-*)
echo "ERROR: Unknown option \"${1}\" specified"
${EXIT_CMD} 1
;;
*)
break
;;
esac
done
# Remove leading zeros from NUM_PACKAGES and NUM_PROCS
NUM_PACKAGES=$(awk '{print $1+0}' <<< "${NUM_PACKAGES}")
NUM_PROCS=$(awk '{print $1+0}' <<< "${NUM_PROCS}")
# Check if we are working within a docker or podman container
[[ -f /.dockerenv || -f /run/.containerenv ]] && IN_CONTAINER="yes" || IN_CONTAINER="no"
# Assemble CMake feature flag list
CMAKE_FEATURE_FLAGS="${CMAKE_FEATURE_FLAG_ALL} ${CMAKE_FEATURE_FLAG_MPI} ${CMAKE_FEATURE_FLAGS}"
# DLA-Future does not work with MPICH yet
case "${MPI_MODE}" in
mpich | openmpi)
if [[ "${CMAKE_FEATURE_FLAGS}" == *"-DCP2K_USE_EVERYTHING=ON"* ]] ||
[[ "${CMAKE_FEATURE_FLAGS}" == *"-DCP2K_USE_DLAF=ON"* ]]; then
echo -e "\nINFO: DLA-Future does not work with ${MPI_MODE^^} yet and is disabled"
CMAKE_FEATURE_FLAGS+=" -DCP2K_USE_DLAF=OFF"
SED_PATTERN_LIST+=" -e '/\s*-\s+\"dla-future.*@/ s/^ /#/'"
SED_PATTERN_LIST+=" -e 's/\+dlaf/\~dlaf/'"
fi
;;
esac
# Clean CMake feature flag list from repeated entries and keep only the last definition
declare -A last=()
order=()
# First pass: record the last occurrence of each flag
for flag in ${CMAKE_FEATURE_FLAGS}; do
name=${flag%=*}
last[${name}]=${flag}
order+=("${name}")
done
# Second pass: output only the last definition per flag
# but respecting original order of last appearance
declare -A seen=()
out=()
for name in "${order[@]}"; do
if [[ -z ${seen[${name}]+_} ]]; then
seen[${name}]=1
out+=("${last[${name}]}")
fi
done
CMAKE_FEATURE_FLAGS="$(printf '%s\n' "${out[*]}")"
export BUILD_DEPS BUILD_DEPS_ONLY BUILD_SHARED_LIBS CMAKE_FEATURE_FLAGS CMAKE_FEATURE_FLAGS_GPU CP2K_BUILD_TYPE \
CRAY CUDA_SM_CODE DEPS_BUILD_TYPE GCC_VERSION GPU_MODEL IN_CONTAINER INSTALL_MESSAGE MPI_MODE NUM_PACKAGES \
NUM_PROCS REBUILD_CP2K RUN_TEST TESTOPTS USE_CACHE USE_OPENCL VERBOSE VERBOSE_FLAG VERBOSE_MAKEFILE VERBOSE_SPACK
# Show help if requested
if [[ "${HELP}" == "yes" ]]; then
echo ""
echo "Usage: ${SCRIPT_NAME} [-bd | --build_deps]"
echo " [-bd_only | --build_deps_only]"
echo " [-bp | --build_path PATH]"
echo " [-bsl | --build_static_libcp2k]"
echo " [-bt | --build_type (Debug | Release | RelWithDebInfo)]"
echo " [-cray]"
echo " [-cv | --cp2k_version (pdbg | psmp | sdbg | ssmp | ssmp-static)]"
echo " [-df | --disable | --disable_feature (all | FEATURE | PACKAGE | none)"
echo " [-ef | --enable | --enable_feature (all | FEATURE | PACKAGE | none)"
echo " [-gm | -gpu | --gpu_model (<CUDA SM code> | P100 | V100 | T400 | A100 | H100 | H200 | GH200 | none)]"
echo " [-gv | --gcc_version (10 | 11 | 12 | 13 | 14 | 15 | 16)]"
echo " [-h | --help]"
echo " [-ip | --install_path PATH]"
echo " [-j #PROCESSES]"
echo " [-mpi | --mpi_mode (mpich | no | openmpi)]"
echo " [-np | --num_packages #PACKAGES]"
echo " [-rc | --rebuild_cp2k]"
echo " [-t | --test \"TESTOPTS\"]"
echo " [-uc | --use_cache (folder | minio | no | none)]"
echo " [-ue | --use_externals]"
echo " [-v | --verbose]"
echo ""
echo "Flags:"
echo " --build_deps : Force a rebuild of all CP2K dependencies from scratch (removes the spack folder)"
echo " --build_deps_only : Rebuild ONLY the CP2K dependencies from scratch (removes the spack folder)"
echo " --build_path : Define the CP2K build path (default: ${CP2K_ROOT})"
echo " --build_static_libcp2k: Build a static CP2K library libcp2k.a instead of the default shared one libcp2k.so"
echo " --build_type : Set preferred CMake build type for CP2K (default: \"Release\")"
echo " --cp2k_version : CP2K version to be built (default: \"psmp\")"
echo " -cray : Use Cray specific spack configuration"
echo " --enable_feature : Enable feature or package (default: all)"
echo " --disable_feature : Disable feature or package"
echo " --help : Print this help information"
echo " --gcc_version : Use the specified GCC version (default: automatically decided by spack)"
echo " --gpu_model : Select GPU model (default: none)"
echo " --install_path : Define the CP2K installation path (default: ./install)"
echo " -j : Maximum number of processes used in parallel"
echo " --mpi_mode : Set preferred MPI mode (default: \"mpich\")"
echo " --num_packages : Maximum number of packages built by spack in parallel (default: 4)"
echo " -opencl : Perform build with OpenCL support"
echo " --rebuild_cp2k : Rebuild CP2K: removes the build folder (default: no)"
echo " --test : Perform a regression test run after a successful build"
echo " --use_cache : Use a \"folder\", a \"MinIO\" object storage container (requires podman) or \"no\" cache"
echo " Set the environment variable SPACK_CACHE to specify the folder name, e.g."
echo " SPACK_CACHE=\"file://${CP2K_ROOT}/spack_cache\" (default)"
echo " --use_externals : Use external packages installed on the host system. This results in much"
echo " faster build times, but it can also cause conflicts with outdated packages"
echo " pulled in from the host system, e.g. old python or gcc versions"
echo " --verbose : Write verbose output"
echo ""
echo "Hints:"
echo " - Remove the folder ${CP2K_ROOT}/build to (re)build CP2K from scratch"
echo " (see also --rebuild_cp2k flag)"
echo " - Remove the folder ${CP2K_ROOT}/spack to (re)build CP2K and all its dependencies from scratch"
echo " (see also --build_deps flag)"
echo " - The folder ${CP2K_ROOT}/install is updated after each successful run"
echo ""
echo "Packages: all | ace | cosma | deepmd | dftd4 | dlaf | elpa | fftw3 | gauxc | greenx | hdf5 | libfci |"
echo " libgint | libint | libsmeagol | libtorch | libvdwxc | libxs | mimic | openpmd | pexsi | plumed |"
echo " sirius | spfft | spglib | spla | tblite | trexio | vori "
echo ""
echo "Features: cray_pm_accel_energy | cusolver_mp | dbm_gpu | elpa_gpu | grid_gpu | pw_gpu |"
echo " spla_gemm_offloading | unified_memory"
echo ""
${EXIT_CMD}
fi
echo ""
echo "BUILD_DEPS = ${BUILD_DEPS}"
echo "BUILD_DEPS_ONLY = ${BUILD_DEPS_ONLY}"
echo "BUILD_PATH = ${BUILD_PATH}"
echo "BUILD_SHARED_LIBS = ${BUILD_SHARED_LIBS}"
echo "CP2K_BUILD_TYPE = ${CP2K_BUILD_TYPE}"
echo "CP2K_VERSION = ${CP2K_VERSION}"
echo "CRAY = ${CRAY}"
echo "DEPS_BUILD_TYPE = ${DEPS_BUILD_TYPE}"
echo "GCC_VERSION = ${GCC_VERSION}"
if ((CUDA_SM_CODE > 0)); then
echo "GPU = ${GPU_MODEL} (CUDA SM code: ${CUDA_SM_CODE})"
else
echo "GPU = ${GPU_MODEL}"
fi
echo "INSTALL_PREFIX = ${INSTALL_PREFIX}"
echo "INSTALL_MESSAGE = ${INSTALL_MESSAGE}"
echo "IN_CONTAINER = ${IN_CONTAINER}"
echo "MPI_MODE = ${MPI_MODE}"
echo "NUM_PACKAGES = ${NUM_PACKAGES} (packages are built by spack concurrently)"
echo "NUM_PROCS = ${NUM_PROCS} (processes)"
echo "Physical cores = $(lscpu -p=Core,Socket | grep -v '#' | sort -u | wc -l) (host view)"
echo "REBUILD_CP2K = ${REBUILD_CP2K}"
echo "RUN_TEST = ${RUN_TEST}"
if [[ "${RUN_TEST}" == "yes" ]]; then
echo "TESTOPTS = \"${TESTOPTS}\""
fi
echo "USE_CACHE = ${USE_CACHE}"
echo "USE_EXTERNALS = ${USE_EXTERNALS}"
echo "USE_OPENCL = ${USE_OPENCL}"
echo "VERBOSE_FLAG = ${VERBOSE_FLAG}"
echo "VERBOSE_MAKEFILE = ${VERBOSE_MAKEFILE}"
echo "VERBOSE = ${VERBOSE}"
if (($# > 0)); then
echo "Remaining args =" "$@" "(not used)"
fi
echo ""
echo "LD_LIBRARY_PATH = ${LD_LIBRARY_PATH:-}"
echo ""
echo "PATH = ${PATH:-}"
echo ""
echo "CMAKE_FEATURE_FLAGS = ${CMAKE_FEATURE_FLAGS}"
echo ""
((VERBOSE > 0)) && echo -e "SED_PATTERN_LIST = ${SED_PATTERN_LIST}\n"
# Check if a valid number for the packages to be built by spack in parallel is given
if ((NUM_PACKAGES < 1)); then
echo -e "\nERROR: The requested number of packages to be built by spack in parallel should be larger than 0, found \"${NUM_PACKAGES}\""
${EXIT_CMD} 1
elif ((NUM_PROCS > 0)) && ((NUM_PACKAGES > NUM_PROCS)); then
echo -e "\nERROR: The requested number of packages to be built in parallel by spack (${NUM_PACKAGES}) is larger than the requested number of processes (${NUM_PROCS})"
${EXIT_CMD} 1
fi
# Check if a valid number of processes is requested
if ((NUM_PROCS < 1)); then
echo "ERROR: The requested number of processes should be larger than 0, found \"${NUM_PROCS}\""
${EXIT_CMD} 1
elif ((MAX_PROCS > 0)) && ((NUM_PROCS > MAX_PROCS)); then
echo "WARNING: The requested number of processes (${NUM_PROCS}) is larger than the detected number of CPU cores (${MAX_PROCS})"
fi
# Check if a valid CMake build type is selected for the dependencies
case "${DEPS_BUILD_TYPE^}" in
Release | RelWithDebInfo)
true
;;
Debug)
echo "ERROR: The CMake build type \"${DEPS_BUILD_TYPE}\" is not supported for building the dependencies"
${EXIT_CMD} 1
;;
*)
echo "ERROR: Invalid CMake build type \"${DEPS_BUILD_TYPE}\" selected for building the dependencies"
${EXIT_CMD} 1
;;
esac
# Check if a valid CMake build type is selected for CP2K
case "${CP2K_BUILD_TYPE^}" in
Debug | Release | RelWithDebInfo)
true
;;
*)
echo "ERROR: Invalid CMake build type \"${CP2K_BUILD_TYPE}\" selected for building CP2K"
${EXIT_CMD} 1
;;
esac
# Check if a valid MPI type is selected
case "${MPI_MODE}" in
mpich | openmpi)
if [[ "${CP2K_VERSION}" == "ssmp"* ]]; then
echo "ERROR: MPI type \"${MPI_MODE}\" specified for building a serial CP2K binary"
${EXIT_CMD} 1
fi
;;
no)
if [[ "${CP2K_VERSION}" == "psmp" ]]; then
echo "ERROR: MPI type \"${MPI_MODE}\" specified for building an MPI-parallel CP2K binary"
${EXIT_CMD} 1
fi
;;
*)
echo "ERROR: Invalid MPI type \"${MPI_MODE}\" selected"
echo " Choose from (mpich | no | openmpi)"
${EXIT_CMD} 1
;;
esac
# Check if CP2K_VERSION and the selected features are compatible
case "${CP2K_VERSION}" in
ssmp | ssmp-static)
for package in cosma dlaf elpa libfabric libsmeagol mimic openpmd pexsi plumed sirius spla; do
if [[ "${CMAKE_FEATURE_FLAGS}" == *" -DCP2K_USE_${package^^}=ON"* ]]; then
echo -e "ERROR: The feature ${package^^} is not available for building serial CP2K binaries (${CP2K_VERSION})\n"
${EXIT_CMD} 1
fi
done
# Further exclusions are needed for statically linked serial CP2K binaries
if [[ "${CP2K_VERSION}" == "ssmp-static" ]]; then
for package in ace deepmd greenx hdf5 libgint libtorch trexio; do
if [[ "${CMAKE_FEATURE_FLAGS}" == *" -DCP2K_USE_${package^^}=ON"* ]]; then
echo -e "ERROR: The feature ${package^^} is not available for building statically linked serial CP2K binaries (${CP2K_VERSION})\n"
${EXIT_CMD} 1
fi
done
fi
;;
esac
# Perform CUDA GPU related settings
if ((CUDA_SM_CODE > 0)); then
if command -v nvcc &> /dev/null; then
CUDA_VERSION=$(nvcc -V | sed -n 's/.*release \([0-9.]*\).*/\1/p')
NVCC_VERSION=$(awk -v x="${CUDA_VERSION}" 'BEGIN{print 10*x}')
else
echo -e "\nERROR: No CUDA toolkit installation found (nvcc compiler not found)\n"
${EXIT_CMD} 1
fi
# Check if the selected CUDA SM code is valid when the nvidia-smi command is available
if command -v nvidia-smi &> /dev/null; then
echo -e "NVIDIA driver installation found:\n"
nvidia-smi
HOST_CUDA_SM_CODE=$(nvidia-smi --query-gpu=compute_cap --format=csv,noheader | tail -n 1 | awk '{print 10*$1}')
if ((CUDA_SM_CODE > HOST_CUDA_SM_CODE)); then
echo ""
echo "ERROR: The requested CUDA SM code (${CUDA_SM_CODE}) is larger than the maximum"
echo " CUDA SM code (${HOST_CUDA_SM_CODE}) supported by the host system"
echo ""
${EXIT_CMD} 1
fi
else
echo "INFO: No NVIDIA driver installation found (nvidia-smi not found)"
fi
# Check GPU support by the CUDA SDK
if ((NVCC_VERSION < 128)) && ((CUDA_SM_CODE > 90)); then
echo ""
echo "ERROR: The CUDA SDK version ${NVCC_VERSION} does not support GPUs with a"
echo " CUDA SM code larger than 90 (found ${CUDA_SM_CODE})"
echo ""
${EXIT_CMD} 1
fi
if ((NVCC_VERSION > 129)) && ((CUDA_SM_CODE < 75)); then
echo ""
echo "ERROR: The CUDA SDK version ${NVCC_VERSION} does not support GPUs with a"
echo " CUDA SM code smaller than 75 (found ${CUDA_SM_CODE})"
echo ""
${EXIT_CMD} 1
fi
CMAKE_CUDA_FLAGS="-DCP2K_USE_ACCEL=CUDA"
CMAKE_CUDA_FLAGS+=" -DCP2K_WITH_GPU=${GPU_MODEL}"
CMAKE_CUDA_FLAGS+=" -DCMAKE_CUDA_ARCHITECTURES=${CUDA_SM_CODE}"
CMAKE_CUDA_FLAGS+=" ${CMAKE_FEATURE_FLAGS_GPU}"
out=()
for flag in ${CMAKE_CUDA_FLAGS}; do
[[ ${seen[${flag}]+_} ]] || {
seen[${flag}]=1
out+=("${flag}")
}
done
CMAKE_CUDA_FLAGS="$(printf '%s\n' "${out[*]}")"
echo -e "\nCMAKE_CUDA_FLAGS = ${CMAKE_CUDA_FLAGS}"
[[ -n "${CUDA_VERSION:-}" ]] && echo -e "\nCUDA_VERSION = ${CUDA_VERSION} (nvcc compiler)"
[[ -n "${CUDA_HOME:-}" ]] && echo -e "\nCUDA_HOME = ${CUDA_HOME}"
echo ""
else
CMAKE_CUDA_FLAGS="-DCP2K_USE_ACCEL=OFF"
fi
export CMAKE_CUDA_FLAGS
# Retrieve and print available resources
free -h
echo ""
ulimit -c 0 -s unlimited
ulimit -a
echo ""
### Build CP2K dependencies with Spack if needed or requested ###
# Spack version
export SPACK_VERSION="${SPACK_VERSION:-1.2.1}"
export SPACK_BUILD_PATH="${BUILD_PATH}/spack"
export SPACK_ROOT="${SPACK_BUILD_PATH}/spack"
# Isolate user configuration for spack
export SPACK_DISABLE_LOCAL_CONFIG=true
export SPACK_USER_CONFIG_PATH="${SPACK_BUILD_PATH}"
export SPACK_USER_CACHE_PATH="${SPACK_BUILD_PATH}/cache"
# Define the CP2K spack configuration file
export CP2K_CONFIG_FILE="${SPACK_BUILD_PATH}/cp2k_deps_${CP2K_VERSION:0:1}${CP2K_VERSION:4}.yaml"
# If requested, remove the spack folder for (re)building all CP2K dependencies
if [[ "${BUILD_DEPS}" == "always" ]]; then
for folder in ${SPACK_BUILD_PATH} ${BUILD_PATH}/build ${INSTALL_PREFIX}; do
if [[ -d "${folder}" ]]; then
echo "Removing folder \"${folder}\""
rm -rf "${folder}"
fi
done
fi
# If requested, remove the build folder for (re)building CP2K
if [[ "${REBUILD_CP2K}" == "yes" ]]; then
for folder in ${BUILD_PATH}/build ${INSTALL_PREFIX}; do
if [[ -d "${folder}" ]]; then
echo "Removing folder \"${folder}\""
rm -rf "${folder}"
fi
done
fi
# An incomplete build already contains the Spack installation, source cache,
# environment, and every successfully installed dependency. Re-enter the
# setup/install path until the completion marker is written.
if [[ ! -f "${SPACK_BUILD_PATH}/BUILD_DEPENDENCIES_COMPLETED" ]]; then
if [[ -d "${SPACK_BUILD_PATH}" ]]; then
echo "INFO: Resuming incomplete CP2K dependency build in ${SPACK_BUILD_PATH}"
else
echo "INFO: Creating local Spack build directory ${SPACK_BUILD_PATH}"
fi
mkdir -p "${SPACK_BUILD_PATH}"
cd "${SPACK_BUILD_PATH}" || ${EXIT_CMD} 1
# Reset the spack environment
unset SPACK_ENV
# Install Spack only when the local bootstrap is absent. wget --continue
# also retains a partially downloaded release archive across interruptions.
if [[ ! -d "${SPACK_ROOT}" ]]; then
echo "Installing Spack ${SPACK_VERSION}"
if ! wget -q -c "https://github.com/spack/spack/archive/v${SPACK_VERSION}.tar.gz"; then
echo "ERROR: Downloading Spack ${SPACK_VERSION} failed"
${EXIT_CMD} 1
fi
if ! tar -xzf "v${SPACK_VERSION}.tar.gz"; then
echo "ERROR: Extracting Spack ${SPACK_VERSION} failed"
${EXIT_CMD} 1
fi
if ! mv -f "${SPACK_BUILD_PATH}/spack-${SPACK_VERSION}" "${SPACK_ROOT}"; then
echo "ERROR: Installing Spack ${SPACK_VERSION} failed"
${EXIT_CMD} 1
fi
rm -f "v${SPACK_VERSION}.tar.gz"
fi
export PATH="${SPACK_ROOT}/bin:${PATH}"
# Create cache folder for user configuration
mkdir -p "${SPACK_USER_CACHE_PATH}"
# Set Spack cache (folder is the default)
export SPACK_CACHE="${SPACK_CACHE:-file://${CP2K_ROOT}/spack_cache}"
# Prepare for package caching
if [[ "${USE_CACHE}" == @("folder"|"minio") ]]; then
# Create the venv only once, then reuse it on a resumed dependency build.
if [[ ! -x "${SPACK_BUILD_PATH}/venv/bin/python3" ]]; then
if command -v python3 -m venv --help &> /dev/null; then
echo "Installing virtual environment for Python packages"
if ! python3 -m venv "${SPACK_BUILD_PATH}/venv"; then
echo "ERROR: The creation of a virtual environment (venv) for Python packages failed"
${EXIT_CMD} 1
fi
else
echo "ERROR: python3 -m venv was not found"
${EXIT_CMD} 1
fi
fi
export PATH="${SPACK_BUILD_PATH}/venv/bin:${PATH}"
# Avoid contacting PyPI again when the previously prepared venv is intact.
if ! python3 -c 'from importlib.metadata import version; assert version("boto3") == "1.38.11"; assert version("google-cloud-storage") == "3.1.0"' &> /dev/null; then
if ! python3 -m pip --version &> /dev/null; then
echo "ERROR: python3 -m pip was not found"
${EXIT_CMD} 1
fi
if ! python3 -m pip install "${VERBOSE_FLAG}" --upgrade pip \
boto3==1.38.11 google-cloud-storage==3.1.0; then
echo "ERROR: The installation of Python packages for the Spack cache failed"
${EXIT_CMD} 1
fi
fi
fi
# Prepare for using an MinIO object storage as cache
if [[ "${USE_CACHE}" == "minio" ]]; then
if [[ "${IN_CONTAINER}" == "yes" ]]; then
echo "ERROR: An external MinIO object storage container cannot be used as cache within a container"
echo " Use \"folder\" or \"no\" caching instead of \"MinIO\""
${EXIT_CMD} 1
fi
# MinIO requires podman
if command -v podman &> /dev/null; then
# Check podman version
((VERBOSE > 0)) && podman version
PODMAN_VERSION=$(podman version --format '{{.Client.Version}}' | awk -F'[.-]' '{print $1}')
if ((PODMAN_VERSION < 4)); then
echo "WARNING: Outdated podman version $(podman version --format '{{.Client.Version}}') found"
fi
export SPACK_CACHE="${SPACK_CACHE:-s3://spack-cache --s3-endpoint-url=http://localhost:9000}"
if ! "${CP2K_ROOT}"/tools/docker/spack_cache_start.sh; then
echo "ERROR: Could not start (new) spack cache"
echo ""
echo "An error message starting with \"Error: initial journal cursor: ...\" indicates that the"
echo "journald logging does not work. Try to switch podman (3.x) to file-based logs by creating"
echo "the file \"~/.config/containers/containers.conf\" with the following two lines:"
echo "[containers]"
echo "log_driver = \"k8s-file\""
${EXIT_CMD} 1
fi
else
echo "INFO: podman was not found"
echo " Install the package podman to use an MinIO object storage as cache"
echo " This accelerates a rebuild of the CP2K dependencies, significantly"
echo " The folder ${SPACK_CACHE} will be used as cache"
USE_CACHE="folder"
fi
fi
# Initialize Spack shell hooks
# shellcheck source=/dev/null
source "${SPACK_ROOT}/share/spack/setup-env.sh"
# Add spack cache as mirror if possible
if [[ "${USE_CACHE}" == @("folder"|"minio") ]]; then
echo "SPACK_CACHE = \"${SPACK_CACHE}\""
spack mirror list
if ! spack mirror list | grep -q "local-cache"; then
echo "Setting up spack cache"
if ((VERBOSE > 0)); then
"${CP2K_ROOT}"/tools/docker/scripts/setup_spack_cache.sh
else
"${CP2K_ROOT}"/tools/docker/scripts/setup_spack_cache.sh &> /dev/null
fi
fi
else
echo "INFO: A spack cache is NOT used"
fi
# Prepare the CP2K spack configuration file
CP2K_DEPS_FILE="${CP2K_ROOT}/tools/spack/cp2k_deps_${CP2K_VERSION:0:1}${CP2K_VERSION:4}.yaml"
if [[ -f "${CP2K_DEPS_FILE}" ]]; then
sed -E \
-e "s|root: /opt/spack|root: ${SPACK_ROOT}/opt/spack|" \
-e "/\"build_type=/s|build_type=[^\"]*|build_type=${DEPS_BUILD_TYPE}|" \
"${CP2K_DEPS_FILE}" > "${CP2K_CONFIG_FILE}"
else
echo -e "\nERROR: The spack configuration file ${CP2K_DEPS_FILE} was not found\n"
${EXIT_CMD} 1
fi
# Apply selected MPI type if needed
# MPICH is selected by default for psmp and no change needed for ssmp
if [[ "${MPI_MODE}" == "openmpi" ]]; then
sed -E \
-e '/\s*-\s+"mpich@/ s/^ /#/' \
-e '/\s*#\s*-\s+"openmpi@/ s/#/ /' \
-e '/\s*-\s+mpich/ s/mpich$/openmpi/' \
-i "${CP2K_CONFIG_FILE}"
fi
# Activate CUDA in the spack configuration file if requested
if ((CUDA_SM_CODE > 0)); then
sed -E \
-e "0,/~cuda/s//+cuda cuda_arch=${CUDA_SM_CODE}/" \
-e 's/"~cuda\s+~gpu_direct"/"\+cuda \+gpu_direct"/' \
-e '/\s*#\s*-\s+"fabrics=efa,ucx"/ s/#/ /' \
-e '/\s*#\s*-\s+"libxstream@/ s/#/ /' \
-i "${CP2K_CONFIG_FILE}"
# Building libfabric with CUDA causes problems
# sed -E -e 's/"~cuda\s+~gdrcopy"/"\+cuda \+gdrcopy"/' -i "${CP2K_CONFIG_FILE}"
sed -E -e 's/"~cuda\s+~gdrcopy"/"\~cuda"/' -i "${CP2K_CONFIG_FILE}"
if [[ -n "${CUDA_VERSION:-}" ]]; then
# Set CUDA SM code
sed -E -e "s/spec:\s+cuda@[.0-9]*/spec: cuda@${CUDA_VERSION}/" -i "${CP2K_CONFIG_FILE}"
fi
if [[ -n "${CUDA_HOME:-}" ]]; then
sed -E -e "s|prefix: /usr/local/cuda|prefix: ${CUDA_HOME}|" -i "${CP2K_CONFIG_FILE}"
fi
else
sed -E -e 's/"~cuda\s+~gdrcopy"/"\~cuda"/' -i "${CP2K_CONFIG_FILE}"
fi
# CUDA is required for libgint is requested
if [[ "${CMAKE_CUDA_FLAGS}" == *"-DCP2K_USE_ACCEL=CUDA"* ]]; then
if [[ "${CMAKE_FEATURE_FLAGS}" == *"-DCP2K_USE_EVERYTHING=ON"* ]] ||
[[ "${CMAKE_FEATURE_FLAGS}" == *"-DCP2K_USE_LIBGINT=ON"* ]]; then
sed -E \
-e '/\s*#\s*-\s+"libgint@/ s/#/ /' \
-i "${CP2K_CONFIG_FILE}"
fi
fi
# Activate OpenCL support if requested
if [[ "${USE_OPENCL}" == "yes" ]]; then
sed -E \
-e 's/"~opencl"/"+opencl"/' \
-e '/\s*#\s*-\s+"libxstream@/ s/#/ /' \
-i "${CP2K_CONFIG_FILE}"
fi
# Apply Cray specific adaptation of the spack configuration if requested (CSCS)
if [[ "${CRAY}" == "yes" ]]; then
sed -E \
-e '/\s*#\s*-\s+"netmod=ofi"/ s/#/ /' \
-e 's/~xpmem/+xpmem/' \
-e 's/"libfabric@[.0-9]*"/"libfabric@1.22.0"/' \
-i "${CP2K_CONFIG_FILE}"
fi
# Apply feature selection to spack configuration file
if [[ -n "${SED_PATTERN_LIST}" ]]; then
eval sed -E "${SED_PATTERN_LIST}" -i "${CP2K_CONFIG_FILE}"
fi
# Find all compilers
echo "Searching for GCC compilers"
if ! spack compiler find &> /dev/null; then
echo "ERROR: The compiler detection of spack failed"
${EXIT_CMD} 1
fi
spack compiler list
# Retrieve the newest compiler version found by spack
GCC_VERSION_NEWEST="$(spack compilers | sed -nE 's/.*gcc@([0-9]+(\.[0-9]+)*).*/\1/p' | sort -V | tail -n 1)"
echo "The newest GCC compiler version found by spack is ${GCC_VERSION_NEWEST}"
GCC_VERSION_NEWEST="$(echo "${GCC_VERSION_NEWEST}" | sed -E -e 's/.*@([0-9]+).*/\1/' | cut -d. -f1)"
# Check if the newest compiler version found on the host system is new enough
GCC_VERSION_MINIMUM="10"
if ((GCC_VERSION_NEWEST < GCC_VERSION_MINIMUM)); then
echo "INFO: The newest GCC compiler version ${GCC_VERSION_NEWEST} is too old,"
echo " because at least version ${GCC_VERSION_MINIMUM} is required"
GCC_VERSION="14"
echo "INFO: The lastest stable GCC version ${GCC_VERSION} will be built and used by spack"
fi
# Add a specific GCC version to the spack configuration if requested
if [[ "${GCC_VERSION}" == "auto" ]]; then
echo "Spack will automatically select the GCC version which is not necessarily the newest one found"
else
sed -E -e "s/gcc@10:/gcc@${GCC_VERSION}/" -i "${CP2K_CONFIG_FILE}"
fi
# Disable PEXSI because of an issue with SuperLU using GCC version 15
if ((CUDA_SM_CODE > 0)) || ((GCC_VERSION_NEWEST > 14)); then
sed -E -e '/\s*-\s+"pexsi@/ s/^ /#/' -i "${CP2K_CONFIG_FILE}"
echo "INFO: PEXSI has been disabled because CUDA or GCC 15 is used"
fi
# Create CP2K environment if needed
if spack env list | grep -q "${CP2K_ENV}"; then
echo "The Spack environment \"${CP2K_ENV}\" exists already"
else
cat "${CP2K_CONFIG_FILE}"
echo "The Spack environment \"${CP2K_ENV}\" does NOT exist"
if spack env create "${CP2K_ENV}" "${CP2K_CONFIG_FILE}" &> /dev/null; then
echo "The Spack environment \"${CP2K_ENV}\" has been created"
else
echo "ERROR: The creation of the Spack environment \"${CP2K_ENV}\" failed"
${EXIT_CMD} 1
fi
fi
# Activate CP2K environment if needed
if spack env activate "${CP2K_ENV}" &> /dev/null; then
echo "The Spack environment \"${CP2K_ENV}\" has been activated"
else
echo "ERROR: The activation of the Spack environment \"${CP2K_ENV}\" failed"
${EXIT_CMD} 1
fi
# Update the repo builtin
if ! spack repo update; then
echo "ERROR: The update of the repo builtin failed"
${EXIT_CMD} 1
fi
# Add the local CP2K development Spack repository when missing
export CP2K_REPO="cp2k_dev"
if ! spack repo list | grep -q "${CP2K_REPO}"; then
spack repo add --scope "env:${CP2K_ENV}" "${CP2K_ROOT}/tools/spack/spack_repo/${CP2K_REPO}"
else
echo "The CP2K development repo ${CP2K_REPO} is already present ... skipping add"
fi
spack -e ${CP2K_ENV} repo list
# Find all external packages
if [[ "${USE_EXTERNALS}" == "yes" ]]; then
if ! spack -C "${SPACK_USER_CONFIG_PATH}" external find; then
echo -e "\nERROR: The detection of externals by spack failed"
${EXIT_CMD} 1
fi
# Concretize CP2K dependencies
if ! spack -e "${CP2K_ENV}" concretize --fresh --jobs "${NUM_PROCS}"; then
echo -e "\nERROR: The spack concretize for environment \"${CP2K_ENV}\" failed"
echo ""
echo "HINT: The (-ue | --use_externals) flags can cause conflicts with outdated"
echo " packages on the host system, e.g. old python or gcc versions"
echo ""
${EXIT_CMD} 1
fi
else
# If the installation of a specific GCC version for building CP2K is requested,
# then an installation of the same GCC version on the host system has to be removed
# from the configuration for a static build of CP2K
if [[ "${CP2K_VERSION}" == *"-static" ]]; then
if spack compilers | grep -q "gcc@${GCC_VERSION}"; then
echo "INFO: A static build of CP2K with GCC ${GCC_VERSION} is requested without using"
echo " any externals which requires to build that GCC version with spack"
echo " while removing a gcc@${GCC_VERSION} installed on the host from the spack"
echo " configuration at the same time"
if ! spack compiler remove "gcc@${GCC_VERSION}"; then
echo -e "\nERROR: Removing the gcc@${GCC_VERSION} compiler failed"
${EXIT_CMD} 1
else
echo -e "\nINFO: gcc@${GCC_VERSION} compiler removed"
fi
spack compiler list
fi
fi
if ! spack -e "${CP2K_ENV}" concretize --fresh --jobs "${NUM_PROCS}"; then
echo -e "\nERROR: The spack concretize for environment \"${CP2K_ENV}\" failed"
${EXIT_CMD} 1
fi
fi
((VERBOSE > 0)) && spack find -c
# Install CP2K dependencies via Spack
if ! spack -e "${CP2K_ENV}" install -j "${NUM_PROCS}" -p "${NUM_PACKAGES}" "${VERBOSE_SPACK}"; then
echo "ERROR: Building the CP2K dependencies with spack failed"
if [[ "${USE_EXTERNALS}" == "yes" ]]; then
echo "HINT: Try to re-run the build without the (-ue | --use_externals) flag which avoids"
echo " errors or conflicts caused by externals from the host system"
fi
${EXIT_CMD} 1
fi
# Find all compilers
if ! spack compiler find; then
echo "ERROR: The compiler detection of spack failed"
${EXIT_CMD} 1
fi
# Fix Libs list in elpa pkg-config file when CUDA is used
if ((CUDA_SM_CODE > 0)); then
ELPA_PKG_CONFIG_FILE="$(find -L "${SPACK_ROOT}/opt/spack/view" -name "elpa*.pc")"
if [[ -f "${ELPA_PKG_CONFIG_FILE}" ]]; then
sed -E -e 's|Libs: |Libs: -L/usr/local/cuda/lib64 |' -i "${ELPA_PKG_CONFIG_FILE}"
fi
fi
# Return from spack folder after all installations are done
cd "${CP2K_ROOT}" || ${EXIT_CMD} 1
# Make a note of the successful build
touch "${SPACK_BUILD_PATH}/BUILD_DEPENDENCIES_COMPLETED"
echo -e '\n*** Installation of CP2K dependencies completed ***\n'
else
# Initialize Spack shell hooks
# shellcheck source=/dev/null
source "${SPACK_ROOT}"/share/spack/setup-env.sh
fi
# Quit after (re)building all CP2K dependencies if requested
if [[ "${BUILD_DEPS_ONLY}" == "yes" ]]; then
${EXIT_CMD}
fi
### End of build CP2K dependencies ###
### Build CP2K ###
if spack env list | grep -q "${CP2K_ENV}"; then
spack env list
else
echo "ERROR: No Spack environment \"${CP2K_ENV}\" found"
${EXIT_CMD} 1
fi
# Activate spack environment
eval "$(spack env activate --sh ${CP2K_ENV})"
spack env status
# CMake configuration step
export CMAKE_BUILD_PATH="${BUILD_PATH}/build"
# PyTorch's TorchConfig.cmake is buried in the Python site-packages directory
Torch_DIR="$(dirname "$(find "${SPACK_ROOT}" ! -type l -name TorchConfig.cmake | tail -n 1)")"
export Torch_DIR
# Check if PEXSI was built
if [[ "${MPI_MODE}" != "no" ]]; then
CP2K_USE_PEXSI="$(grep -Eq '\s*#\s*-\s+"pexsi@' "${CP2K_CONFIG_FILE}" && echo OFF || echo ON)"
else
CP2K_USE_PEXSI="ON"
fi
export CP2K_USE_PEXSI
if [[ ! -d "${CMAKE_BUILD_PATH}" ]]; then
mkdir -p "${CMAKE_BUILD_PATH}"
case "${CP2K_VERSION}" in
pdbg | psmp)
# shellcheck disable=SC2086
cmake -S "${CP2K_ROOT}" -B "${CMAKE_BUILD_PATH}" \
-GNinja \
-DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} \
-DCMAKE_BUILD_TYPE="${CP2K_BUILD_TYPE}" \
-DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \
-DCMAKE_INSTALL_MESSAGE="${INSTALL_MESSAGE}" \
-DCMAKE_SKIP_RPATH="ON" \
-DCMAKE_VERBOSE_MAKEFILE="${VERBOSE_MAKEFILE}" \
${CMAKE_FEATURE_FLAGS} \
-DCP2K_USE_PEXSI="${CP2K_USE_PEXSI}" \
${CMAKE_CUDA_FLAGS} \
-Werror=dev |&
tee "${CMAKE_BUILD_PATH}/cmake.log"
EXIT_CODE=$?
;;
sdbg | ssmp)
# shellcheck disable=SC2086
cmake -S "${CP2K_ROOT}" -B "${CMAKE_BUILD_PATH}" \
-GNinja \
-DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS} \
-DCMAKE_BUILD_TYPE="${CP2K_BUILD_TYPE}" \
-DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \
-DCMAKE_INSTALL_MESSAGE="${INSTALL_MESSAGE}" \
-DCMAKE_SKIP_RPATH="ON" \
-DCMAKE_VERBOSE_MAKEFILE="${VERBOSE_MAKEFILE}" \
${CMAKE_FEATURE_FLAGS} \
${CMAKE_CUDA_FLAGS} \
-Werror=dev |&
tee "${CMAKE_BUILD_PATH}/cmake.log"
EXIT_CODE=$?
;;
ssmp-static)
# Find some static libraries in advance
LIBOPENBLAS=$(find -L "${SPACK_ROOT}"/opt/spack/view -name libopenblas.a)
LIBM="$(find /usr -name libm.a 2> /dev/null)"
# shellcheck disable=SC2086
cmake -S "${CP2K_ROOT}" -B "${CMAKE_BUILD_PATH}" \
-GNinja \
-DBUILD_SHARED_LIBS="OFF" \
-DCMAKE_BUILD_TYPE="${CP2K_BUILD_TYPE}" \
-DCMAKE_EXE_LINKER_FLAGS="-static" \
-DCMAKE_FIND_LIBRARY_SUFFIXES=".a" \
-DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \
-DCMAKE_INSTALL_MESSAGE="${INSTALL_MESSAGE}" \
-DCMAKE_SKIP_RPATH="ON" \
-DCMAKE_VERBOSE_MAKEFILE="${VERBOSE_MAKEFILE}" \
-DCP2K_BLAS_LINK_LIBRARIES="${LIBOPENBLAS};${LIBM}" \
-DCP2K_LAPACK_LINK_LIBRARIES="${LIBOPENBLAS};${LIBM}" \
${CMAKE_FEATURE_FLAGS} \
-Werror=dev |&
tee "${CMAKE_BUILD_PATH}/cmake.log"
EXIT_CODE=$?
# It is almost impossible to avoid that shared libraries are pulled in
# when the CP2K dependencies are built and thus just change all shared
# to static libraries hoping that these are also available
sed -E -e "s/\.so/.a/g" -i build/build.ninja
;;
*)
echo "ERROR: Unknown CP2K version ${CP2K_VERSION} specified"
${EXIT_CMD} 1
;;
esac
if ((EXIT_CODE != 0)); then
echo "ERROR: The CMake configuration step failed with the error code ${EXIT_CODE}"
echo " You can try to remove the build folder with 'rm -rf build' and re-run"
echo " or even start the whole CP2K installation from scratch with the \"-bd\" flag"
${EXIT_CMD} "${EXIT_CODE}"
fi
fi
# CMake build step
echo -e '\n*** Compiling CP2K ***\n'
cmake --build "${CMAKE_BUILD_PATH}" --parallel "${NUM_PROCS}" -- "${VERBOSE_FLAG}" |& tee "${CMAKE_BUILD_PATH}"/ninja.log
EXIT_CODE=${PIPESTATUS[0]}
if ((EXIT_CODE != 0)); then
echo "ERROR: The CMake build step failed with the error code ${EXIT_CODE}"
${EXIT_CMD} "${EXIT_CODE}"
fi
# CMake install step
echo -e '\n*** Installing CP2K ***\n'
cmake --install "${CMAKE_BUILD_PATH}" |& tee "${CMAKE_BUILD_PATH}"/install.log
EXIT_CODE=${PIPESTATUS[0]}
if ((EXIT_CODE != 0)); then
echo -e "\nERROR: The CMake installation step failed with the error code ${EXIT_CODE}"
${EXIT_CMD} "${EXIT_CODE}"
fi
# Install Skala resource files if needed
export GAUXC_SKALA_MODEL="(not available)"
if spack location -i gauxc &> /dev/null; then
GAUXC_PATH="share/gauxc/onedft_models"
GAUXC_PREFIX="$(spack location -i gauxc)"
GAUXC_MODEL_SOURCE_PATH="${GAUXC_PREFIX%/}/${GAUXC_PATH}"
if [[ -d "${GAUXC_MODEL_SOURCE_PATH}" ]]; then
GAUXC_MODEL_TARGET_PATH="${INSTALL_PREFIX%/}/${GAUXC_PATH}"
mkdir -p "${GAUXC_MODEL_TARGET_PATH}"
if compgen -G "${GAUXC_MODEL_SOURCE_PATH}/*.fun" > /dev/null; then
cp "${GAUXC_MODEL_SOURCE_PATH}"/*.fun "${GAUXC_MODEL_TARGET_PATH}/"
else
echo -e "\nERROR: No GauXC model files found in source folder ${GAUXC_MODEL_SOURCE_PATH}"
${EXIT_CMD} 1
fi
shopt -s nullglob
MATCHES=("${GAUXC_MODEL_TARGET_PATH}"/skala*)
shopt -u nullglob
if ((${#MATCHES[@]} > 0)); then
export GAUXC_SKALA_MODEL="${MATCHES[${#MATCHES[@]} - 1]}"
else
echo -e "\nERROR: Failed to resolve GAUXC_SKALA_MODEL in target path ${GAUXC_MODEL_TARGET_PATH}"
${EXIT_CMD} 1
fi
fi
fi
echo -e "\nGAUXC_SKALA_MODEL = ${GAUXC_SKALA_MODEL}"
# Collect and compress all log files when building within a container
if [[ "${IN_CONTAINER}" == "yes" ]]; then
if ! cat "${CMAKE_BUILD_PATH}"/cmake.log \
"${CMAKE_BUILD_PATH}"/ninja.log \
"${CMAKE_BUILD_PATH}"/install.log |
gzip > "${CP2K_ROOT}"/install/build_cp2k.log.gz; then
echo -e "\nERROR: The compressed log file generation failed"
${EXIT_CMD} 1
fi
fi
# Cut extension from the CP2K version (e.g. ssmp-static -> ssmp)
export VERSION=${CP2K_VERSION%%-*}
# Add CP2K lib folder to the LD_LIBRARY_PATH
export LD_LIBRARY_PATH="${INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH}"
# Assemble search paths for libraries
search_paths="${SPACK_ROOT}/opt/spack/view ${INSTALL_PREFIX}/lib"
# Retrieve paths to all libraries needed by the CP2k binary
for library in $(readelf -d "${INSTALL_PREFIX}/bin/cp2k.${VERSION}" "${INSTALL_PREFIX}"/lib/libcp2k.* | awk '/NEEDED/{print $5}' | tr -d '[]' | sort | uniq); do
# Search for missing library path
if ! ldconfig -p | grep -qE "/${library}$"; then
# shellcheck disable=SC2086
library_with_path=$(find -L ${search_paths} -name "${library}" | tail -n 1)
if [[ -n "${library_with_path}" ]]; then
library_path="$(dirname "${library_with_path}")"
case ":${LD_LIBRARY_PATH}:" in
*":${library_path}:"*)
((VERBOSE > 1)) && echo "The library path ${library_path} is already present ... skipping"
;;
*)
LD_LIBRARY_PATH="${LD_LIBRARY_PATH:+${LD_LIBRARY_PATH}:}${library_path}"
((VERBOSE > 0)) && echo "The library path ${library_path} was appended to LD_LIBRARY_PATH"
;;
esac
fi
fi
done
export LD_LIBRARY_PATH
echo -e "\nLD_LIBRARY_PATH = \"${LD_LIBRARY_PATH}\""
# Create an ld configuration file for CP2K because LD_LIBRARY_PATH is fragile
if [[ "${IN_CONTAINER}" == "yes" ]]; then
CP2K_LD_CONF_FILE="/etc/ld.so.conf.d/cp2k.conf"
else
CP2K_LD_CONF_FILE="${INSTALL_PREFIX}/bin/cp2k.conf"
fi
# Either read LD_LIBRARY_PATH from an existing configuration file or write a new one
if [[ -f "${CP2K_LD_CONF_FILE}" ]]; then
# Load LD_LIBRARY_PATH from an existing configuration file
LD_LIBRARY_PATH="$(grep -E '^/' "${CP2K_LD_CONF_FILE}" | paste -sd ':' -)"
else
# Write LD_LIBRARY_PATH to a new configuration file
echo "${LD_LIBRARY_PATH}" | tr ':' '\n' | grep '^/' > "${CP2K_LD_CONF_FILE}"
fi
export LD_LIBRARY_PATH
# Create links to CP2K binaries
cd "${INSTALL_PREFIX}"/bin || ${EXIT_CMD} 1
for binary in *."${VERSION}"; do
if ! ln -sf "${binary}" "${binary%%."${VERSION}"}"; then
echo "ERROR: The creation of a symbolic link for the binary ${binary} failed"
${EXIT_CMD}
fi
done
ln -sf cp2k."${VERSION}" cp2k_shell
cd "${CP2K_ROOT}" || ${EXIT_CMD} 1
# Configure Open MPI environment for local CP2K runs
if [[ "${MPI_MODE}" == "openmpi" ]]; then
OMPI_VARS="export OMPI_MCA_plm_rsh_agent=/bin/false PRTE_MCA_hwloc_default_binding_policy=none"
if [[ "${IN_CONTAINER}" == "yes" ]]; then
OMPI_VARS="${OMPI_VARS} OMPI_ALLOW_RUN_AS_ROOT=1 OMPI_ALLOW_RUN_AS_ROOT_CONFIRM=1"
OMPI_VARS="${OMPI_VARS} OMPI_MCA_mpi_yield_when_idle=1 OMPI_MCA_btl=self,sm OMPI_MCA_pml=ob1"
fi
else
OMPI_VARS=""
fi
export OMPI_VARS
# MPICH and OpenMPI have different flags for exporting environment variables to MPI ranks
if [[ "${MPI_MODE}" == "openmpi" ]]; then
ENV_VAR_FLAG="-x"
else
ENV_VAR_FLAG="-genv"
fi
export ENV_VAR_FLAG
# Install LSAN suppressions (only needed for dbg binaries)
cp "${CP2K_ROOT}"/tools/spack/lsan.supp "${INSTALL_PREFIX}"/bin
# Assemble flags for running the regression tests
TESTOPTS="--cp2kdatadir ${INSTALL_PREFIX}/share/cp2k/data --maxtasks ${NUM_PROCS} --workbasedir ${INSTALL_PREFIX}/regtesting ${TESTOPTS}"
export TESTOPTS
# Create launch script for environment setup
LAUNCH_SCRIPT="${INSTALL_PREFIX}"/bin/launch
export LAUNCH_SCRIPT
cat << *** > "${LAUNCH_SCRIPT}"
#!/bin/bash
ulimit -c 0 -s unlimited
export ASAN_OPTIONS="detect_leaks=1"
export LSAN_OPTIONS="suppressions=${INSTALL_PREFIX}/bin/lsan.supp"
export PATH=${INSTALL_PREFIX}/bin:${PATH}
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}
export OMP_NUM_THREADS=\${OMP_NUM_THREADS:-2}
export OMP_STACKSIZE=256M
${OMPI_VARS}
export GAUXC_SKALA_MODEL=${GAUXC_SKALA_MODEL}
exec "\$@"
***
chmod 750 "${LAUNCH_SCRIPT}"
# Create shortcut for launching the regression tests
cat << *** > "${INSTALL_PREFIX}"/bin/run_tests
#!/bin/bash
if [[ "${VERSION}" =~ ^(s|p)dbg$ ]]; then
echo "ASAN_OPTIONS = \${ASAN_OPTIONS}"
echo "LSAN_OPTIONS = \${LSAN_OPTIONS}"
fi
ldd -- ${INSTALL_PREFIX}/bin/cp2k.${VERSION} 2>&1 | grep -E 'not ' | sort | uniq
export GAUXC_SKALA_MODEL=${GAUXC_SKALA_MODEL}
${CP2K_ROOT}/tests/do_regtest.py ${TESTOPTS} \$* ${INSTALL_PREFIX}/bin ${VERSION}
***
chmod 750 "${INSTALL_PREFIX}"/bin/run_tests
# Set image tag if available
export IMAGE_TAG=${IMAGE_TAG:-<IMAGE ID>}
# Optionally, launch test run
if [[ "${RUN_TEST}" == "yes" ]]; then
echo -e "\n*** Launching regression test run using the script ${INSTALL_PREFIX}/bin/run_tests\n"
${LAUNCH_SCRIPT} run_tests
EXIT_CODE=$?
if ((EXIT_CODE != 0)); then
echo "ERROR: The regression test run failed with the error code ${EXIT_CODE}"
${EXIT_CMD} "${EXIT_CODE}"
fi
else
if [[ "${IN_CONTAINER}" == "yes" ]]; then
if ((CUDA_SM_CODE > 0)); then
DEVICE_FLAG=" --device nvidia.com/gpu=all"
else
DEVICE_FLAG=""
fi
echo ""
echo "*** A regression test run can be launched with"
echo " podman run -it${DEVICE_FLAG} --rm ${IMAGE_TAG} run_tests"
echo ""
if [[ "${VERSION}" == @(sdbg|ssmp) ]]; then
echo "*** A CP2K run using 2 OpenMP threads (default) can be launched with"
echo " podman run -it${DEVICE_FLAG} --rm ${IMAGE_TAG} cp2k ${CP2K_ROOT}/benchmarks/CI/H2O-32_md.inp"
else
echo "*** An MPI-parallel CP2K run using 2 OpenMP threads for each of the 4 MPI ranks can be launched with"
echo " podman run -it${DEVICE_FLAG} --rm ${IMAGE_TAG} mpiexec -n 4 ${ENV_VAR_FLAG} OMP_NUM_THREADS=2 cp2k ${CP2K_ROOT}/benchmarks/CI/H2O-32_md.inp"
fi
echo ""
else
echo ""
echo "*** A regression test run can be launched with"
echo " ${LAUNCH_SCRIPT} run_tests"
echo ""
if [[ "${VERSION}" == @(sdbg|ssmp) ]]; then
echo "*** A CP2K run using 2 OpenMP threads (default) can be launched with"
echo " ${LAUNCH_SCRIPT} cp2k ${CP2K_ROOT}/benchmarks/CI/H2O-32_md.inp"
echo ""
echo "*** A CP2K run using only 4 OpenMP threads can be launched with"
echo " export OMP_NUM_THREADS=4; ${LAUNCH_SCRIPT} cp2k ${CP2K_ROOT}/benchmarks/CI/H2O-32_md.inp"
else
echo "*** An MPI-parallel CP2K run using 2 OpenMP threads for each of the 4 MPI ranks can be launched with"
echo " export OMP_NUM_THREADS=2; ${LAUNCH_SCRIPT} mpiexec -n 4 cp2k ${CP2K_ROOT}/benchmarks/CI/H2O-32_md.inp"
fi
echo ""
fi
fi