NVSHMEM 和 cuFFTMp¶
用法¶
cuFFTMp 基于 NVSHMEM 构建,并与之兼容。在下文中,假设 NVSHMEM 安装在 ${NVSHMEM_HOME}
中。
接受 void *
内存缓冲区指针的 cuFFTMp API(例如 cufftExecC2C
、cufftMpExecReshapeAsync
等)需要传递使用 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 例程。
当调用 cufftMakePlan2d
或 cufftMakePlan3d
时,cuFFTMp 将根据需要自动初始化 NVSHMEM,并在调用 cufftDestroy
时完成初始化。
但是,如果在调用任何 cuFFTMp API 之前初始化 NVSHMEM,则可以减少初始化开销。特别是,如果在循环中重复创建和销毁 cuFFTMp 计划,则在循环之前初始化 NVSHMEM 将最大限度地减少 cuFFTMp 计划时间。
cuFFTMp 中的 NVSHMEM 内存缓冲区¶
由于 cuFFTMp 要么在内部初始化 NVSHMEM 内存缓冲区,要么需要使用 NVSHMEM 分配的内存缓冲区(nvshmem_malloc
和 nvshmem_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/