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包和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

  1. 7.4.3. KOKKOS package — LAMMPS documentation ↩︎

  2. 7.4.1. GPU package — LAMMPS documentation ↩︎

  3. 7.5. Comparison of various accelerator packages — LAMMPS documentation ↩︎