使用DevKit精度分析工具定位LAMMPS应用多个算例的精度问题案例
发表于 2025/09/10
0
作者 | 王嘉淳
一、介绍
在使用鲲鹏平台进行高性能计算时,可能会产生计算结果差异,产生精度问题。可能是由于芯片架构差异、浮点数计算实现、编译器数学库优化等等。其中某些编译选项会进行浮点运算优化以提升计算性能,通过将其禁用或采用精度友好的编译选项,可以提高计算精度。
DevKit精度分析工具的编译选项识别功能可以识别出可能导致精度问题的编译选项并给出提示,帮助开发人员解决精度问题。适用以下场景:
场景一:
Intel在使用O2以上或Ofast优化等级的时候,编译器对浮点运算应用更多的性能优化。为了获取更高的浮点计算精度,需要加上-fp-model=precise来保证精度。毕昇和GNU编译器可以用-ffp-contract=off来获得更高的精度。
修改建议: 毕昇(clang/clang++/flang)、gcc/gfortran增加编译选项:-ffp-contract=off Intel(icc/ifort/ifx)增加编译选项:-fp-model=precise
场景二:
FTZ和DAZ对非规定浮点数转化为0的处理会带来精度上差异,因此不使能FTZ选项会带来更好的精度。Intel编译器中-ftz会在除了-O0的其他-O优化等级上默认打开,可以使用-no-ftz编译选项选择关闭;毕昇编译器在-ffast-math或-Ofast下使能FTZ,也可以通过-fflushz或-Mflushz(仅对flang有效)选项单独开启FTZ功能;gcc/gfortran只在-ffast-math下使能FTZ。
修改建议: 毕昇(clang/clang++/flang)去掉-ffast-math或-fflushz或-Mflushz编译选项 Intel(icc/ifort/ifx)增加编译选项:-no-ftz,或者去掉-ftz编译选项 gcc/gfortran去掉-ffast-math编译选项。
本文将展示通过DevKit的编译选项识别功能识别到可能导致精度问题的编译选项并修复的案例,DevKit精度分析工具的安装及使用请参见《鲲鹏DevKit 用户指南(WebUI)》。
二、环境信息
服务器 | 架构 | CPU | 操作系统 |
---|---|---|---|
鲲鹏服务器 | Arm架构 | Kunpeng 920处理器 | openEuler 22.03 LTS |
三、安装编译LAMMPS
以使用LAMMPS进行计算产生的精度问题为例,LAMMPS是一套开源的分子动力学模拟程序包。本文提供简要介绍,LAMMPS详细的安装及使用方法可以参考官网文档:LAMMPS官网。
下载LAMMPS及依赖
下载LAMMPS、FFTW、MPICH安装包:
LAMMPS下载地址:https://www.lammps.org/download.html
FFTW下载地址:http://www.fftw.org/download.html
MPICH下载地址:https://www.mpich.org/downloads/
将下载的压缩包解压。使用的版本分别为:lammps-5Jun2019、fftw-3.3.8、mpich-4.3.0。
安装LAMMPS及依赖
1、安装fftw。
cd /path/to/fftw-3.3.8
./configure --prefix=/path/to/install --enable-float
make
make install
2、安装mpich。
cd /path/to/mpich-4.3.0
./configure --prefix=/path/to/install --enable-float
make
make install
3、切换至lammps的源码目录。
cd /path/to/lammps-5Jun19/src
4、编译lammps。
在编译前,可通过make package-status查看包状态,使用make yes-package安装所需要的模块。运行算例时若提示缺失,可按提示安装对应的模块后重新编译。
编译时可选择:
make mpi #编译并行计算的可执行程序lmp_mpi
make serial #编译串行计算的可执行程序lmp_serial
5、将软件内置的一个算例deposit作为示范,进入目录lammps-5Jun19/examples/deposit,运行可执行程序。
cd lammps-5Jun19/examples/deposit
串行:
/path/to/lmp_serial < in.deposit.atom
并行:
/path/to/mpirun -n 2 /path/to/lmp_mpi < in.deposit.atom
在终端或者目录下的log.lammps文件中可以查看计算过程和结果。
四、修复精度问题
查看原始结果
运行src/example/deposit的算例:
[test@localhost deposit]$ /home/test/lammps-5Jun19/src/lmp_serial < in.deposit.atom
LAMMPS (5 Jun 2019)
······
Step Atoms Temp E_pair TotEng Press
······
9900 449 1.1501006 -5.3225732 -4.9421947 -0.6732754
10000 450 1.0027842 -5.2994965 -4.9652351 -0.62353406
Loop time of 6.66666 on 1 procs for 10000 steps with 450 atoms
······
运行精度分析工具
为了定位误差来源,在鲲鹏服务器上运行精度分析工具。
1、目标文件和函数选择了pair_lj_cut.cpp中的compute(可选其它的,只要能运行工具就行),在src目录下运行以下命令:
/home/test/DevKit-CLI-25.0.0-Linux-Kunpeng/devkit advisor precision -instrument -c "make clean-all;make serial -j" -p $(pwd) -e $(pwd)/pair_lj_cut.cpp:compute
2、在终端和preccheck.log中可以看到Warning信息(log中为详细信息):
Found inappropriate option/function enabled '-ffp-contract=[on|fast]' in files: angle.cpp, angle_charmm.cpp, angle_cosine.cpp,.... Use -ffp-contract=off for better precision. For details, see preccheck.log with the path below.
由此,我们知道LAMMPS中存在一个精度问题:LAMMPS使用的编译器为g++,默认会开启编译选项-ffp-contract=fast。该选项用于控制浮点运算优化,当等号右边为on或fast时,可能导致精度问题。为了提高浮点计算精度,可将其设置为-ffp-contract=off。
3、为了修复此问题,找到文件src/MAKE/Makefile.serial(若编译时使用的不是make serial而是make mpi,同目录下有对应的Makefile.mpi文件),在其第10行的CCFLAGS后面添加选项-ffp-contract=off。重新编译后再次运行算例,结果如下:
[test@localhost deposit]$ /home/test/lammps-5Jun19_ffp/src/lmp_serial < in.deposit.atom
LAMMPS (5 Jun 2019)
······
Step Atoms Temp E_pair TotEng Press
······
9900 449 1.0038671 -5.1540302 -4.8220162 -0.56356384
10000 450 0.95642062 -5.2046982 -4.8858913 -0.70500643
Loop time of 6.8988 on 1 procs for 10000 steps with 450 atoms
······
与软件内deposit文件夹中给出的样例输出文件log.27Nov18.deposit.atom.g++.1对比,结果是相同的,表示该算例的精度问题已解决。消除误差算例1和消除误差算例2为同样方式消除误差的算例,算例位于example目录下的同名文件夹中。
消除误差算例1
鲲鹏,原版lammps
[test@localhost friction]$ /home/test/lammps-5Jun19/src/lmp_serial < in.friction
LAMMPS (5 Jun 2019)
······
Step Temp E_pair E_mol TotEng Press Volume
······
18000 0.11418143 -3.0485595 0 -3.0014364 -0.24776847 2444.9333
19000 0.11028213 -3.0473558 0 -3.001842 -0.30249398 2444.9333
20000 0.11512925 -3.0504969 0 -3.0029827 -0.36022205 2444.9333
Loop time of 7.26269 on 1 procs for 20000 steps with 1724 atoms
鲲鹏,加了-ffp-contract=off
[test@localhost friction]$ /home/test/lammps-5Jun19_ffp/src/lmp_serial < in.friction
LAMMPS (5 Jun 2019)
······
Step Temp E_pair E_mol TotEng Press Volume
······
18000 0.11159326 -3.0416392 0 -2.9955843 -0.22725121 2444.9333
19000 0.11530974 -3.0457005 0 -2.9981118 -0.36488457 2444.9333
20000 0.1131733 -3.0417814 0 -2.9950744 -0.27902539 2444.9333
Loop time of 7.53781 on 1 procs for 20000 steps with 1724 atoms
······
鲲鹏,原版lammps
[test@localhost friction]$ /home/test/lammps-5Jun19/src/lmp_serial < in.friction
LAMMPS (5 Jun 2019)
······
Step Temp E_pair E_mol TotEng Press Volume
······
18000 0.11418143 -3.0485595 0 -3.0014364 -0.24776847 2444.9333
19000 0.11028213 -3.0473558 0 -3.001842 -0.30249398 2444.9333
20000 0.11512925 -3.0504969 0 -3.0029827 -0.36022205 2444.9333
Loop time of 7.26269 on 1 procs for 20000 steps with 1724 atoms
鲲鹏,加了-ffp-contract=off
[test@localhost friction]$ /home/test/lammps-5Jun19_ffp/src/lmp_serial < in.friction
LAMMPS (5 Jun 2019)
······
Step Temp E_pair E_mol TotEng Press Volume
······
18000 0.11159326 -3.0416392 0 -2.9955843 -0.22725121 2444.9333
19000 0.11530974 -3.0457005 0 -2.9981118 -0.36488457 2444.9333
20000 0.1131733 -3.0417814 0 -2.9950744 -0.27902539 2444.9333
Loop time of 7.53781 on 1 procs for 20000 steps with 1724 atoms
······
消除误差算例2
鲲鹏,原版lammps
[test@localhost obstacle]$ /home/test/lammps-5Jun19/src/lmp_serial < in.obstacle LAMMPS (5 Jun 2019) ······ Step Temp E_pair E_mol TotEng Press Volume ······ 24000 1 -0.36563663 0 0.32096935 0.99829393 1456.1594 25000 1 -0.37625073 0 0.31035525 1.0448379 1460.3972 Loop time of 1.8479 on 1 procs for 25000 steps with 769 atoms
鲲鹏,加了-ffp-contract=off
[test@localhost obstacle]$ /home/test/lammps-5Jun19_ffp/src/lmp_serial < in.obstacle LAMMPS (5 Jun 2019) ······ Step Temp E_pair E_mol TotEng Press Volume ······ 24000 1 -0.33410442 0 0.35250156 0.93960021 1463.5903 25000 1 -0.37437615 0 0.31222983 0.9644765 1464.9391 Loop time of 1.86162 on 1 procs for 25000 steps with 769 atoms ······