如何让CMake自动检测CUDA_ARCHITECTURES的值?

j5fpnvbx  于 2023-08-05  发布在  其他
关注(0)|答案(3)|浏览(462)

较新版本的CMake(3.18和更高版本)“知道”CUDA架构的选择,而CUDA代码编译的目标。目标有一个CUDA_ARCHITECTURES属性,设置该属性后,会为您生成相应的-gencode arch=whatever,code=whatever编译选项。如果不设置此值,您甚至会收到警告:

CMake Error in CMakeLists.txt:
  CUDA_ARCHITECTURES is empty for target "my_cuda_app".

字符串
默认情况下,此target属性初始化为CMAKE_CUDA_ARCHITECTURES。但是CMAKE_CUDA_ARCHITECTURES本身没有初始化为任何东西(!)
如何让CMake自动检测CUDA_ARCHITECTURES或全局CMAKD_CUDA_ARCHITECTURES的适当值?也就是说,使用安装在系统上的GPU架构?

prdp8dxp

prdp8dxp1#

在即将到来的CMake 3.24中,您将能够编写:

set_property(TARGET tgt PROPERTY CUDA_ARCHITECTURES native)

字符串
这将在配置时为系统上可用的GPU的(具体)CUDA架构构建目标tgt
对于更新版本的CUDA(11.5和更高版本),将把native传递给nvcc和其他可执行文件;对于旧版本,它将自动检测哪些体系结构是“原生”体系结构。

**注意:**这实际上并没有给予架构列表(例如在CMake代码中迭代。)

0ejtzxu1

0ejtzxu12#

CMake实际上提供了这样的自动检测功能,但是:
1.它没有文档记录(并且可能在将来的某个时候被重构)。
1.它是已弃用的FindCUDA机制的一部分,面向直接操作CUDA_CMAKE_FLAGS(这不是我们想要的)。
1.它不会“玩得很好”,并且对我们隐藏了它有用的内部变量。
不过,只要费点力气,我们就能成功。
首先,它的位置:它位于一个模块FindCUDA/select_compute_arch中(在Linux系统上,它位于/path/to/cmake/root/share/cmake-X.YY/Modules/FindCUDA/select_compute_arch.cmake中)。
下面是你如何使用它:

include(FindCUDA/select_compute_arch)
CUDA_DETECT_INSTALLED_GPUS(INSTALLED_GPU_CCS_1)
string(STRIP "${INSTALLED_GPU_CCS_1}" INSTALLED_GPU_CCS_2)
string(REPLACE " " ";" INSTALLED_GPU_CCS_3 "${INSTALLED_GPU_CCS_2}")
string(REPLACE "." "" CUDA_ARCH_LIST "${INSTALLED_GPU_CCS_3}")
SET(CMAKE_CUDA_ARCHITECTURES ${CUDA_ARCH_LIST})

字符串
如果您只希望对单个目标执行此操作,则可以将最后一行替换为:

set_property(TARGET my_target PROPERTY "${CUDA_ARCH_LIST}")


备注:

  • 当系统上没有GPU时,您可能会得到以下结果:3.5;5.0;5.3;6.0;6.1;7.0;7.5;7.5+PTX的值。

这是一个issue with CMake which will not be resolved,因为我们在这里使用的子模块不受官方支持。因此,如果你需要在没有GPU的系统上编译,要么避免这个调用,要么解析结果中的“+PTX”条目。

  • select_compute_arch子模块存在的时间要长得多,但在过去,您会以不同的方式使用它,并通过include(FindCUDA)包含它。
  • 我想知道LIST(APPEND CMAKE_CUDA_ARCHITECTURES是否比SET(CMAKE_CUDA_ARCHITECTURES更合适。
  • 请参阅CMake issues 2237519199,了解CMake将来可能会在哪里使用它。警告:我提交了这些bug……
ktca8awb

ktca8awb3#

我在使用CMake 3. 13的系统时遇到了其他解决方案的问题,不确定它是什么,但我不得不使用这个。
也许有更好的方法来做到这一点。

if(${CMAKE_VERSION} VERSION_LESS_EQUAL "3.13.4")
      cuda_select_nvcc_arch_flags(ARCH_FLAGS "Auto") # optional argument for arch to add
      message("ARCH_FLAGS = ${ARCH_FLAGS}")
      string(REPLACE "-gencode;" "--generate-code=" ARCH_FLAGS "${ARCH_FLAGS}")
      string(APPEND CMAKE_CUDA_FLAGS "${ARCH_FLAGS}")
    else()
      include(FindCUDA/select_compute_arch)
      CUDA_DETECT_INSTALLED_GPUS(INSTALLED_GPU_CCS_1)
      string(STRIP "${INSTALLED_GPU_CCS_1}" INSTALLED_GPU_CCS_2)
      string(REPLACE " " ";" INSTALLED_GPU_CCS_3 "${INSTALLED_GPU_CCS_2}")
      string(REPLACE "." "" CUDA_ARCH_LIST "${INSTALLED_GPU_CCS_3}")
      SET(CMAKE_CUDA_ARCHITECTURES ${CUDA_ARCH_LIST})
      set_property(GLOBAL PROPERTY CUDA_ARCHITECTURES "${CUDA_ARCH_LIST}")
    endif()

字符串

相关问题