CMake + CUDA "invalid device function"即使使用正确的 SM 版本
CMake + CUDA "invalid device function" even with correct SM version
我在内核启动时不断收到"无效的设备功能"。 谷歌为此提供了大量的实例,但是所有这些实例似乎都与二进制文件中嵌入的嵌入式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 代码 1 - 要将 cuda 与静态和共享库一起使用,我需要针对与位置无关的代码进行编译并启用可分离的编译
我现在做的是:
- 确认我的泰坦 Xp 6.1 有 SM 5
-
强制 nvcc 生成兼容代码 3
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
我什至尝试将这里的所有 SM 版本编译到相同的二进制文件中,结果仍然相同。
似乎根据这个例子,嵌入 PTX 比仅仅使用 CMake 编译它要做更多的工作,所以现在我会对 SASS 版本感到满意。
我是否误解了上述任何信息?
"设备功能无效"错误还有其他可能的原因吗?
如果有帮助,我可以发布代码,但我觉得这更像是一个构建系统问题。
最终,正如预期的那样,这是由于构建系统设置问题。
TLDR 版本:
我设法通过使用我的 CUDA 代码将库从STATIC
更改为SHARED
来修复它。
为了修复它,我首先使用了来自 FindCuda CMake 的自动架构检测(它似乎已经创建了 SM 6.1,所以我在那里很担心(
cuda_select_nvcc_arch_flags(ARCH_FLAGS Auto)
list(APPEND CUDA_NVCC_FLAGS ${ARCH_FLAGS})
我正在将其集成到其中的应用程序是使用共享库进行模块化的。我无法直接在新模块中包含 .cu 文件,因为 nvcc 不喜欢某些编译标志。因此,我的目的是创建一个单独的静态库,其中只有 cuda 代码将链接到共享模块。但是,这似乎没有正确地将设备代码包含在共享库中(可能是因为它们与"普通"c ++ 链接器链接?
最终,这是我最终使用的代码:
add_library(cuda-interop SHARED [c++ only code])
file(GLOB cuda_SOURCES "modules/cudainterop/cuda/*.cu")
# the library that only has the cuda code
add_library(cuda-interop-cuda SHARED ${cuda_SOURCES})
set_target_properties(cuda-interop-cuda PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
set_target_properties(cuda-interop-cuda PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_link_libraries(cuda-interop PRIVATE cuda-interop-cuda)
相关文章:
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 导入库可以跨dll版本工作吗
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 在clang++预处理器中确定gcc工具链版本
- 码头化的C++应用程序是否向后兼容早期的内核版本
- 不同的Visual Studio版本中缺少.dll
- 用符号版本替换对函数的所有调用
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- 我需要分发哪些版本的可再分发文件
- CV_OCL_RUN宏如何在OpenCV(版本3.4.5)的goodFeaturesToTrack实现中工作?
- 在运行时读取 libstdc++ 版本
- 如何声明一个可以在整个程序中使用的全局 2d 3d 4d .. 数组(堆版本)变量?
- FindPackageHandleStandardArgs.cmake:137 的 CMake 错误(消息):找不到 Boost (缺少:正则表达式)(找到合适的版本"1.72.0",
- Vulkan SDK 版本 1.1.85.0 在 Kubuntu 18.10 上链接
- 如何正确实现与基类不同的版本?
- 从预处理器获取 Windows 版本(C++ Win32)
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 如何在C++中将 Python 字符串转换为其转义版本?
- CMake + CUDA "invalid device function"即使使用正确的 SM 版本