使用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="-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:

刘博​

Sob老师​

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

dmh1998dmh​