LAMPPS编译
LAMMPS的编译和使用
最近需要测试一款GPU,为了对比性能,就编译了GPU版的LAMMPS,首先是对lammps的GPU支持做了功课。
LAMMPS的GPU运算支持
LAMMPS中使用GPU计算有两种实现方式,一种是通过KOKKOS包[1],另一种则是GPU包[2]。
Kokkos本身是C++的一个模板库,能够把C++ kernel映射到不同的计算后端上,这里LAMMPS是直接内置了Kokkos库,因此Kokkos支持4种模式的执行:Serial (MPI-only for CPUs and Intel Phi), OpenMP (threading for many-core CPUs and Intel Phi), CUDA (for NVIDIA GPUs) and HIP (for AMD GPUs)。
GPU包则是完全的LAMMPS开发包,目前支持3种模型的执行:Nvidia support, AMD support, or more general OpenCL support (for Nvidia GPUs, AMD GPUs, Intel GPUs, and multicore CPUs)。
两者之间的区别
虽然Nvida都能被两个包支持,但是在具体细节上还是有一点差异的[3]。
-
首先是GPU包能够通过多MPI ranks来提速(主要是因为GPU包只在pair force,neighbor list和部分的PPPM计算上使用GPU)而Kokkos则是把所有数据(存疑,似乎官网手册提到bonded interactions都是在CPU)放在GPU计算
-
另外,GPU包也支持多个GPU设备的并行计算,而Kokkos则需要额外的配置和编程来实现多GPU的并行计算
-
GPU包在处理大规模粒子系统时可能会出现内存限制,而Kokkos可以更灵活地管理内存和数据分配
-
此外,Kokkos还提供了更丰富的API和工具,使得用户可以更加灵活地对代码进行优化和调试
-
最后,Kokkos还可以在不同架构的硬件上实现高性能计算,包括CPU、GPU和FPGA等。这使得Kokkos在跨平台开发和部署方面具有一定优势。
- GPU包可以支持单精度、双精度、混合精度精算而Kokkos不支持混合精度(但是好像最新版本也支持混合精度了),因此我感觉Kokkos在游戏卡上劣势巨大不如GPU包
- 对于小体系,一般都是GPU包更快。对于单精度的Lennard Jones系统,临界点大概是50k-100k个原子/每块GPU。但是对于双精度计算的话,临界点更小
因此为了对比专业卡,同时也为了测试一下GPU包和Kokkos包在游戏卡上的性能差距,这里选择编译两个版本的LAMMPS。
CUDA环境构建
CUDA环境这里可以通过2种方式配置一个CUDA-TOOLKIT,另一个则是NV-HPC。NV-HPC应该是CUDA-TOOLKIT的超集,CUDA-TOOLKIT中仅有nvcc编译器,也包含了一些库libcufft等而HV-HPC则包含了nvc++, nvc, nvcc, nvfortran等。对于LAMMPS,由于其是由C++编写,因此只需要nvcc,其实只需要CUDA-TOOLKIT就可以了。
Arch Linux下的CUDA环境配置
Arch下可以直接使用以下命令安装CUDA-TOOLKIT
sudo pacman -Sy cuda
Ubuntu下的CUDA环境配置
Ubuntu下貌似也可以直接通过apt安装,但是对于WSL 2,NV官方竟然还提供了专有版本,这里选择NV官网下载,使用IDM貌似也能有不错的下载速度。下载完,直接使用官方给的命令就能进行安装:
wget https://developer.download.nvidia.com/compute/cuda/repos/wsl-ubuntu/x86_64/cuda-wsl-ubuntu.pin
sudo mv cuda-wsl-ubuntu.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/12.3.2/local_installers/cuda-repo-wsl-ubuntu-12-3-local_12.3.2-1_amd64.deb
sudo dpkg -i cuda-repo-wsl-ubuntu-12-3-local_12.3.2-1_amd64.deb
sudo cp /var/cuda-repo-wsl-ubuntu-12-3-local/cuda-*-keyring.gpg /usr/share/keyrings/
sudo apt-get update
sudo apt-get -y install cuda-toolkit-12-3
GPU包版的LAMMPS编译
GPU包版的编译直接跟着官方手册走就可以,这里选择采用CMAKE作为编译工具,下面是全部的编译命令:
export CUDA_ROOT=/opt/cuda # cuda dir
mkdir build; cd build
# 需要注意的是系统C++编译器的版本,由于目前Arch Linux的gcc版本为13,和CUDA或者NVHCP的nvcc不兼容,需要通过“-D CMAKE_CXX_COMPILER=/sbin/g++-12”指定兼容的12版本gcc。主要这里C++编译器最好不要选择nvcc,但是好像nvc++可以
cmake -D BUILD_MPI=on -D BUILD_OMP=on -D PKG_GPU=on -D GPU_API=cuda -D CMAKE_INSTALL_PREFIX=/where/to/install -D GPU_ARCH=sm_61 -C ../cmake/presets/most.cmake ../cmake
make -j all
KOKKOS包版的LAMMPS编译
KOKKOS版的编译要稍微麻烦,耗时更长一点,同样选择CMAKE作为编译工具,下面是全部的编译命令:
export CUDA_ROOT=/opt/cuda
mkdir build; cd build
# 这里同GPU版本的一样,注意在Arch下的g++版本。~~但是对于Kokkos,似乎使用了lammps/lib/kokkos/bin/nvcc_wrapper,因此可以使用NVCC_WRAPPER_DEFAULT_COMPILER=g++-12这个环境变量,然后指定使用nvcc_wrapper作为CXX_COMPILER~~。然而上面那个环境变量并不行,还是得用CMAKE_CXX_COMPILER
# 这里对Kokkos编译了serial版本,这是因为在运行时提示单进程运行的话serial版本性能更好。[[#两者之间的区别]]这里也说Kokkos基本所有计算在GPU进行,因此大多都是单线程
# 20240424Update: 对于使用了most的preset,有一些包还需要额外的以来,遇到的情况是缺少LAPACK和BLAS,根据LAMMPS官方文档,需要此以来的包有:ML-QUIP package和ELECTRODE package。对于Ubuntu系统直接使用安装:sudo apt-get install libblas-dev liblapack-dev
cmake -C ../cmake/presets/most.cmake -D PKG_KOKKOS=yes -D Kokkos_ENABLE_CUDA=yes -D Kokkos_ENABLE_SERIAL=yes -D Kokkos_ARCH_PASCAL61=on ../cmake
# FFT对计算速度的影响很大,采用自带KISS和编译版的FFTW3的速度可能相差近10倍。因此推荐安装FFTW3,或者编译FFTW3,这里也给出如何指定FFT后端
export NVCC_WRAPPER_DEFAULT_COMPILER=/sbin/g++-12
cmake -D PKG_KOKKOS=YES -D Kokkos_ENABLE_CUDA=yes -D Kokkos_ENABLE_SERIAL=yes -D Kokkos_ARCH_PASCAL61=on -D FFT=FFTW3 -D FFTW3_LIBRARY=/path/to/libfftw3.so -D FFTW3_OMP_LIBRARY=/path/to/libfftw3_omp.so -D FFT_FFTW_THREADS=on -D FFTW3_INCLUDE_DIR=/path/to/fftw3/include -D CMAKE_CXX_COMPILER=/home/gll/lammps/lib/kokkos/bin/nvcc_wrapper -C ../cmake/presets/most.cmake ../cmake
make -j all
Kokkos本版编译时的BUG
在最新的develop分支,使用FFTW3编译Kokkos版的LAMMPS时,会出现:
/usr/bin/ld: cannot find -lcufft
make[2]: *** [CMakeFiles/lmp.dir/build.make:109: lmp_issue3775_fft_kokkos-power9-volta70-cufft] Error 2
make[1]: *** [CMakeFiles/Makefile2:997: CMakeFiles/lmp.dir/all] Error 2
make: *** [Makefile:136: all] Error 2
根据LAMMPS Issues这里需要添加-D BUILD_SHARED_LIBS=yes,其实我在Arch下尝试以下命令也可以成功编译:
# 删除cuda的lib /etc/ld.so.conf.d/cuda.conf
# 更新缓存
sudo ldconfig
# 再次查看,没有libcufft.so
ldconfig -p | grep libcufft
#Update(20240523) 上面通过ldconfig查看libcufft可能是不对的,因为ldconfig是通过/etc/ld.so.conf或者子目录下的/etc/ld.so.conf.d/下的配置文件控制的。仅仅添加到LD_LIBRARY_PATH在3卡服务器上行不通的。
离线编译
在3卡服务器上需要采用离线的方式,可以直接通过以下的命令进行
module load nvhpc/24.3
mkdir build_cuda; cd build_cuda
cmake -C ../preset/most.cmake \
-D PKG_KOKKOS=ON \
-D Kokkos_ENABLE_CUDA=ON \
-D Kokkos_ENABLE_OPENMP=ON \
-D Kokkos_ENABLE_CUDA_LAMBDA=ON \
-D Kokkos_ENABLE_HWLOC=ON \ # 依赖于libhwloc-dev
-D PKG_VORONOI=OFF \
-D USE_SPGLIB=OFF \
-D FFT=MKL \
-D FFT_KOKKOS=CUFFT \
-D CMAKE_LIBRARY_PATH=/path/to/libcufft.so \ # cmake 并不搜索LD_LIBRARY_PATH
-D BUILD_MPI=ON \
-D BUILD_OMP=ON \
-D LAMMPS_MACHINE=mpi \
-D CMAKE_BUILD_TYPE=Release \
-D CMAKE_CXX_STANDARD=17 \
-D CMAKE_CXX_COMPILER="${pwd}/../lib/kokkos/bin/nvcc_wrapper" \
../cmake