chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:47:05 +08:00
commit 4f3b7da785
7394 changed files with 2005594 additions and 0 deletions
+850
View File
@@ -0,0 +1,850 @@
################################################################################
# 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()