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:
main.cpp
) I have included cuda_runtime.h
, device_launch_parameters.h
, optix.h
, and optix_stubs.h
, but I'm still getting the error at compile time.CMakeLists.txt
, I've used find_package(CUDAToolkit REQUIRED)
to get CUDA. I then used target_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!
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.
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, and cuCtxGetCurrent()
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 named ERPT_Render_Engine
, you need to add the command:
target_link_libraries(ERPT_Render_Engine cuda)
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:
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.
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.