我正在努力学习如何在我的OptiX项目中实现C++。第一步是使用cuCtxGetCurrent(&some_CUcontext_variable)
获取当前的CUDA上下文,但是我得到了一个编译时错误,说明我对cuCtxGetCurrent
进行了一个未定义的引用。
我现在拥有的是:
main.cpp
)中,我包含了cuda_runtime.h
、device_launch_parameters.h
、optix.h
和optix_stubs.h
,但在编译时仍然会收到错误。CMakeLists.txt
中,我使用了find_package(CUDAToolkit REQUIRED)
来获取数据自动化系统。然后我使用target_link_libraries{ ... CUDA::cudart}
链接到数据自动化系统中。我相信这个错误与链接器有关,所以我假设我在我的CMakeLists中遗漏了什么,但我不知道是什么。请告诉我如何解决这个问题!
谢谢你们的帮助!
更新2:解决
就像这样的时刻让我不得不把我的头发拔出来:我所要做的就是把cuda
放在我的目标链接库中。不是-lcuda
或CUDA::cuda
,只有cuda
。不知怎么的,在驱动程序中有关联,现在看起来正在编译。
更新1:这是我的CMakeLists.txt
。
对不起,我原来的帖子中缺少代码。我试图避免粘贴大量的任意代码。
cmake_minimum_required(VERSION 3.17)
project(My_Project_Name CUDA CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_MODULE_PATH
"${CMAKE_SOURCE_DIR}/cmake"
${CMAKE_MODULE_PATH})
find_package(CUDAToolkit REQUIRED)
find_package(OptiX REQUIRED VERSION 7.0)
add_executable(
${PROJECT_NAME}
main.cpp [and other cpp and cu files])
# For project
set_target_properties(
${PROJECT_NAME}
PROPERTIES
CUDA_SEPARABLE_COMPILATION ON
)
target_compile_options(
${PROJECT_NAME}
PRIVATE
$<$<COMPILE_LANGUAGE:CUDA>:
-arch=sm_61
-gencode arch=compute_52,code=sm_52>
)
target_include_directories(
${PROJECT_NAME}
PRIVATE
include
${OptiX_INCLUDE}
)
target_link_libraries(
${PROJECT_NAME}
PRIVATE
CUDA::cudart
CUDA::cublas
)
发布于 2021-02-19 15:50:49
正如@talonmies注意到的,CUDA有两个(官方的)主机端API:"CUDA运行时API“和"CUDA驱动程序API";您可以看到它们之间的差异这里。
您已经提到了与Runtime相关的文件和CMake标识符:cuda_runtime.h
,CUDA::cudart
。但是- "CUDA上下文“是驱动程序API的概念,而cuCtxGetCurrent()
等是驱动程序API调用。
具体来说,“未定义的引用”确实是链接器错误。在你的情况下,你需要连接到数据自动化系统的驱动程序。作为一个库,在Linux系统上,这被称为libcuda.so
。要做到这一点,对于名为ERPT_Render_Engine
的可执行文件,需要添加以下命令:
target_link_libraries(ERPT_Render_Engine cuda)
我还要说,上面列出的CMakeLists.txt
看起来很奇怪,因为它定义了不存在的目标的依赖项--项目名称;相关的目标是您的可执行文件。
此外-一个CUDA上下文并不仅仅因为你创造了你的过程而存在。在使用cuCtxGetCurrent()
获得当前上下文之前,您需要初始化驱动程序,创建上下文并使其成为当前的--或者让其他东西为您做一些事情(比如库)。
最后,如果您感兴趣,我将开发一个C++包装器库,它涵盖(大部分)驱动程序和运行时API的主机端功能。一些示例代码:
cuda::initialize_driver();
(cuda::device::count() > 0) or die_("No CUDA devices on this system") {}
auto device_id = cuda::device::default_device_id;
auto device = cuda::device::get(device_id);
auto context = cuda::context::create(device);
//etc. etc.
但是再说一遍--你真的不用用这个,它只是可选的,而且还在信封里。
发布于 2022-07-24 00:14:42
使用普通的旧"cuda“可能有效,但它确实为您创建了一个"CUDA”目标供您使用,因此您可能应该使用它。我用的东西如下所示。
target_link_libraries(${TARGET_NAME}
PUBLIC CUDA::cudart
PUBLIC CUDA::cuda_driver
)
https://stackoverflow.com/questions/66273536
复制相似问题