【发布时间】:2020-04-09 02:21:03
【问题描述】:
我有一个包含一些 __host__ __device__ 函数的库。我还有一个 #ifdef __CUDACC__ 小工具,它可以确保常规 C++ 编译器看不到 __host__ __device__,从而可以编译这些函数。
现在,我想在普通 C++ 静态库文件(Linux 上的.a)中使用库函数的编译主机端版本——我什至希望在 CUDA 不可用时可以编译该库;我希望在单独的静态库中编译设备端版本。
我快到了(我想),但遇到链接错误。以下是此类库的玩具源代码、测试程序(调用设备端和主机端版本的函数)和我使用的构建命令。
我做错了什么?
-
my_lib.hpp(库头):
#ifdef __CUDACC__
__host__ __device__
#endif
void foo(int*x, int* y);
int bar();
-
my_lib.cu(库来源):
#include "my_lib.hpp"
#ifdef __CUDACC__
__host__ __device__
#endif
void foo(int*x, int* y) { *x = *y; }
int bar() { return 5; }
-
main.cu(测试程序):
#include "my_lib.hpp"
__global__ void my_kernel() {
int z { 78 };
int w { 90 };
foo(&z,&w);
}
int main() {
int z { 123 };
int w { 456 };
foo(&z,&w);
my_kernel<<<1,1>>>();
cudaDeviceSynchronize();
cudaDeviceReset();
}
我的构建命令:
c++ -c -x c++ -o my_lib-noncuda.o my_lib.cu
ar qc my_lib-noncuda.a my_lib-noncuda.o
ranlib my_lib-noncuda.a
nvcc -dc -o my_lib-cuda.o my_lib.cu
ar qc my_lib-cuda.a my_lib-cuda.o
ranlib my_lib-cuda.a
nvcc -dc -o main.rdc.o main.cu
nvcc -dlink -o main.o main.rdc.o my_lib-cuda.a
c++ -o main main.o my_lib-noncuda.a -lcudart
以及我得到的错误 - 最后一个,链接,命令:
/usr/bin/ld: main.o: in function `__cudaRegisterLinkedBinary_39_tmpxft_00003f88_00000000_6_main_cpp1_ii_e7ab3416':
link.stub:(.text+0x5a): undefined reference to `__fatbinwrap_39_tmpxft_00003f88_00000000_6_main_cpp1_ii_e7ab3416'
/usr/bin/ld: main.o: in function `__cudaRegisterLinkedBinary_41_tmpxft_00003f69_00000000_6_my_lib_cpp1_ii_ab44b3f6':
link.stub:(.text+0xaa): undefined reference to `__fatbinwrap_41_tmpxft_00003f69_00000000_6_my_lib_cpp1_ii_ab44b3f6'
collect2: error: ld returned 1 exit status
注意事项:
- 我在 Devuan GNU/Linux 上使用 CUDA 10.1 和 g++ 9.2.1。
- 这是对已删除问题的“跟进”; @talonmies 评论说我最好准确地展示我的所作所为;这在一定程度上改变了问题。
- 有点相关的问题:this one。
【问题讨论】:
-
@talonmies:现在我向你展示我正在做的事情。
-
该示例超出了您描述的错误。在该构建序列中的任何地方都不应该发出 main 并且应该也应该有一个 main not found 错误,除非我读错了
-
@talonmies:嗯,错误就是这样,虽然我明白你对
main()和-dc的意思。问题是,如果我删除-dc,我会得到一个编译错误:nvcc -o main.o main.cu导致Unresolved extern function '_Z3fooPiS_'。 -
我对你想做什么感到困惑。我以为您想将“普通 C++ 静态库文件”链接到 C++ 程序。但正如我所见,您希望在最后一步中使用 C++ 编译器仅用于链接,并且仍然存在所有 CUDA 内容。也许这就是你要找的东西:devblogs.nvidia.com/… - “高级用法:使用不同的链接器”部分
-
@Shadow:不完全是。我想要一个“拆分库”:一个包含主机端版本函数的
.a文件,无论CUDA如何,我都可以在常规C++链接中使用它;和另一个.a文件,它是设备端版本的函数,我可以将其与从内核中调用这些函数的CUDA 代码链接。测试程序举例说明了第二种使用方式。
标签: c++ cuda linker static-libraries unresolved-external