问题描述
我正在尝试构建以下程序:
#include <iostream>
#include <cuda.h>
int main() {
const char* str;
auto status = cuInit(0);
cuGetErrorString(status,&str);
std::cout << "status = " << str << std::endl;
int device_id = 0;
CUcontext primary_context_id;
status = cuDevicePrimaryCtxRetain(&primary_context_id,device_id);
cuGetErrorString(status,&str);
std::cout << "status = " << str << std::endl;
status = cuDevicePrimaryCtxRelease(device_id);
cuGetErrorString(status,&str);
std::cout << "status = " << str << std::endl;
}
编译总是很顺利;但是,使用 CUDA 10.2,链接工作,而使用 CUDA 11.2,我得到:
/usr/bin/ld: a.o: in function `main':
a.cpp:(.text+0xcc): undefined reference to `cuDevicePrimaryCtxRelease_v2'
collect2: error: ld returned 1 exit status
为什么会发生这种情况,我该如何解决?
注意:我使用的是 Devuan Beowulf 驱动程序版本 440.82(尚未安装 CUDA 11.2 的新驱动程序)。
解决方法
好吧,我想我知道为什么会发生这种情况。
这是关于如何定义 cuDevicePrimaryCtxRelease()
。让我们跑起来:
grep PrimaryCtxRelease /usr/local/cuda/include/cuda.h | grep -v "^ "
在 CUDA 10.2 中,我们得到:
CUresult CUDAAPI cuDevicePrimaryCtxRelease(CUdevice dev);
在 CUDA 11.2 中,我们得到:
#define cuDevicePrimaryCtxRelease cuDevicePrimaryCtxRelease_v2
CUresult CUDAAPI cuDevicePrimaryCtxRelease(CUdevice dev);
即 API 名称已更改,但头文件为新名称保留了别名。 (我会说这是一段令人困惑的代码。)
现在,让我们使用 objdump -t | c++filt | grep cu
查看我在两个不同版本的 CUDA 中获得的目标文件。使用 CUDA 10.2,它是:
0000000000000000 *UND* 0000000000000000 cuInit
0000000000000000 *UND* 0000000000000000 cuGetErrorString
0000000000000000 *UND* 0000000000000000 cuDevicePrimaryCtxRetain
0000000000000000 *UND* 0000000000000000 cuDevicePrimaryCtxRelease
使用 CUDA 11.2 时:
0000000000000000 *UND* 0000000000000000 cuInit
0000000000000000 *UND* 0000000000000000 cuGetErrorString
0000000000000000 *UND* 0000000000000000 cuDevicePrimaryCtxRetain
0000000000000000 *UND* 0000000000000000 cuDevicePrimaryCtxRelease_v2
(注意 _v2
)。
所以很可能是安装的驱动程序只包含非_v2
符号,因此是未定义的符号。
我仍然希望得到帮助的是如何解决此问题,而不是更新驱动程序。