NVSHMEM安装及使用

1 NVSHMEM简介

1.1 基本介绍

NVSHMEM 是 NVIDIA 提供的一个并行编程库,专门用于在 GPU 集群或多 GPU 系统中实现高效的共享内存访问。它通过使用共享内存来实现 GPU 间的数据通信,适合大规模并行计算应用,尤其是那些需要在多个 GPU 之间快速交换数据的场景。

1.2 关键特点

1. 一对多通信模型:NVSHMEM 提供了一种 “一对多” 的编程模型,使得一个线程可以直接访问和操作其他线程的数据。这种模型基于 SHMEM(共享内存)标准,并扩展到了多 GPU 环境。
2. 全局地址空间:NVSHMEM 允许多个 GPU 共享一个全局的地址空间,用户可以在多个 GPU 之间读写数据,而不需要显式的消息传递操作。
3. 高效的 GPU 间通信:NVSHMEM 使用 GPU 之间的高带宽互联(如 NVLink、InfiniBand)来实现数据的快速传输。相比传统的 CPU 主导的通信方式,它消除了 CPU 的干预,使得 GPU 间通信更加高效。
4. 同步原语:NVSHMEM 提供了多种同步原语,包括屏障(barriers)和锁(locks),方便开发者在并行计算中协调 GPU 之间的操作。
5. 易于集成:NVSHMEM 可以与其他 NVIDIA 的并行计算库(如 CUDA、NCCL 等)结合使用,提升多 GPU 应用程序的性能。

1.3 NVSHMEM 和 NCCL

请添加图片描述
总体来说,NVSHMEM较轻量级,适合小规模的不规则复杂通信;NCCL较重量级,适合大规模的规则通信。

2 NVSHMEM安装

实验环境
操作系统:CentOS7
CPU:Gold5218 32核 v5@2.3GHz          CPU内存:192GB
GPU:4 * NVIDIA®Tesla®V100               GPU显存:4 * 32G (897 GB/s)
节点内互连:NVLink 双向通信300 GB/s
节点间互连:100G InfiniBand

  • 由于是在服务器环境中且无管理员权限,只能安装并添加路径到用户目录下。
  • 若有其他问题,所有步骤参考官方文档!!!
1 下载nvshmem v3.0.6nccl的压缩包,放在 ~/dat01/soft/ 文件夹中。
2 首先安装NCCL:(若有管理员权限,直接 sudo yum install nccl 即可)
# 解压文件
[soft]$ unzip nccl-master.zip
[soft]$ rm nccl-master.zip
[soft]$ cd nccl-master

# 安装nccl前必须安装/加载cuda
[soft]$ module load nvidia/cuda/12.2

# 编译并安装至 ~/dat01/soft/nccl
[nccl-master]$ make -j src.build CUDA_HOME=/software/nvidia/cuda/12.2 BUILDDIR=~/dat01/soft/nccl

# 安装完成,删除安装包
[nvshmem]$ cd ..
[soft]$ rm -rf nccl-master

# 配置环境变量
[nccl-master]$ export NCCL_HOME=~/dat01/soft/nccl
[nccl-master]$ export LD_LIBRARY_PATH=$NCCL_HOME/lib:$LD_LIBRARY_PATH
3 然后安装NVSHMEM:
# 解压到当前文件夹并移除压缩包
[soft]$ tar -xvf nvshmem_src_3.0.6-4.txz
[soft]$ rm nvshmem_src_3.0.6-4.txz

# 进入安装包并配置环境
[soft]$ cd nvshmem_src_3.0.6-4/

# 必选,必须加载cuda并设置CUDA_HOME
[nvshmem_src_3.0.6-4]$ module load nvidia/cuda/12.2
[nvshmem_src_3.0.6-4]$ export CUDA_HOME=/software/nvidia/cuda/12.2

# 可选,加载mpi并设置MPI_HOME
[nvshmem_src_3.0.6-4]$ module load openmpi/4.1.0_IB_gcc9.3
[nvshmem_src_3.0.6-4]$ export MPI_HOME=/software/openmpi/4.1.0_IB_gcc9.3

# 可选,安装nccl并设置NCCL_HOME
[nvshmem_src_3.0.6-4]$ export NCCL_HOME=~/dat01/soft/nccl

# 编译及安装,安装路径为 '~/dat01/soft/nvshmem'
[nvshmem_src_3.0.6-4]$ cmake -D NVSHMEM_USE_GDRCOPY=0 -D NVSHMEM_MPI_SUPPORT=1 -D NVSHMEM_USE_NCCL=1 -D NVSHMEM_DEFAULT_PMIX=1 -D NVSHMEM_PREFIX=~/dat01/soft/nvshmem -S . -B ./build
[nvshmem_src_3.0.6-4]$ cd ./build
[nvshmem]$ make -j install

