Skip to content

如何设置并行参数提升ABINIT计算效率

ABINIT 是一个开源的材料科学软件包,主要用于预测、理解和计算材料的电子结构及其他相关性质,如能带结构、密度态、光学性质、机械性质等。ABINIT 可以计算任何化学成分的分子、纳米结构和固体,并附带多个完整、强大的原子势能表。

然而,当ABINIT软件处理的计算系统的尺寸增加至数百乃至数千个以上原子时,计算所需的时间和资源呈指数级增加,这会面临几个主要难点:

1、内存限制:由于每个原子的数据以及它们之间的相互作用都需要存储在内存中,随着系统尺寸的增加,所需的内存量也会激增; 2、计算效率问题:随着计算量呈平方或指数级增长,计算任务的完成时间显著增加; 3、并行化挑战:为了提高计算效率,通常需要将计算任务并行化。如何有效地在多个处理器或计算节点上分配任务并同步状态是一项技术挑战; 4、收敛性问题:在大规模系统中,自洽场计算可能难以收敛,或者收敛速度变慢,这需要更多的迭代步骤和调整计算参数。

在常规的并行计算策略中,大多数程序会选择在多个计算节点上分布式处理或共享数据,并对耗时的计算环节进行并行化。本文,我们将介绍ABINIT软件KGB(K-Point Grid Block,即波矢点网格块)并行化策略,探讨如何更好的优化ABINIT的计算效率和收敛性,以实现更高效的大规模计算。

目前,超算互联网提供预编译的ABINIT v8.6.1至v10.0.7.1版本,支持一键使用。本文实验测试使用intelmpi2021编译的ABINIT v9.10.5版本。

https://www.scnet.cn/ui/mall/detail/goods?type=software&common1=APP_SOFTWARE&id=1768279452479246338&resource=APP_SOFTWARE&keyword=ABINIT+v9.10.5%E7%89%88%E6%9C%AC

您可以在超算互联网搜索“ABINIT v9.10.5版本”购买软件,通过“我的商品”,在“应用软件”中找到“ABINIT v9.10.5版本”,点击“命令行”,即可选择区域中心、命令行快速使用该软件。

1.png

软件默认安装在家目录的apprepo下,环境变量默认放在软件scripts目录下的env.sh中,可执行如下命令添加环境变量:Source ~/apprepo/abinit/9.10.5-intelmpi2021/scripts/env.sh

此外,超算互联网还提供软件运行测试算例和slurm作业脚本,用户可以在~/apprepo/abinit/9.10.5-intelmpi2021/case得到相应内容并直接使用。本次实践,我们将使用内置脚本来进行相关测试。

一、快速设置分布式并行化参数

在 ABINIT 中激活 KGB 并行化的最简单方法是在输入文件中添加一个输入变量 paral_kgb,此变量能够控制与 KGB 并行化相关的所有设置,包括选择迭代求解器以及是否使用激活三维快速傅里叶变换(3dim-FFT)。通过调整paral_kgb的值,用户可以配置和优化KGB并行化选项,以适应不同的计算需求和资源配置。

例如,在ABINIT的.abi文件中,设置autoparal=1,让程序自动分配并行化参数。在输入文件中添加如下字段(默认的k点数量设置为1),即可得到在限定CPU数量内(展示算例64核)的并行化参数设置。

shell
autoparal       1   #激活KGB并行化
max_ncpus       64 #指定可以使用的最大CPU数量

随后提交作业进行计算,作业并不会持续计算,而是会在一定条件下提前终止,并输出KGB并行化参数相关的配置设置。

shell
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 |  np_spkpt|  npfft|  npband|   bandpp| #MPI(proc)|  WEIGHT|
 |  1<<  1|  1<<  22|  1<<  64|  1<< 640|  1<<  64| <=   64| 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 |       1|        4|       16|       10|       64|  42.328|
 |       1|        8|        8|       20|       64|  41.844|
 |       1|       16|        4|       40|       64|  41.730|
 |       1|        6|       10|       16|       60|  40.093|
 |       1|       15|        4|       40|       60|  39.054|
 |       1|        4|       16|        8|       64|  39.043|
 |       1|       12|        5|       32|       60|  39.026|
 |       1|        8|        8|       16|       64|  38.598|
 |       1|       16|        4|       32|       64|  38.493|
 |       1|        3|       20|        8|       60|  38.319|
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

