CMake + CUDA“无效的设备功能”,即使SM版本正确

时间:2019-09-12 22:10:32

标签: c++ cmake cuda

在内核启动时,我一直得到“无效的设备功能”。 Google为此提供了很多实例,但是它们似乎都与二进制文件中嵌入的SASS / PTX代码不匹配有关。

我了解它如何工作的方式是:

  • SASS代码只能由具有完全相同的SM版本2的GPU解释
  • PTX代码是向前兼容的,也就是说,任何较新的GPU都可以运行该代码(但是,驱动程序需要JIT)2
  • 我需要通过将合适的-arch命令传递给nvcc来指定要定位的对象:-gencode arch=compute_30,code=sm_30将创建一个定位SM 3.0的SASS,-gencode arch=compute_60,code=compute_60将创建一个PTX代码{{3 }}
  • 要将cuda与静态库和共享库一起使用,我需要编译位置无关的代码并启用可分离的编译

我现在要做的是:

  • 确认我的Titan Xp 1具有SM 6.1
  • 强制nvcc生成兼容代码5

    set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -gencode arch=compute_61,code=sm_61 -gencode arch=compute_61,code=compute_61 -gencode arch=compute_30,code=sm_30 -gencode arch=compute_30,code=compute_30")
    
  • 确认使用cuobjdump将其编译到我的目标文件中:

    ./cuobjdump /mnt/linuxdata/campvis-nx/build/bin/libcuda-interop-cuda.a 
    
    member /mnt/linuxdata/campvis-nx/build/bin/libcuda-interop-cuda.a:test.cu.o:
    
    Fatbin ptx code:
    ================
    arch = sm_61
    code version = [6,4]
    producer = <unknown>
    host = linux
    compile_size = 64bit
    compressed
    ptxasOptions = --compile-only  
    
    Fatbin elf code:
    ================
    arch = sm_61
    code version = [1,7]
    producer = <unknown>
    host = linux
    compile_size = 64bit
    compressed
    
    Fatbin ptx code:
    ================
    arch = sm_30
    code version = [6,4]
    producer = <unknown>
    host = linux
    compile_size = 64bit
    compressed
    ptxasOptions = --compile-only  
    
    Fatbin elf code:
    ================
    arch = sm_30
    code version = [1,7]
    producer = <unknown>
    host = linux
    compile_size = 64bit
    compressed
    
    member /mnt/linuxdata/campvis-nx/build/bin/libcuda-interop-cuda.a:mocs_compilation.cpp.o:
    
  • 意识到只有一部分(SASS部分?)链接到我的共享库中(为什么?):

    ./cuobjdump /mnt/linuxdata/campvis-nx/build/bin/libcampvis-modules.so 
    
    Fatbin elf code:
    ================
    arch = sm_61
    code version = [1,7]
    producer = <unknown>
    host = linux
    compile_size = 64bit
    
    Fatbin elf code:
    ================
    arch = sm_30
    code version = [1,7]
    producer = <unknown>
    host = linux
    compile_size = 64bit
    

我什至尝试将3中的所有SM版本编译为相同的二进制文件,结果仍然相同。

here看来,嵌入PTX不仅需要使用CMake对其进行编译,还需要做更多的工作,所以到目前为止,我对SASS版本感到满意。

我是否误解了以上任何信息?

“设备功能无效”错误还有其他可能原因吗?

如果有帮助,我可以发布代码,但我觉得这更多是构建系统问题。

1 个答案:

答案 0 :(得分:0)

最终,正如预期的那样,这是由于构建系统设置问题所致。

TLDR版本:
我设法通过使用我的CUDA代码将库从$someJSON = '[{"id": 1,"gender":"male"},{"id": 3,"gender":"other"}]'; 更改为STATIC来对其进行了修复。

要解决此问题,我首先使用了FindCuda CMake中的自动体系结构检测功能(它似乎已经创建了SM 6.1,所以我至少在那儿了)

SHARED

我将其集成到其中的应用程序使用共享库进行了模块化。我无法直接在新模块中包括.cu文件,因为nvcc不喜欢某些编译标志。因此,我的意图是创建一个单独的静态库,其中仅包含将链接到共享模块的cuda代码。但是,这似乎没有将设备代码正确地包含到共享库中(可能是因为它们是通过“常规” c ++链接器链接的?)。

最终,这是我最终使用的代码:

cuda_select_nvcc_arch_flags(ARCH_FLAGS Auto)
list(APPEND CUDA_NVCC_FLAGS ${ARCH_FLAGS})