Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 37 additions & 6 deletions src/cmake/externalpackages.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,42 @@ if (OSL_USE_OPTIX)
message (STATUS "CUDA_TOOLKIT_ROOT_DIR = ${CUDA_TOOLKIT_ROOT_DIR}")
endif ()

checked_find_package (CUDA REQUIRED
if (CUDA_TOOLKIT_ROOT_DIR)
set (CUDAToolkit_ROOT "${CUDA_TOOLKIT_ROOT_DIR}")
endif ()

checked_find_package (CUDAToolkit REQUIRED
VERSION_MIN 9.0
RECOMMEND_MIN 11.0
RECOMMEND_MIN_REASON
"We don't actively test CUDA older than 11"
PRINT CUDA_INCLUDES)
set (CUDA_INCLUDES ${CUDA_TOOLKIT_ROOT_DIR}/include)
include_directories (BEFORE "${CUDA_INCLUDES}")
PRINT CUDAToolkit_INCLUDE_DIRS CUDAToolkit_NVCC_EXECUTABLE)

# Compatibility bridge: legacy CUDA variables.
set (CUDA_FOUND ${CUDAToolkit_FOUND})
set (CUDA_VERSION ${CUDAToolkit_VERSION})
set (CUDA_INCLUDES ${CUDAToolkit_INCLUDE_DIRS})
if (CUDA_INCLUDES)
list (GET CUDA_INCLUDES 0 CUDA_INCLUDES)
endif ()

# Derive the root dir. See https://cmake.org/cmake/help/latest/module/FindCUDAToolkit.html
if (CUDAToolkit_LIBRARY_ROOT)
set (CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_LIBRARY_ROOT}")
elseif (CUDAToolkit_TARGET_DIR)
set (CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_TARGET_DIR}")
elseif (CUDAToolkit_BIN_DIR)
get_filename_component (CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_BIN_DIR}" DIRECTORY)
Comment on lines +141 to +146
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CUDA_TOOLKIT_ROOT_DIR is later treated as a full toolkit root (used for --cuda-path=..., .../bin nvcc lookup, and .../lib64 paths). Setting it from CUDAToolkit_LIBRARY_ROOT can be inconsistent with those uses on toolkits where the library root is not the same as the toolkit root. Consider preferring CUDAToolkit_TARGET_DIR (or deriving from CUDAToolkit_BIN_DIR) for CUDA_TOOLKIT_ROOT_DIR, and using CUDAToolkit_LIBRARY_ROOT only for library searches.

Suggested change
if (CUDAToolkit_LIBRARY_ROOT)
set (CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_LIBRARY_ROOT}")
elseif (CUDAToolkit_TARGET_DIR)
set (CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_TARGET_DIR}")
elseif (CUDAToolkit_BIN_DIR)
get_filename_component (CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_BIN_DIR}" DIRECTORY)
if (CUDAToolkit_TARGET_DIR)
set (CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_TARGET_DIR}")
elseif (CUDAToolkit_BIN_DIR)
get_filename_component (CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_BIN_DIR}" DIRECTORY)
elseif (CUDAToolkit_LIBRARY_ROOT)
# Fallback: library root may not always equal the full toolkit root,
# but is used here as a last-resort compatibility measure.
set (CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_LIBRARY_ROOT}")

Copilot uses AI. Check for mistakes.
endif ()
if (NOT CUDA_TOOLKIT_ROOT_DIR)
message (FATAL_ERROR "Could not determine CUDA toolkit root directory.")
endif ()

if (CUDAToolkit_NVCC_EXECUTABLE)
set (CUDA_NVCC_EXECUTABLE "${CUDAToolkit_NVCC_EXECUTABLE}")
else ()
find_program (CUDA_NVCC_EXECUTABLE NAMES nvcc HINTS "${CUDA_TOOLKIT_ROOT_DIR}/bin")
endif ()

