似乎最近对 Thrust(CUDA 工具包的一部分)进行了更改,以使用编译时 CUDA 架构来标记
host_vector
类名称。当链接使用 Thrust 对象的共享对象(.cu
vs .cpp
文件)时,这会产生问题(未定义的引用),甚至仅托管像 host_vector
这样的对象。我不确定他们为什么要这样做。
我们有一个大型应用程序,在许多
host_vector
文件中使用 .cpp
,有人知道解决这个问题的好方法吗?我不认为使用 nvcc 编译所有内容是一种选择,有些文件需要 moc(即 Qt)。
要在带有 Cuda 12.6 的 Ubuntu 20.04.6 LTS 上重现:
主要.cpp
#include <cuda_runtime.h>
#include <thrust/host_vector.h>
bool cudaFunc(thrust::host_vector<int> &vec);
int main()
{
thrust::host_vector<int> vec;
cudaFunc(vec);
}
cudaFunc.cu
#include <cuda_runtime.h>
#include <thrust/host_vector.h>
bool cudaFunc(thrust::host_vector<int> &vec)
{
return true;
}
编译:
/usr/local/cuda/bin/nvcc -c cudaFunc.cu
g++ -I /usr/local/cuda/include -L /usr/local/cuda/targets/x86_64-linux/lib main.cpp cudaFunc.o -lcudart -ldl
会产生错误:
/usr/bin/ld: /tmp/cc5fFAJC.o: in function \`main':
main.cpp:(.text+0x30): undefined reference to \`cudaFunc(thrust::THRUST_200500___CUDA_ARCH_LIST___NS::host_vector\<int, std::allocator\<int\> \>&)'
collect2: error: ld returned 1 exit status
这将在 Ubuntu 20 和 Cuda 12.3 上正常链接。
@paleonix 谢谢您的回复。我下载了 cccl-2.6.1 并编译为:
/usr/local/cuda/bin/nvcc -c -Icccl-2.6.1/thrust -Icccl-2.6.1/libcudacxx/include -Icccl-2.6.1/cub cudaFunc.cu
g++ -Icccl-2.6.1/thrust -Icccl-2.6.1/libcudacxx/include -Icccl-2.6.1/cub -I/usr/local/cuda/include main.cpp cudaFunc.o -L/usr/local/cuda/targets/x86_64-linux/lib -lcudart -ldl
错误仍然存在:
/usr/bin/ld: /tmp/cc966x8Y.o: in function `main':
main.cpp:(.text+0x30): undefined reference to `cudaFunc(thrust::THRUST_200601___CUDA_ARCH_LIST___NS::host_vector<int, std::allocator<int> >&)'
collect2: error: ld returned 1 exit status
看来 cuda 架构已添加到推力对象的命名空间名称中,以避免与使用不同架构编译的共享库发生冲突,请参阅以下部分中的符号可见性: https://github.com/NVIDIA/cccl?tab=readme-ov-file#application-binary-interface-abi https://github.com/NVIDIA/cccl/issues/2737
因此,这本身并不是一个错误,而是最近为解决其他问题而进行的更改的预期副作用。
感谢 https://github.com/jrhemstad 和 https://forums.developer.nvidia.com/u/Robert_Crovella 的回答。