# 安装完成,删除安装包
[nvshmem]$ cd ../..
[soft]$ rm -rf nvshmem_src_3.0.6-4

配置说明:

  • NVSHMEM_USE_GDRCOPY=0 仅支持节点内通信。若要支持跨节点通信,需设置GDRCOPY_HOME,并让NVSHMEM_USE_GDRCOPY=1即可。
  • NVSHMEM_MPI_SUPPORT=1 支持了NVSHMEM与MPI的集成。也可以选择SHMEM集成。
  • NVSHMEM_USE_NCCL=1 支持了NVSHMEM与NCCL的集成
  • NVSHMEM_DEFAULT_PMIX=1 使用PMIX作为默认的bootstrap,同时支持mpirun和slurm两种方式启动nvshmem程序

现在NVSHMEM已经成功安装到 ~/dat01/soft/nvshmem 文件夹中。

4 准备测试代码 test.cu
#include <stdio.h>
#include <cuda.h>
#include "nvshmem.h"
#include "nvshmemx.h"
#include "mpi.h"

__global__ void simple_shift(int *destination) {
    int mype = nvshmem_my_pe();
    int npes = nvshmem_n_pes();
    int peer = (mype + 1) % npes;

    nvshmem_int_p(destination, mype, peer);
}

int main(void) {
    int mype_node, msg;
    cudaStream_t stream;

    nvshmem_init();
    mype_node = nvshmem_team_my_pe(NVSHMEMX_TEAM_NODE);
    cudaSetDevice(mype_node);
    cudaStreamCreate(&stream);

    int *destination = (int *) nvshmem_malloc(sizeof(int));

    simple_shift<<<1, 1, 0, stream>>>(destination);
    nvshmemx_barrier_all_on_stream(stream);
    cudaMemcpyAsync(&msg, destination, sizeof(int), cudaMemcpyDeviceToHost, stream);

    cudaStreamSynchronize(stream);
    printf("Total %d PEs.\n", nvshmem_n_pes());
    printf("%d: received message %d\n", nvshmem_my_pe(), msg);

    nvshmem_free(destination);
    nvshmem_finalize();
    return 0;
}

由于安装在用户空间,在运行nvshmem程序前需手动添加路径,这里我采用slurm脚本运行程序:

#!/bin/bash
#SBATCH -N 1                
#SBATCH --ntasks-per-node=4
#SBATCH --gres=gpu:4          

# 加载cuda和mpi
module load nvidia/cuda/12.2
module load openmpi/4.1.0_IB_gcc9.3

# 分别配置nvshmem, mpi, cuda, nccl的路径
export NVSHMEM_HOME=$HOME/dat01/soft/nvshmem
export MPI_HOME=/software/openmpi/4.1.0_IB_gcc9.3
export CUDA_HOME=/software/nvidia/cuda/12.2
export NCCL_HOME=$HOME/dat01/soft/nccl

# 将nvshmem, mpi, nccl的头文件和库文件都添加到路径中
export CPATH=$CPATH:$NVSHMEM_HOME/include:$MPI_HOME/include:$NCCL_HOME/include
export LIBRARY_PATH=$LIBRARY_PATH:$NVSHMEM_HOME/lib:$MPI_HOME/lib:$NCCL_HOME/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$NVSHMEM_HOME/lib:$MPI_HOME/lib:$NCCL_HOME/lib

# 配置编译的其他参数
export NVCC_GENCODE="arch=compute_70,code=sm_70"
export NVSHMEM_MPI_SUPPORT=1
export NVSHMEM_USE_NCCL=1

# 编译执行
nvcc -rdc=true -ccbin g++ -gencode=$NVCC_GENCODE test.cu -o test.out -lnvshmem_host -lnvshmem_device -lmpi 
srun ./test.out
rm ./test.out
5 slurm提交脚本程序作业:
$ sbatch -p gpu -n 4 -N 1 --gres=gpu:4 run.sh

若运行成功,则NVSHMEM安装成功。默认只能在节点内通信。

3 NVSHMEM代码结构及常用API解析

NVSHMEM所使用的API都可以在官网上查到。

3.1 API

nvshmem_init():初始化 NVSHMEM 环境。
nvshmem_malloc():分配对称共享内存。
nvshmem_free():释放共享内存。
nvshmem_put():远程写入数据到其他 GPU。
nvshmem_get():从其他 GPU 读取数据。
nvshmem_barrier_all():全局同步,确保所有处理单元都到达同步点。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值