玩具计划:
nvcc -arch=sm_52 -std=c++11 cuda_invalid_symbol_error.cu -o cuda_invalid_symbol_error
编译
nvcc -gencode arch=compute_52,code=sm_52 -std=c++11 cuda_invalid_symbol_error.cu -o cuda_invalid_symbol_error
在运行时不会出现任何错误。但是,用
MemcpyToSymbol error: invalid device symbol
它将失败并显示消息df
。
为什么后面的编译指令会给出运行时错误?
规格:cuda 8.0,Ubuntu 16.04,GeForce GTX 1060(我知道这张卡的cc是6.1)。
答案 0 :(得分:1)
为什么后面的编译指令会给出运行时错误?
-arch=sm_xx
shorthand为:
-gencode arch=compute_xx,code=sm_xx -gencode arch=compute_xx,code=compute_xx
在您的情况下,xx
为52,此命令将嵌入cc 5.2 PTX代码(第二个gencode
实例)和cc 5.2 SASS代码(第一个gencode
实例)。 cc 5.2的SASS代码不能在cc6.1设备上运行,因此运行时JIT编译cc 5.2 PTX代码以创建与cc 6.1体系结构兼容的对象。一切都很开心,一切正常。
当您使用:
进行编译时nvcc -gencode arch=compute_52,code=sm_52 ...
您正在从编译对象中省略PTX代码。仅存在cc 5.2 SASS代码。此代码不会在您的cc6.1设备上运行,并且运行时没有其他选项,因此当运行时尝试加载程序的GPU映像时,会发生NO_BINARY_FOR_GPU的“隐藏”错误。由于没有加载图像,因此没有设备符号存在/可用。由于它不存在/不可用,因此当您尝试使用CUDA运行时API引用它时会出现invalid device symbol
错误。
如果您在此之前执行了另一个CUDA运行时API调用,这会强制执行CUDA运行时的足够或等效的初始化(并检查返回的错误代码),那么您将收到NO_BINARY_FOR_GPU错误或类似错误。当然,例如,如果您尝试启动GPU内核,则会收到该错误。可能还有其他CUDA运行时API调用会强制执行等效或足够级别的延迟初始化,但我没有这些调用列表。