在写本文之前,已经尝试了刘博刘锦程的教程 (b站用户名:啦啦黑还黑)。刘博的教程使用GNU编译器加Intel 的MKL库来编译CP2K。奈何本人对Linux系统不甚了解,在系统已经安装了Intel编译器的情况下,无论如何注释掉Intel编译器来让系统用GNU编译器进行编译,却屡屡报错,最后无奈之下,只好尝试直接用装好的Intel编译器来进行安装。各位同学如果电脑之前已经安装了Intel编译器,可以把此文作为一个参考。
本人系统:centos 7.6,Intel 2019 update 4 编译器,另外python3,cmake 等一些必备组件需要事先安装,当然后面编译出错时也可以根据 .log文件看是否系统缺少某些重要文件。
在正式介绍安装步骤之前,先了解一下CP2K官方对于编译器的要求(如下图),请同学们对照要求下载相应的版本。

cp2k对于编译器的要求

Intel编译器的安装在此就不再赘述,我是之前为了安装VASP,按照sobereva老师的教程一步步来装的,具体传送门:Intel编译器的安装

1. 安装Intel编译器完成后,在terminal里输入 gedit ~/.bashrc ,在打开的文件中,添加以下内容:
source /opt/intel/parallel_studio_xe_2019/psxevars.sh
source /opt/intel/mkl/bin/mklvars.sh intel64
source /opt/intel/bin/compilervars.sh intel64
source /opt/intel/compilers_and_libraries_2019.4.243/linux/mpi/intel64/bin/mpivars.sh
export CC=icc
export CXX=icpc
export FC=ifort
export MPICC=mpiicc
export MPICXX=mpiicpc
export MPIFC=mpiifort
然后关闭bashrc,在terminal里输入source ~/.bashrc即可

2. centos默认的gnu时4.8.5,此时必须将gnu升级到9.3.1,这里也是按照刘博的教程:
yum install centos-release-scl yum install devtoolset-9-gcc* scl enable devtoolset-9 bash
装完后,在terminal输入gcc -v看一下是不是已经变为9.3.1了。此时可以先用gnu编译器把cmake3.15装到系统里备用。

3. 下载cp2k安装包,地址:https://github.com/cp2k/cp2k/releases/download/v7.1.0/cp2k-7.1.tar.bz2,然后解压到特定文件夹。

