我想知道如何使用CMake动态链接CUDA库,我知道这似乎需要一些额外的限制,但不知 prop 体如何操作。下面是我写的一个简单的例子来说明我的问题。
目录结构:
Dir/
├── CMakeLists.txt
├── header.cuh
├── kernel.cu
└── main.cpp
环境:
- 操作系统:Windows 11
- GPU:RTX 3060笔记本电脑
- CUDA工具包:11.6
- 平台:Visual Studio 2022
标题.cuh:
#include "stdio.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
extern "C" void f();
内核.cu:
#include "header.cuh"
void __global__ print()
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
printf("%d\n", idx);
}
void f()
{
print<<<1, 10>>>();
}
主要cpp:
#include "header.cuh"
extern "C" void f();
int main()
{
f();
return 0;
}
CMakeLists.文本文件:
cmake_minimum_required(VERSION 3.17)
project(test)
set(CMAKE_CXX_STANDARD 17)
find_package(CUDA REQUIRED)
enable_language("CUDA")
set(CMAKE_CUDA_STANDARD 14)
set(CUDA_SEPARABLE_COMPILATION ON)
string(APPEND CMAKE_CUDA_FLAGS " -rdc=true --cudart shared")
add_library(CUDA_COMP SHARED header.cuh kernel.cu)
set_property(TARGET CUDA_COMP PROPERTY CUDA_ARCHITECTURES 86-real 86-virtual)
add_executable(main main.cpp)
target_link_libraries(main CUDA_COMP)
项目可以配置成功,但是在构建时出现了函数main中引用的外部符号f无法解析的问题。
我也在Stackoverflow上查找了相应的解决方案,但是没有成功,例如,Stackoverflow上的一个答案提到在cmake中添加**”-rdc=true --cudart shared”,我也做了同样的操作(参见CMakeLists.txt的第10行**)。
这个问题困扰我很久了,希望您能告诉我问题的原因和解决方法,非常感谢!
1条答案
按热度按时间5gfr0r5j1#
OP的代码有很多问题。
CUDA/C++问题:
f()
声明为extern "C"
。.cpp
文件),它应该被命名为.h
(或.hpp
)。我希望.cuh
文件只包含在.cu
文件中。人们通常也会在接口和实现上使用相同的名称,所以我将头文件重命名为kernel.h
。main.cpp
中重新声明f()
?这就是头文件的作用。C制造问题:
CMakeLists.txt
中全局设置属性等。应该尽可能使用特定于目标的API。这些全局属性中的一些必须在project()
之前设置才能工作。CUDA_SEPARABLE_COMPILATION
时自动设置-rdc=true
。CUDA_RUNTIME_LIBRARY
属性用于动态链接CUDA运行时。find_package(CUDA)
,而赞成使用CUDA
作为语言。在极少数情况下,一个人不想使用CUDA
,但仍然需要找到CUDA工具包,还有FindCUDAToolkit
。OP只需要语言。但是链接的文档也列出了工具包附带的所有CUDA库。在这里我们可以看到,大多数库都提供了_static
版本来区分静态链接和动态链接。当使用CUDA
时,也可以使用CUDA::
版本,但是没有CUDA::
“命名空间”。当使用语言时,不要使用target_link_libraries(... cudart)
**,因为这不会影响CUDA_RUNTIME_LIBRARY
属性,也就是说,你可能会得到某种未定义的CMake行为。但是,当你想动态链接时,例如CUBLAS,你可以使用target_link_libraries(... cublas)
。CMakeLists.txt
中。相反,应在配置时指定架构。CMake 3.18在版本中添加了CMAKE_CUDA_ARCHITECTURES
,因此我建议将最低配置设置为3.18而不是3.17。然后,您可以调用cmake -DCMAKE_CUDA_ARCHITECTURES=86
(不确定这在VisualStudio中是如何处理的)。我为X1 M28 N1 X添加了一个默认值,在需要时仍然可以在配置时覆盖它。固定示例
以下文件适用于Linux下的CMake 3.23.1、CUDA 11.8.0和GCC 11.3.0:
kernel.h
:kernel.cu
:main.cpp
:CMakeLists.txt
: