使用Intel 2019_update4结合toolchain 编译CP2K7.1
具怀逸兴
编辑于 2020年09月16日 10:10

在写本文之前,已经尝试了刘博刘锦程的教程 (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=&#​34;-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__&#​34; -        mkl_optional_libs="libmkl_scalapack_lp64.a&#​34; -        case $MPI_MODE in -            mpich) -                mkl_blacs_lib="libmkl_blacs_intelmpi_lp64.a&#​34; -                ;; -            openmpi) -                mkl_blacs_lib="libmkl_blacs_openmpi_lp64.a&#​34; -                ;; -            *) -                enable_mkl_scalapack="__FALSE__&#​34; -                ;; -        esac -        mkl_optional_libs="$mkl_optional_libs $mkl_blacs_lib" -        for ii in $mkl_optional_libs ; do -            if ! [ -f "${mkl_lib_dir}/${ii}&#​34; ] ; then -                enable_mkl_scalapack="__FALSE__&#​34; -            fi -        done -        if [ $enable_mkl_scalapack = "__TRUE__&#​34; ] ; 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__&#​34; -    fi -    MKL_LIBS="${MKL_LIBS} -Wl,--end-group -lpthread -lm -ldl" +    #    mkl_optional_libs=&#​34;libmkl_scalapack_lp64.a" +    #    case $MPI_MODE in +    #        mpich) +    #            mkl_blacs_lib=&#​34;libmkl_blacs_intelmpi_lp64.a" +    #            ;; +    #        openmpi) +    #            mkl_blacs_lib=&#​34;libmkl_blacs_openmpi_lp64.a" +    #            ;; +    #        *) +    #            enable_mkl_scalapack="__FALSE__&#​34; +    #            ;; +    #    esac +        mkl_optional_libs="&#​34; +    #    for ii in $mkl_optional_libs ; do +    #        if ! [ -f &#​34;${mkl_lib_dir}/${ii}" ] ; then +    #            enable_mkl_scalapack="__FALSE__&#​34; +    #        fi +    #    done +    #    if [ $enable_mkl_scalapack = "__TRUE__&#​34; ] ; then +    #        echo &#​34;Using MKL provided ScaLAPACK and BLACS" +    #        MKL_LIBS=&#​34;${mkl_lib_dir}/libmkl_scalapack_lp64.a ${MKL_LIBS} ${mkl_lib_dir}/${mkl_blacs_lib}" +    #    fi +    #else +    #    echo &#​34;Not using MKL provided ScaLAPACK and BLACS" +    #    enable_mkl_scalapack=&#​34;__FALSE__" +    #fi +    #MKL_LIBS=&#​34;${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&#​34; -        check_command mpicc "mpich&#​34; -        check_command mpif90 "mpich&#​34; -        check_command mpic++ "mpich&#​34; -        check_lib -lmpi "mpich&#​34; -        check_lib -lmpicxx "mpich&#​34; -        add_include_from_paths MPICH_CFLAGS "mpi.h&#​34; $INCLUDE_PATHS -        add_lib_from_paths MPICH_LDFLAGS "libmpi.*&#​34; $LIB_PATHS +        #check_command mpirun &#​34;mpich" +        #check_command mpicc &#​34;mpich" +        #check_command mpif90 &#​34;mpich" +        #check_command mpic++ &#​34;mpich" +        #check_lib -lmpi &#​34;mpich" +        #check_lib -lmpicxx &#​34;mpich" +        #add_include_from_paths MPICH_CFLAGS "mpi.h&#​34; $INCLUDE_PATHS +        #add_lib_from_paths MPICH_LDFLAGS "libmpi.*&#​34; $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:&#​34; | awk '{print $2}&#​39;) -    major_version=$(echo $raw_version | cut -d '.&#​39; -f 1) -    minor_version=$(echo $raw_version | cut -d '.&#​39; -f 2) -    if [ $major_version -lt 3 ] ; then -        mpi2_dflags="-D__MPI_VERSION=2&#​34; -    else +    #raw_version=$($mpi_bin --version | \ +    #                  grep &#​34;Version:" | awk &#​39;{print $2}') +    #major_version=$(echo $raw_version | cut -d '.&#​39; -f 1) +    #minor_version=$(echo $raw_version | cut -d '.&#​39; -f 2) +    #if [ $major_version -lt 3 ] ; then +    #    mpi2_dflags=&#​34;-D__MPI_VERSION=2" +    #else          mpi2_dflags='&#​39; -    fi +    #fi +    MPICH_CFLAGS="-I${I_MPI_ROOT}/include64&#​34; +    MPICH_LDFLAGS="-L${I_MPI_ROOT}/lib64 -Wl,-rpath=${I_MPI_ROOT}/lib64"      cat <<EOF >> "${BUILDDIR}/setup_mpich&#​34;  export MPI_MODE="${MPI_MODE}&#​34;  export MPICH_CFLAGS="${MPICH_CFLAGS}&#​34;

  • 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&#​34; \                          --with-cxx-optflags="$LIBINT_CXXFLAGS&#​34; \

  • 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}&#​34; \                     -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="${SIRIUS_DBG}&#​34; \ -                   -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}&#​34; \                        -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}&#​34; OMP) -lgfortran +LIBS=\$(DSUPERLULIB) ${PARMETIS_LDFLAGS} ${METIS_LDFLAGS} ${MATH_LDFLAGS} ${PARMETIS_LIBS} ${METIS_LIBS} $(resolve_string "${MATH_LIBS}&#​34; 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&#​34; = "no&#​34; ]; 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}&#​34; \                      --libdir="${pkg_install_dir}/lib&#​34; \                      --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}&#​34; \                      --libdir="${pkg_install_dir}/lib&#​34; \                      --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}&#​34; --prefix=${pkg_install_dir} --libdir="${pkg_install_dir}/lib&#​34; > configure.log 2>&1 +            ./configure CXX="${MPICXX}&#​34; --prefix=${pkg_install_dir} --libdir="${pkg_install_dir}/lib&#​34; CXXFLAGS="-I${GSLROOT}/include&#​34; 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}&#​34; "${SCRIPT_DIR}/$(basename ${SCRIPT_NAME})" @@ -63,7 +63,7 @@  esac    if [ "$with_plumed&#​34; != "__DONTUSE__&#​34; ] ; then -    PLUMED_LIBS='-lplumed -ldl -lstdc++ -lz -ldl' +    PLUMED_LIBS='-lplumedKernel -lplumed -ldl -lstdc++ -lz -ldl'      if [ "$with_plumed&#​34; != "__SYSTEM__&#​34; ] ; then          cat <<EOF > "${BUILDDIR}/setup_plumed&#​34;  prepend_path LD_LIBRARY_PATH "$pkg_install_dir/lib&#​34;

将这些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&#​34;, 实在不行就 --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:

刘博​

Sob老师​

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

dmh1998dmh​