4. 使用Intel编译器进行toolchain安装时需要注意,在 */cp2k-7.1/tools/toolchain/scripts 里的一些脚本需要进行修改,主要是以下这些
install_cp2k_toolchain.sh.diff
--- install_cp2k_toolchain.sh 2020-01-31 17:07:19.000000000 +0900
+++ install_cp2k_toolchain.sh 2020-01-31 17:07:30.000000000 +0900
@@ -942,8 +942,8 @@
./scripts/install_superlu.sh
./scripts/install_pexsi.sh
./scripts/install_quip.sh
- ./scripts/install_plumed.sh
./scripts/install_gsl.sh
+ ./scripts/install_plumed.sh
./scripts/install_spglib.sh
./scripts/install_hdf5.sh
./scripts/install_libvdwxc.sh
install_mkl.sh.intel.diff
--- install_mkl.sh 2020-01-31 15:58:56.000000000 +0900
+++ install_mkl.sh 2020-02-04 17:20:01.000000000 +0900
@@ -66,37 +66,38 @@
fi
done
# set the correct lib flags from MLK link adviser
- MKL_LIBS="-Wl,--start-group ${mkl_lib_dir}/libmkl_gf_lp64.a ${mkl_lib_dir}/libmkl_core.a ${mkl_lib_dir}/libmkl_sequential.a"
+ #MKL_LIBS="-Wl,--start-group ${mkl_lib_dir}/libmkl_gf_lp64.a ${mkl_lib_dir}/libmkl_core.a ${mkl_lib_dir}/libmkl_sequential.a"
+ MKL_LIBS="-L${mkl_lib_dir} -Wl,--no-as-needed -lmkl_scalapack_lp64 -lmkl_blacs_intelmpi_lp64 -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl"
# check optional libraries
- if [ $MPI_MODE != no ] ; then
+ #if [ $MPI_MODE != no ] ; then
enable_mkl_scalapack="__TRUE__"
- mkl_optional_libs="libmkl_scalapack_lp64.a"
- case $MPI_MODE in
- mpich)
- mkl_blacs_lib="libmkl_blacs_intelmpi_lp64.a"
- ;;
- openmpi)
- mkl_blacs_lib="libmkl_blacs_openmpi_lp64.a"
- ;;
- *)
- enable_mkl_scalapack="__FALSE__"
- ;;
- esac
- mkl_optional_libs="$mkl_optional_libs $mkl_blacs_lib"
- for ii in $mkl_optional_libs ; do
- if ! [ -f "${mkl_lib_dir}/${ii}" ] ; then
- enable_mkl_scalapack="__FALSE__"
- fi
- done
- if [ $enable_mkl_scalapack = "__TRUE__" ] ; then
- echo "Using MKL provided ScaLAPACK and BLACS"
- MKL_LIBS="${mkl_lib_dir}/libmkl_scalapack_lp64.a ${MKL_LIBS} ${mkl_lib_dir}/${mkl_blacs_lib}"
- fi
- else
- echo "Not using MKL provided ScaLAPACK and BLACS"
- enable_mkl_scalapack="__FALSE__"
- fi
- MKL_LIBS="${MKL_LIBS} -Wl,--end-group -lpthread -lm -ldl"
+ # mkl_optional_libs="libmkl_scalapack_lp64.a"
+ # case $MPI_MODE in
+ # mpich)
+ # mkl_blacs_lib="libmkl_blacs_intelmpi_lp64.a"
+ # ;;
+ # openmpi)
+ # mkl_blacs_lib="libmkl_blacs_openmpi_lp64.a"
+ # ;;
+ # *)
+ # enable_mkl_scalapack="__FALSE__"
+ # ;;
+ # esac
+ mkl_optional_libs=""
+ # for ii in $mkl_optional_libs ; do
+ # if ! [ -f "${mkl_lib_dir}/${ii}" ] ; then
+ # enable_mkl_scalapack="__FALSE__"
+ # fi
+ # done
+ # if [ $enable_mkl_scalapack = "__TRUE__" ] ; then
+ # echo "Using MKL provided ScaLAPACK and BLACS"
+ # MKL_LIBS="${mkl_lib_dir}/libmkl_scalapack_lp64.a ${MKL_LIBS} ${mkl_lib_dir}/${mkl_blacs_lib}"
+ # fi
+ #else
+ # echo "Not using MKL provided ScaLAPACK and BLACS"
+ # enable_mkl_scalapack="__FALSE__"
+ #fi
+ #MKL_LIBS="${MKL_LIBS} -Wl,--end-group -lpthread -lm -ldl"
MKL_CFLAGS="${MKL_CFLAGS} -I${MKLROOT}/include -I${MKLROOT}/include/fftw"
# write setup files
install_mpich.sh.intel.diff
--- install_mpich.sh 2020-01-29 15:58:59.000000000 +0900
+++ install_mpich.sh 2020-01-29 16:03:53.000000000 +0900
@@ -50,14 +50,14 @@
;;
__SYSTEM__)
echo "==================== Finding MPICH from system paths ===================="
- check_command mpirun "mpich"
- check_command mpicc "mpich"
- check_command mpif90 "mpich"
- check_command mpic++ "mpich"
- check_lib -lmpi "mpich"
- check_lib -lmpicxx "mpich"
- add_include_from_paths MPICH_CFLAGS "mpi.h" $INCLUDE_PATHS
- add_lib_from_paths MPICH_LDFLAGS "libmpi.*" $LIB_PATHS
+ #check_command mpirun "mpich"
+ #check_command mpicc "mpich"
+ #check_command mpif90 "mpich"
+ #check_command mpic++ "mpich"
+ #check_lib -lmpi "mpich"
+ #check_lib -lmpicxx "mpich"
+ #add_include_from_paths MPICH_CFLAGS "mpi.h" $INCLUDE_PATHS
+ #add_lib_from_paths MPICH_LDFLAGS "libmpi.*" $LIB_PATHS
;;
__DONTUSE__)
;;
@@ -87,15 +87,17 @@
mpi_bin=mpirun
fi
# check MPICH version, versions less than 3.0 will get -D__MPI_VERSION=2 flag
- raw_version=$($mpi_bin --version | \
- grep "Version:" | awk '{print $2}')
- major_version=$(echo $raw_version | cut -d '.' -f 1)
- minor_version=$(echo $raw_version | cut -d '.' -f 2)
- if [ $major_version -lt 3 ] ; then
- mpi2_dflags="-D__MPI_VERSION=2"
- else
+ #raw_version=$($mpi_bin --version | \
+ # grep "Version:" | awk '{print $2}')
+ #major_version=$(echo $raw_version | cut -d '.' -f 1)
+ #minor_version=$(echo $raw_version | cut -d '.' -f 2)
+ #if [ $major_version -lt 3 ] ; then
+ # mpi2_dflags="-D__MPI_VERSION=2"
+ #else
mpi2_dflags=''
- fi
+ #fi
+ MPICH_CFLAGS="-I${I_MPI_ROOT}/include64"
+ MPICH_LDFLAGS="-L${I_MPI_ROOT}/lib64 -Wl,-rpath=${I_MPI_ROOT}/lib64"
cat <<EOF >> "${BUILDDIR}/setup_mpich"
export MPI_MODE="${MPI_MODE}"
export MPICH_CFLAGS="${MPICH_CFLAGS}"
install_libint.sh.intel.diff
--- install_libint.sh 2020-02-03 18:13:20.000000000 +0900
+++ install_libint.sh 2020-02-03 19:16:36.000000000 +0900
@@ -72,6 +72,8 @@
#cmake --build . > cmake.log 2>&1
#cmake --build . --target install > install.log 2>&1
+ # extremely ad hoc workaround
+ sed -i -e "s/fortran_example check_test/libint_f.o check_test/" fortran/Makefile.in
./configure --prefix=${pkg_install_dir} \
--with-cxx="$CXX $LIBINT_CXXFLAGS" \
--with-cxx-optflags="$LIBINT_CXXFLAGS" \
install_sirius.sh.diff
--- install_sirius.sh 2020-02-25 14:50:50.000000000 +0900
+++ install_sirius.sh 2020-02-25 14:48:01.000000000 +0900
@@ -131,8 +131,8 @@
-DSpFFT_DIR="${SPFFT_ROOT}/lib/cmake/SpFFT" \
-DCMAKE_CXXFLAGS_RELEASE="${SIRIUS_OPT}" \
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="${SIRIUS_DBG}" \
- -DCMAKE_CXX_COMPILER=mpic++ \
- -DCMAKE_C_COMPILER=mpicc \
+ -DCMAKE_CXX_COMPILER=${MPICXX} \
+ -DCMAKE_C_COMPILER=${MPICC} \
${COMPILATION_OPTIONS} .. > compile.log 2>&1
make -j $NPROCS -C src >> compile.log 2>&1
@@ -155,8 +155,8 @@
-DCMAKE_CXX_FLAGS_RELWITHDEBINFO="${SIRIUS_DBG}" \
-DUSE_CUDA=ON \
-DGPU_MODEL=P100 \
- -DCMAKE_CXX_COMPILER=mpic++ \
- -DCMAKE_C_COMPILER=mpicc ${COMPILATION_OPTIONS} .. >> compile.log 2>&1
+ -DCMAKE_CXX_COMPILER=${MPICXX} \
+ -DCMAKE_C_COMPILER=${MPICC} ${COMPILATION_OPTIONS} .. >> compile.log 2>&1
make -j $NPROCS -C src >> compile.log 2>&1
install -d ${pkg_install_dir}/lib/cuda
install -d ${pkg_install_dir}/include/cuda
install_superlu.sh.intel.diff
--- install_superlu.sh 2020-02-04 11:46:01.000000000 +0900
+++ install_superlu.sh 2020-02-04 11:46:22.000000000 +0900
@@ -46,12 +46,12 @@
cat <<EOF >> make.inc
PLAT=_${OPENBLAS_ARCH}
DSUPERLULIB= ${PWD}/lib/libsuperlu_dist.a
-LIBS=\$(DSUPERLULIB) ${PARMETIS_LDFLAGS} ${METIS_LDFLAGS} ${MATH_LDFLAGS} ${PARMETIS_LIBS} ${METIS_LIBS} $(resolve_string "${MATH_LIBS}" OMP) -lgfortran
+LIBS=\$(DSUPERLULIB) ${PARMETIS_LDFLAGS} ${METIS_LDFLAGS} ${MATH_LDFLAGS} ${PARMETIS_LIBS} ${METIS_LIBS} $(resolve_string "${MATH_LIBS}" OMP)
ARCH=ar
ARCHFLAGS=cr
RANLIB=ranlib
CC=${MPICC}
-CFLAGS=${CFLAGS} ${PARMETIS_CFLAGS} ${METIS_CFLAGS} ${MATH_CFLAGS}
+CFLAGS=${CFLAGS} -std=c99 -fPIC ${PARMETIS_CFLAGS} ${METIS_CFLAGS} ${MATH_CFLAGS}
NOOPTS=-O0
FORTRAN=${MPIFC}
F90FLAGS=${FFLAGS}
install_libvdwxc.sh.intel.diff
--- install_libvdwxc.sh 2020-02-04 16:23:50.000000000 +0900
+++ install_libvdwxc.sh 2020-02-04 16:48:35.000000000 +0900
@@ -65,7 +65,7 @@
unset MPICC MPICXX MPIF90 MPIFC MPIF77
if [ "$MPI_MODE" = "no" ]; then
# compile libvdwxc without mpi support since fftw (or mkl) do not have mpi support activated
- ./configure \
+ CC=${CC} FC=${FC} ./configure \
--prefix="${pkg_install_dir}" \
--libdir="${pkg_install_dir}/lib" \
--with-fftw3=${FFTW_ROOT} \
@@ -73,12 +73,11 @@
--without-mpi \
>> configure.log 2>&1
else
- CC=mpicc FC=mpifort ./configure \
+ MPICC=mpiicc MPIFC=mpiifort ./configure \
--prefix="${pkg_install_dir}" \
--libdir="${pkg_install_dir}/lib" \
--with-fftw3=${FFTW_ROOT} \
--disable-shared \
- --with-mpi \
>> configure.log 2>&1
fi
make -j $NPROCS > compile.log 2>&1
install_plumed.sh.diff
--- install_plumed.sh 2020-02-04 15:13:41.986747619 +0900
+++ install_plumed.sh 2020-02-04 16:00:15.980396838 +0900
@@ -40,7 +40,7 @@
echo "Installing from scratch into ${pkg_install_dir}"
cd plumed-${plumed_ver}
- ./configure CXX="${MPICXX}" --prefix=${pkg_install_dir} --libdir="${pkg_install_dir}/lib" > configure.log 2>&1
+ ./configure CXX="${MPICXX}" --prefix=${pkg_install_dir} --libdir="${pkg_install_dir}/lib" CXXFLAGS="-I${GSLROOT}/include" LIBS="-L${GSLROOT}/lib -L${MKLROOT}/lib/intel64 -Wl,--no-as-needed -lmkl_intel_lp64 -lmkl_sequential -lmkl_core -lpthread -lm -ldl" > configure.log 2>&1
make -j $NPROCS > make.log 2>&1
make install > install.log 2>&1
write_checksums "${install_lock_file}" "${SCRIPT_DIR}/$(basename ${SCRIPT_NAME})"
@@ -63,7 +63,7 @@
esac
if [ "$with_plumed" != "__DONTUSE__" ] ; then
- PLUMED_LIBS='-lplumed -ldl -lstdc++ -lz -ldl'
+ PLUMED_LIBS='-lplumedKernel -lplumed -ldl -lstdc++ -lz -ldl'
if [ "$with_plumed" != "__SYSTEM__" ] ; then
cat <<EOF > "${BUILDDIR}/setup_plumed"
prepend_path LD_LIBRARY_PATH "$pkg_install_dir/lib"
将这些diff文件(复制代码,另存为xxxx.diff)复制到*/cp2k-7.1/tools/toolchain/scripts,(toolchain那个diff文件放到*/cp2k-7.1/tools/toolchain),依次执行 patch < ***.diff就可以将对应脚本修改好了。

