I'm trying to learn how to implement OptiX into my C++ project. One of the first steps is to get the current CUDA context with cuCtxGetCurrent(&some_CUcontext_variable)
, however I'm getting a compile time error saying that I've made an undefined reference to cuCtxGetCurrent
.
Here's what I have:
- I'm following code from this repo to learn about OptiX and I'm on example 2 (where you get the CUDA context).
- In my code (
main.cpp
) I have includedcuda_runtime.h
,device_launch_parameters.h
,optix.h
, andoptix_stubs.h
, but I'm still getting the error at compile time. - Interestingly, my IDE, JetBrains' CLion, is not showing any undefined reference errors/warnings inline. Errors only show up when I compile.
- In my
CMakeLists.txt
, I've usedfind_package(CUDAToolkit REQUIRED)
to get CUDA. I then usedtarget_link_libraries{ ... CUDA::cudart}
to link in CUDA.
I believe this error is linker related, so I'm assume I'm missing something in my CMakeLists, but I don't know what. Please let me know how I can fix this issue!
Thank you in advanced for your help!
Update #2: Solved
It's moments like this make make me pull my hair out: all I had to do with literally put cuda
in my target link libraries. Not -lcuda
or CUDA::cuda
, just cuda
. Somehow that linked in the drivers and it looks to be compiling now.
[OLD, BUT KEPT FOR REFERENCE] Update #1: Here's my CMakeLists.txt
.
Sorry for the lack of code in my original post. I was trying to avoid pasting large chunks of arbitrary code.
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
)
As @talonmies notes, CUDA has two (official) host-side APIs: The "CUDA Runtime API" and the "CUDA Driver API"; you can read about the difference between them here.
You have mentioned files and CMake identifiers relating to the Runtime API:
cuda_runtime.h
,CUDA::cudart
. But - "CUDA Contexts" are concepts of the Driver API, andcuCtxGetCurrent()
etc. are driver API calls.Specifically, an "undefined reference" is indeed a linker error. In your case, you need to link with the CUDA driver. As a library, on Linux systems, that's called
libcuda.so
. For that to happen, and for your executable namedERPT_Render_Engine
, you need to add the command:I'll also say that the
CMakeLists.txt
you listed above looks weird, because it defines dependencies for a target that doesn't exist - the project name; your relevant target is your executable.Additionally - a CUDA context doesn't exist merely by virtue of you creating your process. You need to initialize the driver, create a context and make it current - or have something else do that for you (like a library) - before you can obtain the current context using
cuCtxGetCurrent()
.Finally, and in case you're interested, I am the author of the C++ cuda-api-wrappers library, which covers (most of) the host-side functionality of both the driver and runtime APIs. Some example code:
and when you using it within CMake (explained on the repository page), the dependencies are taken care of. But again - you really don't have to use this, it's just a convenience.