根据软件选择npband(用于并行处理能带)和npfft(用于并行处理快速傅里叶变换)的设置,推荐使用WEIGHT(权重)较高的分布设置。通过修改如下.abi文件,确保np_spkpt x npfft x npband = 给定的CPU数量,即可在限定的CPU数量内进行较优化设置计算。为了便于分析,我们先取npfft、npband、bandpp这三个参数来进行调整并分析总结计算结果:

shell
-  autoparal  1  #-注释 +新增
-  max_ncpus  64
 npband  16+
 npfft  4

我们可以对软件给出的参数设置进行效率验证,通过分别取不同的参数组合进行测试,如 (1x64x1), (1x32x2), (1x16x4), (1x8x8), (1x4x16),所有算例的bandpp默认为1。计算完成后,检索每次计算所需的时间:

shell
tparal_bandpw_01_64x1.abo:- Proc.   0 individual time (sec): cpu= 62.6  wall= 65.4    # np_spkpt 为1,npfft为1,npband为64,即 1x64x1的情况
tparal_bandpw_01_32x2.abo:- Proc.   0 individual time (sec): cpu= 54.0  wall= 57.3    # np_spkpt 为1,npfft为2,npband为32,即 1x32x2的情况
tparal_bandpw_01_16x4.abo:- Proc.   0 individual time (sec): cpu= 53.3  wall= 56.7    # np_spkpt 为1,npfft为4,npband为16,即 1x16x4的情况
tparal_bandpw_01_8x8.abo:-  Proc.   0 individual time (sec): cpu= 55.8  wall= 59.5    # np_spkpt 为1,npfft为8,npband为8,即 1x8x8的情况
tparal_bandpw_01_4x16.abo:- Proc.   0 individual time (sec): cpu= 65.0  wall= 68.1    # np_spkpt 为1,npfft为16,npband为4,即 1x4x16的情况

在计算效率方面,结果显示计算效率最好的分布是(1x16x4),由此可见,使用 autoparal=1 时得到的预测结果是可信的。然而,除了对比时间效率外,我们还需要同时考虑计算的收敛性(最后一列表示密度残差的收敛性):

shell
tparal_bandpw_01_64x1.abo: ETOT  5  -3654.9083410155    -1.580E-04 6.181E-05 1.440E-04    #1x64x1,npband为64
tparal_bandpw_01_32x2.abo: ETOT  5  -3654.9081759902    -2.737E-04 2.495E-05 1.968E-04    #1x32x2,npband为32
tparal_bandpw_01_16x4.abo: ETOT  5  -3654.9082768015    -6.727E-05 5.277E-05 1.490E-04    #1x16x4,npband为16
tparal_bandpw_01_8x8.abo:  ETOT  5  -3654.9081359132    -2.710E-04 6.111E-05 2.318E-04    #1x8x8,npband为8
tparal_bandpw_01_4x16.abo: ETOT  5  -3654.9080524851    -1.683E-04 6.622E-05 2.509E-04    #1x4x16,npband为4

可以看到,当 npband 设置为最大值时,密度残差的收敛性最小。这意味着,npband 设置越大,收敛性越好。但这种最佳收敛性是在 (1x 64 x1) 分布,计算效率最差计时获得的。

那么可以说明一个问题是,虽然1x16x4 的配比在单次迭代的速度是最快的,但可能是最晚计算完成的,因为要达到的收敛精度 1 x 16 x 4 的配置相比其他配置需要更多的迭代步数,即KGB并行迭代次数最少的计算(收敛性最好)在一次迭代的时间上并不是最好的(效率最高),反之亦然。

在MPI计算过程中影响计算效率的还有一个参数:bandpp,这个参数主要用来控制能带的插值密度,我们选取 1x16x4 配置的情况,然后分别增加迭代步数,并设置bandpp为1和2进行计算观察:

shell
tparal_bandpw_01_16x4_bandpp_1.abo:- Proc.   0 individual time (sec): cpu=         86.7  wall=         90.2    #1x16x4,bandpp=1
tparal_bandpw_01_16x4_bandpp_2.abo:- Proc.   0 individual time (sec): cpu=         91.5  wall=         94.6    #1x16x4,bandpp=2

