环境信息:
Rocky Linux 8.6 Linux server 4.18.0-425.19.2.el8_7.x86_64
gcc version 8.5.0 20210514 (Red Hat 8.5.0-16) (GCC)
OneAPI 2023
Intel(R) oneAPI DPC++/C++ Compiler 2023.0.0 (2023.0.0.20221201)
ifort version 2021.8.0
一、编译cp2k 9.1
这里用的是gcc编译器编译串行的依赖和cp2k,然后并行版本依赖和cp2k还是用到Intel的工具mpiifort,mpiicc。且用了Intel的MKL。
首先要载入Intel OneAPI的module或者用source的方法载入环境变量。
module load compiler mkl mpi
然后解压cp2k,并进入toolchain目录
# wget https://github.com/cp2k/cp2k/releases/download/v9.1.0/cp2k-9.1.tar.bz2
tar -xvjf cp2k-9.1.tar.bz2
cd cp2k-9.1/tools/toolchain
然后运行toolchain自动编译工具
./install_cp2k_toolchain.sh \
--with-gcc=system \
--math-mode=mkl \
--with-mkl=system \
--with-intelmpi=system \
--with-scalapack=no \
--with-sirius=no \
--with-plumed=install
一切正常会提示成功
Done!
Now copy:
cp /home/xxx/cp2k/cp2k-9.1/tools/toolchain/install/arch/* to the cp2k/arch/ directory
To use the installed tools and libraries and cp2k version
compiled with it you will first need to execute at the prompt:
source /home/xxx/cp2k/cp2k-9.1/tools/toolchain/install/setup
To build CP2K you should change directory:
cd cp2k/
make -j 48 ARCH=local VERSION="ssmp sdbg psmp pdbg"
按照上边的操作,拷贝相关文件,添加环境变量,然后编译。这里先编译ssmp 和 psmp。
cp install/arch/* ../../arch/
source install/setup
cd ../../
make -j 48 ARCH=local VERSION="ssmp psmp"
小编自己测试ssmp 和 psmp通过。pdbg 没有编译通过,而sdbg有一个依赖库liblsan需要安装
sudo yum install -y liblsan
make -j 48 ARCH=local VERSION="sdbg"
成功之后可以看到在exe/local目录里边有这么一些文件
lrwxrwxrwx 1 sam sam 9 May 5 23:32 cp2k.popt -> cp2k.psmp
-rwxrwxr-x 1 sam sam 509M May 5 23:32 cp2k.psmp
-rwxrwxr-x 1 sam sam 339M May 6 00:16 cp2k.sdbg
lrwxrwxrwx 1 sam sam 9 May 5 23:32 cp2k_shell.psmp -> cp2k.psmp
lrwxrwxrwx 1 sam sam 9 May 6 00:16 cp2k_shell.sdbg -> cp2k.sdbg
lrwxrwxrwx 1 sam sam 9 May 6 06:57 cp2k_shell.ssmp -> cp2k.ssmp
lrwxrwxrwx 1 sam sam 9 May 6 06:57 cp2k.sopt -> cp2k.ssmp
-rwxrwxr-x 1 sam sam 292M May 6 06:57 cp2k.ssmp
可以看到popt是连接到psmp的,这是我们常用的版本。
如果要测试编译的文件是否正常运行,可以
make test
不得不提的问题是:libint的问题,在编译依赖库(运行toolchain)时,libint编译会报错使得libint的mod(fortran模块)文件没有被正确安装(脚本里边的make install没有执行)。
报错信息如下:
/home/sam/cp2k/cp2k-9.1-oneapi2023/cp2k-2023.1/tools/toolchain/build/libint-v2.6.0-cp2k-lmax-5/lib/.libs/libint2.a(libint2_static_init.o): In function `__st i__$E':
libint2_static_init.cc:(.text+0xc): undefined reference to `std::ios_base::Init::Init()'
libint2_static_init.cc:(.text+0x21): undefined reference to `std::ios_base::Init::~Init()'
/home/sam/cp2k/cp2k-9.1-oneapi2023/cp2k-9.1/tools/toolchain/build/libint-v2.6.0-cp2k-lmax-5/lib/.libs/libint2.a(libint2_static_init.o):(.gnu.linkonce.d.D W.ref.__gxx_personality_v0+0x0): undefined reference to `__gxx_personality_v0'
………………………….
………………………………….
OSVRRP0InBra_aB_p__0__pp__1___TwoPRep_unit__0__s__1___Ab__up_0.cc:(.text+0x23ec): undefined reference to `std::ios_base::Init::Init()'
OSVRRP0InBra_aB_p__0__pp__1___TwoPRep_unit__0__s__1___Ab__up_0.cc:(.text+0x2401): undefined reference to `std::ios_base::Init::~Init()'
make[1]: *** [Makefile:35: fortran_example] Error 1
make[1]: Leaving directory '/home/sam/cp2k/cp2k-9.1/tools/toolchain/build/libint-v2.6.0-cp2k-lmax-5/fortran'
make: *** [Makefile:38: fortran] Error 1
解决方法如下:
先进入目录(根据实际情况)
cd /home/sam/cp2k/cp2k-9.1/tools/toolchain/build/libint-v2.6.0-cp2k-lmax-5/fortran
将fortran/Makefile.in 改成如下
fortran_example: fortran_example.o libint_f.o $(LTLINK) $(CXX) $(CXXFLAGS) $(LDFLAGS) $(COMPUTE_LIB) $(SYSLIBS) $(FCLIBS) -o $@ $^ |
变成
fortran_example: fortran_example.o libint_f.o $(LTLINK) $(CXX) $(CXXFLAGS) $(LDFLAGS) $(COMPUTE_LIB) $(SYSLIBS) $(FCLIBS) -lstdc++ -o $@ $^ |
然后
make
make install
然后再去编译cp2k。
二、编译cp2k 2023.1
这里串行和并行用的都是OneAPI的编译器以及MKL。基本步骤一致,toolchain的参数要稍微变化一下。
module load compiler mkl mpi
cd tools/toolchain
./install_cp2k_toolchain.sh \
--math-mode=mkl \
--with-intelmpi=system \
--with-scalapack=no \
--with-sirius=no \
--with-plumed=install
成功后进行编译
cp install/arch/* to the ../../arch/
source install/setup
cd ../../
make -j 48 ARCH=local VERSION="ssmp sdbg psmp pdbg"
这里也有一个不得不提到的错误:
在最终make ARCH=local VERSION="ssmp sdbg psmp pdbg" 时,
/home/sam/cp2k/cp2k-2023.1/src/fm/cp_fm_types.F(2261): error #6780: A dummy argument with the INTENT(IN) attribute shall not be defined nor become undefined. [FM]
READ (unit) fm%local_data(:, j)
---------------------^
使得 ssmp和sdbg 没产生。这个应该是代码里边的一个问题,串行代码对一个INTENT(IN) 的变量进行了赋值,暂时的办法就是把INTENT(IN) 改成INTENT(INOUT) ,这实际上不会改变程序的运行,INTENT实际上应该在代码编译时能让编译器检查代码的错误(告诉编译器,在向一个函数里传入一个“地址”,但是这个地址对应的值不应该在这个函数里边被改变)。具体修改:
vi src/fm/cp_fm_types.F
把cp_fm_types.F里边的函数cp_fm_read_unformatted里边的声明
YPE(cp_fm_type), INTENT(IN) :: fm |
改成
YPE(cp_fm_type), INTENT(INOUT) :: fm |
三、一些Tips
首先, tools/toolchain里边的scripts目录,是install_cp2k_toolchain.sh要调用的脚本,这些脚本里边包含下载的依赖代码的版本和下载地址。在运行install_cp2k_toolchain.sh时,代码压缩包被下载到build目录,并在里边进行编译。且,下载前会检测build里边是否有这个包,如果已经有了,就会跳过下载进行解压。对于下载未完成的包会提示解压报错,这时需要删除这个未完成的包重新来过。如果下载太慢,可以自己手动下载然后拷贝到build里边,但是要注意版本和文件名要严格对应。另外一种方法是给wget添加代理参数:
cd ./tools/toolchain
vi scripts/tool_kit.sh
将(两处)
local __wget_flags='--quiet' |
改成
local __wget_flags='--quiet -e use_proxy=yes -e http_proxy=http://192.168.1.99:8090' |
另外,install文件夹是依赖软件包的安装目录,如果要重新编译这个依赖包,需要将install里边相应的文件夹删除。
最后,可以将下载好的依赖,修改掉“bug”连同cp2k的源码一起打包,以便下次使用。如有需要小编打好的包,请mail我(Email: fangjzh#foxmail.com , 将#改成@)。