850 lines
36 KiB
CMake
850 lines
36 KiB
CMake
################################################################################
|
||
# CUDA Configuration Functions
|
||
# Functions for CUDA-specific build configuration and optimization
|
||
################################################################################
|
||
|
||
# Enhanced CUDA toolkit detection with proper include path setup
|
||
function(setup_cuda_toolkit_paths)
|
||
message(STATUS "🔍 Setting up CUDA toolkit paths...")
|
||
|
||
# Find CUDA toolkit first
|
||
find_package(CUDAToolkit REQUIRED)
|
||
|
||
if(NOT CUDAToolkit_FOUND)
|
||
message(FATAL_ERROR "CUDA toolkit not found. Please install CUDA toolkit or set CUDA_PATH environment variable.")
|
||
endif()
|
||
|
||
# Get CUDA include directories
|
||
get_target_property(CUDA_INCLUDE_DIRS CUDA::toolkit INTERFACE_INCLUDE_DIRECTORIES)
|
||
|
||
# If the above doesn't work, try alternative methods
|
||
if(NOT CUDA_INCLUDE_DIRS)
|
||
set(CUDA_INCLUDE_DIRS "${CUDAToolkit_INCLUDE_DIRS}")
|
||
endif()
|
||
|
||
# Still not found? Try environment variables and common paths
|
||
if(NOT CUDA_INCLUDE_DIRS)
|
||
set(CUDA_SEARCH_PATHS
|
||
$ENV{CUDA_PATH}
|
||
$ENV{CUDA_HOME}
|
||
$ENV{CUDA_ROOT}
|
||
${CUDAToolkit_ROOT}
|
||
)
|
||
|
||
if(WIN32)
|
||
list(APPEND CUDA_SEARCH_PATHS
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.6"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.5"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.4"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.3"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.2"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.1"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.0"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.8"
|
||
"C:/tools/cuda"
|
||
)
|
||
else()
|
||
list(APPEND CUDA_SEARCH_PATHS
|
||
/usr/local/cuda
|
||
/opt/cuda
|
||
/usr/cuda
|
||
)
|
||
endif()
|
||
|
||
foreach(search_path ${CUDA_SEARCH_PATHS})
|
||
if(EXISTS "${search_path}/include/cuda.h")
|
||
set(CUDA_INCLUDE_DIRS "${search_path}/include")
|
||
message(STATUS "✅ Found CUDA include directory: ${CUDA_INCLUDE_DIRS}")
|
||
break()
|
||
endif()
|
||
endforeach()
|
||
endif()
|
||
|
||
# Verify we found CUDA headers
|
||
if(NOT CUDA_INCLUDE_DIRS)
|
||
message(FATAL_ERROR "❌ CUDA include directories not found. Please ensure CUDA toolkit is properly installed.")
|
||
endif()
|
||
|
||
# Verify cuda.h exists
|
||
set(CUDA_H_FOUND FALSE)
|
||
foreach(include_dir ${CUDA_INCLUDE_DIRS})
|
||
if(EXISTS "${include_dir}/cuda.h")
|
||
set(CUDA_H_FOUND TRUE)
|
||
message(STATUS "✅ Found cuda.h in: ${include_dir}")
|
||
break()
|
||
endif()
|
||
endforeach()
|
||
|
||
if(NOT CUDA_H_FOUND)
|
||
message(FATAL_ERROR "❌ cuda.h not found in CUDA include directories: ${CUDA_INCLUDE_DIRS}")
|
||
endif()
|
||
|
||
# Set variables for parent scope
|
||
set(CUDA_INCLUDE_DIRS "${CUDA_INCLUDE_DIRS}" PARENT_SCOPE)
|
||
set(CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_ROOT}" PARENT_SCOPE)
|
||
|
||
message(STATUS "✅ CUDA toolkit paths configured:")
|
||
message(STATUS " Root: ${CUDAToolkit_ROOT}")
|
||
message(STATUS " Include: ${CUDA_INCLUDE_DIRS}")
|
||
message(STATUS " Version: ${CUDAToolkit_VERSION}")
|
||
endfunction()
|
||
|
||
# Modern cuDNN detection using updated FindCUDNN.cmake practices
|
||
function(setup_modern_cudnn)
|
||
set(HAVE_CUDNN FALSE PARENT_SCOPE)
|
||
|
||
if(NOT (HELPERS_cudnn AND SD_CUDA))
|
||
message(STATUS "🔍 cuDNN: Skipped (HELPERS_cudnn=${HELPERS_cudnn}, SD_CUDA=${SD_CUDA})")
|
||
return()
|
||
endif()
|
||
|
||
message(STATUS "🔍 Searching for cuDNN...")
|
||
|
||
# Find the CUDA toolkit first to get the proper paths
|
||
find_package(CUDAToolkit REQUIRED)
|
||
|
||
# Enhanced search paths for CI environments and common installations
|
||
set(CUDNN_SEARCH_PATHS
|
||
# Environment variables
|
||
$ENV{CUDNN_ROOT_DIR}
|
||
$ENV{CUDNN_ROOT}
|
||
$ENV{CUDA_PATH}
|
||
$ENV{CUDA_HOME}
|
||
|
||
# CMake variables
|
||
${CUDNN_ROOT_DIR}
|
||
${CUDAToolkit_ROOT}
|
||
)
|
||
|
||
# Add platform-specific paths
|
||
if(WIN32)
|
||
# Windows-specific paths
|
||
list(APPEND CUDNN_SEARCH_PATHS
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.6"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.5"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.4"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.3"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.2"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.1"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v12.0"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.8"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.7"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.6"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.5"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.4"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.3"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.2"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.1"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA/v11.0"
|
||
"$ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit/CUDA"
|
||
"C:/tools/cuda" # Common CI path on Windows
|
||
)
|
||
else()
|
||
# Linux/Unix-specific paths
|
||
list(APPEND CUDNN_SEARCH_PATHS
|
||
# CI-specific paths (GitHub Actions, etc.)
|
||
/usr/local/cuda-12.6
|
||
/usr/local/cuda-12.5
|
||
/usr/local/cuda-12.4
|
||
/usr/local/cuda-12.3
|
||
/usr/local/cuda-12.2
|
||
/usr/local/cuda-12.1
|
||
/usr/local/cuda-12.0
|
||
/usr/local/cuda-11.8
|
||
/usr/local/cuda-11.7
|
||
/usr/local/cuda-11.6
|
||
/usr/local/cuda-11.5
|
||
/usr/local/cuda-11.4
|
||
/usr/local/cuda-11.3
|
||
/usr/local/cuda-11.2
|
||
/usr/local/cuda-11.1
|
||
/usr/local/cuda-11.0
|
||
/usr/local/cuda
|
||
|
||
# Package manager paths
|
||
/usr/include/cudnn
|
||
/usr/local/include/cudnn
|
||
/opt/cuda
|
||
/opt/cudnn
|
||
|
||
# System paths
|
||
/usr
|
||
/usr/local
|
||
)
|
||
endif()
|
||
|
||
message(STATUS "🔍 Searching for cuDNN headers...")
|
||
|
||
# Search for cuDNN headers with comprehensive path coverage
|
||
find_path(CUDNN_INCLUDE_DIR
|
||
NAMES cudnn.h
|
||
HINTS ${CUDNN_SEARCH_PATHS}
|
||
PATHS ${CUDNN_SEARCH_PATHS}
|
||
PATH_SUFFIXES
|
||
include
|
||
targets/x86_64-linux/include
|
||
targets/aarch64-linux/include
|
||
include/cudnn
|
||
cudnn/include
|
||
x86_64-linux/include
|
||
aarch64-linux/include
|
||
NO_DEFAULT_PATH
|
||
)
|
||
|
||
# If not found, try system paths
|
||
if(NOT CUDNN_INCLUDE_DIR)
|
||
find_path(CUDNN_INCLUDE_DIR
|
||
NAMES cudnn.h
|
||
PATHS /usr/include /usr/local/include /opt/include
|
||
PATH_SUFFIXES cudnn
|
||
)
|
||
endif()
|
||
|
||
message(STATUS "🔍 Searching for cuDNN libraries...")
|
||
|
||
# Search for cuDNN libraries
|
||
find_library(CUDNN_LIBRARY
|
||
NAMES cudnn libcudnn cudnn8 libcudnn8
|
||
HINTS ${CUDNN_SEARCH_PATHS}
|
||
PATHS ${CUDNN_SEARCH_PATHS}
|
||
PATH_SUFFIXES
|
||
lib64
|
||
lib
|
||
lib/x64
|
||
targets/x86_64-linux/lib
|
||
targets/aarch64-linux/lib
|
||
lib64/cudnn
|
||
lib/cudnn
|
||
cudnn/lib64
|
||
cudnn/lib
|
||
x86_64-linux/lib
|
||
aarch64-linux/lib
|
||
NO_DEFAULT_PATH
|
||
)
|
||
|
||
# If not found, try system paths
|
||
if(NOT CUDNN_LIBRARY)
|
||
find_library(CUDNN_LIBRARY
|
||
NAMES cudnn libcudnn cudnn8 libcudnn8
|
||
PATHS /usr/lib64 /usr/lib /usr/local/lib64 /usr/local/lib /opt/lib64 /opt/lib
|
||
PATH_SUFFIXES cudnn
|
||
)
|
||
endif()
|
||
|
||
message(STATUS "🔍 cuDNN search results:")
|
||
message(STATUS " CUDNN_INCLUDE_DIR: ${CUDNN_INCLUDE_DIR}")
|
||
message(STATUS " CUDNN_LIBRARY: ${CUDNN_LIBRARY}")
|
||
|
||
# Check if we found both header and library
|
||
if(CUDNN_INCLUDE_DIR AND CUDNN_LIBRARY)
|
||
message(STATUS "✅ cuDNN found!")
|
||
|
||
# Extract version information from cudnn.h
|
||
if(EXISTS "${CUDNN_INCLUDE_DIR}/cudnn.h")
|
||
file(READ "${CUDNN_INCLUDE_DIR}/cudnn.h" CUDNN_HEADER_CONTENTS)
|
||
|
||
# Try different version detection methods
|
||
string(REGEX MATCH "define CUDNN_MAJOR[ \t]+([0-9]+)" CUDNN_VERSION_MAJOR_MATCH "${CUDNN_HEADER_CONTENTS}")
|
||
string(REGEX MATCH "define CUDNN_MINOR[ \t]+([0-9]+)" CUDNN_VERSION_MINOR_MATCH "${CUDNN_HEADER_CONTENTS}")
|
||
string(REGEX MATCH "define CUDNN_PATCHLEVEL[ \t]+([0-9]+)" CUDNN_VERSION_PATCH_MATCH "${CUDNN_HEADER_CONTENTS}")
|
||
|
||
if(CUDNN_VERSION_MAJOR_MATCH)
|
||
string(REGEX REPLACE "define CUDNN_MAJOR[ \t]+([0-9]+)" "\\1" CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR_MATCH}")
|
||
string(REGEX REPLACE "define CUDNN_MINOR[ \t]+([0-9]+)" "\\1" CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR_MATCH}")
|
||
string(REGEX REPLACE "define CUDNN_PATCHLEVEL[ \t]+([0-9]+)" "\\1" CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH_MATCH}")
|
||
|
||
set(CUDNN_VERSION_STRING "${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}")
|
||
else()
|
||
# Try alternative version detection
|
||
string(REGEX MATCH "#define CUDNN_MAJOR ([0-9]+)" CUDNN_VERSION_MAJOR_MATCH2 "${CUDNN_HEADER_CONTENTS}")
|
||
if(CUDNN_VERSION_MAJOR_MATCH2)
|
||
string(REGEX REPLACE "#define CUDNN_MAJOR ([0-9]+)" "\\1" CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR_MATCH2}")
|
||
string(REGEX MATCH "#define CUDNN_MINOR ([0-9]+)" CUDNN_VERSION_MINOR_MATCH2 "${CUDNN_HEADER_CONTENTS}")
|
||
string(REGEX MATCH "#define CUDNN_PATCHLEVEL ([0-9]+)" CUDNN_VERSION_PATCH_MATCH2 "${CUDNN_HEADER_CONTENTS}")
|
||
string(REGEX REPLACE "#define CUDNN_MINOR ([0-9]+)" "\\1" CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR_MATCH2}")
|
||
string(REGEX REPLACE "#define CUDNN_PATCHLEVEL ([0-9]+)" "\\1" CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH_MATCH2}")
|
||
set(CUDNN_VERSION_STRING "${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}")
|
||
else()
|
||
set(CUDNN_VERSION_STRING "Unknown")
|
||
endif()
|
||
endif()
|
||
else()
|
||
message(WARNING "⚠️ cuDNN header found but cannot read version")
|
||
set(CUDNN_VERSION_STRING "Unknown")
|
||
endif()
|
||
|
||
# Create imported target if it doesn't exist
|
||
if(NOT TARGET CUDNN::cudnn)
|
||
add_library(CUDNN::cudnn UNKNOWN IMPORTED)
|
||
set_target_properties(CUDNN::cudnn PROPERTIES
|
||
IMPORTED_LOCATION "${CUDNN_LIBRARY}"
|
||
INTERFACE_INCLUDE_DIRECTORIES "${CUDNN_INCLUDE_DIR}"
|
||
)
|
||
endif()
|
||
|
||
message(STATUS "✅ cuDNN configuration:")
|
||
message(STATUS " Include: ${CUDNN_INCLUDE_DIR}")
|
||
message(STATUS " Library: ${CUDNN_LIBRARY}")
|
||
message(STATUS " Version: ${CUDNN_VERSION_STRING}")
|
||
|
||
# Set all the variables that might be needed
|
||
set(HAVE_CUDNN TRUE PARENT_SCOPE)
|
||
set(CUDNN_FOUND TRUE PARENT_SCOPE)
|
||
set(CUDNN_INCLUDE_DIR "${CUDNN_INCLUDE_DIR}" PARENT_SCOPE)
|
||
set(CUDNN_LIBRARIES "${CUDNN_LIBRARY}" PARENT_SCOPE)
|
||
set(CUDNN_LIBRARY "${CUDNN_LIBRARY}" PARENT_SCOPE)
|
||
set(CUDNN_VERSION_STRING "${CUDNN_VERSION_STRING}" PARENT_SCOPE)
|
||
|
||
return()
|
||
endif()
|
||
|
||
# Try package manager detection as fallback
|
||
find_package(PkgConfig QUIET)
|
||
if(PkgConfig_FOUND)
|
||
pkg_check_modules(PC_CUDNN QUIET cudnn)
|
||
if(PC_CUDNN_FOUND)
|
||
message(STATUS "✅ Found cuDNN via pkg-config")
|
||
set(HAVE_CUDNN TRUE PARENT_SCOPE)
|
||
set(CUDNN_INCLUDE_DIR "${PC_CUDNN_INCLUDE_DIRS}" PARENT_SCOPE)
|
||
set(CUDNN_LIBRARIES "${PC_CUDNN_LIBRARIES}" PARENT_SCOPE)
|
||
set(CUDNN_VERSION_STRING "${PC_CUDNN_VERSION}" PARENT_SCOPE)
|
||
return()
|
||
endif()
|
||
endif()
|
||
|
||
# Final attempt: check if cuDNN is embedded in CUDA installation
|
||
if(CUDAToolkit_FOUND AND CUDAToolkit_INCLUDE_DIRS)
|
||
foreach(cuda_include_dir ${CUDAToolkit_INCLUDE_DIRS})
|
||
if(EXISTS "${cuda_include_dir}/cudnn.h")
|
||
message(STATUS "✅ Found cuDNN embedded in CUDA installation")
|
||
set(HAVE_CUDNN TRUE PARENT_SCOPE)
|
||
set(CUDNN_INCLUDE_DIR "${cuda_include_dir}" PARENT_SCOPE)
|
||
set(CUDNN_LIBRARIES "" PARENT_SCOPE) # May be linked with CUDA
|
||
set(CUDNN_VERSION_STRING "Embedded" PARENT_SCOPE)
|
||
return()
|
||
endif()
|
||
endforeach()
|
||
endif()
|
||
|
||
message(STATUS "❌ cuDNN not found. Searched extensively in:")
|
||
message(STATUS " Environment variables: CUDNN_ROOT_DIR, CUDNN_ROOT, CUDA_PATH, CUDA_HOME")
|
||
message(STATUS " CUDA installation: ${CUDAToolkit_ROOT}")
|
||
if(WIN32)
|
||
message(STATUS " System paths: $ENV{ProgramFiles}/NVIDIA GPU Computing Toolkit")
|
||
else()
|
||
message(STATUS " System paths: /usr, /usr/local, /opt")
|
||
endif()
|
||
message(STATUS " Package manager: pkg-config")
|
||
message(STATUS "")
|
||
message(STATUS "💡 To fix this issue:")
|
||
message(STATUS " 1. Install cuDNN development libraries")
|
||
message(STATUS " 2. Set CUDNN_ROOT_DIR to your cuDNN installation")
|
||
message(STATUS " 3. Ensure cuDNN headers are in CUDA_PATH/include")
|
||
message(STATUS " 4. Or disable cuDNN with -DHELPERS_cudnn=OFF")
|
||
|
||
# Debug information
|
||
message(STATUS "")
|
||
message(STATUS "🔍 Debug information:")
|
||
message(STATUS " CUDAToolkit_ROOT: ${CUDAToolkit_ROOT}")
|
||
message(STATUS " CUDAToolkit_INCLUDE_DIRS: ${CUDAToolkit_INCLUDE_DIRS}")
|
||
message(STATUS " ENV CUDNN_ROOT_DIR: $ENV{CUDNN_ROOT_DIR}")
|
||
message(STATUS " ENV CUDA_PATH: $ENV{CUDA_PATH}")
|
||
message(STATUS " ENV CUDA_HOME: $ENV{CUDA_HOME}")
|
||
endfunction()
|
||
|
||
function(configure_cuda_linking main_target_name)
|
||
# Setup CUDA toolkit paths first
|
||
setup_cuda_toolkit_paths()
|
||
|
||
# Find the CUDAToolkit to define the CUDA::toolkit target
|
||
find_package(CUDAToolkit REQUIRED)
|
||
|
||
# Setup modern cuDNN detection
|
||
setup_modern_cudnn()
|
||
|
||
# This ensures cuda.h and other CUDA headers are found
|
||
if(CUDA_INCLUDE_DIRS)
|
||
target_include_directories(${main_target_name} PUBLIC ${CUDA_INCLUDE_DIRS})
|
||
message(STATUS "✅ Added CUDA include directories to ${main_target_name}: ${CUDA_INCLUDE_DIRS}")
|
||
endif()
|
||
|
||
# Apply GNU-specific CUDA compiler flags for duplicate instantiation handling
|
||
# ONLY for non-Windows builds
|
||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT WIN32)
|
||
message(STATUS "🔧 Applying GNU-specific CUDA flags for duplicate instantiation handling")
|
||
target_compile_options(${main_target_name} PRIVATE
|
||
$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=-fno-implicit-templates>
|
||
)
|
||
endif()
|
||
|
||
# Modern CMake uses imported targets which handle all necessary dependencies.
|
||
# Linking against CUDA::toolkit automatically adds include directories,
|
||
# runtime libraries, and all other required flags.
|
||
target_link_libraries(${main_target_name} PUBLIC CUDA::toolkit)
|
||
|
||
# If cuDNN was found, link against its imported target
|
||
if(HAVE_CUDNN AND TARGET CUDNN::cudnn)
|
||
message(STATUS "✅ Linking with modern CUDNN::cudnn target")
|
||
target_link_libraries(${main_target_name} PUBLIC CUDNN::cudnn)
|
||
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=1)
|
||
elseif(HAVE_CUDNN AND CUDNN_LIBRARIES)
|
||
message(STATUS "✅ Linking with cuDNN libraries: ${CUDNN_LIBRARIES}")
|
||
target_link_libraries(${main_target_name} PUBLIC ${CUDNN_LIBRARIES})
|
||
target_include_directories(${main_target_name} PUBLIC ${CUDNN_INCLUDE_DIR})
|
||
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=1)
|
||
elseif(HAVE_CUDNN AND CUDNN_INCLUDE_DIR)
|
||
message(STATUS "✅ Linking with cuDNN include-only (embedded in CUDA)")
|
||
target_include_directories(${main_target_name} PUBLIC ${CUDNN_INCLUDE_DIR})
|
||
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=1)
|
||
else()
|
||
message(STATUS "ℹ️ Building without cuDNN support")
|
||
target_compile_definitions(${main_target_name} PUBLIC HAVE_CUDNN=0)
|
||
endif()
|
||
|
||
target_link_libraries(${main_target_name} PUBLIC flatbuffers_interface)
|
||
install(TARGETS ${main_target_name} DESTINATION .)
|
||
endfunction()
|
||
|
||
function(setup_cuda_architectures_early)
|
||
if(NOT SD_CUDA)
|
||
return()
|
||
endif()
|
||
|
||
# Fix missing _CMAKE_CUDA_WHOLE_FLAG (note the underscore prefix)
|
||
if(NOT DEFINED _CMAKE_CUDA_WHOLE_FLAG)
|
||
message(STATUS "Setting _CMAKE_CUDA_WHOLE_FLAG (was missing)")
|
||
if(WIN32)
|
||
set(_CMAKE_CUDA_WHOLE_FLAG "/WHOLEARCHIVE:" CACHE INTERNAL "CUDA whole archive flag")
|
||
else()
|
||
set(_CMAKE_CUDA_WHOLE_FLAG "-Wl,--whole-archive" CACHE INTERNAL "CUDA whole archive flag")
|
||
endif()
|
||
endif()
|
||
|
||
if(NOT DEFINED CMAKE_CUDA_WHOLE_FLAG)
|
||
if(WIN32)
|
||
set(CMAKE_CUDA_WHOLE_FLAG "/WHOLEARCHIVE:" CACHE STRING "CUDA whole archive flag")
|
||
else()
|
||
set(CMAKE_CUDA_WHOLE_FLAG "-Wl,--whole-archive" CACHE STRING "CUDA whole archive flag")
|
||
endif()
|
||
endif()
|
||
|
||
message(STATUS "🔧 Early CUDA: Configuring architectures before project() call")
|
||
|
||
if(DEFINED COMPUTE)
|
||
string(TOLOWER "${COMPUTE}" COMPUTE_CMP)
|
||
if(COMPUTE_CMP STREQUAL "all")
|
||
set(CUDA_ARCHITECTURES "75;80;86;89" PARENT_SCOPE)
|
||
message(STATUS " CUDA architectures (all): 75;80;86;89")
|
||
elseif(COMPUTE_CMP STREQUAL "auto")
|
||
set(CMAKE_CUDA_ARCHITECTURES "86" PARENT_SCOPE)
|
||
message(STATUS " CUDA architectures (auto): 86")
|
||
else()
|
||
string(REPLACE "," ";" ARCH_LIST "${COMPUTE}")
|
||
set(PARSED_ARCHS "")
|
||
foreach(ARCH ${ARCH_LIST})
|
||
string(REPLACE "." "" ARCH_CLEAN "${ARCH}")
|
||
if(ARCH_CLEAN MATCHES "^[0-9][0-9]$")
|
||
list(APPEND PARSED_ARCHS "${ARCH_CLEAN}")
|
||
endif()
|
||
endforeach()
|
||
if(PARSED_ARCHS)
|
||
set(CUDA_ARCHITECTURES "${PARSED_ARCHS}" PARENT_SCOPE)
|
||
message(STATUS " CUDA architectures (custom): ${PARSED_ARCHS}")
|
||
else()
|
||
set(CUDA_ARCHITECTURES "86" PARENT_SCOPE)
|
||
message(STATUS " CUDA architectures (default): 86")
|
||
endif()
|
||
endif()
|
||
else()
|
||
set(CUDA_ARCHITECTURES "86" PARENT_SCOPE)
|
||
message(STATUS " CUDA architectures (no COMPUTE): 86")
|
||
endif()
|
||
endfunction()
|
||
|
||
function(setup_cuda_language)
|
||
if(NOT DEFINED _CMAKE_CUDA_WHOLE_FLAG)
|
||
message(STATUS "Setting _CMAKE_CUDA_WHOLE_FLAG (was missing)")
|
||
if(WIN32)
|
||
set(_CMAKE_CUDA_WHOLE_FLAG "/WHOLEARCHIVE:" CACHE INTERNAL "CUDA whole archive flag")
|
||
else()
|
||
set(_CMAKE_CUDA_WHOLE_FLAG "-Wl,--whole-archive" CACHE INTERNAL "CUDA whole archive flag")
|
||
endif()
|
||
endif()
|
||
|
||
include(CheckLanguage)
|
||
check_language(CUDA)
|
||
|
||
if(NOT CMAKE_CUDA_COMPILER)
|
||
find_program(NVCC_EXECUTABLE nvcc)
|
||
if(NVCC_EXECUTABLE)
|
||
set(CMAKE_CUDA_COMPILER ${NVCC_EXECUTABLE} PARENT_SCOPE)
|
||
message(STATUS "CUDA compiler found: ${CMAKE_CUDA_COMPILER}")
|
||
else()
|
||
message(FATAL_ERROR "CUDA compiler not found. Please ensure CUDA toolkit is installed and nvcc is in PATH.")
|
||
endif()
|
||
endif()
|
||
|
||
message(STATUS "CUDA language enabled successfully with compiler: ${CMAKE_CUDA_COMPILER}")
|
||
endfunction()
|
||
|
||
function(configure_windows_cuda_build)
|
||
if(NOT WIN32)
|
||
return()
|
||
endif()
|
||
|
||
message(STATUS "Configuring Windows CUDA build with verbose mode...")
|
||
|
||
# Enable verbose output for the build system
|
||
set(CMAKE_VERBOSE_MAKEFILE ON PARENT_SCOPE)
|
||
set(CMAKE_CUDA_VERBOSE_FLAG ON PARENT_SCOPE)
|
||
|
||
# Completely disable response files to prevent command line issues
|
||
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS OFF PARENT_SCOPE)
|
||
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES OFF PARENT_SCOPE)
|
||
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES OFF PARENT_SCOPE)
|
||
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LINK_OBJECTS OFF PARENT_SCOPE)
|
||
|
||
# Remove problematic dependency generation that causes NVCC failures
|
||
set(CMAKE_CUDA_DEPFILE_FORMAT "" PARENT_SCOPE)
|
||
set(CMAKE_CUDA_DEPENDS_USE_COMPILER OFF PARENT_SCOPE)
|
||
|
||
# Clean MSVC runtime library settings
|
||
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreaded "" PARENT_SCOPE)
|
||
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL "" PARENT_SCOPE)
|
||
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug "" PARENT_SCOPE)
|
||
set(CMAKE_CUDA_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL "" PARENT_SCOPE)
|
||
|
||
# Force clean CXX flags to prevent contamination
|
||
set(CMAKE_CXX_FLAGS "" PARENT_SCOPE)
|
||
|
||
# Enable verbose rule and target messages
|
||
set_property(GLOBAL PROPERTY RULE_MESSAGES ON)
|
||
set_property(GLOBAL PROPERTY TARGET_MESSAGES ON)
|
||
|
||
message(STATUS "Windows CUDA: Verbose mode enabled with clean flags")
|
||
endfunction()
|
||
function(configure_cuda_architecture_flags COMPUTE)
|
||
string(TOLOWER "${COMPUTE}" COMPUTE_CMP)
|
||
if(COMPUTE_CMP STREQUAL "all")
|
||
set(CUDA_ARCH_FLAGS "-gencode arch=compute_75,code=sm_75 -gencode arch=compute_80,code=sm_80 -gencode arch=compute_86,code=sm_86 -gencode arch=compute_89,code=sm_89" PARENT_SCOPE)
|
||
message(STATUS "Building for all CUDA architectures (gencode flags)")
|
||
elseif(COMPUTE_CMP STREQUAL "auto")
|
||
set(CUDA_ARCH_FLAGS "-gencode arch=compute_86,code=sm_86" PARENT_SCOPE)
|
||
message(STATUS "Auto-detecting CUDA architectures (gencode flags)")
|
||
else()
|
||
string(REPLACE "," ";" ARCH_LIST "${COMPUTE}")
|
||
set(ARCH_FLAGS "")
|
||
foreach(ARCH ${ARCH_LIST})
|
||
string(REPLACE "." "" ARCH_CLEAN "${ARCH}")
|
||
if(ARCH_CLEAN MATCHES "^[0-9][0-9]$")
|
||
set(ARCH_FLAGS "${ARCH_FLAGS} -gencode arch=compute_${ARCH_CLEAN},code=sm_${ARCH_CLEAN}")
|
||
endif()
|
||
endforeach()
|
||
string(STRIP "${ARCH_FLAGS}" ARCH_FLAGS)
|
||
if(ARCH_FLAGS)
|
||
set(CUDA_ARCH_FLAGS "${ARCH_FLAGS}" PARENT_SCOPE)
|
||
message(STATUS "Using custom CUDA architectures (gencode flags): ${ARCH_FLAGS}")
|
||
else()
|
||
set(CUDA_ARCH_FLAGS "-gencode arch=compute_86,code=sm_86" PARENT_SCOPE)
|
||
message(STATUS "Using default CUDA architecture (gencode flags)")
|
||
endif()
|
||
endif()
|
||
endfunction()
|
||
|
||
function(build_cuda_compiler_flags CUDA_ARCH_FLAGS)
|
||
set(LOCAL_CUDA_FLAGS "")
|
||
|
||
if(WIN32 AND MSVC)
|
||
message(STATUS "Configuring CUDA for Windows MSVC with verbose mode...")
|
||
set(CMAKE_CUDA_HOST_COMPILER ${CMAKE_CXX_COMPILER} PARENT_SCOPE)
|
||
set(LOCAL_CUDA_FLAGS "-maxrregcount=128")
|
||
|
||
# Enable verbose mode for Windows CUDA compilation
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --verbose")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --ptxas-options=-v")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --resource-usage")
|
||
|
||
# Host compiler verbose flags
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=/showIncludes")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=/verbose")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=/diagnostics:caret")
|
||
|
||
# Linker verbose flags
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xlinker=/VERBOSE")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xlinker=/TIME")
|
||
|
||
# Explicitly enable C++17 for the host compiler
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=/std:c++17")
|
||
|
||
if(WIN32 AND NOT CMAKE_CUDA_HOST_COMPILER)
|
||
find_program(CL_IN_PATH cl.exe)
|
||
if(CL_IN_PATH)
|
||
# Check if this cl.exe is 64-bit by examining its path
|
||
get_filename_component(CL_DIR ${CL_IN_PATH} DIRECTORY)
|
||
if(CL_DIR MATCHES "x64")
|
||
set(CMAKE_CUDA_HOST_COMPILER ${CL_IN_PATH})
|
||
message(STATUS "Found x64 cl.exe in PATH: ${CMAKE_CUDA_HOST_COMPILER}")
|
||
else()
|
||
# Try to find x64 version relative to this cl.exe
|
||
get_filename_component(CL_PARENT ${CL_DIR} DIRECTORY)
|
||
if(EXISTS "${CL_PARENT}/x64/cl.exe")
|
||
set(CMAKE_CUDA_HOST_COMPILER "${CL_PARENT}/x64/cl.exe")
|
||
message(STATUS "Found x64 cl.exe relative to PATH cl.exe: ${CMAKE_CUDA_HOST_COMPILER}")
|
||
endif()
|
||
endif()
|
||
endif()
|
||
endif()
|
||
|
||
if(WIN32 AND NOT CMAKE_CUDA_HOST_COMPILER)
|
||
# Only check the most common paths that exist in barebones installs
|
||
set(COMMON_PATHS
|
||
"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC"
|
||
"C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Tools/MSVC"
|
||
"C:/Program Files/Microsoft Visual Studio/2022/BuildTools/VC/Tools/MSVC"
|
||
)
|
||
|
||
foreach(BASE_PATH ${COMMON_PATHS})
|
||
if(EXISTS ${BASE_PATH})
|
||
file(GLOB MSVC_VERSIONS "${BASE_PATH}/*")
|
||
if(MSVC_VERSIONS)
|
||
# Get the lexicographically last version (should be newest)
|
||
list(SORT MSVC_VERSIONS)
|
||
list(REVERSE MSVC_VERSIONS)
|
||
list(GET MSVC_VERSIONS 0 LATEST_MSVC)
|
||
|
||
set(CANDIDATE_COMPILER "${LATEST_MSVC}/bin/Hostx64/x64/cl.exe")
|
||
if(EXISTS ${CANDIDATE_COMPILER})
|
||
set(CMAKE_CUDA_HOST_COMPILER ${CANDIDATE_COMPILER})
|
||
message(STATUS "Found CUDA host compiler in standard path: ${CMAKE_CUDA_HOST_COMPILER}")
|
||
break()
|
||
endif()
|
||
endif()
|
||
endif()
|
||
endforeach()
|
||
endif()
|
||
|
||
# Validation and warning
|
||
if(WIN32)
|
||
if(CMAKE_CUDA_HOST_COMPILER)
|
||
if(NOT EXISTS ${CMAKE_CUDA_HOST_COMPILER})
|
||
message(WARNING "CUDA host compiler path does not exist: ${CMAKE_CUDA_HOST_COMPILER}")
|
||
unset(CMAKE_CUDA_HOST_COMPILER)
|
||
else()
|
||
message(STATUS "Final CUDA host compiler: ${CMAKE_CUDA_HOST_COMPILER}")
|
||
endif()
|
||
else()
|
||
message(WARNING "Could not auto-detect x64 CUDA host compiler.")
|
||
message(STATUS "Manual options:")
|
||
message(STATUS " 1. Use x64 Native Tools Command Prompt")
|
||
message(STATUS " 2. Set manually: -DCMAKE_CUDA_HOST_COMPILER=\"path/to/x64/cl.exe\"")
|
||
message(STATUS " 3. Ensure x64 cl.exe is in your PATH")
|
||
endif()
|
||
endif()
|
||
|
||
# Windows/MSVC flags: bigobj, EHsc, *and* disable the new preprocessor
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}
|
||
-Xcompiler=/std:c++17
|
||
-Xcompiler=/bigobj
|
||
-Xcompiler=/EHsc
|
||
-Xcompiler=/Zc:preprocessor-")
|
||
|
||
# Force clean host compiler flags
|
||
set(CMAKE_CXX_FLAGS "" PARENT_SCOPE)
|
||
|
||
message(STATUS "CUDA Windows verbose flags configured")
|
||
else()
|
||
message(STATUS "Configuring CUDA for Unix/Linux with verbose mode...")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -maxrregcount=128")
|
||
|
||
# Enable verbose mode for Unix/Linux CUDA compilation
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --verbose")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --ptxas-options=-v")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --resource-usage")
|
||
|
||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||
# Host compiler verbose flags for GCC
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=-v")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=-H")
|
||
|
||
# Linker verbose flags
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xlinker=-v")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xlinker=--verbose")
|
||
|
||
if(SD_GCC_FUNCTRACE)
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=-fPIC --device-debug -lineinfo -G")
|
||
else()
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=-fPIC -Xcompiler=-fpermissive")
|
||
# Add flags to handle duplicate instantiations for GNU compiler
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -Xcompiler=-fno-implicit-templates")
|
||
endif()
|
||
endif()
|
||
|
||
message(STATUS "CUDA Unix/Linux verbose flags configured")
|
||
endif()
|
||
|
||
if("${SD_PTXAS}" STREQUAL "ON")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --ptxas-options=-v")
|
||
endif()
|
||
|
||
if(SD_KEEP_NVCC_OUTPUT)
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} --keep")
|
||
endif()
|
||
|
||
if(DEFINED CUDA_ARCH_FLAGS)
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} ${CUDA_ARCH_FLAGS}")
|
||
endif()
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -w --cudart=shared --expt-extended-lambda -Xfatbin -compress-all")
|
||
|
||
if(CMAKE_CUDA_COMPILER_VERSION)
|
||
string(REGEX MATCH "^([0-9]+)" CUDA_VERSION_MAJOR "${CMAKE_CUDA_COMPILER_VERSION}")
|
||
set(LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS} -DCUDA_VERSION_MAJOR=${CUDA_VERSION_MAJOR}")
|
||
endif()
|
||
|
||
# Clean up any problematic flags for Windows
|
||
if(WIN32)
|
||
# Remove any GCC-style flags that might have been added
|
||
string(REGEX REPLACE "-MD[^a-zA-Z]" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
string(REGEX REPLACE "-MT[^a-zA-Z]" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
string(REGEX REPLACE "-MF[^a-zA-Z]" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
string(REGEX REPLACE "-x cu" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
string(REGEX REPLACE "-fpermissive" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
string(REGEX REPLACE "-Wno-error" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
string(REGEX REPLACE "/FS[ ]*" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
string(REGEX REPLACE "-Xcompiler=-Fd[^,]*,?" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
string(REGEX REPLACE "-Xcompiler=," "-Xcompiler=" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
string(REGEX REPLACE "-Xcompiler=$" "" LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
endif()
|
||
|
||
string(REGEX REPLACE " +" " " LOCAL_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}")
|
||
string(STRIP "${LOCAL_CUDA_FLAGS}" LOCAL_CUDA_FLAGS)
|
||
|
||
set(CMAKE_CUDA_SEPARABLE_COMPILATION ON PARENT_SCOPE)
|
||
set(CMAKE_CUDA_FLAGS "${LOCAL_CUDA_FLAGS}" PARENT_SCOPE)
|
||
|
||
message(STATUS "Final CMAKE_CUDA_FLAGS (with verbose): ${LOCAL_CUDA_FLAGS}")
|
||
endfunction()
|
||
|
||
# Debug configuration function
|
||
function(debug_cuda_configuration)
|
||
message(STATUS "=== CUDA Configuration Debug Info ===")
|
||
message(STATUS "CMAKE_CUDA_COMPILER: ${CMAKE_CUDA_COMPILER}")
|
||
message(STATUS "CMAKE_CUDA_COMPILER_VERSION: ${CMAKE_CUDA_COMPILER_VERSION}")
|
||
message(STATUS "CMAKE_CUDA_ARCHITECTURES: ${CMAKE_CUDA_ARCHITECTURES}")
|
||
message(STATUS "CMAKE_CUDA_FLAGS: ${CMAKE_CUDA_FLAGS}")
|
||
message(STATUS "CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES: ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}")
|
||
message(STATUS "CMAKE_CUDA_COMPILE_OBJECT: ${CMAKE_CUDA_COMPILE_OBJECT}")
|
||
message(STATUS "CUDA_INCLUDE_DIRS: ${CUDA_INCLUDE_DIRS}")
|
||
message(STATUS "CUDAToolkit_ROOT: ${CUDAToolkit_ROOT}")
|
||
message(STATUS "CUDAToolkit_INCLUDE_DIRS: ${CUDAToolkit_INCLUDE_DIRS}")
|
||
if(HAVE_CUDNN)
|
||
message(STATUS "CUDNN_INCLUDE_DIR: ${CUDNN_INCLUDE_DIR}")
|
||
message(STATUS "CUDNN_LIBRARIES: ${CUDNN_LIBRARIES}")
|
||
message(STATUS "CUDNN_VERSION: ${CUDNN_VERSION_STRING}")
|
||
endif()
|
||
message(STATUS "=== End CUDA Debug Info ===")
|
||
endfunction()
|
||
|
||
# Enhanced CUDA include directory setup for global configuration
|
||
function(setup_cuda_include_directories)
|
||
setup_cuda_toolkit_paths()
|
||
|
||
# Set global include directories that will be inherited by all targets
|
||
if(CUDA_INCLUDE_DIRS)
|
||
include_directories(${CUDA_INCLUDE_DIRS})
|
||
message(STATUS "✅ Added global CUDA include directories: ${CUDA_INCLUDE_DIRS}")
|
||
endif()
|
||
|
||
# Also set the CMAKE variable for compatibility
|
||
if(CUDAToolkit_INCLUDE_DIRS)
|
||
set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES ${CUDAToolkit_INCLUDE_DIRS} PARENT_SCOPE)
|
||
endif()
|
||
endfunction()
|
||
|
||
function(setup_cuda_build)
|
||
message(STATUS "=== CUDA BUILD CONFIGURATION (VERBOSE MODE) ===")
|
||
|
||
# Enable verbose output for the build system
|
||
set(CMAKE_VERBOSE_MAKEFILE ON PARENT_SCOPE)
|
||
set(CMAKE_CUDA_VERBOSE_FLAG ON PARENT_SCOPE)
|
||
|
||
if(NOT DEFINED _CMAKE_CUDA_WHOLE_FLAG)
|
||
message(STATUS "Setting _CMAKE_CUDA_WHOLE_FLAG (was missing)")
|
||
if(WIN32)
|
||
set(_CMAKE_CUDA_WHOLE_FLAG "/WHOLEARCHIVE:" CACHE INTERNAL "CUDA whole archive flag")
|
||
else()
|
||
set(_CMAKE_CUDA_WHOLE_FLAG "-Wl,--whole-archive" CACHE INTERNAL "CUDA whole archive flag")
|
||
endif()
|
||
endif()
|
||
|
||
# Setup CUDA toolkit paths and include directories early
|
||
setup_cuda_include_directories()
|
||
|
||
if(NOT DEFINED COMPUTE)
|
||
set(COMPUTE "auto")
|
||
endif()
|
||
configure_cuda_architecture_flags("${COMPUTE}")
|
||
set_property(GLOBAL PROPERTY CUDA_ARCHITECTURES "${CMAKE_CUDA_ARCHITECTURES}")
|
||
|
||
setup_cuda_language()
|
||
|
||
if(NOT CMAKE_CUDA_COMPILER)
|
||
message(FATAL_ERROR "CUDA compiler not found after enabling CUDA language")
|
||
endif()
|
||
|
||
message(STATUS "CUDA Compiler: ${CMAKE_CUDA_COMPILER}")
|
||
message(STATUS "CUDA Include Dirs: ${CUDA_INCLUDE_DIRS}")
|
||
message(STATUS "CUDAToolkit Include Dirs: ${CUDAToolkit_INCLUDE_DIRS}")
|
||
message(STATUS "Host CXX Compiler: ${CMAKE_CXX_COMPILER_ID}")
|
||
|
||
configure_windows_cuda_build()
|
||
build_cuda_compiler_flags("${CUDA_ARCH_FLAGS}")
|
||
|
||
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS}" PARENT_SCOPE)
|
||
|
||
# Also set the toolkit include directories for global access
|
||
set(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES "${CUDA_INCLUDE_DIRS}" PARENT_SCOPE)
|
||
|
||
# Enable verbose rule and target messages
|
||
set_property(GLOBAL PROPERTY RULE_MESSAGES ON)
|
||
set_property(GLOBAL PROPERTY TARGET_MESSAGES ON)
|
||
|
||
debug_cuda_configuration()
|
||
|
||
add_compile_definitions(SD_CUDA=true)
|
||
set(DEFAULT_ENGINE "samediff::ENGINE_CUDA" PARENT_SCOPE)
|
||
|
||
message(STATUS "=== CUDA BUILD CONFIGURATION (VERBOSE MODE) COMPLETE ===")
|
||
endfunction()
|
||
|
||
# Enhanced function to ensure CUDA paths are available at configure time
|
||
function(ensure_cuda_paths_available)
|
||
if(NOT SD_CUDA)
|
||
return()
|
||
endif()
|
||
|
||
message(STATUS "🔍 Ensuring CUDA paths are available...")
|
||
|
||
# Find CUDA early
|
||
find_package(CUDAToolkit REQUIRED)
|
||
|
||
# Set up paths immediately
|
||
setup_cuda_toolkit_paths()
|
||
|
||
# Export to parent scope for immediate use
|
||
set(CUDA_INCLUDE_DIRS "${CUDA_INCLUDE_DIRS}" PARENT_SCOPE)
|
||
set(CUDA_TOOLKIT_ROOT_DIR "${CUDAToolkit_ROOT}" PARENT_SCOPE)
|
||
|
||
message(STATUS "✅ CUDA paths configured and available")
|
||
endfunction()
|
||
|
||
# Legacy function for backward compatibility - now calls modern version
|
||
function(setup_cudnn)
|
||
setup_modern_cudnn()
|
||
|
||
# Set legacy variables for backward compatibility
|
||
set(HAVE_CUDNN ${HAVE_CUDNN} PARENT_SCOPE)
|
||
if(HAVE_CUDNN)
|
||
set(CUDNN_INCLUDE_DIR ${CUDNN_INCLUDE_DIR} PARENT_SCOPE)
|
||
set(CUDNN ${CUDNN_LIBRARIES} PARENT_SCOPE)
|
||
endif()
|
||
endfunction() |