当 bandpp=2 时,计算更为收敛!由此可见,在给定CPU数量的情况下,更快的计算效率和更好的收敛性是要有一定取舍的。但是如果仍然想要在保证速度的同时提高收敛性,那么不妨试一下MPI+OpenMP的模式。

二、MPI+OpenMP模式

我们使用1x32x2的配置算例进行验证,在脚本中添加OMP_NUM_THREADS=XX的变量来控制线程,分别测试(32 npband x 2npfft x 2 bandpp x 1 threads)(32 npband x 1npfft x 2 bandpp x 2 threads)三个算例验证MPI+OpenMP模式的加速效果:

shell
#.abi 文件变动内容,需要尽量保证 npband x npfft x threads == CPU数量
+ npband        32
 + bandpp        2
  + npfft         1

计算完成后检索每次计算的时间:

shell
64x1/tparal_bandpw_01.abo:- Proc.   0 individual time (sec): cpu=        105.2  wall=        108.5  # 32 npband x 2npfft x 2 bandpp x 1 threads
32x2/tparal_bandpw_01.abo:- Proc.   0 individual time (sec): cpu=        174.6  wall=        101.6  # 32 npband x 1npfft x 2 bandpp x 2 threads

MPI+OpenMP模式计算所需的CPU计算时间更长了,或许第一眼的结果是令人失望的,但是事实是:计算出来的时间是单个MPI进程的计时,即计算时间是此进程的所有OpenMP任务的时间相加。在纯MPI情况下,每个任务需要105.2秒;但是在MPI+OPENMP混合情况下,(32 npband x 1npfft x 2 bandpp x 2 threads)每个任务需要174.6/2=87.3秒,每个任务的CPU计算时间实际是要更快的。我们再对收敛性进行检索:

shell
64x1/tparal_bandpw_01.abo: ETOT 10  -3654.9085401628    -5.132E-09 2.274E-05 1.673E-09
32x2/tparal_bandpw_01.abo: ETOT 10  -3654.9085401628    -5.109E-09 2.274E-05 1.673E-09

可以得到,在相同CPU核数的情况下使用MPI+OpenMP的模式是可以得到更高的效率并且维持更好的收敛性。

shell
64x1/tparal_bandpw_01.abo:+Overall time at end (sec) : cpu=       6820.6  wall=       6945.2
32x2/tparal_bandpw_01.abo:+Overall time at end (sec) : cpu=       5609.9  wall=       3249.9

三、完整的KGB并行化

到目前,我们只进行了“GB”并行化,实际只是针对bands和fft进行了2层并行化,当系统有1个以上的k-point存在,则可进行第三层并行化,进行完整的“KBG”并行化。我们可以继续贯彻之前的两层优化策略,在前两层的基础上根据k-point数量增加使用的核数来进行提速。将前文算例的k-point从1提升到2,并且对应k-point核数的增加将使用的核数增加2倍提升至128核,检索每次计算的时间:

shell
64x1x2/tparal_bandpw_01.abo:- Proc.   0 individual time (sec): cpu=        108.7  wall=        113.5    # 32 npband x 2npfft x 2 bandpp x 1 threads x 128 cpus
32x2x2/tparal_bandpw_01.abo:- Proc.   0 individual time (sec): cpu=        179.0  wall=        103.9    # 32 npband x 1npfft x 2 bandpp x 2 threads x 128 cpus

可以发现增加了k-point优化之后,MPI+OpenMP的模式仍然是较好的选择,然后再对比下收敛性也是符合更好的收敛性预期的:

shell
64x1x2/tparal_bandpw_01.abo: ETOT 10  -3654.9085401628    -5.131E-09 2.274E-05 1.673E-09    # 32 npband x 2npfft x 2 bandpp x 1 threads x 128 cpus
32x2x2/tparal_bandpw_01.abo: ETOT 10  -3654.9085401628    -5.107E-09 2.274E-05 1.673E-09    # 32 npband x 1npfft x 2 bandpp x 2 threads x 128 cpus

通过上述实践内容,我们得出ABINIT软件的KGB并行化的优化策略:首先评估MPI和OpenMP在处理ABINIT计算中的效率,然后优化计算的收敛性。在此基础上,根据k-point的数量和分布,合理扩展计算的核数,以实现更高效的并行计算。