CentOS 7/8 编译 VASP 5.4.1:Intel 编译器 + OpenMPI + FFTW 全流程指南 CentOS上装VASP 5.4.1可能是很多课题组最常遇见的坑。VASP 5.4.1本身不算新却因为兼容性、MPI库和数学库的排列组合问题装起来比用现成预编译脚本的新版本还要麻烦。尤其当你面对的是intel、openmpi、fftw这套组合时任何一个库编译时手一滑后面都会回报你一段莫名其妙的错误。这篇文章是我自己在某课题组服务器上反复重装后整理的完整流程适合要在CentOS系统上用Intel编译器加OpenMPI、FFTW环境编译VASP 5.4.1的同行参考。不管你是刚进组的学生还是要帮师弟师妹兜底的学长照着走一遍基本能把环境和可执行文件顺利搞定。1. 安装前的环境规划与版本选择动手敲命令之前先把要装的东西理清楚。VASP 5.4.1是材料计算领域很经典的版本尽管官方早就有更新但很多老脚本、赝势库、后处理工具都是围绕这个版本跑的所以它至今还在各种服务器上服役。编译VASP本身并不复杂真正的难点在于它依赖了三条链子编译器、MPI库、FFT库这三者必须能“对话”。你用了Intel的ifort编译程序mpif90就必须是用Intel编译器包装出来的FFTW又必须能被ifort顺利调用否则链接阶段会出现一堆找不到符号、类型不匹配的报错。CentOS上做这套环境优先选择经典的Intel编译器路线。原因很简单VASP的原生代码对Intel编译器优化得最充分性能通常比gfortran版本高出一截而且MKL数学库自带LAPACK、BLAS和ScaLAPACK能省掉很多手动拼库的麻烦。但要注意VASP 5.4.1发布较早对太新的Intel编译器支持并不算好不建议一上来就装最新版的oneAPI。我这边验证过比较稳定的组合是Intel Parallel Studio XE 2017到2019版本中的ifort配合OpenMPI 3.1.x。OpenMPI版本的选择也有讲究。VASP 5.4.1在OpenMPI 4.x之后偶尔会碰到比较新的接口变化导致编译过但要运行时报MPI库版本冲突。所以如果没有特殊需求OpenMPI 3.1.6是性价比很高的选择网上资料多踩坑记录也丰富。FFTW则建议使用3.3.8或3.3.10这两个版本都经过很长时间考验用默认参数编译出来就能满足VASP需求。另外要做一个操作系统的检验。CentOS 7.9和CentOS 8都支持这套流程但CentOS 8的gcc默认版本更高编译OpenMPI时可能会影响旧兼容性建议装完基础包后先确认gcc、g、make、wget这些工具都在。很多人在装依赖之前忽略了一个问题没有安装libtool和bison库文件编译OpenMPI时就会报缺少遗留文件。最好提前运行sudo yum install -y gcc gcc-c gfortran make wget tar sudo yum install -y libtool bison flex确认系统里没有残留的其他MPI版本也很关键。如果之前装过建议先卸载或者把PATH、LD_LIBRARY_PATH里相关路径清理干净免得后面的VASP编译链接到一套错误的MPI库。2. Intel编译器、OpenMPI与FFTW的安装细节2.1 Intel编译器的安装与环境变量拿到Intel Parallel Studio XE安装包后执行install脚本即可。安装过程中选择典型安装不需要装太多组件但必须确保ifort编译器、MKL数学库这两个核心模块被选中。装完后默认位置一般是/opt/intel/但要注意设置环境变量。很多人安装步骤照做后面编译VASP却报ifort命令不存在十有八九就是没有执行source /opt/intel/bin/compilervars.sh intel64这个命令会同时载入MKL环境变量和Intel的库搜索路径。你可以把这行写进/etc/bashrc这样每次打开终端都自动生效。但要注意如果服务器上有其他用户不同版本的Intel编译器写在全局目录可能冲突更稳妥的方式是放到自己用户的.bashrc里echo source /opt/intel/bin/compilervars.sh intel64 ~/.bashrc完成后验证一下ifort --version如果能看到类似ifort (IFORT) 18.0.5的输出说明编译器这部分已经就绪。这里要插一句很多新手的误区是光有ifort就够了其实VASP 5.4.1默认还要用C预处理器对源码做预处理所以gcc也是必须的不能为了追求“纯净”把系统自带gcc删掉。2.2 用Intel编译器包装OpenMPIOpenMPI本身要编译而不是直接用系统的二进制安装。原因正如前面所说mpif90这个包装脚本必须知道调用哪个Fortran编译器。如果系统里的OpenMPI是用gfortran编译的你后面的FC只能写gfortran那VASP就无法用ifort优化。所以这里要自己动手编译。下载OpenMPI 3.1.6源码后配置命令建议如下./configure CCgcc CXXg F77ifort FCifort --prefix/opt/openmpi-3.1.6这里指定F77和FC都用ifort这样OpenMPI生成的mpif90就会在背后调用ifort。configure过程会检查很多依赖项包括Fortran编译器是否可用、是否支持MPI模块等。如果检查到某些库缺失往往会提示你安装但也有警告是不影响编译的比如“是否支持Java”之类的提示忽略即可。编译和安装make -j4 make install-j4是并行编译参数根据机器核数调整。之后设置环境变量export PATH/opt/openmpi-3.1.6/bin:$PATH export LD_LIBRARY_PATH/opt/openmpi-3.1.6/lib:$LD_LIBRARY_PATH export MANPATH/opt/openmpi-3.1.6/share/man:$MANPATH仍然建议写进.bashrc。然后用mpif90 --version验证不出意外应该能看到ifort的版本号这说明mpif90的底层确实是ifort。注意OpenMPI从某个版本开始禁止以root用户直接运行mpirun如果你当前是root登录测试并行程序时会收到“cannot run as root”的提示。要么切到普通用户运行要么给mpirun加--allow-run-as-root参数。我一般建议用普通用户做实际计算更安全也更贴近集群使用习惯。2.3 编译FFTW避免精度踩雷FFTW也需要源码编译VASP链接的是Fourier变换库这个库要支持双精度计算。很多人在configure阶段习惯性加上--enable-float认为单精度能省内存结果编译VASP时就会因为复数类型大小不匹配链接阶段报一串“undefined reference”或者类型不匹配错误。VASP默认的DFT计算使用双精度FFTW必须使用默认的双精度版本。我常用的编译命令./configure CCgcc FCifort F77ifort --prefix/opt/fftw-3.3.8 --enable-mpi --enable-shared make -j4 make install--enable-shared生成动态库一会儿让VASP链接比较方便。--enable-mpi可以启用FFTW的并行变换但VASP内部又有自己的一套FFT封装很多时候只用串行库就够了。我保留这个选项是因为有些测试应用会需要不影响VASP本身的链接。装好后检查/opt/fftw-3.3.8/lib下有没有libfftw3.so和libfftw3_mpi.so。如果只看到mpi版本说明串行库没生成需要检查configure输出。也可以顺便编译一个Fortran接口的测试程序确认ifort能正确找到fftw3.mod。这里有个小技巧为了防止目录混乱建议把OpenMPI和FFTW都安装在/opt下的独立目录中版本号写清楚。比如/opt/openmpi-3.1.6和/opt/fftw-3.3.8这样后续切换版本或者清理环境时一目了然。3. VASP源码准备与makefile.include配置3.1 源码目录结构与arch模板VASP是有版权的商业软件需要跟随课题组购买许可证或从合法渠道获取源码包。拿到源码包后解压你会看到src/目录以及arch/目录下面有一个makefile.include的模板文件。VASP编译时不会自动选择编译器配置需要你把合适的配置复制为源码根目录下的makefile.include然后执行make。arch/目录下有很多已经写好的模板例如makefile.include.linux_intel等你可以先看看。但直接照搬往往不够因为模板里的FFTW路径、MKL库名、MPI编译器名可能和你的实际环境不匹配。所以最好的办法是复制模板后再按照自己机器的路径逐项修改。3.2 一个可用的makefile.include参考下面是我在CentOS 7.9 ifort 18 OpenMPI 3.1.6 FFTW 3.3.8环境里验证过的配置模板供参考# Precompiler CPP gcc -E -P -C -traditional-cpp CPP_OPTIONS -DHOST\LinuxIFC\ -Dkind8 -Ddcabs1 -DNGZhalf -DCACHE_SIZE4000 -DPGF90 -DMPI -DMPI_BLOCK8000 -Duse_collective -DscaLAPACK -DnoAugFillMeta -DCCDNE -Dw_work # Fortran compiler FC mpif90 FCL mpif90 # Compilation flags FREE -free FFLAGS -O2 -FR OFLAG -O2 OFLAG_IN -O2 DEBUG -O0 CFLAGS -O2 # MKL path and libraries MKL_PATH $(MKLROOT) BLAS -L$(MKL_PATH)/lib/intel64 -lmkl_intel_lp64 -lmkl_sequential -lmkl_core LAPACK $(BLAS) BLACS -lmkl_blacs_openmpi_lp64 SCALAPACK $(BLACS) -lmkl_scalapack_lp64 # FFTW path FFTW_PATH /opt/fftw-3.3.8 OBJECTS fftmpiw.o fftmpi_map.o fft3dlib.o fftw3d.o FFT3D_LIBS -L$(FFTW_PATH)/lib -lfftw3 LIBS $(SCALAPACK) $(LAPACK) $(BLAS) $(FFT3D_LIBS)这个配置里有几个关键点值得说明。第一FC和FCL写的是mpif90而不是mpiifort。mpiifort是Intel MPI的包装器既然我们用的是OpenMPI就要用OpenMPI的mpif90包装器它才能正确连接OpenMPI的库。第二CPP_OPTIONS里的-DMPI和-DscaLAPACK是开启并行和ScaLAPACK支持的开关不能漏掉。-Duse_collective会使用MPI群集通信对大规模计算有性能帮助。第三BLACS我写的是-lmkl_blacs_openmpi_lp64这对应OpenMPI接口。如果MKL版本较老可能没有这个库名那时可以试试-lmkl_blacs_intelmpi_lp64不过需要额外把OpenMPI的动态库加入LD_LIBRARY_PATH保证能解析。LIBS行的顺序也有讲究ScaLAPACK、LAPACK、BLAS、FFTW依次排列因为静态库链接时有依赖顺序库列表前面的必须是被后面需要的。如果你把FFTW放在最前面可能会遇到fftw3库被使用时找不到依赖的符号。3.3 路径检查与常见陷阱配置文件里最容易出错的就是MKL_PATH。如果你执行source compilervars.sh intel64之后echo $MKLROOT是空的那后面-L$(MKLROOT)/lib就会变成-L/lib链接阶段会有一堆找不到库的错误。遇到这种问题先回过来检查Intel环境变量是否正常。另一个常见问题是FFTW的include路径没有加入。VASP源文件里有include fftw3.f03这样的语句如果你的FFTW_PATH没有指向正确目录预编译时就会报找不到fftw3.f03。可以在makefile.include的CPP_OPTIONS里增加-I$(FFTW_PATH)/include或者在链接库路径里保证FFTW_PATH/lib存在。我通常还会单独写一个环境变量export FFTW_HOME/opt/fftw-3.3.8然后在makefile.include里引用$(FFTW_HOME)这样项目里其他地方也能复用。4. 编译过程、链接测试与性能验证4.1 make的流程和产物说明配置好makefile.include后进入VASP源码目录先执行make veryclean这个命令会清除历史编译缓存防止之前失败的编译残留影响新一轮编译。然后make allVASP 5.4.1的make all会依次编译三个可执行文件vasp_std、vasp_gam和vasp_low。其中高精度版本是vasp_std大多数计算会用到vasp_gam针对Gamma点计算优化vasp_low是低精度版本。如果机器性能不够也可以只编译vasp_std修改目标为make std。编译过程中会看到大量的Fortran编译输出这是正常现象。最终成功结束后源码目录下会看到三个蓝色或者带有可执行权限的文件。如果不放心可以用file vasp_std确认是ELF可执行文件。4.2 编译失败时的错误定位思路编译报错时不要慌先看错误类型分成三类。第一类找不到ifort、mpif90或者头文件。这多半是环境变量没有生效或者路径拼写错误。比如报错ifort: command not found需要回到第2章检查source命令报错fftw3.f03: No such file or directory需要检查FFTW_PATH是否正确。第二类OpenMPI相关库无法解析。常见的报错是libmpi_so.so: cannot open shared object file。这时候给LD_LIBRARY_PATH加上OpenMPI的lib目录就行。还有一种情况是链接时MPI版本不一致比如VASP源码里有的模块是基于MPI-2函数写的而OpenMPI 4.x对某些旧接口有所调整会报symbol not found。解决方案就是我之前建议的用OpenMPI 3.1.x。第三类Intel编译器的数据类型或语法兼容性报错。更常见的表现是MKL的ScaLAPACK库和LAPACK库冲突提示multiple definition of ...。出现这类报错时先回去检查BLACS库名是否和MPI匹配。如果用的是OpenMPI但库名误写成intelmpi就会产生这种问题。修改为-lmkl_blacs_openmpi_lp64后重新make veryclean make all即可。另外还有一个很容易忽略的问题在make all的过程中如果某一阶段中断残留的.o文件可能会让下一次编译变得莫名其妙。此时不要急着搜索错误执行make veryclean再来一遍往往能解决一半的灵异问题。4.3 小体系测试与并行验证编译完成后找个非常简单的小体系测试例如晶格常数为5.43埃的硅、4个原子或者VASP自带的一些benchmark目录。先准备POSCAR、POTCAR、KPOINTS和INCAR文件。如果你是第一次运行建议用串行方式先跑通./vasp_std如果能正常产生OUTCAR并且能量收敛说明程序本身没有故障。然后测试并行mpirun -np 4 ./vasp_std这一步可以检验OpenMPI配置是否正常。如果mpirun报错orte_abort或者“unable to allocate shared memory”通常是因为节点上的共享内存限制或者是root用户运行限制。实在不行可以加--mca shmem_mmap_enable_nls_support 1但治标不治本最好还是切换普通用户。测试并行时还要顺便看下CPU占用率用top观察每个进程是否都满负荷。如果某些核闲置说明MPI没有完全跑起来需要检查INCAR文件里的并行参数尤其是NPAR。经验上NPAR通常设置为节点核心数的平方根同时不要大于总核数。对于小体系用4核并行时NPAR28核并行时NPAR2或4。这个参数直接影响通信开销调好了能明显改善加速比。5. 常见问题排查与实战经验5.1 Intel编译器版本过旧或过新怎么处理VASP 5.4.1的代码里有一些老式的Fortran语法如果编译器版本太老比如ifort 2011可能会因为不支持某些新特性而报错如果版本太新比如oneAPI 2023反而会警告甚至因为整数长度默认值变化导致计算结果异常。面对这种情况我的建议是专门准备一套旧版Intel环境放在/opt/intel-2018避免影响其他新项目。如果你必须用新编译器可以尝试给FFLAGS加上-assume byterecl或-std 2008这类兼容选项但这属于“碰运气”不如直接切编译器版本稳定。5.2 OpenMPI运行时出现“无法生成共享库文件”真实场景中很常见的情况是mpirun在多个节点跨机运行时报错而单机测试没问题。原因是OpenMPI运行时需要访问每个节点上的相同路径。例如你安装在/opt/openmpi-3.1.6那所有计算节点都要在该路径下有相同版本的OpenMPI。一个简单的方法是下载官方打包的二进制或者把整个目录同步到每个节点。另外一个更隐蔽的问题是登录节点与计算节点共享/home目录但/opt不共享导致mpirun在计算节点上找不到库。解决思路要么将/opt也做成网络磁盘挂载要么在提交作业脚本里带上module load或者source环境变量的语句确保每个计算节点都能得到正确的环境。5.3 FFTW库造成的虚惊有一个特别容易让人误解的报错是undefined reference: zf_fftw_plan_dft_3d。看到这种错误很多人以为是FFTW没有编好其实是编译VASP时选择了自带的fft3dlib而不是外部的FFTW。VASP源码在src/内部有一套自己的FFT实现叫fft3dlib官方makefile默认使用它。如果你在makefile.include中设置了OBJECTS一定确保里面包含fft3dlib.o和fftw3d.o的组合不要只留一个。另外如果你想让VASP使用MKL的FFTW接口可以把FFTW_PATH改成MKL路径并设置-Dmkl_fft但那样就不算独立FFTW环境了。既然标题用的是intel、openmpi、fftw环境保持独立FFTW更符合本教程意图。5.4 运行时的“非法指令”错误这种情况在校园集群中常见登录节点CPU有新指令集但计算节点是老的架构。你在登录节点上用-xHost编译VASP会利用当前CPU的最大指令集比如AVX512。然后作业被调度到不支持AVX512的老节点上程序一运行就崩溃。解决方式是编译时不要用-xHost而是选择一个所有节点都支持的保守指令集。比如Sandy Bridge及以后都有AVX可以写-xCORE-AVX2或者-xAVX。性能损失不多但稳定性大大提升。6. 编译完成后的若干细节优化可执行文件生成后用起来还会有一些小地方可以打磨。首先是环境变量一条龙。建议写一个vasp_env.sh文件里面把Intel、OpenMPI、FFTW的环境变量一次性加载好然后在VASP计算脚本里source这个文件。这样既能避免每次手敲也能防止提交作业时环境变量丢失。一个简单版本source /opt/intel/bin/compilervars.sh intel64 export PATH/opt/openmpi-3.1.6/bin:$PATH export LD_LIBRARY_PATH/opt/openmpi-3.1.6/lib:/opt/fftw-3.3.8/lib:$LD_LIBRARY_PATH其次是编译缓存。VASP运行生成的OUTCAR、WAVECAR、CHGCAR都很大建议在计算目录用软链接指向大容量磁盘。如果在同一个目录反复计算记得清理旧的WAVECAR否则VASP会从旧波函数继续迭代可能影响新计算的结果。这个不算编译问题但确实是很多人踩过的坑。最后是关于要不要真正使用libfftw3库的思考。有时你会发现不装FFTW直接用MKL自带的FFTW接口VASP也能编译通过。那为什么还要独立编译FFTW我的理解是VASP 5.4.1自带源码在个别体系上性能偏弱而独立FFTW允许你针对自己的CPU做更精细的编译优化同时避免MKL库版本升级带来的ABI变化。尤其是当你需要在一个特定集群比如旧处理器qxed系统上折腾时独立FFTW更可控。当然如果你只有一套环境直接MKL也是省事的选择。这个取舍没有绝对答案只是取决于你后续运维的舒适度。从流程上看CentOS安装VASP 5.4.1的难度其实不大核心在于把Intel编译器、OpenMPI、FFTW三者匹配好。如果这三者和谐整个编译过程甚至不需要改动太多源码。我的个人习惯是拿到一套服务器后先把这几个库装进/opt统一管理再写一个环境脚本固化下来以后不管编译什么版本的计算软件都能少走弯路。如果你在配置中卡了很久不妨从版本匹配角度重新审视一遍而不是盯着某一个报错反复硬怼。希望这篇教程能帮你把环境一次配好顺利跑起来。