1#!/bin/bash -e 2 3[ "${BASH_SOURCE[0]}" ] && SCRIPT_NAME="${BASH_SOURCE[0]}" || SCRIPT_NAME=$0 4SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_NAME")" && pwd -P)" 5 6source "${SCRIPT_DIR}"/common_vars.sh 7source "${SCRIPT_DIR}"/tool_kit.sh 8source "${SCRIPT_DIR}"/signal_trap.sh 9source "${INSTALLDIR}"/toolchain.conf 10source "${INSTALLDIR}"/toolchain.env 11 12# ------------------------------------------------------------------------ 13# generate arch file for compiling cp2k 14# ------------------------------------------------------------------------ 15 16echo "==================== generating arch files ====================" 17echo "arch files can be found in the ${INSTALLDIR}/arch subdirectory" 18! [ -f "${INSTALLDIR}/arch" ] && mkdir -p ${INSTALLDIR}/arch 19cd ${INSTALLDIR}/arch 20 21# ------------------------- 22# set compiler flags 23# ------------------------- 24 25# need to switch between FC and MPICC etc in arch file, but cannot use 26# same variable names, so use _arch suffix 27CC_arch="$CC" 28CXX_arch="$CXX" 29FC_arch="IF_MPI(${MPIFC}|${FC})" 30LD_arch="IF_MPI(${MPIFC}|${FC})" 31 32# we always want good line information and backtraces 33BASEFLAGS="-march=native -fno-omit-frame-pointer -g ${TSANFLAGS}" 34OPT_FLAGS="-O3 -funroll-loops" 35NOOPT_FLAGS="-O1" 36 37# those flags that do not influence code generation are used always, the others if debug 38FCDEB_FLAGS="-ffree-form -std=f2008 -fimplicit-none" 39FCDEB_FLAGS_DEBUG="-fsanitize=leak -fcheck=all -ffpe-trap=invalid,zero,overflow -finit-derived -finit-real=snan -finit-integer=-42 -Werror=realloc-lhs -finline-matmul-limit=0" 40 41# code coverage generation flags 42COVERAGE_FLAGS="-O1 -coverage -fkeep-static-functions" 43COVERAGE_DFLAGS="-D__NO_ABORT" 44 45# profile based optimization, see https://www.cp2k.org/howto:pgo 46PROFOPT_FLAGS="\$(PROFOPT)" 47 48# special flags for gfortran 49# https://gcc.gnu.org/onlinedocs/gfortran/Error-and-Warning-Options.html 50# we error out for these warnings (-Werror=uninitialized -Wno-maybe-uninitialized -> error on variables that must be used uninitialized) 51WFLAGS_ERROR="-Werror=aliasing -Werror=ampersand -Werror=c-binding-type -Werror=intrinsic-shadow -Werror=intrinsics-std -Werror=line-truncation -Werror=tabs -Werror=target-lifetime -Werror=underflow -Werror=unused-but-set-variable -Werror=unused-variable -Werror=unused-dummy-argument -Werror=conversion -Werror=zerotrip -Werror=uninitialized -Wno-maybe-uninitialized" 52# we just warn for those (that eventually might be promoted to WFLAGSERROR). It is useless to put something here with 100s of warnings. 53WFLAGS_WARN="-Wuse-without-only" 54# while here we collect all other warnings, some we'll ignore 55WFLAGS_WARNALL="-pedantic -Wall -Wextra -Wsurprising -Wunused-parameter -Warray-temporaries -Wcharacter-truncation -Wconversion-extra -Wimplicit-interface -Wimplicit-procedure -Wreal-q-constant -Wunused-parameter -Walign-commons -Wfunction-elimination -Wrealloc-lhs -Wcompare-reals -Wzerotrip" 56 57# IEEE_EXCEPTIONS dependency 58IEEE_EXCEPTIONS_DFLAGS="-D__HAS_IEEE_EXCEPTIONS" 59 60# check all of the above flags, filter out incompatible flags for the 61# current version of gcc in use 62BASEFLAGS=$(allowed_gfortran_flags $BASEFLAGS) 63OPT_FLAGS=$(allowed_gfortran_flags $OPT_FLAGS) 64NOOPT_FLAGS=$(allowed_gfortran_flags $NOOPT_FLAGS) 65FCDEB_FLAGS=$(allowed_gfortran_flags $FCDEB_FLAGS) 66FCDEB_FLAGS_DEBUG=$(allowed_gfortran_flags $FCDEB_FLAGS_DEBUG) 67COVERAGE_FLAGS=$(allowed_gfortran_flags $COVERAGE_FLAGS) 68WFLAGS_ERROR=$(allowed_gfortran_flags $WFLAGS_ERROR) 69WFLAGS_WARN=$(allowed_gfortran_flags $WFLAGS_WARN) 70WFLAGS_WARNALL=$(allowed_gfortran_flags $WFLAGS_WARNALL) 71 72# check if ieee_exeptions module is available for the current version 73# of gfortran being used 74if ! (check_gfortran_module ieee_exceptions) ; then 75 IEEE_EXCEPTIONS_DFLAGS="" 76fi 77 78# concatenate the above flags into WFLAGS, FCDEBFLAGS, DFLAGS and 79# finally into FCFLAGS and CFLAGS 80WFLAGS="$WFLAGS_ERROR $WFLAGS_WARN IF_WARNALL(${WFLAGS_WARNALL}|)" 81FCDEBFLAGS="$FCDEB_FLAGS IF_DEBUG($FCDEB_FLAGS_DEBUG|)" 82DFLAGS="${CP_DFLAGS} IF_DEBUG($IEEE_EXCEPTIONS_DFLAGS -D__CHECK_DIAG|) IF_COVERAGE($COVERAGE_DFLAGS|)" 83# language independent flags 84# valgrind with avx can lead to spurious out-of-bound results 85G_CFLAGS="$BASEFLAGS IF_VALGRIND(-mno-avx -mno-avx2|)" 86G_CFLAGS="$G_CFLAGS IF_COVERAGE($COVERAGE_FLAGS|IF_DEBUG($NOOPT_FLAGS|$OPT_FLAGS))" 87G_CFLAGS="$G_CFLAGS IF_DEBUG(|$PROFOPT_FLAGS)" 88G_CFLAGS="$G_CFLAGS $CP_CFLAGS" 89# FCFLAGS, for gfortran 90FCFLAGS="$G_CFLAGS \$(FCDEBFLAGS) \$(WFLAGS) \$(DFLAGS)" 91# CFLAGS, special flags for gcc (currently none) 92CFLAGS="$G_CFLAGS \$(DFLAGS)" 93 94# Linker flags 95LDFLAGS="\$(FCFLAGS) ${CP_LDFLAGS}" 96 97# Library flags 98# add standard libs 99LIBS="${CP_LIBS} -lstdc++" 100 101# CUDA handling 102CUDA_LIBS="-lcudart -lnvrtc -lcuda -lcufft -lcublas -lrt IF_DEBUG(-lnvToolsExt|)" 103CUDA_DFLAGS="-D__ACC -D__DBCSR_ACC -D__PW_CUDA IF_DEBUG(-D__CUDA_PROFILING|)" 104if [ "${ENABLE_CUDA}" = __TRUE__ ] && [ "${GPUVER}" != no ] ; then 105 LIBS="${LIBS} IF_CUDA(${CUDA_LIBS}|)" 106 DFLAGS="IF_CUDA(${CUDA_DFLAGS}|) ${DFLAGS}" 107 NVFLAGS="-arch sm_${ARCH_NUM} -O3 -Xcompiler='-fopenmp' --std=c++11 \$(DFLAGS)" 108 check_command nvcc "cuda" 109 check_lib -lcudart "cuda" 110 check_lib -lnvrtc "cuda" 111 check_lib -lcuda "cuda" 112 check_lib -lcufft "cuda" 113 check_lib -lcublas "cuda" 114 115 # Set include flags 116 CUDA_CFLAGS='' 117 add_include_from_paths CUDA_CFLAGS "cuda.h" $INCLUDE_PATHS 118 export CUDA_CFLAGS="${CUDA_CFLAGS}" 119 CFLAGS+=" ${CUDA_CFLAGS}" 120 121 # Set LD-flags 122 CUDA_LDFLAGS='' 123 add_lib_from_paths CUDA_LDFLAGS "libcudart.*" $LIB_PATHS 124 add_lib_from_paths CUDA_LDFLAGS "libnvrtc.*" $LIB_PATHS 125 add_lib_from_paths CUDA_LDFLAGS "libcuda.*" $LIB_PATHS 126 add_lib_from_paths CUDA_LDFLAGS "libcufft.*" $LIB_PATHS 127 add_lib_from_paths CUDA_LDFLAGS "libcublas.*" $LIB_PATHS 128 export CUDA_LDFLAGS="${CUDA_LDFLAGS}" 129 LDFLAGS+=" ${CUDA_LDFLAGS}" 130fi 131 132# ------------------------- 133# generate the arch files 134# ------------------------- 135 136# generator for CP2K ARCH files 137gen_arch_file() { 138 # usage: gen_arch_file file_name flags 139 # 140 # If the flags are present they are assumed to be on, otherwise 141 # they switched off 142 require_env ARCH_FILE_TEMPLATE 143 local __filename=$1 144 shift 145 local __flags=$@ 146 local __full_flag_list="MPI OMP DEBUG CUDA WARNALL VALGRIND COVERAGE" 147 local __flag='' 148 for __flag in $__full_flag_list ; do 149 eval "local __${__flag}=off" 150 done 151 for __flag in $__flags ; do 152 eval "__${__flag}=on" 153 done 154 # generate initial arch file 155 cat $ARCH_FILE_TEMPLATE > $__filename 156 # add additional parts 157 if [ "$__CUDA" = "on" ] ; then 158 cat <<EOF >> $__filename 159# 160CXX = \${CC} 161CXXFLAGS = \${CXXFLAGS} -I\\\${CUDA_PATH}/include -std=c++11 IF_OMP(-fopenmp|) 162GPUVER = \${GPUVER} 163NVCC = \${NVCC} 164NVFLAGS = \${NVFLAGS} 165EOF 166 fi 167 if [ "$__WARNALL" = "on" ] ; then 168 cat <<EOF >> $__filename 169# 170FCLOGPIPE = 2> \\\$(notdir \\\$<).warn 171export LC_ALL=C 172EOF 173 fi 174 if [ "$with_gcc" != "__DONTUSE__" ] ; then 175 cat <<EOF >> $__filename 176# 177FYPPFLAGS = -n --line-marker-format=gfortran5 178EOF 179 fi 180 # replace variable values in output file using eval 181 local __TMPL=$(cat $__filename) 182 eval "printf \"${__TMPL}\n\"" > $__filename 183 # pass this to parsers to replace all of the IF_XYZ statements 184 "${SCRIPTDIR}/parse_if.py" -i -f "${__filename}" $__flags 185 echo "Wrote ${INSTALLDIR}/arch/$__filename" 186} 187 188rm -f ${INSTALLDIR}/arch/local* 189# normal production arch files 190 { gen_arch_file "local.sopt" ; arch_vers="sopt"; } 191 { gen_arch_file "local.sdbg" DEBUG; arch_vers="${arch_vers} sdbg"; } 192[ "$ENABLE_OMP" = __TRUE__ ] && \ 193 { gen_arch_file "local.ssmp" OMP; arch_vers="${arch_vers} ssmp"; } 194[ "$MPI_MODE" != no ] && \ 195 { gen_arch_file "local.popt" MPI; arch_vers="${arch_vers} popt"; } 196[ "$MPI_MODE" != no ] && \ 197 { gen_arch_file "local.pdbg" MPI DEBUG; arch_vers="${arch_vers} pdbg"; } 198[ "$MPI_MODE" != no ] && \ 199[ "$ENABLE_OMP" = __TRUE__ ] && \ 200 { gen_arch_file "local.psmp" MPI OMP; arch_vers="${arch_vers} psmp"; } 201[ "$MPI_MODE" != no ] && \ 202[ "$ENABLE_OMP" = __TRUE__ ] && \ 203 gen_arch_file "local_warn.psmp" MPI OMP WARNALL 204# cuda enabled arch files 205if [ "$ENABLE_CUDA" = __TRUE__ ] ; then 206 [ "$ENABLE_OMP" = __TRUE__ ] && \ 207 gen_arch_file "local_cuda.ssmp" CUDA OMP 208 [ "$MPI_MODE" != no ] && \ 209 [ "$ENABLE_OMP" = __TRUE__ ] && \ 210 gen_arch_file "local_cuda.psmp" CUDA OMP MPI 211 [ "$ENABLE_OMP" = __TRUE__ ] && \ 212 gen_arch_file "local_cuda.sdbg" CUDA DEBUG OMP 213 [ "$MPI_MODE" != no ] && \ 214 [ "$ENABLE_OMP" = __TRUE__ ] && \ 215 gen_arch_file "local_cuda.pdbg" CUDA DEBUG OMP MPI 216 [ "$MPI_MODE" != no ] && \ 217 [ "$ENABLE_OMP" = __TRUE__ ] && \ 218 gen_arch_file "local_cuda_warn.psmp" CUDA MPI OMP WARNALL 219fi 220# valgrind enabled arch files 221if [ "$ENABLE_VALGRIND" = __TRUE__ ] ; then 222 gen_arch_file "local_valgrind.sopt" VALGRIND 223 [ "$MPI_MODE" != no ] && \ 224 gen_arch_file "local_valgrind.popt" VALGRIND MPI 225fi 226# coverage enabled arch files 227gen_arch_file "local_coverage.sdbg" COVERAGE 228[ "$MPI_MODE" != no ] && \ 229 gen_arch_file "local_coverage.pdbg" COVERAGE MPI 230[ "$ENABLE_CUDA" = __TRUE__ ] && \ 231 gen_arch_file "local_coverage_cuda.pdbg" COVERAGE MPI CUDA 232 233cd "${ROOTDIR}" 234 235# ------------------------- 236# print out user instructions 237# ------------------------- 238 239cat <<EOF 240========================== usage ========================= 241Done! 242Now copy: 243 cp ${INSTALLDIR}/arch/* to the cp2k/arch/ directory 244To use the installed tools and libraries and cp2k version 245compiled with it you will first need to execute at the prompt: 246 source ${SETUPFILE} 247To build CP2K you should change directory: 248 cd cp2k/ 249 make -j ${NPROCS} ARCH=local VERSION="${arch_vers}" 250 251arch files for GPU enabled CUDA versions are named "local_cuda.*" 252arch files for valgrind versions are named "local_valgrind.*" 253arch files for coverage versions are named "local_coverage.*" 254 255Note that these pre-built arch files are for the GNU compiler, users have to adapt them for other compilers. 256It is possible to use the provided CP2K arch files as guidance. 257EOF 258 259#EOF 260