为 OptiX 获取 CUDA 上下文时未定义对 `cuCtxGetCurrent` 的引用
undefined reference to `cuCtxGetCurrent` while getting CUDA context for OptiX
我正在尝试学习如何将 OptiX 实施到我的 C++ 项目中。第一步是使用 cuCtxGetCurrent(&some_CUcontext_variable)
获取当前 CUDA 上下文,但是我收到一个编译时错误,指出我对 cuCtxGetCurrent
.
进行了未定义的引用
这是我的:
- 我正在按照 this repo 中的代码来了解 OptiX,我在示例 2 中(您在其中获得 CUDA 上下文)。
- 在我的代码 (
main.cpp
) 中,我包含了 cuda_runtime.h
、device_launch_parameters.h
、optix.h
和 optix_stubs.h
,但我仍然得到编译时出错。
- 有趣的是,我的 IDE、JetBrains 的 CLion 没有显示任何未定义的内联引用 errors/warnings。只有在我编译时才会出现错误。
- 在我的
CMakeLists.txt
中,我使用 find_package(CUDAToolkit REQUIRED)
获取 CUDA。然后我在 CUDA 中使用 target_link_libraries{ ... CUDA::cudart}
到 link。
我认为这个错误与 linker 相关,所以我假设我的 CMakeLists 中遗漏了一些东西,但我不知道是什么。请告诉我如何解决这个问题!
在此先感谢您的帮助!
更新 #2:已解决
像这样的时刻让我惊慌失措:我所要做的只是将 cuda
直接放入我的目标 link 库中。不是 -lcuda
或 CUDA::cuda
,只是 cuda
。 link 以某种方式在驱动程序中编辑,现在看起来正在编译。
[旧的,但保留以供参考] 更新 #1:这是我的 CMakeLists.txt
。
很抱歉我的原始代码中缺少代码 post。我试图避免粘贴大块的任意代码。
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
)
正如@talonmies 所说,CUDA 有两个(官方)主机端 API:“CUDA 运行时 API”和“CUDA 驱动程序 API”;你可以阅读它们之间的区别 here.
您提到了与运行时相关的文件和 CMake 标识符 API:cuda_runtime.h
、CUDA::cudart
。但是 - “CUDA 上下文”是驱动程序 API 的概念,cuCtxGetCurrent()
等是驱动程序 API 调用。
具体来说,“未定义的引用”确实是一个 linker 错误。在您的情况下,您需要 link 使用 CUDA 驱动程序。作为一个库,在 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.
但同样 - 你真的不必使用它,它只是可选的并且仍在开发中。
我正在尝试学习如何将 OptiX 实施到我的 C++ 项目中。第一步是使用 cuCtxGetCurrent(&some_CUcontext_variable)
获取当前 CUDA 上下文,但是我收到一个编译时错误,指出我对 cuCtxGetCurrent
.
这是我的:
- 我正在按照 this repo 中的代码来了解 OptiX,我在示例 2 中(您在其中获得 CUDA 上下文)。
- 在我的代码 (
main.cpp
) 中,我包含了cuda_runtime.h
、device_launch_parameters.h
、optix.h
和optix_stubs.h
,但我仍然得到编译时出错。 - 有趣的是,我的 IDE、JetBrains 的 CLion 没有显示任何未定义的内联引用 errors/warnings。只有在我编译时才会出现错误。
- 在我的
CMakeLists.txt
中,我使用find_package(CUDAToolkit REQUIRED)
获取 CUDA。然后我在 CUDA 中使用target_link_libraries{ ... CUDA::cudart}
到 link。
我认为这个错误与 linker 相关,所以我假设我的 CMakeLists 中遗漏了一些东西,但我不知道是什么。请告诉我如何解决这个问题!
在此先感谢您的帮助!
更新 #2:已解决
像这样的时刻让我惊慌失措:我所要做的只是将 cuda
直接放入我的目标 link 库中。不是 -lcuda
或 CUDA::cuda
,只是 cuda
。 link 以某种方式在驱动程序中编辑,现在看起来正在编译。
[旧的,但保留以供参考] 更新 #1:这是我的 CMakeLists.txt
。
很抱歉我的原始代码中缺少代码 post。我试图避免粘贴大块的任意代码。
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
)
正如@talonmies 所说,CUDA 有两个(官方)主机端 API:“CUDA 运行时 API”和“CUDA 驱动程序 API”;你可以阅读它们之间的区别 here.
您提到了与运行时相关的文件和 CMake 标识符 API:cuda_runtime.h
、CUDA::cudart
。但是 - “CUDA 上下文”是驱动程序 API 的概念,cuCtxGetCurrent()
等是驱动程序 API 调用。
具体来说,“未定义的引用”确实是一个 linker 错误。在您的情况下,您需要 link 使用 CUDA 驱动程序。作为一个库,在 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.
但同样 - 你真的不必使用它,它只是可选的并且仍在开发中。