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

Creating a static CUDA library to be linked with a C++ program

本文关键字:静态 CUDA 链接 程序 C++ 创建      更新时间:2023-10-16

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

我有一个文件 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 库,但这在概念上与您的项目可能依赖的任何其他库相同。

编辑:

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

这是一个完整的示例:

$ cat GPUFloydWarshall.cu
#include <stdio.h>
__global__ void mykernel(){
  printf("hellon");
}
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
$