CUDA 13.0 来了,cuda-samples 迁移 5 步搞定
【免费下载链接】cuda-samplesSamples for CUDA Developers which demonstrates features in CUDA Toolkit项目地址: https://gitcode.com/GitHub_Trending/cu/cuda-samples
CUDA 13.0 发布,cuda-samples 仓库已同步适配。如果你把旧版示例代码搬到自己项目里,大概率会撞上编译报错——cudaDeviceProp 字段没了、cuCtxCreate 签名变了、CUFFT 错误码换了一半。下面按迁移顺序逐项讲清旧新代码对照,改完直接编译就能过。
影响面速查
先建立全局认知:这次 CUDA 13.0 升级共 6 项变更,波及 30 多个示例目录。对照表如下,后面按影响面从大到小逐项改。
| CUDA 13.0 API 变更 | 版本变化 | 受影响示例 | 代表示例 |
|---|---|---|---|
cuCtxCreate | 默认指向cuCtxCreate_v4 | 16 个示例 + nvrtc_helper.h | matrixMulDrv、memMapIPCDrv |
cudaDeviceProp字段 | 6 个字段废弃或移除 | 11 个示例 | deviceQuery、simpleHyperQ |
| CUFFT 错误码 | 删 3 个、新增 4 个 | 4 个示例 + helper_cuda.h | simpleCUFFT |
cudaMemAdvise/cudaMemPrefetchAsync | 默认指向_v2,设备号变cudaMemLocation | 2 个示例 | conjugateGradientMultiDeviceCG、UnifiedMemoryPerf |
cudaGraphAddNode/cudaStreamGetCaptureInfo | 升级为_v2/_v3,新增cudaGraphEdgeData参数 | 1 个示例 | graphConditionalNodes |
thrust::identity | 移除 | 1 个示例 | segmentationTreeThrust |
完整对应清单在 CHANGELOG.md 的 CUDA 13.0 段落,可以直接当核对单用。
动手改:按影响面逐项替换
先改 cuCtxCreate,波及面最广
CUDA 13.0 把驱动 API 的cuCtxCreate默认指向了cuCtxCreate_v4,旧的三参形式没了,必须传CUctxCreateParams结构体。这段演示驱动 API 创建上下文的新写法,仓库里的改法可直接照抄:
// 旧 CUcontext ctx; checkCudaErrors(cuCtxCreate(&ctx, CU_CTX_SCHED_AUTO, 0, cuDevice)); // 新 CUctxCreateParams params = {}; params.flags = CU_CTX_SCHED_AUTO; checkCudaErrors(cuCtxCreate(&ctx, ¶ms, 0, cuDevice));注意函数名仍叫cuCtxCreate,只是第二参变成了结构体指针,设备号还在第三参,填 0 行为和以前一致。涉及 matrixMulDrv、simpleTextureDrv、EGLStream_CUDA_CrossGPU、threadMigration、jitLto、7_libNVVM 下 4 个示例,以及公共头 nvrtc_helper.h。
cudaDeviceProp 字段消失,改查 cudaDeviceGetAttribute
CUDA 13.0 把clockRate、computeMode等 6 个cudaDeviceProp字段废弃或移除,这些属性要改用cudaDeviceGetAttribute逐个查询。这段对照以最常被引用的 clockRate 为例:
// 旧 cudaDeviceProp prop; checkCudaErrors(cudaGetDeviceProperties(&prop, dev)); int clock = prop.clockRate; // 新 int clock; checkCudaErrors(cudaDeviceGetAttribute(&clock, cudaDevAttrClockRate, dev));字段映射:clockRate→cudaDevAttrClockRate、memoryClockRate→cudaDevAttrMemoryClockRate、deviceOverlap→cudaDevAttrGpuOverlap、computeMode→cudaDevAttrComputeMode、kernelExecTimeoutEnabled→cudaDevAttrKernelExecTimeout;cooperativeMultiDeviceLaunch整体废弃且无替代属性,新代码别走这条路。共 11 个示例,改法最完整的参照 deviceQuery,其余还有 simpleHyperQ、simpleIPC、systemWideAtomics、streamOrderedAllocationIPC、simpleCUBLASXT、vulkanImageCUDA。
CUFFT 错误码换血,switch 分支要重写
CUFFT 错误码集合调整:CUFFT_INCOMPLETE_PARAMETER_LIST、CUFFT_PARSE_ERROR、CUFFT_LICENSE_ERROR三个被删,新增CUFFT_MISSING_DEPENDENCY、CUFFT_NVRTC_FAILURE、CUFFT_NVJITLINK_FAILURE、CUFFT_NVSHMEM_FAILURE四个细分错误码。这段对照是错误码分支的改法示意:
// 旧 if (result == CUFFT_PARSE_ERROR) fprintf(stderr, "parse error\n"); // 新 if (result == CUFFT_NVJITLINK_FAILURE) fprintf(stderr, "nvJitLink failure\n");注意 helper_cuda.h 的错误码映射已同步更新,你项目里自写的 CUFFT 错误 if/switch 链也要跟着清一遍。涉及 simpleCUFFT、simpleCUFFT_2d_MGPU、simpleCUFFT_MGPU、simpleCUFFT_callback。
cudaMemAdvise 和 cudaMemPrefetchAsync:设备号变 cudaMemLocation
这两个 API 在 CUDA 13.0 默认指向_v2,签名里的int device参数换成了cudaMemLocation结构体。这段是多设备协同里设置内存建议与预取的改法:
// 旧 checkCudaErrors(cudaMemAdvise(ptr, size, cudaMemAdviseSetPreferredLocation, deviceId)); checkCudaErrors(cudaMemPrefetchAsync(ptr, size, deviceId, stream)); // 新 cudaMemLocation loc; loc.type = cudaMemLocationTypeDevice; loc.id = deviceId; checkCudaErrors(cudaMemAdvise(ptr, size, cudaMemAdviseSetPreferredLocation, loc)); checkCudaErrors(cudaMemPrefetchAsync(ptr, size, loc, 0, stream));注意loc.id在设备位置时就是设备序号;预取目标如果是 CPU,用cudaMemLocationTypeHost,新签名下这是表达 host 的唯一方式。涉及 conjugateGradientMultiDeviceCG 和 UnifiedMemoryPerf。
CUDA Graphs 接口多传两个参数
cudaGraphAddNode和cudaStreamGetCaptureInfo升级为_v2/_v3,新增了cudaGraphEdgeData参数用来描述图的边级属性。这段是节点添加接口的签名变化:
// 旧 checkCudaErrors(cudaGraphAddNode(&node, graph, deps, 0, ¶ms)); // 新 checkCudaErrors(cudaGraphAddNode(&node, graph, deps, NULL, 0, ¶ms));注意不需要边属性时直接传NULL即可,cudaStreamGetCaptureInfo同理,edgeData位置传NULL、依赖计数挪到最后一个参数。涉及 graphConditionalNodes。
thrust::identity 移除,换 cuda::std::identity
thrust::identity<uint>()在 CUDA 13.0 被移除,等价能力转到了 CCCL。这段是无类型转换算法调用的替换:
// 旧 thrust::transform(in.begin(), in.end(), out.begin(), thrust::identity<uint>()); // 新 thrust::transform(in.begin(), in.end(), out.begin(), cuda::std::identity());注意补一个<cuda/std/functional>头文件即可,算法本体仍留在thrust命名空间,改动面很小。涉及 segmentationTreeThrust。
编译与环境
先正常整仓构建一遍:
mkdir build && cd build cmake .. make -j$(nproc)改完先别急着怀疑代码,九成问题是环境。这里要特别盯住"新工具链 + 旧驱动"的组合:如果你用 CUDA Toolkit 13.0+ 和 UMD 580+,但 KMD 还停在 550-,cmake 时必须把CMAKE_PREFIX_PATH指到新版驱动库:
cmake -DCMAKE_PREFIX_PATH=/usr/local/cuda/lib64/stubs/ ..否则会链接到旧驱动,运行时直接报驱动版本不匹配,细节见 README.md 的 Forward Compatibility 一节。Tegra 平台要加平台开关和交叉编译工具链:
cmake .. -DBUILD_TEGRA=True \ -DCMAKE_TOOLCHAIN_FILE=../cmake/toolchains/toolchain-aarch64-linux.cmake \ -DTARGET_FS=/path/to/target/fsCUDA 13.0 同期更新了 QNX 交叉编译工具链,对应配置文件在 cmake/toolchains/ 下。
改完怎么验
分三层验,每层信号不同:
- 基础层:跑 simpleCUBLAS。跑通说明运行时 API 主链路没断,Common 头文件也没有 API 残留。
- 多设备协同层:跑 conjugateGradientMultiDeviceCG。通过则说明
cudaMemLocation新签名正确,且多 GPU 间的内存建议与预取真正生效。 - 性能层:跑 UnifiedMemoryPerf。拿带宽数字和升级前基线对比,确认迁移没引入性能回退。
想全量回归就一行搞定,仓库自带run_tests.py:
python3 run_tests.py --output ./test --dir ./build/cpp --config test_args.json输出目录会保存每个示例的 stdout 日志,失败直接看对应 txt,不用逐个跑。
容易踩的坑
- 如果你遇到
CUFFT_PARSE_ERROR之类 undeclared 的编译错误,大概率是 CUFFT 错误码瘦身了——那 3 个旧错误码已经不存在,换成CUFFT_MISSING_DEPENDENCY、CUFFT_NVRTC_FAILURE、CUFFT_NVJITLINK_FAILURE、CUFFT_NVSHMEM_FAILURE四个新码,以 helper_cuda.h 为准。 - 如果你在新 Toolkit + 旧 KMD 环境下刚启动就报驱动版本不匹配,大概率是 cmake 时没设
CMAKE_PREFIX_PATH,链接到了旧驱动 stubs;UMD 580+ 配 KMD 550- 正是 README.md Forward Compatibility 一节描述的组合。 - 如果你发现 EGLStream 相关示例在桌面 Linux 上不编译或缺文件,大概率是平台问题:8_Platform_Specific/Tegra 下的示例只对 Tegra 设备有意义,需要
-DBUILD_TEGRA=True加 aarch64 工具链,桌面构建默认不含它们。
下次 Toolkit 再升级时,先把 CHANGELOG.md 的 CUDA 段落逐条 diff 一遍,是效率最高的适配路径;本轮改完记得用run_tests.py全量跑一次,让迁移结果可复现。
【免费下载链接】cuda-samplesSamples for CUDA Developers which demonstrates features in CUDA Toolkit项目地址: https://gitcode.com/GitHub_Trending/cu/cuda-samples
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考