在写本文之前,已经尝试了刘博刘锦程的教程 (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