1. 环境搭建与验证
任务目标
本案例完成RDMA与GPU通信开发的最小环境搭建,并验证两点:网卡支持RDMA(InfiniBand或RoCE)且GPU可被系统识别。验证通过后,后续案例可直接在此环境上运行。
环境需求
- 操作系统:Linux(内核≥3.10,推荐Ubuntu 20.04+ / CentOS 7.6+)
- 硬件:支持RDMA的网卡(Mellanox ConnectX系列、Broadcom RoCE网卡等)+ NVIDIA GPU
- 驱动:NVIDIA驱动(≥450.80.02)、MLNX_OFED驱动(Mellanox网卡必需)或系统自带rdma-core(RoCE网卡)
- 软件包:
ibverbs-utils、rdma-core、cuda-toolkit、pciutils
环境检查与配置
以下命令在终端逐条执行,确认输出符合预期。
# 1. 检查GPU是否被系统识别
lspci | grep -i nvidia
# 预期输出:包含 NVIDIA 设备行,如 "NVIDIA Corporation GA102 [GeForce RTX 3080]"
# 2. 检查NVIDIA驱动是否加载
nvidia-smi
# 预期输出:显示GPU名称、驱动版本、显存等信息
# 3. 检查RDMA网卡是否存在
ibv_devinfo
# 预期输出:显示端口状态为 PORT_ACTIVE,链路层为 InfiniBand 或 Ethernet(RoCE)
# 4. 检查内核是否加载RDMA模块
lsmod | grep rdma
# 预期输出:包含 rdma_cm、ib_core、mlx5_core(Mellanox)等模块
# 5. 确认CUDA可用(若需GPU计算)
nvcc --version
# 预期输出:显示CUDA版本号
最小验证代码
以下C程序同时查询RDMA设备与GPU设备,验证两者在当前环境中均可用。编译运行后,输出设备名称与状态。
// rdma_gpu_check.c
#include <stdio.h>
#include <infiniband/verbs.h>
#include <cuda_runtime.h>
int main() {
// ---- RDMA 设备检查 ----
struct ibv_device **dev_list;
int num_devices, i;
dev_list = ibv_get_device_list(&num_devices, NULL);
if (!dev_list || num_devices == 0) {
printf("[FAIL] 未找到RDMA设备,请检查网卡驱动与固件。\n");
return 1;
}
printf("[OK] 发现 %d 个RDMA设备:\n", num_devices);
for (i = 0; i < num_devices; i++) {
struct ibv_context *ctx = ibv_open_device(dev_list[i]);
if (!ctx) {
printf(" - %s (打开失败)\n", ibv_get_device_name(dev_list[i]));
continue;
}
struct ibv_port_attr port_attr;
if (ibv_query_port(ctx, 1, &port_attr) == 0) {
const char *link = (port_attr.link_layer == IBV_LINK_LAYER_INFINIBAND) ?
"InfiniBand" : "RoCE/Ethernet";
printf(" - %s | 端口状态: %s | 链路层: %s\n",
ibv_get_device_name(dev_list[i]),
(port_attr.state == IBV_PORT_ACTIVE) ? "ACTIVE" : "DOWN",
link);
}
ibv_close_device(ctx);
}
ibv_free_device_list(dev_list);
// ---- GPU 设备检查 ----
int gpu_count = 0;
cudaError_t err = cudaGetDeviceCount(&gpu_count);
if (err != cudaSuccess || gpu_count == 0) {
printf("[FAIL] CUDA运行时无法访问GPU: %s\n", cudaGetErrorString(err));
return 1;
}
printf("[OK] 发现 %d 个GPU设备:\n", gpu_count);
for (i = 0; i < gpu_count; i++) {
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, i);
printf(" - %s | 显存: %.1f GB | SM版本: %d.%d\n",
prop.name, prop.totalGlobalMem / (1024.0*1024*1024),
prop.major, prop.minor);
}
printf("\n环境验证通过:RDMA与GPU均可用。\n");
return 0;
}
编译与运行
# 编译(需安装libibverbs-dev与cuda-toolkit)
gcc rdma_gpu_check.c -o rdma_gpu_check -libverbs -lcudart -L/usr/local/cuda/lib64
# 运行
./rdma_gpu_check
验证判定标准
- 程序退出码为0,且输出包含
[OK]行 - RDMA设备端口状态为
ACTIVE,链路层为InfiniBand或RoCE/Ethernet - GPU设备列表非空,且显示正确的设备名称与显存大小
- 若任一检查输出
[FAIL],按提示检查对应驱动或硬件连接
常见问题
- ibv_devinfo 无输出:确认网卡驱动已安装(Mellanox网卡需MLNX_OFED),或尝试
modprobe mlx5_core加载模块 - nvidia-smi 报错:NVIDIA驱动未安装或与内核版本不匹配,重新安装驱动
- 编译时找不到libibverbs:安装
libibverbs-dev(Ubuntu)或rdma-core-devel(CentOS) - cudaGetDeviceCount返回0:确认CUDA toolkit与驱动版本兼容,运行
nvcc --version检查