5. 下面开始用toolchain安装,在*/cp2k-7.1/tools/toolchain 页面打开terminal,输入
./install_cp2k_toolchain.sh --math-mode=mkl \ --mpi-mode=mpich \ --with-cmake=system \ --with-mpich=system \ --with-openmpi=no \ --with-libxc=install \ --with-libint=install \ --with-fftw=install \ --with-openblas=no \ --with-scalapack=no \ --with-reflapack=no \ --with-libxsmm=install \ --with-elpa=install \ --with-ptscotch=install \ --with-pexsi=install \ --with-parmetis=install \ --with-superlu=install \ --with-quip=no \ --with-plumed=install \ --with-gsl=install \ --with-libvdwxc=install \ --with-spglib=install \ --with-hdf5=install \ --with-spfft=install
即可把所需要的文件都安装好。
安装过程中可能会遇到一些错误,需要进入*/cp2k-7.1/tools/toolchain/build,去对应的文件夹里找 find -name *.log,看具体什么错误类型。

如果elpa错误,可以加
SCALAPACK_LDFLAGS="-L$MKL_HOME/lib/intel64 -lmkl_scalapack_lp64 -lmkl_gf_lp64 -lmkl_sequential \ -lmkl_core -lmkl_blacs_intelmpi_lp64 -lpthread -lm -Wl,-rpath,$MKL_HOME/lib/intel64" \ SCALAPACK_FCFLAGS="-L$MKL_HOME/lib/intel64 -lmkl_scalapack_lp64 -lmkl_gf_lp64 -lmkl_sequential \ -lmkl_core -lmkl_blacs_intelmpi_lp64 -lpthread -lm -I$MKL_HOME/include/intel64/lp64"
到84行的 ../configure 前面

