CP2K第一性原理程序在CentOS中的簡易安裝方法
CP2K第一性原理程序在CentOS中的簡易安裝方法
文/Sobereva@北京科音
First release: 2021-Feb-16 Last update: 2023-Jan-21
1 前言
CP2K(https://www.cp2k.org)是非常好的第一性原理程序,開源免費,跑中、大周期性體系比起主流的基于平面波的程序如Quantum ESPRESSO、VASP等速度快得多,而且筆者寫的Multiwfn(http://www.shanxitv.org/multiwfn)的創建CP2K輸入文件的功能使得CP2K做常見任務用起來比較簡單(見《使用Multiwfn非常便利地創建CP2K程序的輸入文件》http://www.shanxitv.org/587),以后用CP2K的人肯定會越來越多。本文介紹一下CP2K怎么在非常適合做科學計算的Linux發行版CentOS上進行安裝。本文的內容對于其它Linux系統在一定程度上也適用。
最初寫本文的時候CP2K最新的是8.1版。后來以同樣的方法,經測試也可以順利編譯8.2、9.1、2022.1、2023.1。最初寫本文的時候我用的是CentOS,后來我改用Rocky Linux后實測也可以用本文完全相同的方式安裝。
CP2K有sopt、ssmp、popt、psmp四種版本,如果你不了解的話,先看一下本文文末附錄中的介紹。
CP2K有三種安裝方式:
(1)先依次手動編譯CP2K所需要的各個庫,然后再編譯CP2K,具體過程見官方說明https://github.com/cp2k/cp2k/blob/master/INSTALL.md。我不推薦這種做法,因為CP2K涉及的庫特別多,一個一個手動編譯頗為麻煩。如果你有經驗和耐心可以這么鼓搗。
(2)使用CP2K自帶的toolchain腳本。toolchain可以自動把CP2K依賴的各種庫都一一下載并且自動編譯,最后輸入幾行命令再把CP2K編譯出來就OK了。整個過程非常簡單省事,下文第2節就介紹這種做法。
(3)直接用官方預編譯的ssmp版,下載后直接就能用,極為方便,下文第3節會說具體做法。
2 基于toolchain安裝CP2K
2.1 相關知識
CP2K是基于Fortran的程序,但它依賴的一堆庫很多都是C/C++寫的,所以Fortran和C/C++編譯器都得有。CP2K的編譯對于編譯器有明確的要求,兼容情況見https://www.cp2k.org/dev:compiler_support。可見如果用gcc+gfortran來編譯的話,gcc必須>=5.5版。CentOS 7.x自帶的gcc是4.8.5版,因此沒法直接編譯,要么升級gcc編譯器(具體做法自行google,有把系統弄出毛病的風險),要么用CentOS >=8.0版。CentOS 8.0自帶的gcc是8.3.1,可以非常順利地結合toolchain編譯CP2K。下面筆者所述的情況和編譯方式對于CentOS 8.0和CentOS 8 Stream是完全適用的,不適用于更老的CentOS。(PS:常有人問我裝CentOS 8的時候應該選什么,建議Base Environment選Workstation,組件選GNOME Applications、Legacy UNIX Compatibility、Development Tools、Scientific Support)
用合適版本的Intel的icc和ifort編譯器來編譯CP2K及相關的庫也可以,這樣CentOS 7.x的用戶也省得升級gcc或者換系統了。但19.0.1版結合toolchain用的時候筆者發現有的庫編譯不過去,筆者不打算深究,本文就不說這種做法了。
toolchain運行過程中會自動下載很多庫的壓縮包,所以必須聯網,而且網速還不能太慢,否則有的庫半天也下不下來,甚至最終失敗。如果你在大陸,強烈建議通過科學的方式加速對外部網絡的訪問。
關于MKL數學庫
CP2K會利用到BLAS和LAPACK標準庫中的子程序。默認情況下會用OpenBLAS庫提供的這部分子程序,但據說OpenBLAS的LAPACK子程序的效率不如Intel的MKL數學庫好,因此改用MKL可能計算速度更快,不過筆者的一些簡單的對比測試并未發現用MKL時速度有顯著優勢。如果你想用MKL的話,那么運行下一節的toolchain前先把MKL裝到系統里,即運行下列命令:
dnf config-manager --add-repo https://yum.repos.intel.com/mkl/setup/intel-mkl.repo
rpm --import https://yum.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS-2019.PUB
dnf install intel-mkl
此時MKL會被裝到/opt/intel/目錄下,被裝到筆者機子里的是MKL 2018版,占2.2GB硬盤。把下面的語句加入到~/.bashrc文件中,然后重新進入終端使之生效
source /opt/intel/parallel_studio_xe_2018.0.033/bin/psxevars.sh
上面這行語句會使得MKLROOT環境變量指向MKL庫的目錄。當運行toolchain的時候發現MKLROOT環境變量被指定了,就會自動利用MKL數學庫(無需額外寫--with-mkl選項)。
如果你想離線安裝MKL,可以去Intel官網免費注冊并下載Intel OneAPI base toolkit離線安裝包。安裝的時候只選擇安裝其中的MKL就夠了。裝好后把下面這句加入~/.bashrc文件里,然后重新進入終端使之生效
source /opt/intel/oneapi/mkl/[實際版本號]/env/vars.sh
但這樣裝MKL的情況下,筆者遇到過CP2K 8.1的toolchain在裝COSMA庫的時候編譯不過去的問題。如果你也遇到了此問題,把toolchain的命令后頭加上--with-cosma=no避免裝COSMA庫即可,這對性能影響甚微。
2.2 通過toolchain安裝CP2K依賴的庫
去https://github.com/cp2k/cp2k/releases/下載CP2K壓縮包cp2k-8.1.tar.bz2,運行tar -xf cp2k-8.1.tar.bz2命令解壓之。下文假設解壓后的目錄是/sob/cp2k-8.1/。
運行以下命令
cd /sob/cp2k-8.1/tools/toolchain/
./install_cp2k_toolchain.sh --with-sirius=no --with-openmpi=install --with-plumed=install
之后這個toolchain腳本就會依次下載各個庫的壓縮包到toolchain/build目錄下并解壓和自動編譯,編譯產生的可執行文件、庫文件、頭文件等都自動裝到了toolchain/install目錄下。在筆者的普通四核機子結合非常暢通的網絡下,整個過程耗時約兩個小時。其中最耗時的是編譯libint那一步,花了一個小時有余,一定要耐心。
以下信息應了解一下
? 如果運行上述腳本后提示ERROR: (./scripts/install_gcc.sh) cannot find gfortran,應當運行dnf install gcc-gfortran先把gfortran編譯器裝上,然后重新運行腳本。
? 運行./install_cp2k_toolchain.sh --help可以查看toolchain的幫助。可見有的庫默認是安裝的,有的默認不裝,通過選項來決定,可以按需調整。toolchain腳本的使用細節見https://github.com/cp2k/cp2k/blob/master/tools/toolchain/README.md
? --with-sirius=no選項代表不裝本來自動會裝的SIRIUS庫。這個庫使得CP2K可以像Quantum ESPRESSO那樣完全基于平面波+贗勢做計算,但一般這用不上,想做這種計算的人一般直接就用Quantum ESPRESSO了,其安裝見《Quantum ESPRESSO在Linux中的安裝方法》(http://www.shanxitv.org/562)。
? --with-openmpi=install代表安裝OpenMPI庫,這使得編譯出來的CP2K可以通過MPI方式并行計算。CP2K也支持其它MPI庫如Intel MPI和MPICH。我個人比較習慣用OpenMPI,這也是目前最主流的。重要提示:如果你的機子里已經有了OpenMPI,應當用--with-openmpi=system,這使得CP2K直接用機子里現成的OpenMPI,否則額外再自動裝一個OpenMPI可能造成一些沖突。
? --with-plumed=install代表安裝默認不自動裝的PLUMED庫,這使得CP2K可以結合PLUMED做增強采樣的從頭算動力學。如果你不需要此功能的話可以不加這個選項,可以節約少量編譯時間。
? toolchain默認用所有CPU核心并行編譯,可以自行加上-j [并行核數]來明確指定用多少核。編譯的耗時和CPU核數關系很大。筆者在36核機子上也就花了不到20分鐘就把toolchain過程全都完成了。
? toolchain默認自動下載和編譯cmake。如果你通過yum或dnf已經裝過cmake而且其版本較新,可以再加上--with-cmake=system用當前系統里的cmake,能節約編譯時間。
? 注意硬盤的空余空間應當足夠。對于CP2K 8.1在上述命令執行完畢后,toolchain/build目錄約占9GB,toolchain/install目錄占約2GB。如果硬盤吃緊,建議toolchain運行成功后把這個build目錄刪掉,里面的文件之后用不著。
? 如果toolchain運行過程中某個庫編譯失敗,可以去toolchain/build目錄下的那個庫的目錄中去找編譯過程輸出的log文件,在里面搜error根據報錯試圖分析原因。toolchain運行失敗后可以重新運行,它會根據根據toolchain/build目錄的內容做判斷,之前已經下載和編譯成功的庫會自動跳過,而從失敗的庫繼續編譯。如果把build和install目錄都刪了,則toolchain會從頭執行。
? 如果在安裝某個庫的過程中一直卡著,通過top命令發現CPU也沒在編譯庫,那么幾乎一定是因為網速太慢導致那些庫的壓縮包老也下載不完(在大陸區域不可描述的訪問國際互聯網的條件下尤為常見)。可以去tools/toochain/build目錄下看看正在裝的這個庫的壓縮包,如果尺寸特別小,而且尺寸增加得特別緩慢,說明就是這個問題所致。解決方法是開微屁恩加速訪問國際互聯網。還一個辦法是找個訪問國際互聯網通暢的機子或者拜托朋友,在那里安裝一次當前版本的CP2K,然后把build目錄下的.tgz、.tar.gz、.tar.bz2那些庫的壓縮包拷到之前那個機子的build目錄下,這樣那個機子在安裝CP2K過程中就會直接用這些包而不會試圖下載了,對于沒法訪問Internet的機子也可以這樣離線安裝CP2K。
2.3 編譯CP2K
接著上一節,現在把/sob/cp2k-8.1/tools/toolchain/install/arch/下所有文件拷到/sob/cp2k-8.1/arch目錄下。這些文件定義了編譯不同版本的CP2K所需的參數,其內容是toolchain腳本根據裝的庫和當前環境自動產生的。
然后運行以下命令
source /sob/cp2k-8.1/tools/toolchain/install/setup
cd /sob/cp2k-8.1
make -j 4 ARCH=local VERSION="ssmp psmp"
-j后面的數字是并行編譯用的核數,機子有多少物理核心建議就設多少。在筆者的普通4核機子上花了40分鐘編譯完。
注:如果編譯中途報錯,并且從后往前找error的時候看到cannot find -lz的報錯提示,則運行dnf install zlib-devel命令裝上zlib庫,再重新運行上面的make那行命令即可。
編譯出的可執行程序現在都產生在了/sob/cp2k-8.1/exe/local目錄下,共1.1GB。這里面cp2k.popt、cp2k.psmp、cp2k.sopt、cp2k.ssmp就是我們所需要的CP2K的可執行文件了(popt和sopt其實分別是psmp和ssmp的符號鏈接)。
把以下內容加入到~/.bashrc文件里:
source /sob/cp2k-8.1/tools/toolchain/install/setup
export PATH=$PATH:/sob/cp2k-8.1/exe/local
重新進入終端后,就可以通過cp2k.ssmp等命令運行cp2k了。運行諸如cp2k.ssmp -v可以查看CP2K的版本、編譯時用的庫和參數信息。
注1:上面source這行必須有,因為有的庫提供的.so文件是CP2K啟動時所需的,source這個腳本使得相應的庫的目錄被加入到動態庫的搜索路徑中。而且用了這個之后toolchain過程中裝的OpenMPI的可執行文件mpirun等才能直接用。
注2:cp2k-8.1目錄下的lib和obj目錄分別存的是CP2K編譯過程產生的靜態庫文件和.o文件,總體積不小。由于之后用不著,因此如果想省硬盤可以把這倆目錄刪掉。
3 直接用官方的預編譯版CP2K
對于CP2K 8.1,官方預編譯版只提供了ssmp的,并且為了兼容性考慮,編譯選項比較保守,沒有根據CPU內核進行優化、沒有利用SIMD指令集、用的是-O2而非更激進優化的-O3選項,也沒用MKL。不過這并不代表官方預編譯版的就很慢,筆者對簡單任務測試過發現在速度上和自己編譯的ssmp版差異不太大。不過,如果對某些類型任務發現ssmp版的CPU占用率普遍較低,吐血建議自己編譯popt版,此時有可能二者速度差異超大、用ssmp完全發揮不出CP2K本來的代碼效率,甚至可能ssmp版幾乎算不動。
使用官方的預編譯的ssmp版CP2K的做法如下:
和2.2節所述相同,先下載cp2k-8.1.tar.bz2壓縮包并解壓到比如/sob/cp2k-8.1目錄。
去https://github.com/cp2k/cp2k/releases/下載CP2K的預編譯版可執行文件cp2k-8.1-Linux-x86_64.ssmp,改名為cp2k.ssmp并隨便放到一個位置,假設放到了/sob/cp2k-8.1目錄下。
將下面兩行加入到~/.bashrc文件中:
export PATH=$PATH:/sob/cp2k-8.1
export CP2K_DATA_DIR=/sob/cp2k-8.1/data
保存后重新進入終端,CP2K就可以通過cp2k.ssmp命令使用了(ssmp版CP2K不是必須叫cp2k.ssmp,也可以改名為cp2k,這樣運行更方便)。
為什么設CP2K_DATA_DIR環境變量這里說一下。在CP2K輸入文件中,如果諸如BASIS_SET_FILE_NAME、POTENTIAL_FILE_NAME等關鍵詞只定義了文件名而沒有給路徑,程序默認先在當前目錄下搜索相應文件,找不到的話去CP2K_DATA_DIR搜索。CP2K_DATA_DIR對應的是編譯的時候CP2K目錄下的data目錄的路徑,但開發者在編譯的時候其對應的路徑顯然跟我們當前情況不符,因此這里通過export來將CP2K_DATA_DIR環境變量改成自己機子里實際的data目錄的路徑。
4 運行和測試CP2K
這里提供一個簡單的輸入文件用于測試:http://www.shanxitv.org/attach/586/test.inp。這是Multiwfn生成的2*2*2金剛石超胞做PBE/DZVP-MOLOPT-SR-GTH單點計算的輸入文件。
先測試ssmp版。將test.inp放到當前目錄下,運行:cp2k.ssmp test.inp |tee test.out。輸出信息會在屏幕上顯示,也同時寫入到了test.out里。默認情況下所有CPU核心都會被用于OpenMP并行計算,如果比如想只用4核,就先運行export OMP_NUM_THREADS=4命令然后再運行CP2K,此時運行過程中CP2K進程的CPU占用率應當在300~400%。
再測試popt版。假設用4核通過MPI方式并行,就執行:mpirun -np 4 cp2k.popt test.inp |tee test.out。在top中看到會有4個cp2k.popt在運行,占用率皆接近100%。
如果你是自己編譯的CP2K,建議默認用popt版而不要用ssmp版,因為在某些情況下后者運行效率遠不及popt版(但也有些任務二者速度差異不大,看具體情況)。為了運行popt版省事,建議在~/.bashrc里面加入一行alias cp2k='mpirun -np 4 cp2k.popt'。重新進入終端后,只要輸入cp2k test.inp |tee test.out就等價于輸入mpirun -np 4 cp2k.popt test.inp |tee test.out了,用起來省事多了。
注:跑sopt、popt版時,不管設不設OMP_NUM_THREADS、設多少,OMP_NUM_THREADS都會被強行視為1。
附:CP2K的并行以及四種版本
CP2K支持MPI方式并行也支持OpenMP方式并行。最初CP2K是完全基于MPI并行的,但每個核心對應一個MPI進程來并行跑CP2K的話,對某些任務、較大體系消耗內存較高。CP2K如今很多代碼也利用OpenMP方式實現了并行化,OpenMP并行的好處是很多數據可以在不同線程之間共享而不用保存副本,從而比MPI并行明顯更節約內存。但由于有些CP2K代碼仍只能通過MPI方式并行,因此單純靠OpenMP并行的話某些任務的速度可能明顯不及MPI并行,而且并行核數很多時純OpenMP的并行效率比純MPI并行的略低是很多科學計算程序中常見的現象。CP2K也支持MPI和OpenMP混合并行,比如CPU有36核,那么可以比如用9個MPI進程,每個MPI進程下屬4個OpenMP線程,這樣9*4把36個核都利用上,比直接用36個OpenMP線程并行效率可能明顯更高,而比用36個MPI進程則明顯更省內存(這對于雜化泛函計算比較重要。雜化泛函耗內存遠高于純泛函,如果借助OpenMP節約內存,使得有足夠內存儲存所有雙電子積分,即in-core方式做SCF,就可以避免每次迭代過程中重算這些積分,令SCF迭代過程耗時低得多)。
MPI或MPI+OpenMP可以跨節點并行(OpenMP限于節點內),而純OpenMP只能單機并行,因為OpenMP是基于共享內存的并行技術。
根據支持的并行方式的不同,CP2K分為四個版本:
sopt:只能單機單核計算,無法并行。s意為single
ssmp:OpenMP并行,可以單機多核運行。smp意為Symmetric multiprocessing
popt:MPI并行,可以單機并行也可以跨節點并行。p意為parallel
psmp:MPI+OpenMP混合并行,可以單機并行也可以跨節點并行
sopt版嚴格等價于ssmp版結合OMP_NUM_THREADS=1,popt版嚴格等價于psmp版結合OMP_NUM_THREADS=1。
實際上還有sdbg和pdbg版,前者相當于ssmp結合debug設置,后者相當于psmp結合debug設置,但這對于開發者調試程序才有意義,所以本文2.3節我們沒有編譯這倆版本。