创建与C+链接的静态CUDA库+;程序 我试图将CUDA内核与C++ AutoToo工具项目链接,但似乎无法通过链接阶段。

创建与C+链接的静态CUDA库+;程序 我试图将CUDA内核与C++ AutoToo工具项目链接,但似乎无法通过链接阶段。,c++,cuda,C++,Cuda,我有一个文件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/loca

我有一个文件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函数是我的包装函数

这有可能吗

是的,有可能。并且围绕它创建一个(非CUDA)包装函数使它变得更加容易。如果您依赖C++链接(您可以提到包装器C函数),那么您可以使您的生活更轻松。MPICXX是C++编译器/链接器别名,默认情况下CUDA文件(.Cu)遵循C++编译器/链接器行为。一个非常简单的问题,讨论如何将cuda代码(封装在包装器函数中)构建到静态库中

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

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

编辑:

现在还不清楚您是否需要使用设备链接来完成您想要做的事情。(但这是可以接受的,只是让事情复杂了一点。)无论如何,既然您已经展示了命令序列,那么您对库的构造就不太正确。“设备链接”命令生成一个设备可链接对象,该对象不包括所有必需的主机部件。为了将所有内容放在一个地方,我们希望将GPUFloydWarshall.o(具有设备链接的片段)和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
$
$cat GPUFloydWarshall.cu
#包括
__全局_uu; void mykernel(){
printf(“hello\n”);
}
无效gpu_fw(){
mykernel();
cudaDeviceSynchronize();
}
$cat main.cpp
#包括
无效gpu_fw();
int main(){
gpu_fw();
}
$nvcc-rdc=true-c-o温度o GPUFloydWarshall.cu
$nvcc-dlink-o GPUFloydwar.o温度o-lcudart
$rm-f libgpu.a
$ar cru libgpu.a GPUFloydwar.o温度o
$ranlib libgpu.a
$g++main.cpp-L.-lgpu-o main-L/usr/local/cuda/lib64-lcudart
美元/主要
你好
$

我不太清楚我是否理解,主要是因为自动工具为我生成了库。我已经编辑了我的原始问题,加入了额外的细节,希望能让事情变得更清楚一些。按照这种方法,我现在可以成功地编译代码了。然而,执行时会产生以下错误。“文件GPUFloydWarshall.cu中第84行的错误无效设备功能”。这是否意味着内核没有被编译?我知道内核是正确的,因为我已经在它自己的外部测试了它。所以它不是一个真正的聊天室。你现在有一个不同的问题。建议您发布一个新问题。内核已编译,但体系结构/目标与运行它的GPU不匹配。需要其他详细信息,如实际编译命令、正在运行的GPU、CUDA版本等。如果未指定
-arch
开关(即默认值为
-arch=sm_20
),CUDA 6.5默认为针对cc2.0设备编译。如果您按照上面所示进行编译,然后尝试在cc1.x设备上运行,您可能会收到指示的错误消息(“无效的设备函数”)