如果出现类似如下错误,Error: Variable ‘i’ at (1) set to undefined value inside loop beginning at (2) as INTENT(OUT) argument to subroutine ‘sirius_option_get_name_and_type’ make【3】: *** 【input_cp2k_pwdft.o】 Error 1 make【3】: *** Waiting for unfinished jobs.... make【2】: *** 【all】 Error 2 make【1】: *** 【psmp】 Error 2 make: *** 【all】 Error 2
找到对应的log看是哪个文件出错,我遇到的都是某一个Fortran文件的bug,主要是do语句里(1) 定义的整数 i 在子程序 (2) 未被定义,那就在前面的integer部分多加一个参数 i_tmp,然后在do i=0,10 下面加上 i_tmp = i,然后在 子程序 (2) sirius_option_get_name_and_type (...)括号里的 i 换成 i_tmp 即可。凡是遇到这种在subroutine里有undefined variable X, 那就再定义一个新的参数X_tmp (或其他不和程序里参数重名的名字),并将之前的X 赋值给新的X_tmp,在子程序里调用X_tmp即可。

如果plumed出错,参照 plumed 修改 scripts/install_plumed.sh 在44行 make 后面加 LD_RO="ld.gold -r -o", 实在不行就 --with-plumed=no

6. toolchain 安装完毕后,系统会提示把 toolchain/install/arch/* 复制到 ../../arch/,复制完成后,在terminal 里 输入 source /home/cp2k-7.1/tools/toolchain/install/setup, 去cp2k7.1/arch 里找到local.psmp 和 local.popt,在 “LDFLAGS = $(FCFLAGS)
后插入-static-intel -nofor_main (dmh1998dmh)
然后 make -j xx (机器最多的核数) ARCH=local VERSION=“popt psmp” 看 exe文件夹的local里有没有对应的可执行文件。配置对应文件的环境变量 export PATH=$PATH=.......到 bashrc
make完成后 make -j xx (机器最多的核数) ARCH=local VERSION=“popt psmp” test 看是否可以正常运行CP2K。

Acknowledgements:
https://ccportal.ims.ac.jp/en/node/2640