创建要与C ++程序链接的静态CUDA库

时间:2014-11-12 18:07:21

标签: c++ cuda

我正在尝试将CUDA内核与C ++ autotools项目链接,但似乎无法通过链接阶段。

我有一个文件GPUFloydWarshall.cu,它包含内核和一个包装器C函数,我想放入库libgpu.a。这将与项目的其余部分保持一致。这有可能吗?

其次,然后需要将库链接到主要可执行文件的大约十个其他库,目前使用mpicxx。

目前我正在使用/生成以下命令来编译和创建libgpu.a库

nvcc   -rdc=true -c -o temp.o GPUFloydWarshall.cu
nvcc -dlink -o GPUFloydWarshall.o temp.o -L/usr/local/cuda/lib64 -lcuda -lcudart
rm -f libgpu.a
ar cru libgpu.a GPUFloydWarshall.o
ranlib libgpu.a

当这全部链接到主可执行文件时,我收到以下错误

problem/libproblem.a(libproblem_a-UTRP.o): In function `UTRP::evaluate(Solution&)':
UTRP.cpp:(.text+0x1220): undefined reference to `gpu_fw(double*, int)'

gpu_fw函数是我的包装函数。

1 个答案:

答案 0 :(得分:4)

  

这一切都可能吗?

是的,这是可能的。并且围绕它创建(非CUDA)包装函数使其更加容易。如果你依赖于C ++链接(你提到了一个包装器C函数),你可以让你的生活更轻松。 mpicxx是C ++编译器/链接器别名,cuda文件(.cu)默认遵循C ++编译器/链接器行为。 Here's一个非常简单的问题,讨论将cuda代码(封装在包装函数中)构建到静态库中。

  

其次,然后需要将库链接到主要可执行文件的大约十个其他库,目前使用mpicxx。

一旦你的库中暴露了C / C ++(非CUDA)包装器,链接应该与普通库的普通链接没有什么不同。您可能仍需要在链接步骤中传递cuda运行时库和您可能正在使用的任何其他cuda库,但这与您的项目可能依赖的任何其他库在概念上相同。

修改

您不清楚是否需要使用设备链接来完成您想要的操作。 (但它是可以接受的,它只会让事情变得复杂。)无论如何,你的库的构造并不完全正确,因为你已经显示了命令序列。 device link命令生成一个设备可链接对象,该对象不包含所有必需的主机片段。为了将所有内容集中在一个地方,我们希望将GPUFloydWarshall.o(具有设备链接的部分) AND temp.o(具有主机代码片段)添加到库中。

这是一个功能齐全的例子:

$ cat GPUFloydWarshall.cu
#include <stdio.h>

__global__ void mykernel(){
  printf("hello\n");
}

void gpu_fw(){
  mykernel<<<1,1>>>();
  cudaDeviceSynchronize();
}


$ cat main.cpp
#include <stdio.h>

void gpu_fw();

int main(){

  gpu_fw();
}

$ nvcc   -rdc=true -c -o temp.o GPUFloydWarshall.cu
$ nvcc -dlink -o GPUFloydWarshall.o temp.o -lcudart
$ rm -f libgpu.a
$ ar cru libgpu.a GPUFloydWarshall.o temp.o
$ ranlib libgpu.a
$ g++ main.cpp -L. -lgpu -o main -L/usr/local/cuda/lib64 -lcudart
$ ./main
hello
$