前言

本系列将介绍如何使用第一性原理电子结构计算Python包GPAW,进行材料的电子结构模拟,包括最基本的DFT基态计算以及更高级的准粒子GW和BSE的光谱性质计算。本文作为该系列的第一篇文章,对GPAW在本地和集群上的安装、样例测试进行介绍,总结了这一过程中遇到的问题和解决方案。

背景

相比较VASP、WIEN2k、QE等主流材料几何和电子结构计算程序,GPAW具有的最大特点就是它是一个Python模块,而不是一个独立的程序。你可以像读其他Python模块代码一样读它,查看它属性和docstring,函数依赖参数明确。GPAW中体系构筑依赖于ASE,一个集成度很高的原子模拟函数模块,作为各种DFT calculator的接口和数据处理及可视化模块被广泛使用。事实上GPAW和ASE都是DTU Thygesen课题组开发维护,因此可以把GPAW看成是ASE自己的first-principles calculator。GPAW中一些performance-critical组件由NumPy或自编的C扩展实现,因此GPAW的计算效率也是有保证的。

我对GPAW的了解始于对低维体系准粒子能带结构的研究,在这方面Thygesen课题组做了很多重要的工作,这些自然是在GPAW中进行的代码实现,包括参数收敛测试和analytical correction to long wavelength limit,尤其后者是我们希望在LAPW框架下实现的。在读懂代码之前,总应该先熟悉它的使用吧。于是想到了做这个系列。这一回从编译安装开始。

GPAW安装基于Python模块ASE、NumPy,线性代数库BLAS/LAPACK以及交换关联泛函库LIBXC。快速傅里叶变换可以通过链接FFTW3加速,并行计算可(大规模并行时必须)链接ScaLAPACK。本文将利用以上所有的库,其中线性代数库和ScaLAPACK用Intel MKL代替。

以下过程所用的python均为在北京大学高性能计算平台上anaconda/2-4.4.0.1模块[anaconda (version 1.6.3)]内的python 2.7.15,C扩展的编译器为Intel 2017 update 1的mpiicc,FFTW3(3.3.4)和LIBXC(4.2.3)均由该版本Intel编译器编译。

正文

作为Python模块,GPAW在Python Package Index有项目记录,因此可以使用

1
pip install gpaw --user

将其安装到本地用户目录。但这种安装方式不容易控制和自定义外部库的链接,因此我们采用从源码手动安装的方式。主要分以下几步进行。

依赖的安装

NumPy

载入anaconda环境中已经预装了NumPy环境

ASE

使用pip安装

1
pip install ase --user

FFTW3

留待补充,可先参考官方文档。

LIBXC

留待补充,可先参考官方文档。

下载源码

登录GPAW的GitLab-tags,或者在这里获取最新版本GPAW的tarball, 解压缩得到文件夹gpaw-x.x.x,其中x.x.x为版本号。该文件夹的结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.
├── c/ # C扩展源码
├── CHANGELOG.rst
├── config.py
├── configuration.log
├── CONTRIBUTING.rst
├── COPYING
├── customize.py # 自定义文件
├── gpaw/ # Python源码
├── LICENSE
├── MANIFEST.in
├── PKG-INFO
├── README.rst
├── setup.py
└── tools/ # 可执行程序,包括并行解释器gpaw-python

我们暂时将其放在家目录下,即~/gpaw-x.x.x,之后我们将称其为GPAW家目录。

修改customize.py

经过各种标准的和愚蠢的试错,一个可行的自定义文件写法为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import numpy as np

compiler = 'mpiicc -fPIC'
mpicompiler = 'mpiicc -fPIC' # use None if you don't want to build a gpaw-python
mpilinker = mpicompiler

# the following variables should be defined according to your own environment
FFTW3_HOME = '/path/to/FFTW3'
MKLROOT = '/path/to/mkl'
LIBXC_HOME = '/path/to/libxc'

# the order is adapted from Intel MKL link advisor
libraries = [
'mkl_scalapack_lp64',
'mkl_intel_lp64' ,'mkl_sequential' ,'mkl_core',
'mkl_blacs_intelmpi_lp64',
'pthread','m','dl',
]
mpi_libraries = []

