NVSHMEM 和 cuFFTMp

用法

cuFFTMp 基于 NVSHMEM 构建,并与之兼容。在下文中,假设 NVSHMEM 安装在 ${NVSHMEM_HOME} 中。

接受 void * 内存缓冲区指针的 cuFFTMp API(例如 cufftExecC2CcufftMpExecReshapeAsync 等)需要传递使用 nvshmem_malloc 分配并使用 nvshmem_free 释放的内存缓冲区。这些 API 在 NVSHMEM 头文件中可用,通过使用 #include <nvshmem.h> 并添加 -I${NVSHMEM_HOME}/include 作为编译器标志来包含。

用户应用程序应始终在链接时链接到 libnvshmem_host.so 库,如果直接使用任何 NVSHMEM API,则还应链接到 libnvshmem_device.a 库。这通常可以通过将 -L${NVSHMEM_HOME}/lib -lnvshmem_host -lnvshmem_device 标志传递给链接器来完成。

最后,cuFFTMp 要求所有 NVSHMEM 库在运行时在系统上可用,例如通过定义

export LD_LIBRARY_PATH="${NVSHMEM_HOME}/lib:$LD_LIBRARY_PATH"

在使用 cuFFTMp 之前在环境中。

NVSHMEM 初始化

希望使用任何 NVSHMEM API 的用户应在其应用程序中初始化 NVSHMEM,然后再调用 cuFFTMp 例程。

当调用 cufftMakePlan2dcufftMakePlan3d 时,cuFFTMp 将根据需要自动初始化 NVSHMEM,并在调用 cufftDestroy 时完成初始化。

但是,如果在调用任何 cuFFTMp API 之前初始化 NVSHMEM,则可以减少初始化开销。特别是,如果在循环中重复创建和销毁 cuFFTMp 计划,则在循环之前初始化 NVSHMEM 将最大限度地减少 cuFFTMp 计划时间。

cuFFTMp 中的 NVSHMEM 内存缓冲区

由于 cuFFTMp 要么在内部初始化 NVSHMEM 内存缓冲区,要么需要使用 NVSHMEM 分配的内存缓冲区(nvshmem_mallocnvshmem_free),因此 NVSHMEM 为内存管理定义的环境变量也与 cuFFTMp 相关。

有关详细信息,请参阅 NVSHMEM 文档中的 内存管理环境变量

以下是一些使用 NVSHMEM 环境变量调整 cuFFTMp 中内存管理的示例

  • NVSHMEM 对称堆可以静态分配(在 NVSHMEM 初始化时预先分配一次,并且永远不会增长)或动态分配(它随着程序的运行而增长/缩小)。可以使用 NVSHMEM_DISABLE_CUDA_VMM 打开/关闭动态增长。请注意,CUDA VMM 功能要求 CUDA 驱动程序版本大于或等于 11.3。

  • 对于动态分配的对称堆,可以通过 NVSHMEM_MAX_MEMORY_PER_GPU 设置最大堆大小。默认情况下,这设置为 128 GB,对于大多数应用程序来说已经足够了。

  • 对于静态分配的对称堆,用户可以通过设置 NVSHMEM_SYMMETRIC_SIZE 环境变量来增加为 NVSHMEM 保留的内存量。默认情况下,这设置为 1 GB。需要更大分配的应用程序应将其调整为更大的值。(动态堆分配不需要这样做。)

例如,设置为 10GB

export NVSHMEM_SYMMETRIC_SIZE=10G

兼容性

cuFFTMp 需要在系统上安装特定版本的 NVSHMEM。== 表示需要完全匹配。>=, <= 表示与一系列版本兼容。

cuFFTMp

NVSHMEM

11.2.6 (HPC-SDK 24.07)

>= 3.0.6

11.0.14 (HPC-SDK 23.11)

== 2.10.1

11.0.5 (HPC-SDK 23.3)

== 2.8.0

10.8.1 (HPC-SDK 22.5+, 23.1)

>= 2.5.0, <= 2.6.0

0.0.2 (HPC-SDK 22.3)

== 2.4.1

此外,请注意,用于 CUDA 11(或 CUDA 12)的 cuFFTMp 需要为 CUDA 11(或 CUDA 12)构建的 NVSHMEM。

注意

从 cuFFTMp 11.2.6 开始,在主要的 NVSHMEM 版本内,主机和设备库之间的 NVSHMEM ABI 向后兼容性得到支持。这意味着 cuFFTMp 11.2.6 现在与 3.0.6 和未来的 NVSHMEM 3.x 版本兼容。只要更新后的 NVSHMEM 在同一主要版本内,将 NVSHMEM 更新到较新版本将不再需要将 cuFFTMp 更新到较新版本。

HPC-SDK、cuFFTMp 和 NVSHMEM

如上所示,cuFFTMp 和 NVSHMEM 的版本需要彼此兼容。

因此,HPC-SDK 可能包含多个 NVSHMEM 版本。例如,HPC-SDK 23.05 同时包含 2.9(最新版本)和 2.8(因为 cuFFTMp 11.0.5 需要 NVSHMEM 2.8)。在这种情况下,必须注意确保将正确的 NVSHMEM 与 cuFFTMp 结合使用。

下表指示了从 HPC-SDK 23.03 开始,要使用的适当 NVSHMEM 的位置。$NVHPC_ROOT 是 HPC-SDK 安装的根目录(例如 /opt/nvidia/hpc_sdk/Linux_x86_64/23.7/),$CUDA 是 CUDA 版本,格式为 major.minor(例如 12.0)。$NVSHMEM_ROOT 是要与 cuFFTMp 一起使用的适当 NVSHMEM 安装的位置。

注意

cuFFTMp 和 NVSHMEM 都应使用相同的 $CUDA(主版本)。具体而言,用于 CUDA 12(或 CUDA 11)的 cuFFTMp 应使用用于 CUDA 12(或 CUDA 11)的 NVSHMEM。具体的次要版本无关紧要,因为 NVSHMEM 在次要版本之间兼容。这与多 CUDA 裸机安装(来自 https://developer.nvidia.com/hpc-sdk-downloads)或容器(例如 nvcr.io/nvidia/nvhpc:23.11-devel-cuda_multi-centos7)相关。

在编译时,用户应包含位于 $NVSHMEM_ROOT/include 中的头文件。在运行时,$NVSHMEM_ROOT/lib 应存在于 LD_LIBRARY_PATH 中。

另请参阅 HPC-SDK 发行说明

HPC-SDK

cuFFTMp

NVSHMEM 安装位置 ($NVSHMEM_ROOT)

23.03

11.0.5

$NVHPC_ROOT/comm_libs/$CUDA/nvshmem/

23.05

11.0.5

$NVHPC_ROOT/comm_libs/$CUDA/nvshmem_cufftmp_compat/

23.07

11.0.5

$NVHPC_ROOT/comm_libs/$CUDA/nvshmem_cufftmp_compat/

23.09

11.0.5

$NVHPC_ROOT/comm_libs/$CUDA/nvshmem_cufftmp_compat/

23.11

11.0.14

$NVHPC_ROOT/comm_libs/$CUDA/nvshmem/

24.01

11.0.14

$NVHPC_ROOT/comm_libs/$CUDA/nvshmem/

24.03

11.0.14

$NVHPC_ROOT/comm_libs/$CUDA/nvshmem/

24.05

11.0.14

$NVHPC_ROOT/comm_libs/$CUDA/nvshmem_cufftmp_compat/

24.07

11.2.6

$NVHPC_ROOT/comm_libs/$CUDA/nvshmem/