STRING (FIND ${LLVM_TARGETS} "NVPTX" nvptx_index)
if (NOT ${nvptx_index} GREATER -1)
Expand All @@ -138,7 +166,11 @@ if (OSL_USE_OPTIX)
# suffixes earlier in the suffix list. Don't forget to restore after
# so that this only applies to these library searches right here.
set (save_lib_path ${CMAKE_FIND_LIBRARY_SUFFIXES})
if (CUDA_PREFER_STATIC_LIBS)
if (CUDA_PREFER_STATIC_LIBS AND TARGET CUDA::cudart_static)
set (cudart_lib CUDA::cudart_static)
elseif (TARGET CUDA::cudart)
set (cudart_lib CUDA::cudart)
elseif (CUDA_PREFER_STATIC_LIBS)
set (CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
find_library(cudart_lib REQUIRED
NAMES cudart_static cudart
Expand All @@ -148,7 +180,6 @@ if (OSL_USE_OPTIX)
NAMES cudart
PATHS "${CUDA_TOOLKIT_ROOT_DIR}/lib64" "${CUDA_TOOLKIT_ROOT_DIR}/x64" "${CUDA_TOOLKIT_ROOT_DIR}/lib/x64")
endif ()
# Is it really a good idea to completely reset CUDA_LIBRARIES here?
set(CUDA_LIBRARIES ${cudart_lib})
set(CUDA_EXTRA_LIBS ${CUDA_EXTRA_LIBS} dl rt)
set (CMAKE_FIND_LIBRARY_SUFFIXES ${save_lib_path})
Expand Down
32 changes: 30 additions & 2 deletions testsuite/example-cuda/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# https://github.com/AcademySoftwareFoundation/OpenShadingLanguage

cmake_minimum_required(VERSION 3.15)
cmake_minimum_required(VERSION 3.19) # Same as top-level CMakeLists.txt
project(examplecuda LANGUAGES CXX)

if (NOT CMAKE_BUILD_TYPE)
Expand All @@ -19,12 +19,16 @@ include(check_is_enabled)
include(checked_find_package)

find_package(OSL REQUIRED)
find_package(CUDA REQUIRED)
find_package(CUDAToolkit REQUIRED)
checked_find_package(LLVM 7.0 REQUIRED)
checked_find_package(Imath 3.1 REQUIRED)
checked_find_package(OpenImageIO 2.4 REQUIRED)
checked_find_package(OptiX REQUIRED)

set(CUDA_TOOLKIT_ROOT_DIR ${CUDAToolkit_ROOT_DIR})
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CUDAToolkit_ROOT_DIR doesn’t appear to be set anywhere in this repo and is not one of the variables exposed/used elsewhere for FindCUDAToolkit. As written, CUDA_TOOLKIT_ROOT_DIR will likely be empty, which then defeats the find_library(... HINTS ${CUDA_TOOLKIT_ROOT_DIR} ...) calls below. Consider deriving the toolkit root from CUDAToolkit_TARGET_DIR / CUDAToolkit_BIN_DIR (parent dir) / CUDAToolkit_LIBRARY_ROOT (if appropriate), similar to the logic used in src/cmake/externalpackages.cmake.

Suggested change
set(CUDA_TOOLKIT_ROOT_DIR ${CUDAToolkit_ROOT_DIR})
# Derive a usable CUDA toolkit root directory from CUDAToolkit variables.
set(CUDA_TOOLKIT_ROOT_DIR "")
if (CUDAToolkit_LIBRARY_ROOT)
# Use the library root directly when available.
set(CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_LIBRARY_ROOT}")
elseif (CUDAToolkit_BIN_DIR)
# Fall back to the parent of the bin directory.
get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_BIN_DIR}" DIRECTORY)
elseif (CUDAToolkit_ROOT)
# As a last resort, use the generic CUDAToolkit root, if defined.
set(CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_ROOT}")
endif ()

Copilot uses AI. Check for mistakes.
set(CUDA_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIRS})
set(CUDA_NVCC_EXECUTABLE ${CUDAToolkit_NVCC_EXECUTABLE})
set(CUDA_LIBRARIES CUDA::cudart)

# Make the build area layout look like we expect
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
Expand All @@ -34,13 +38,37 @@ set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# TODO: what are the path suffixes on other platforms?
find_library(CUDA_nvrtc_LIBRARY nvrtc HINTS ${CUDA_TOOLKIT_ROOT_DIR} PATH_SUFFIXES lib lib64)
find_library(CUDA_cuda_LIBRARY cuda HINTS ${CUDA_TOOLKIT_ROOT_DIR} PATH_SUFFIXES lib/stubs lib64/stubs)
if (TARGET CUDA::nvrtc)
set(CUDA_nvrtc_LIBRARY CUDA::nvrtc)
endif ()
if (TARGET CUDA::cuda_driver)
set(CUDA_cuda_LIBRARY CUDA::cuda_driver)
endif ()

# TODO: move to sm_60?
set(CUDA_TARGET_ARCH sm_35)

set (CMAKE_CXX_STANDARD 17 CACHE STRING
"C++ standard to build with (17, 20, etc.)")

# Compile a CUDA source file to PTX with NVCC. (Formerly provided by FindCUDA.cmake)
function(cuda_compile_ptx out_var cuda_src)
cmake_parse_arguments(_ccp "" "" "OPTIONS" ${ARGN})
get_filename_component(cuda_src_we ${cuda_src} NAME_WE)
set(cuda_ptx "${CMAKE_CURRENT_BINARY_DIR}/${cuda_src_we}.ptx")
add_custom_command(OUTPUT ${cuda_ptx}
COMMAND ${CUDA_NVCC_EXECUTABLE}
${_ccp_OPTIONS}
-ptx
Comment on lines +59 to +62
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cuda_compile_ptx() invokes ${CUDA_NVCC_EXECUTABLE}, but CUDAToolkit_NVCC_EXECUTABLE may be unset on systems that have CUDA runtime libraries/headers but no nvcc installed. Add a configure-time fallback/check (e.g., find_program(CUDA_NVCC_EXECUTABLE NAMES nvcc ...) and message(FATAL_ERROR ...) if still not found) so this fails during configuration rather than at build time.

Copilot uses AI. Check for mistakes.
${cuda_src}
-o ${cuda_ptx}
MAIN_DEPENDENCY ${cuda_src}
DEPENDS ${cuda_src}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
)
set(${out_var} ${cuda_ptx} PARENT_SCOPE)
endfunction()

# Compile our "renderer" to PTX
cuda_compile_ptx(CUDA_PTX_FILES cuda_grid_renderer.cu
OPTIONS --gpu-architecture=${CUDA_TARGET_ARCH} --use_fast_math -dc
Expand Down