library_dirs = [ MKLROOT+'/lib/intel64/' , FFTW3_HOME+'/lib/']
# include numpy header to use array object
include_dirs += [np.get_include(), MKLROOT+'/include/', FFTW3_HOME+'/include/']

# switch on ScaLAPACK
scalapack = True
if scalapack:
define_macros += [('GPAW_NO_UNDERSCORE_CBLACS', '1')]
define_macros += [('GPAW_NO_UNDERSCORE_CSCALAPACK', '1')]

# - dynamic linking LIBXC (requires rpath or setting LD_LIBRARY_PATH at runtime):
if True:
include_dirs += [LIBXC_HOME+'/include']
library_dirs += [LIBXC_HOME+'/lib']
# You can use rpath to avoid changing LD_LIBRARY_PATH:
extra_link_args += ['-Wl,-rpath=%s/lib' % LIBXC_HOME]
if 'xc' not in libraries:
libraries.append('xc')
问题 之前在这里遇到过一个问题是,当设置compiler=icc时,尽管可以编译通过,但在运行测试时会报错

1
libmkl_blacs_intelmpi_lp64.so: undefined symbol 'MPI_Finalize'
解决事实上MPI_Finalize本就不是在BLACS里定义的符号,而是MPI库中libmpi.so.12中定义的。这个错误的原因在于libraries是由compilermpicompiler公用的链接选项,尽管mpiicc会自动链接libmpi.so,但icc不会,所以会缺少MPI符号定义。将compiler=icc改成compiler=mpiicc即可解决问题。另一种办法是在libraries中增加成员mpi,同时在library_dirslibrary_include中分别增加MPI库的lib和include,但这就比较繁琐了。

其他尝试 在出现上面错误的时候,我也尝试了不链接ScaLAPACK和BLACS的办法(scalapack=False),可以正常通过所有串行和并行测试,但在做Diamond (两原子) GW的全节点32核并行计算时报错

1
AttributeError: BLACS is unavailable. GPAW must be compiled with BLACS/ScaLAPACK, and must run in MPI-enabled interpreter (gpaw-python)

所以看来在做大规模并行时,GPAW要求BLACS/ScaLAPACK是必须的,从计算的经济性角度上来看也是可以理解的,帮用户省些钱。我也尝试了用GCC(4.8.5)编译依赖和GPAW,但在链接ScaLAPACK时遇到了问题,要求我用-fPIC选项重新编译所有静态库,但其实我在编译时一直带着该选项。在此注明。

开始编译

在GPAW根目录下,输入

1
python setup.py install --user

开始编译。C扩展的编译过程会创建build文件夹,编译结束后会将gpaw文件夹和编译产生的C扩展库_gpaw.so复制到~/.local/lib/python2.7/site-packages/下,复制gpaw等可执行程序到~/.local/bin下。

安装PAW集测试

测试前需要将~/.local/bin添加到PATH下。此时还仍然无法进行计算,因为GPAW依赖于赝势和PAW数据集,而下载的源代码中并不包含这一部分。此时需要执行(例如在GPAW根目录下)

1
gpaw install-data pawdir

让GPAW下载PAW数据集(需要联网,PKUHPC上请使用connect命令,见pku-its-download)。下载完成后,GPAW会将pawdir绝对路径添加到~/.gpaw/rc.py中,以作为赝势PAW搜索路径。

结束以上步骤后即可进行测试,四核独立串行测试

1
gpaw test -j 4

四核并行测试

1
gpaw -P 4 test

1
mpiexec -np 4 gpaw-python -m gpaw test

用上面的customize.py做并行测试时会在parallel/augment_grid.pyMPI_Barrier错误从而无法全部通过, 但可以使用32核跑官网Tutorial准粒子计算的例子C_ecut_k_conv_GW.py

实际计算

测试通过(Hopefully)!可以做具体计算啦。如果写好了名为runscript.py的GPAW并行计算脚本,那么在添加可执行权限后,可以按照如下指令在本地或登录节点执行计算

1
mpiexec -np 4 gpaw-python runscript.py

runscript.py具体要怎么写,就是后面教程要做的事情了。

总结

经过了一段比较挣扎和丢人的编译历程,总算将GPAW编译成功并能用PKUHPC上一整个节点的核心并行计算官方算例。

Comments