CUDA项目CMake中最小NVIDIA微架构检查的相关需求问询
实现CUDA项目按源文件指定最小微架构并验证的CMake方案
CMake的CMAKE_CUDA_ARCHITECTURES主要控制编译生成的目标架构集合,但没法直接按源文件指定最小要求。下面是一套完全满足你需求的实现方案,直接贴到CMakeLists.txt里就能用:
1. 手动指定每个源文件的最小计算能力(CC)
CMake没有自动分析CUDA源文件所需最小微架构的功能,所以我们手动维护一个映射表,把每个.cu文件和它要求的最低CC对应起来:
# 定义每个CUDA源文件对应的最小计算能力(CC),格式为"文件名" "CC值" set(CUDA_SOURCE_MIN_ARCHS "src/kernel_featureX.cu" "70" # 对应Volta架构 "src/kernel_featureY.cu" "75" # 对应Turing架构 "src/common_utils.cu" "60" # 对应Pascal架构 )
2. 计算项目的整体最小CC要求
遍历上面的映射表,取所有源文件最小CC的最大值——这就是项目能正常运行的最低要求,相当于所有源文件支持范围的交集:
# 计算项目所需的最小计算能力:取所有源文件最小CC的最大值 set(PROJECT_MIN_CC 0) # 循环处理映射表中的每一对(文件名, CC) while(CUDA_SOURCE_MIN_ARCHS) list(GET CUDA_SOURCE_MIN_ARCHS 0 current_file) list(GET CUDA_SOURCE_MIN_ARCHS 1 current_cc) list(REMOVE_AT CUDA_SOURCE_MIN_ARCHS 0 1) if(current_cc GREATER PROJECT_MIN_CC) set(PROJECT_MIN_CC ${current_cc}) endif() endforeach() message(STATUS "Project minimum required compute capability: sm_${PROJECT_MIN_CC}")
3. 验证系统GPU或目标架构是否达标
分三种情况处理:用户指定目标架构、本地编译检测GPU、交叉编译强制指定:
# 优先处理用户直接指定的目标GPU CC(可选参数) if(DEFINED TARGET_GPU_CC) if(TARGET_GPU_CC LESS PROJECT_MIN_CC) message(FATAL_ERROR "Specified target GPU CC ${TARGET_GPU_CC} is below project minimum ${PROJECT_MIN_CC}") endif() set(CMAKE_CUDA_ARCHITECTURES "sm_${TARGET_GPU_CC}" CACHE STRING "CUDA architectures to build for" FORCE) message(STATUS "Using explicitly specified target GPU CC: sm_${TARGET_GPU_CC}") elseif(DEFINED CMAKE_CUDA_ARCHITECTURES) # 处理用户通过CMAKE_CUDA_ARCHITECTURES指定的架构集合 list(GET CMAKE_CUDA_ARCHITECTURES 0 FIRST_TARGET_CC) # 提取纯数字CC值(比如从"sm_75"得到"75") string(REGEX REPLACE "sm_" "" FIRST_TARGET_CC_NUM "${FIRST_TARGET_CC}") if(FIRST_TARGET_CC_NUM LESS PROJECT_MIN_CC) message(FATAL_ERROR "First target architecture sm_${FIRST_TARGET_CC_NUM} is below project minimum sm_${PROJECT_MIN_CC}") endif() message(STATUS "Using user-specified CUDA architectures: ${CMAKE_CUDA_ARCHITECTURES}") else() # 非交叉编译时,自动检测系统GPU的支持情况 if(NOT CMAKE_CROSSCOMPILING) # 用nvcc查询系统GPU支持的所有架构 execute_process( COMMAND ${CMAKE_CUDA_COMPILER} --query-gpu-arch OUTPUT_VARIABLE GPU_ARCHS_OUTPUT ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE ) # 解析输出提取所有sm_xx格式的架构 string(REGEX MATCHALL "sm_[0-9]+" GPU_SUPPORTED_ARCHS "${GPU_ARCHS_OUTPUT}") # 检查是否有GPU满足项目最小要求 set(GPU_MEETS_REQ OFF) foreach(arch IN LISTS GPU_SUPPORTED_ARCHS) string(REPLACE "sm_" "" arch_cc "${arch}") if(arch_cc GREATER_EQUAL PROJECT_MIN_CC) set(GPU_MEETS_REQ ON) break() endif() endforeach() if(NOT GPU_MEETS_REQ) message(FATAL_ERROR "No GPU in system supports minimum CC sm_${PROJECT_MIN_CC}. Supported archs: ${GPU_SUPPORTED_ARCHS}") endif() message(STATUS "System GPU meets requirement. Using detected architectures: ${GPU_ARCHS_OUTPUT}") # 把检测到的架构设置为CMAKE_CUDA_ARCHITECTURES set(CMAKE_CUDA_ARCHITECTURES "${GPU_SUPPORTED_ARCHS}" CACHE STRING "CUDA architectures to build for" FORCE) else() # 交叉编译时必须指定目标架构 message(FATAL_ERROR "Cross-compiling: Please set CMAKE_CUDA_ARCHITECTURES. Project minimum is sm_${PROJECT_MIN_CC}") endif() endif()
4. 常规CUDA目标设置
最后添加你的项目目标,比如可执行文件或库:
# 添加CUDA可执行文件示例 add_executable(my_cuda_app src/main.cpp src/kernel_featureX.cu src/kernel_featureY.cu src/common_utils.cu ) # 可选:启用CUDA分离编译 set_target_properties(my_cuda_app PROPERTIES CUDA_SEPARABLE_COMPILATION ON )
使用说明
- 要指定单个目标GPU,编译时加参数:
cmake .. -DTARGET_GPU_CC=75 - 要指定多个目标架构,用:
cmake .. -DCMAKE_CUDA_ARCHITECTURES="70;75;80" - 本地编译时会自动检测GPU,不满足最小要求直接报错终止配置
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

