Initial import: grid-bot — grid trading bot for BTC-USDT on Cifra Markets

This commit is contained in:
Kolp
2026-09-24 13:22:23 +07:00
commit 642cc11a9f
18968 changed files with 5683248 additions and 0 deletions
@@ -0,0 +1,140 @@
# - Config file for the Caffe2 package
# It defines the following variable(s)
# CAFFE2_INCLUDE_DIRS - include directories for FooBar
# as well as Caffe2 targets for other cmake libraries to use.
# library version information
# Utils functions.
include("${CMAKE_CURRENT_LIST_DIR}/public/utils.cmake")
# Depending on whether Caffe2 uses gflags during compile time or
# not, invoke gflags.
if(OFF)
include("${CMAKE_CURRENT_LIST_DIR}/public/gflags.cmake")
if(NOT TARGET gflags)
message(FATAL_ERROR
"Your installed Caffe2 version uses gflags but the gflags library "
"cannot be found. Did you accidentally remove it, or have you set "
"the right CMAKE_PREFIX_PATH and/or GFLAGS_ROOT_DIR? If you do not "
"have gflags, you will need to install gflags and set the library "
"path accordingly.")
endif()
endif()
# Depending on whether Caffe2 uses glog during compile time or
# not, invoke glog.
if(OFF)
include("${CMAKE_CURRENT_LIST_DIR}/public/glog.cmake")
if(NOT TARGET glog::glog)
message(FATAL_ERROR
"Your installed Caffe2 version uses glog but the glog library "
"cannot be found. Did you accidentally remove it, or have you set "
"the right CMAKE_PREFIX_PATH and/or GFLAGS_ROOT_DIR? If you do not "
"have glog, you will need to install glog and set the library "
"path accordingly.")
endif()
endif()
# Protobuf
if(ON)
if(NOT TARGET protobuf::libprotobuf)
# Define protobuf::libprotobuf as a dummy target to resolve references to
# protobuf::libprotobuf in Caffe2Targets.cmake.
add_library(dummy INTERFACE)
add_library(protobuf::libprotobuf ALIAS dummy)
endif()
else()
include("${CMAKE_CURRENT_LIST_DIR}/public/protobuf.cmake")
if(NOT TARGET protobuf::libprotobuf)
message(FATAL_ERROR
"Your installed Caffe2 version uses protobuf but the protobuf library "
"cannot be found. Did you accidentally remove it, or have you set "
"the right CMAKE_PREFIX_PATH? If you do not have protobuf, you will "
"need to install protobuf and set the library path accordingly.")
endif()
message(STATUS "Caffe2: Protobuf version " ${Protobuf_VERSION})
# If during build time we know the protobuf version, we will also do a sanity
# check to ensure that the protobuf library that Caffe2 found is consistent
# with the compiled version.
if(FALSE)
if(NOT (${Protobuf_VERSION} VERSION_EQUAL Protobuf_VERSION_NOTFOUND))
message(FATAL_ERROR
"Your installed Caffe2 is built with protobuf "
"Protobuf_VERSION_NOTFOUND"
", while your current cmake setting discovers protobuf version "
${Protobuf_VERSION}
". Please specify a protobuf version that is the same as the built "
"version.")
endif()
endif()
endif()
if (OFF)
include("${CMAKE_CURRENT_LIST_DIR}/public/LoadHIP.cmake")
endif()
if(0)
# The file public/cuda.cmake exclusively uses CAFFE2_USE_*.
# If Caffe2 was compiled with the libraries below, they must
# be found again when including the Caffe2 target.
set(CAFFE2_USE_CUDA 0)
# Add current directory to module path so we pick up FindCUDAToolkit.cmake
set(old_CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
include("${CMAKE_CURRENT_LIST_DIR}/public/cuda.cmake")
set(CMAKE_MODULE_PATH "${old_CMAKE_MODULE_PATH}")
if( AND NOT CAFFE2_USE_CUDA)
message(FATAL_ERROR
"Your installed Caffe2 version uses CUDA but I cannot find the CUDA "
"libraries. Please set the proper CUDA prefixes and / or install "
"CUDA.")
endif()
endif()
if(OFF)
# Add current directory to module path so we pick up FindSYCLToolkit.cmake
set(old_CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
include("${CMAKE_CURRENT_LIST_DIR}/public/xpu.cmake")
set(CMAKE_MODULE_PATH "${old_CMAKE_MODULE_PATH}")
if(OFF AND NOT PYTORCH_FOUND_XPU)
message(FATAL_ERROR
"Your installed Caffe2 version uses XPU but I cannot find the XPU runtime"
"libraries. Please set the proper oneAPI paths and / or install "
"oneAPI.")
endif()
endif()
if(ON)
include("${CMAKE_CURRENT_LIST_DIR}/public/mkl.cmake")
endif()
if(ON)
include("${CMAKE_CURRENT_LIST_DIR}/public/mkldnn.cmake")
endif()
# import targets
include ("${CMAKE_CURRENT_LIST_DIR}/Caffe2Targets.cmake")
# Interface libraries, that allows one to build proper link flags.
# We will also define a helper variable, Caffe2_MAIN_LIBS, that resolves to
# the main caffe2 libraries in cases of cuda presence / absence.
set(Caffe2_MAIN_LIBS torch_library)
# include directory.
#
# Newer versions of CMake set the INTERFACE_INCLUDE_DIRECTORIES property
# of the imported targets. It is hence not necessary to add this path
# manually to the include search path for targets which link to gflags.
# The following lines are here for backward compatibility, in case one
# would like to use the old-style include path.
get_filename_component(
CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
# Note: the current list dir is _INSTALL_PREFIX/share/cmake/Gloo.
get_filename_component(
_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
set(CAFFE2_INCLUDE_DIRS "${_INSTALL_PREFIX}/include")
@@ -0,0 +1,39 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "c10" for configuration "Release"
set_property(TARGET c10 APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(c10 PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libc10.so"
IMPORTED_SONAME_RELEASE "libc10.so"
)
list(APPEND _cmake_import_check_targets c10 )
list(APPEND _cmake_import_check_files_for_c10 "${_IMPORT_PREFIX}/lib/libc10.so" )
# Import target "torch_cpu" for configuration "Release"
set_property(TARGET torch_cpu APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(torch_cpu PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libtorch_cpu.so"
IMPORTED_SONAME_RELEASE "libtorch_cpu.so"
)
list(APPEND _cmake_import_check_targets torch_cpu )
list(APPEND _cmake_import_check_files_for_torch_cpu "${_IMPORT_PREFIX}/lib/libtorch_cpu.so" )
# Import target "torch" for configuration "Release"
set_property(TARGET torch APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(torch PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libtorch.so"
IMPORTED_SONAME_RELEASE "libtorch.so"
)
list(APPEND _cmake_import_check_targets torch )
list(APPEND _cmake_import_check_files_for_torch "${_IMPORT_PREFIX}/lib/libtorch.so" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
@@ -0,0 +1,164 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
message(FATAL_ERROR "CMake >= 3.0.0 required")
endif()
if(CMAKE_VERSION VERSION_LESS "3.0.0")
message(FATAL_ERROR "CMake >= 3.0.0 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 3.0.0...4.1)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS headeronly c10 torch_cpu torch_cpu_library torch torch_library)
list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
if(TARGET "${_cmake_expected_target}")
list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
else()
list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
unset(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target headeronly
add_library(headeronly INTERFACE IMPORTED)
# Create imported target c10
add_library(c10 SHARED IMPORTED)
set_target_properties(c10 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "headeronly"
)
# Create imported target torch_cpu
add_library(torch_cpu SHARED IMPORTED)
set_target_properties(torch_cpu PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "USE_DISTRIBUTED;USE_C10D_GLOO;USE_RPC;USE_TENSORPIPE"
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
INTERFACE_LINK_LIBRARIES "protobuf::libprotobuf;c10;caffe2::mkl"
)
# Create imported target torch_cpu_library
add_library(torch_cpu_library INTERFACE IMPORTED)
set_target_properties(torch_cpu_library PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "\$<TARGET_PROPERTY:torch_cpu,INTERFACE_COMPILE_DEFINITIONS>"
INTERFACE_COMPILE_OPTIONS "\$<TARGET_PROPERTY:torch_cpu,INTERFACE_COMPILE_OPTIONS>"
INTERFACE_INCLUDE_DIRECTORIES "\$<TARGET_PROPERTY:torch_cpu,INTERFACE_INCLUDE_DIRECTORIES>"
INTERFACE_LINK_LIBRARIES "-Wl,--no-as-needed,\"\$<TARGET_FILE:torch_cpu>\" -Wl,--as-needed;\$<TARGET_PROPERTY:torch_cpu,INTERFACE_LINK_LIBRARIES>"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "\$<TARGET_PROPERTY:torch_cpu,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>"
)
# Create imported target torch
add_library(torch SHARED IMPORTED)
set_target_properties(torch PROPERTIES
INTERFACE_LINK_LIBRARIES "torch_cpu_library"
)
# Create imported target torch_library
add_library(torch_library INTERFACE IMPORTED)
set_target_properties(torch_library PROPERTIES
INTERFACE_COMPILE_DEFINITIONS "\$<TARGET_PROPERTY:torch,INTERFACE_COMPILE_DEFINITIONS>"
INTERFACE_COMPILE_OPTIONS "\$<TARGET_PROPERTY:torch,INTERFACE_COMPILE_OPTIONS>"
INTERFACE_INCLUDE_DIRECTORIES "\$<TARGET_PROPERTY:torch,INTERFACE_INCLUDE_DIRECTORIES>"
INTERFACE_LINK_LIBRARIES "-Wl,--no-as-needed,\"\$<TARGET_FILE:torch>\" -Wl,--as-needed;\$<TARGET_PROPERTY:torch,INTERFACE_LINK_LIBRARIES>"
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "\$<TARGET_PROPERTY:torch,INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>"
)
# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/Caffe2Targets-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
if(CMAKE_VERSION VERSION_LESS "3.28"
OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target}
OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}")
foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
if(NOT EXISTS "${_cmake_file}")
message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
\"${_cmake_file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
endif()
unset(_cmake_file)
unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)
# Make sure the targets which have been exported in some other
# export set exist.
unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)
foreach(_target "protobuf::libprotobuf" )
if(NOT TARGET "${_target}" )
set(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets "${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets} ${_target}")
endif()
endforeach()
if(DEFINED ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)
if(CMAKE_FIND_PACKAGE_NAME)
set( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)
set( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "The following imported targets are referenced, but are missing: ${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets}")
else()
message(FATAL_ERROR "The following imported targets are referenced, but are missing: ${${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets}")
endif()
endif()
unset(${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE_targets)
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
@@ -0,0 +1,67 @@
# Find the CUDSS library
#
# The following variables are optionally searched for defaults
# CUDSS_ROOT: Base directory where CUDSS is found
# CUDSS_INCLUDE_DIR: Directory where CUDSS header is searched for
# CUDSS_LIBRARY: Directory where CUDSS library is searched for
#
# The following are set after configuration is done:
# CUDSS_FOUND
# CUDSS_INCLUDE_PATH
# CUDSS_LIBRARY_PATH
include(FindPackageHandleStandardArgs)
set(CUDSS_ROOT $ENV{CUDSS_ROOT_DIR} CACHE PATH "Folder containing NVIDIA CUDSS")
if (DEFINED $ENV{CUDSS_ROOT_DIR})
message(WARNING "CUDSS_ROOT_DIR is deprecated. Please set CUDSS_ROOT instead.")
endif()
list(APPEND CUDSS_ROOT $ENV{CUDSS_ROOT_DIR} ${CUDA_TOOLKIT_ROOT_DIR})
# Compatible layer for CMake <3.12. CUDSS_ROOT will be accounted in for searching paths and libraries for CMake >=3.12.
list(APPEND CMAKE_PREFIX_PATH ${CUDSS_ROOT})
set(CUDSS_INCLUDE_DIR $ENV{CUDSS_INCLUDE_DIR} CACHE PATH "Folder containing NVIDIA CUDSS header files")
find_path(CUDSS_INCLUDE_PATH cudss.h
HINTS ${CUDSS_INCLUDE_DIR}
PATH_SUFFIXES cuda/include cuda include)
set(CUDSS_LIBRARY $ENV{CUDSS_LIBRARY} CACHE PATH "Path to the CUDSS library file (e.g., libcudss.so)")
set(CUDSS_LIBRARY_NAME "libcudss.so")
if(MSVC)
set(CUDSS_LIBRARY_NAME "cudss.lib")
endif()
find_library(CUDSS_LIBRARY_PATH ${CUDSS_LIBRARY_NAME}
PATHS ${CUDSS_LIBRARY}
PATH_SUFFIXES lib lib64 cuda/lib cuda/lib64 lib/x64)
find_package_handle_standard_args(CUDSS DEFAULT_MSG CUDSS_LIBRARY_PATH CUDSS_INCLUDE_PATH)
if(CUDSS_FOUND)
# Get CUDSS version
file(READ ${CUDSS_INCLUDE_PATH}/cudss.h CUDSS_HEADER_CONTENTS)
string(REGEX MATCH "define CUDSS_VER_MAJOR * +([0-9]+)"
CUDSS_VERSION_MAJOR "${CUDSS_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUDSS_VER_MAJOR * +([0-9]+)" "\\1"
CUDSS_VERSION_MAJOR "${CUDSS_VERSION_MAJOR}")
string(REGEX MATCH "define CUDSS_VER_MINOR * +([0-9]+)"
CUDSS_VERSION_MINOR "${CUDSS_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUDSS_VER_MINOR * +([0-9]+)" "\\1"
CUDSS_VERSION_MINOR "${CUDSS_VERSION_MINOR}")
string(REGEX MATCH "define CUDSS_VER_PATCH * +([0-9]+)"
CUDSS_VERSION_PATCH "${CUDSS_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUDSS_VER_PATCH * +([0-9]+)" "\\1"
CUDSS_VERSION_PATCH "${CUDSS_VERSION_PATCH}")
# Assemble CUDSS version. Use minor version since current major version is 0.
if(NOT CUDSS_VERSION_MINOR)
set(CUDSS_VERSION "?")
else()
set(CUDSS_VERSION
"${CUDSS_VERSION_MAJOR}.${CUDSS_VERSION_MINOR}.${CUDSS_VERSION_PATCH}")
endif()
endif()
mark_as_advanced(CUDSS_ROOT CUDSS_INCLUDE_DIR CUDSS_LIBRARY CUDSS_VERSION)
@@ -0,0 +1,67 @@
# Find the CUSPARSELT library
#
# The following variables are optionally searched for defaults
# CUSPARSELT_ROOT: Base directory where CUSPARSELT is found
# CUSPARSELT_INCLUDE_DIR: Directory where CUSPARSELT header is searched for
# CUSPARSELT_LIBRARY: Directory where CUSPARSELT library is searched for
#
# The following are set after configuration is done:
# CUSPARSELT_FOUND
# CUSPARSELT_INCLUDE_PATH
# CUSPARSELT_LIBRARY_PATH
include(FindPackageHandleStandardArgs)
set(CUSPARSELT_ROOT $ENV{CUSPARSELT_ROOT_DIR} CACHE PATH "Folder containing NVIDIA cuSPARSELt")
if (DEFINED $ENV{CUSPARSELT_ROOT_DIR})
message(WARNING "CUSPARSELT_ROOT_DIR is deprecated. Please set CUSPARSELT_ROOT instead.")
endif()
list(APPEND CUSPARSELT_ROOT $ENV{CUSPARSELT_ROOT_DIR} ${CUDA_TOOLKIT_ROOT_DIR})
# Compatible layer for CMake <3.12. CUSPARSELT_ROOT will be accounted in for searching paths and libraries for CMake >=3.12.
list(APPEND CMAKE_PREFIX_PATH ${CUSPARSELT_ROOT})
set(CUSPARSELT_INCLUDE_DIR $ENV{CUSPARSELT_INCLUDE_DIR} CACHE PATH "Folder containing NVIDIA cuSPARSELt header files")
find_path(CUSPARSELT_INCLUDE_PATH cusparseLt.h
HINTS ${CUSPARSELT_INCLUDE_DIR}
PATH_SUFFIXES cuda/include cuda include)
set(CUSPARSELT_LIBRARY $ENV{CUSPARSELT_LIBRARY} CACHE PATH "Path to the cusparselt library file (e.g., libcusparseLt.so)")
set(CUSPARSELT_LIBRARY_NAME "libcusparseLt.so")
if(MSVC)
set(CUSPARSELT_LIBRARY_NAME "cusparseLt.lib")
endif()
find_library(CUSPARSELT_LIBRARY_PATH ${CUSPARSELT_LIBRARY_NAME}
PATHS ${CUSPARSELT_LIBRARY}
PATH_SUFFIXES lib lib64 cuda/lib cuda/lib64 lib/x64)
find_package_handle_standard_args(CUSPARSELT DEFAULT_MSG CUSPARSELT_LIBRARY_PATH CUSPARSELT_INCLUDE_PATH)
if(CUSPARSELT_FOUND)
# Get cuSPARSELt version
file(READ ${CUSPARSELT_INCLUDE_PATH}/cusparseLt.h CUSPARSELT_HEADER_CONTENTS)
string(REGEX MATCH "define CUSPARSELT_VER_MAJOR * +([0-9]+)"
CUSPARSELT_VERSION_MAJOR "${CUSPARSELT_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUSPARSELT_VER_MAJOR * +([0-9]+)" "\\1"
CUSPARSELT_VERSION_MAJOR "${CUSPARSELT_VERSION_MAJOR}")
string(REGEX MATCH "define CUSPARSELT_VER_MINOR * +([0-9]+)"
CUSPARSELT_VERSION_MINOR "${CUSPARSELT_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUSPARSELT_VER_MINOR * +([0-9]+)" "\\1"
CUSPARSELT_VERSION_MINOR "${CUSPARSELT_VERSION_MINOR}")
string(REGEX MATCH "define CUSPARSELT_VER_PATCH * +([0-9]+)"
CUSPARSELT_VERSION_PATCH "${CUSPARSELT_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUSPARSELT_VER_PATCH * +([0-9]+)" "\\1"
CUSPARSELT_VERSION_PATCH "${CUSPARSELT_VERSION_PATCH}")
# Assemble cuSPARSELt version. Use minor version since current major version is 0.
if(NOT CUSPARSELT_VERSION_MINOR)
set(CUSPARSELT_VERSION "?")
else()
set(CUSPARSELT_VERSION
"${CUSPARSELT_VERSION_MAJOR}.${CUSPARSELT_VERSION_MINOR}.${CUSPARSELT_VERSION_PATCH}")
endif()
endif()
mark_as_advanced(CUSPARSELT_ROOT CUSPARSELT_INCLUDE_DIR CUSPARSELT_LIBRARY CUSPARSELT_VERSION)
@@ -0,0 +1,141 @@
# This will define the following variables:
# SYCL_FOUND : True if the system has the SYCL library.
# SYCL_INCLUDE_DIR : Include directories needed to use SYCL.
# SYCL_LIBRARY_DIR : The path to the SYCL library.
# SYCL_LIBRARY : SYCL library fullname.
# SYCL_COMPILER_VERSION : SYCL compiler version.
include(FindPackageHandleStandardArgs)
set(SYCL_ROOT "")
if(DEFINED ENV{SYCL_ROOT})
set(SYCL_ROOT $ENV{SYCL_ROOT})
elseif(DEFINED ENV{CMPLR_ROOT})
set(SYCL_ROOT $ENV{CMPLR_ROOT})
else()
# Use the default path to ensure proper linking with torch::xpurt when the user is working with libtorch.
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(SYCL_ROOT "/opt/intel/oneapi/compiler/latest")
elseif(CMAKE_SYSTEM_NAME MATCHES "Windows")
set(SYCL_ROOT "C:/Program Files (x86)/Intel/oneAPI/compiler/latest")
endif()
if(NOT EXISTS ${SYCL_ROOT})
set(SYCL_ROOT "")
endif()
endif()
string(COMPARE EQUAL "${SYCL_ROOT}" "" nosyclfound)
if(nosyclfound)
set(SYCL_FOUND False)
set(SYCL_REASON_FAILURE "SYCL library not set!!")
set(SYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}")
return()
endif()
# Find SYCL compiler executable.
find_program(
SYCL_COMPILER
NAMES icx
PATHS "${SYCL_ROOT}"
PATH_SUFFIXES bin bin64
NO_DEFAULT_PATH
)
function(parse_sycl_compiler_version version_number)
# Execute the SYCL compiler with the --version flag to match the version string.
execute_process(COMMAND ${SYCL_COMPILER} --version OUTPUT_VARIABLE SYCL_VERSION_STRING)
string(REGEX REPLACE "Intel\\(R\\) (.*) Compiler ([0-9]+\\.[0-9]+\\.[0-9]+) (.*)" "\\2"
SYCL_VERSION_STRING_MATCH ${SYCL_VERSION_STRING})
string(REPLACE "." ";" SYCL_VERSION_LIST ${SYCL_VERSION_STRING_MATCH})
# Split the version number list into major, minor, and patch components.
list(GET SYCL_VERSION_LIST 0 VERSION_MAJOR)
list(GET SYCL_VERSION_LIST 1 VERSION_MINOR)
list(GET SYCL_VERSION_LIST 2 VERSION_PATCH)
# Calculate the version number in the format XXXXYYZZ, using the formula (major * 10000 + minor * 100 + patch).
math(EXPR VERSION_NUMBER_MATCH "${VERSION_MAJOR} * 10000 + ${VERSION_MINOR} * 100 + ${VERSION_PATCH}")
set(${version_number} "${VERSION_NUMBER_MATCH}" PARENT_SCOPE)
endfunction()
if(SYCL_COMPILER)
parse_sycl_compiler_version(SYCL_COMPILER_VERSION)
endif()
if(NOT SYCL_COMPILER_VERSION)
set(SYCL_FOUND False)
set(SYCL_REASON_FAILURE "Cannot parse sycl compiler version to get SYCL_COMPILER_VERSION!")
set(SYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}")
return()
endif()
# Find include path from binary.
find_file(
SYCL_INCLUDE_DIR
NAMES include
HINTS ${SYCL_ROOT}
NO_DEFAULT_PATH
)
# Find include/sycl path from include path.
find_file(
SYCL_INCLUDE_SYCL_DIR
NAMES sycl
HINTS ${SYCL_ROOT}/include/
NO_DEFAULT_PATH
)
# Due to the unrecognized compilation option `-fsycl` in other compiler.
list(APPEND SYCL_INCLUDE_DIR ${SYCL_INCLUDE_SYCL_DIR})
# Find library directory from binary.
find_file(
SYCL_LIBRARY_DIR
NAMES lib lib64
HINTS ${SYCL_ROOT}
NO_DEFAULT_PATH
)
# Define the old version of SYCL toolkit that is compatible with the current version of PyTorch.
set(PYTORCH_2_5_SYCL_TOOLKIT_VERSION 20249999)
# By default, we use libsycl.so on Linux and sycl.lib on Windows as the SYCL library name.
if (SYCL_COMPILER_VERSION VERSION_LESS_EQUAL PYTORCH_2_5_SYCL_TOOLKIT_VERSION)
# Don't use if(WIN32) here since this requires cmake>=3.25 and file is installed
# and used by other projects.
# See: https://cmake.org/cmake/help/v3.25/variable/LINUX.html
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
# On Windows, the SYCL library is named sycl7.lib until PYTORCH_2_5_SYCL_TOOLKIT_VERSION.
# sycl.lib is supported in the later version.
set(sycl_lib_suffix "7")
endif()
endif()
# Find SYCL library fullname.
find_library(
SYCL_LIBRARY
NAMES "sycl${sycl_lib_suffix}"
HINTS ${SYCL_LIBRARY_DIR}
NO_DEFAULT_PATH
)
# Find OpenCL library fullname, which is a dependency of oneDNN.
find_library(
OCL_LIBRARY
NAMES OpenCL
HINTS ${SYCL_LIBRARY_DIR}
NO_DEFAULT_PATH
)
if((NOT SYCL_LIBRARY) OR (NOT OCL_LIBRARY))
set(SYCL_FOUND False)
set(SYCL_REASON_FAILURE "SYCL library is incomplete!!")
set(SYCL_NOT_FOUND_MESSAGE "${SYCL_REASON_FAILURE}")
return()
endif()
find_package_handle_standard_args(
SYCL
FOUND_VAR SYCL_FOUND
REQUIRED_VARS SYCL_INCLUDE_DIR SYCL_LIBRARY_DIR SYCL_LIBRARY
REASON_FAILURE_MESSAGE "${SYCL_REASON_FAILURE}"
VERSION_VAR SYCL_COMPILER_VERSION
)
@@ -0,0 +1,10 @@
# This is a wrapper of the upstream `./upstream/FindCUDA.cmake` that
# automatically includes `./upstream/CMakeInitializeConfigs.cmake` before
# `./upstream/FindCUDA.cmake`. The `CMakeInitializeConfigs.cmake`, which is
# absent in old CMake versions, creates some necessary variables for the later
# to run.
# See ./README.md for details.
set(UPSTREAM_FIND_CUDA_DIR "${CMAKE_CURRENT_LIST_DIR}/upstream/")
include("${UPSTREAM_FIND_CUDA_DIR}/FindCUDA.cmake")
@@ -0,0 +1,78 @@
# Find the CUDNN libraries
#
# The following variables are optionally searched for defaults
# CUDNN_ROOT: Base directory where CUDNN is found
# CUDNN_INCLUDE_DIR: Directory where CUDNN header is searched for
# CUDNN_LIBRARY: Directory where CUDNN library is searched for
# CUDNN_STATIC: Are we looking for a static library? (default: no)
#
# The following are set after configuration is done:
# CUDNN_FOUND
# CUDNN_INCLUDE_PATH
# CUDNN_LIBRARY_PATH
#
include(FindPackageHandleStandardArgs)
set(CUDNN_ROOT $ENV{CUDNN_ROOT_DIR} CACHE PATH "Folder containing NVIDIA cuDNN")
if (DEFINED $ENV{CUDNN_ROOT_DIR})
message(WARNING "CUDNN_ROOT_DIR is deprecated. Please set CUDNN_ROOT instead.")
endif()
list(APPEND CUDNN_ROOT $ENV{CUDNN_ROOT_DIR} ${CUDA_TOOLKIT_ROOT_DIR})
# Compatible layer for CMake <3.12. CUDNN_ROOT will be accounted in for searching paths and libraries for CMake >=3.12.
list(APPEND CMAKE_PREFIX_PATH ${CUDNN_ROOT})
set(CUDNN_INCLUDE_DIR $ENV{CUDNN_INCLUDE_DIR} CACHE PATH "Folder containing NVIDIA cuDNN header files")
find_path(CUDNN_INCLUDE_PATH cudnn.h
HINTS ${CUDNN_INCLUDE_DIR}
PATH_SUFFIXES cuda/include cuda include)
option(CUDNN_STATIC "Look for static CUDNN" OFF)
if (CUDNN_STATIC)
set(CUDNN_LIBNAME "libcudnn_static.a")
else()
set(CUDNN_LIBNAME "cudnn")
endif()
set(CUDNN_LIBRARY $ENV{CUDNN_LIBRARY} CACHE PATH "Path to the cudnn library file (e.g., libcudnn.so)")
if (CUDNN_LIBRARY MATCHES ".*cudnn_static.a" AND NOT CUDNN_STATIC)
message(WARNING "CUDNN_LIBRARY points to a static library (${CUDNN_LIBRARY}) but CUDNN_STATIC is OFF.")
endif()
find_library(CUDNN_LIBRARY_PATH ${CUDNN_LIBNAME}
PATHS ${CUDNN_LIBRARY}
PATH_SUFFIXES lib lib64 cuda/lib cuda/lib64 lib/x64)
find_package_handle_standard_args(CUDNN DEFAULT_MSG CUDNN_LIBRARY_PATH CUDNN_INCLUDE_PATH)
if(CUDNN_FOUND)
# Get cuDNN version
if(EXISTS ${CUDNN_INCLUDE_PATH}/cudnn_version.h)
file(READ ${CUDNN_INCLUDE_PATH}/cudnn_version.h CUDNN_HEADER_CONTENTS)
else()
file(READ ${CUDNN_INCLUDE_PATH}/cudnn.h CUDNN_HEADER_CONTENTS)
endif()
string(REGEX MATCH "define CUDNN_MAJOR * +([0-9]+)"
CUDNN_VERSION_MAJOR "${CUDNN_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUDNN_MAJOR * +([0-9]+)" "\\1"
CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR}")
string(REGEX MATCH "define CUDNN_MINOR * +([0-9]+)"
CUDNN_VERSION_MINOR "${CUDNN_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUDNN_MINOR * +([0-9]+)" "\\1"
CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR}")
string(REGEX MATCH "define CUDNN_PATCHLEVEL * +([0-9]+)"
CUDNN_VERSION_PATCH "${CUDNN_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUDNN_PATCHLEVEL * +([0-9]+)" "\\1"
CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH}")
# Assemble cuDNN version
if(NOT CUDNN_VERSION_MAJOR)
set(CUDNN_VERSION "?")
else()
set(CUDNN_VERSION
"${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}")
endif()
endif()
mark_as_advanced(CUDNN_ROOT CUDNN_INCLUDE_DIR CUDNN_LIBRARY CUDNN_VERSION)
@@ -0,0 +1,40 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
# Present in upstream, but not supported on versions of cmake we need to support
# include_guard(GLOBAL)
# Initializes `<_PREFIX>_<CONFIG>` variables from the corresponding
# `<_PREFIX>_<CONFIG>_INIT`, for the configurations currently used.
function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING)
string(STRIP "${${_PREFIX}_INIT}" _INIT)
set("${_PREFIX}" "${_INIT}"
CACHE STRING "${_DOCSTRING} during all build types.")
mark_as_advanced("${_PREFIX}")
if (NOT CMAKE_NOT_USING_CONFIG_FLAGS)
set(_CONFIGS Debug Release MinSizeRel RelWithDebInfo)
get_property(_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if (_GENERATOR_IS_MULTI_CONFIG)
list(APPEND _CONFIGS ${CMAKE_CONFIGURATION_TYPES})
else()
if (NOT CMAKE_NO_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE_INIT}" CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel ...")
endif()
list(APPEND _CONFIGS ${CMAKE_BUILD_TYPE})
endif()
list(REMOVE_DUPLICATES _CONFIGS)
foreach(_BUILD_TYPE IN LISTS _CONFIGS)
if (NOT "${_BUILD_TYPE}" STREQUAL "")
string(TOUPPER "${_BUILD_TYPE}" _BUILD_TYPE)
string(STRIP "${${_PREFIX}_${_BUILD_TYPE}_INIT}" _INIT)
set("${_PREFIX}_${_BUILD_TYPE}" "${_INIT}"
CACHE STRING "${_DOCSTRING} during ${_BUILD_TYPE} builds.")
mark_as_advanced("${_PREFIX}_${_BUILD_TYPE}")
endif()
endforeach()
endif()
endfunction()
@@ -0,0 +1,106 @@
# James Bigler, NVIDIA Corp (nvidia.com - jbigler)
# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html
#
# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
#
# Copyright (c) 2007-2009
# Scientific Computing and Imaging Institute, University of Utah
#
# This code is licensed under the MIT License. See the FindCUDA.cmake script
# for the text of the license.
# The MIT License
#
# License for the specific language governing rights and limitations under
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
#######################################################################
# This converts a file written in makefile syntax into one that can be included
# by CMake.
# Input variables
#
# verbose:BOOL=<> OFF: Be as quiet as possible (default)
# ON : Extra output
#
# input_file:FILEPATH=<> Path to dependency file in makefile format
#
# output_file:FILEPATH=<> Path to file with dependencies in CMake readable variable
#
file(READ ${input_file} depend_text)
if (NOT "${depend_text}" STREQUAL "")
# message("FOUND DEPENDS")
string(REPLACE "\\ " " " depend_text ${depend_text})
# This works for the nvcc -M generated dependency files.
string(REGEX REPLACE "^.* : " "" depend_text ${depend_text})
string(REGEX REPLACE "[ \\\\]*\n" ";" depend_text ${depend_text})
set(dependency_list "")
foreach(file ${depend_text})
string(REGEX REPLACE "^ +" "" file ${file})
# OK, now if we had a UNC path, nvcc has a tendency to only output the first '/'
# instead of '//'. Here we will test to see if the file exists, if it doesn't then
# try to prepend another '/' to the path and test again. If it still fails remove the
# path.
if(NOT EXISTS "${file}")
if (EXISTS "/${file}")
set(file "/${file}")
else()
if(verbose)
message(WARNING " Removing non-existent dependency file: ${file}")
endif()
set(file "")
endif()
endif()
# Make sure we check to see if we have a file, before asking if it is not a directory.
# if(NOT IS_DIRECTORY "") will return TRUE.
if(file AND NOT IS_DIRECTORY "${file}")
# If softlinks start to matter, we should change this to REALPATH. For now we need
# to flatten paths, because nvcc can generate stuff like /bin/../include instead of
# just /include.
get_filename_component(file_absolute "${file}" ABSOLUTE)
list(APPEND dependency_list "${file_absolute}")
endif()
endforeach()
else()
# message("FOUND NO DEPENDS")
endif()
# Remove the duplicate entries and sort them.
list(REMOVE_DUPLICATES dependency_list)
list(SORT dependency_list)
foreach(file ${dependency_list})
string(APPEND cuda_nvcc_depend " \"${file}\"\n")
endforeach()
file(WRITE ${output_file} "# Generated by: make2cmake.cmake\nSET(CUDA_NVCC_DEPEND\n ${cuda_nvcc_depend})\n\n")
@@ -0,0 +1,109 @@
# James Bigler, NVIDIA Corp (nvidia.com - jbigler)
# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html
#
# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
#
# Copyright (c) 2007-2009
# Scientific Computing and Imaging Institute, University of Utah
#
# This code is licensed under the MIT License. See the FindCUDA.cmake script
# for the text of the license.
# The MIT License
#
# License for the specific language governing rights and limitations under
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
#######################################################################
# Parses a .cubin file produced by nvcc and reports statistics about the file.
file(READ ${input_file} file_text)
if (NOT "${file_text}" STREQUAL "")
string(REPLACE ";" "\\;" file_text ${file_text})
string(REPLACE "\ncode" ";code" file_text ${file_text})
list(LENGTH file_text len)
foreach(line ${file_text})
# Only look at "code { }" blocks.
if(line MATCHES "^code")
# Break into individual lines.
string(REGEX REPLACE "\n" ";" line ${line})
foreach(entry ${line})
# Extract kernel names.
if (${entry} MATCHES "[^g]name = ([^ ]+)")
set(entry "${CMAKE_MATCH_1}")
# Check to see if the kernel name starts with "_"
set(skip FALSE)
# if (${entry} MATCHES "^_")
# Skip the rest of this block.
# message("Skipping ${entry}")
# set(skip TRUE)
# else ()
message("Kernel: ${entry}")
# endif ()
endif()
# Skip the rest of the block if necessary
if(NOT skip)
# Registers
if (${entry} MATCHES "reg([ ]+)=([ ]+)([^ ]+)")
set(entry "${CMAKE_MATCH_3}")
message("Registers: ${entry}")
endif()
# Local memory
if (${entry} MATCHES "lmem([ ]+)=([ ]+)([^ ]+)")
set(entry "${CMAKE_MATCH_3}")
message("Local: ${entry}")
endif()
# Shared memory
if (${entry} MATCHES "smem([ ]+)=([ ]+)([^ ]+)")
set(entry "${CMAKE_MATCH_3}")
message("Shared: ${entry}")
endif()
if (${entry} MATCHES "^}")
message("")
endif()
endif()
endforeach()
endif()
endforeach()
else()
# message("FOUND NO DEPENDS")
endif()
@@ -0,0 +1,303 @@
# James Bigler, NVIDIA Corp (nvidia.com - jbigler)
#
# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
#
# This code is licensed under the MIT License. See the FindCUDA.cmake script
# for the text of the license.
# The MIT License
#
# License for the specific language governing rights and limitations under
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
##########################################################################
# This file runs the nvcc commands to produce the desired output file along with
# the dependency file needed by CMake to compute dependencies. In addition the
# file checks the output of each command and if the command fails it deletes the
# output files.
# Input variables
#
# verbose:BOOL=<> OFF: Be as quiet as possible (default)
# ON : Describe each step
#
# build_configuration:STRING=<> Typically one of Debug, MinSizeRel, Release, or
# RelWithDebInfo, but it should match one of the
# entries in CUDA_HOST_FLAGS. This is the build
# configuration used when compiling the code. If
# blank or unspecified Debug is assumed as this is
# what CMake does.
#
# generated_file:STRING=<> File to generate. This argument must be passed in.
#
# generated_cubin_file:STRING=<> File to generate. This argument must be passed
# in if build_cubin is true.
cmake_policy(PUSH)
cmake_policy(SET CMP0007 NEW)
cmake_policy(SET CMP0010 NEW)
if(NOT generated_file)
message(FATAL_ERROR "You must specify generated_file on the command line")
endif()
# Set these up as variables to make reading the generated file easier
set(CMAKE_COMMAND "@CMAKE_COMMAND@") # path
set(source_file "@source_file@") # path
set(NVCC_generated_dependency_file "@NVCC_generated_dependency_file@") # path
set(cmake_dependency_file "@cmake_dependency_file@") # path
set(CUDA_make2cmake "@CUDA_make2cmake@") # path
set(CUDA_parse_cubin "@CUDA_parse_cubin@") # path
set(build_cubin @build_cubin@) # bool
set(CUDA_HOST_COMPILER "@CUDA_HOST_COMPILER@") # path
# We won't actually use these variables for now, but we need to set this, in
# order to force this file to be run again if it changes.
set(generated_file_path "@generated_file_path@") # path
set(generated_file_internal "@generated_file@") # path
set(generated_cubin_file_internal "@generated_cubin_file@") # path
set(CUDA_NVCC_EXECUTABLE "@CUDA_NVCC_EXECUTABLE@") # path
set(CUDA_NVCC_FLAGS @CUDA_NVCC_FLAGS@ ;; @CUDA_WRAP_OPTION_NVCC_FLAGS@) # list
@CUDA_NVCC_FLAGS_CONFIG@
set(nvcc_flags @nvcc_flags@) # list
set(CUDA_NVCC_INCLUDE_DIRS [==[@CUDA_NVCC_INCLUDE_DIRS@]==]) # list (needs to be in lua quotes to address backslashes)
string(REPLACE "\\" "/" CUDA_NVCC_INCLUDE_DIRS "${CUDA_NVCC_INCLUDE_DIRS}")
set(CUDA_NVCC_COMPILE_DEFINITIONS [==[@CUDA_NVCC_COMPILE_DEFINITIONS@]==]) # list (needs to be in lua quotes see #16510 ).
set(format_flag "@format_flag@") # string
set(cuda_language_flag @cuda_language_flag@) # list
# Clean up list of include directories and add -I flags
list(REMOVE_DUPLICATES CUDA_NVCC_INCLUDE_DIRS)
set(CUDA_NVCC_INCLUDE_ARGS)
foreach(dir ${CUDA_NVCC_INCLUDE_DIRS})
# Extra quotes are added around each flag to help nvcc parse out flags with spaces.
list(APPEND CUDA_NVCC_INCLUDE_ARGS "-I${dir}")
endforeach()
# Clean up list of compile definitions, add -D flags, and append to nvcc_flags
list(REMOVE_DUPLICATES CUDA_NVCC_COMPILE_DEFINITIONS)
foreach(def ${CUDA_NVCC_COMPILE_DEFINITIONS})
list(APPEND nvcc_flags "-D${def}")
endforeach()
if(build_cubin AND NOT generated_cubin_file)
message(FATAL_ERROR "You must specify generated_cubin_file on the command line")
endif()
# This is the list of host compilation flags. It C or CXX should already have
# been chosen by FindCUDA.cmake.
@CUDA_HOST_FLAGS@
# Take the compiler flags and package them up to be sent to the compiler via -Xcompiler
set(nvcc_host_compiler_flags "")
# If we weren't given a build_configuration, use Debug.
if(NOT build_configuration)
set(build_configuration Debug)
endif()
string(TOUPPER "${build_configuration}" build_configuration)
#message("CUDA_NVCC_HOST_COMPILER_FLAGS = ${CUDA_NVCC_HOST_COMPILER_FLAGS}")
foreach(flag ${CMAKE_HOST_FLAGS} ${CMAKE_HOST_FLAGS_${build_configuration}})
# Extra quotes are added around each flag to help nvcc parse out flags with spaces.
string(APPEND nvcc_host_compiler_flags ",\"${flag}\"")
endforeach()
if (nvcc_host_compiler_flags)
set(nvcc_host_compiler_flags "-Xcompiler" ${nvcc_host_compiler_flags})
endif()
#message("nvcc_host_compiler_flags = \"${nvcc_host_compiler_flags}\"")
# Add the build specific configuration flags
list(APPEND CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS_${build_configuration}})
# Any -ccbin existing in CUDA_NVCC_FLAGS gets highest priority
list( FIND CUDA_NVCC_FLAGS "-ccbin" ccbin_found0 )
list( FIND CUDA_NVCC_FLAGS "--compiler-bindir" ccbin_found1 )
if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 AND CUDA_HOST_COMPILER )
if (CUDA_HOST_COMPILER STREQUAL "@_CUDA_MSVC_HOST_COMPILER@" AND DEFINED CCBIN)
set(CCBIN -ccbin "${CCBIN}")
else()
set(CCBIN -ccbin "${CUDA_HOST_COMPILER}")
endif()
endif()
# cuda_execute_process - Executes a command with optional command echo and status message.
#
# status - Status message to print if verbose is true
# command - COMMAND argument from the usual execute_process argument structure
# ARGN - Remaining arguments are the command with arguments
#
# CUDA_result - return value from running the command
#
# Make this a macro instead of a function, so that things like RESULT_VARIABLE
# and other return variables are present after executing the process.
macro(cuda_execute_process status command)
set(_command ${command})
if(NOT "x${_command}" STREQUAL "xCOMMAND")
message(FATAL_ERROR "Malformed call to cuda_execute_process. Missing COMMAND as second argument. (command = ${command})")
endif()
if(verbose)
execute_process(COMMAND "${CMAKE_COMMAND}" -E echo -- ${status})
# Now we need to build up our command string. We are accounting for quotes
# and spaces, anything else is left up to the user to fix if they want to
# copy and paste a runnable command line.
set(cuda_execute_process_string)
foreach(arg ${ARGN})
# If there are quotes, escape them, so they come through.
string(REPLACE "\"" "\\\"" arg ${arg})
# Args with spaces need quotes around them to get them to be parsed as a single argument.
if(arg MATCHES " ")
list(APPEND cuda_execute_process_string "\"${arg}\"")
else()
list(APPEND cuda_execute_process_string ${arg})
endif()
endforeach()
# Echo the command
execute_process(COMMAND ${CMAKE_COMMAND} -E echo ${cuda_execute_process_string})
endif()
# Run the command
execute_process(COMMAND ${ARGN} RESULT_VARIABLE CUDA_result )
endmacro()
# Delete the target file
cuda_execute_process(
"Removing ${generated_file}"
COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}"
)
# For CUDA 2.3 and below, -G -M doesn't work, so remove the -G flag
# for dependency generation and hope for the best.
set(depends_CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}")
set(CUDA_VERSION @CUDA_VERSION@)
# nvcc doesn't define __CUDACC__ for some reason when generating dependency files. This
# can cause incorrect dependencies when #including files based on this macro which is
# defined in the generating passes of nvcc invocation. We will go ahead and manually
# define this for now until a future version fixes this bug.
set(CUDACC_DEFINE -D__CUDACC__)
# Generate the dependency file
cuda_execute_process(
"Generating dependency file: ${NVCC_generated_dependency_file}"
COMMAND "${CUDA_NVCC_EXECUTABLE}"
-M
${CUDACC_DEFINE}
"${source_file}"
-o "${NVCC_generated_dependency_file}"
${CCBIN}
${nvcc_flags}
${nvcc_host_compiler_flags}
${depends_CUDA_NVCC_FLAGS}
-DNVCC
${CUDA_NVCC_INCLUDE_ARGS}
)
if(CUDA_result)
message(FATAL_ERROR "Error generating ${generated_file}")
endif()
# Generate the cmake readable dependency file to a temp file. Don't put the
# quotes just around the filenames for the input_file and output_file variables.
# CMake will pass the quotes through and not be able to find the file.
cuda_execute_process(
"Generating temporary cmake readable file: ${cmake_dependency_file}.tmp"
COMMAND "${CMAKE_COMMAND}"
-D "input_file:FILEPATH=${NVCC_generated_dependency_file}"
-D "output_file:FILEPATH=${cmake_dependency_file}.tmp"
-D "verbose=${verbose}"
-P "${CUDA_make2cmake}"
)
if(CUDA_result)
message(FATAL_ERROR "Error generating ${generated_file}")
endif()
# Copy the file if it is different
cuda_execute_process(
"Copy if different ${cmake_dependency_file}.tmp to ${cmake_dependency_file}"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${cmake_dependency_file}.tmp" "${cmake_dependency_file}"
)
if(CUDA_result)
message(FATAL_ERROR "Error generating ${generated_file}")
endif()
# Delete the temporary file
cuda_execute_process(
"Removing ${cmake_dependency_file}.tmp and ${NVCC_generated_dependency_file}"
COMMAND "${CMAKE_COMMAND}" -E remove "${cmake_dependency_file}.tmp" "${NVCC_generated_dependency_file}"
)
if(CUDA_result)
message(FATAL_ERROR "Error generating ${generated_file}")
endif()
# Generate the code
cuda_execute_process(
"Generating ${generated_file}"
COMMAND "${CUDA_NVCC_EXECUTABLE}"
"${source_file}"
${cuda_language_flag}
${format_flag} -o "${generated_file}"
${CCBIN}
${nvcc_flags}
${nvcc_host_compiler_flags}
${CUDA_NVCC_FLAGS}
-DNVCC
${CUDA_NVCC_INCLUDE_ARGS}
)
if(CUDA_result)
# Since nvcc can sometimes leave half done files make sure that we delete the output file.
cuda_execute_process(
"Removing ${generated_file}"
COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}"
)
message(FATAL_ERROR "Error generating file ${generated_file}")
else()
if(verbose)
message("Generated ${generated_file} successfully.")
endif()
endif()
# Cubin resource report commands.
if( build_cubin )
# Run with -cubin to produce resource usage report.
cuda_execute_process(
"Generating ${generated_cubin_file}"
COMMAND "${CUDA_NVCC_EXECUTABLE}"
"${source_file}"
${CUDA_NVCC_FLAGS}
${nvcc_flags}
${CCBIN}
${nvcc_host_compiler_flags}
-DNVCC
-cubin
-o "${generated_cubin_file}"
${CUDA_NVCC_INCLUDE_ARGS}
)
# Execute the parser script.
cuda_execute_process(
"Executing the parser script"
COMMAND "${CMAKE_COMMAND}"
-D "input_file:STRING=${generated_cubin_file}"
-P "${CUDA_parse_cubin}"
)
endif()
cmake_policy(POP)
@@ -0,0 +1,297 @@
# Synopsis:
# CUDA_SELECT_NVCC_ARCH_FLAGS(out_variable [target_CUDA_architectures])
# -- Selects GPU arch flags for nvcc based on target_CUDA_architectures
# target_CUDA_architectures : Auto | Common | All | LIST(ARCH_AND_PTX ...)
# - "Auto" detects local machine GPU compute arch at runtime.
# - "Common" and "All" cover common and entire subsets of architectures
# ARCH_AND_PTX : NAME | NUM.NUM | NUM.NUM(NUM.NUM) | NUM.NUM+PTX
# NAME: Kepler Maxwell Kepler+Tegra Kepler+Tesla Maxwell+Tegra Pascal Volta Turing Ampere
# NUM: Any number. Only those pairs are currently accepted by NVCC though:
# 3.5 3.7 5.0 5.2 5.3 6.0 6.2 7.0 7.2 7.5 8.0
# Returns LIST of flags to be added to CUDA_NVCC_FLAGS in ${out_variable}
# Additionally, sets ${out_variable}_readable to the resulting numeric list
# Example:
# CUDA_SELECT_NVCC_ARCH_FLAGS(ARCH_FLAGS 3.0 3.5+PTX 5.2(5.0) Maxwell)
# LIST(APPEND CUDA_NVCC_FLAGS ${ARCH_FLAGS})
#
# More info on CUDA architectures: https://en.wikipedia.org/wiki/CUDA
#
if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language
if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA"
AND CMAKE_CUDA_COMPILER_VERSION MATCHES "^([0-9]+\\.[0-9]+)")
set(CUDA_VERSION "${CMAKE_MATCH_1}")
endif()
endif()
# See: https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/index.html#gpu-feature-list
# This list will be used for CUDA_ARCH_NAME = All option
set(CUDA_KNOWN_GPU_ARCHITECTURES "Kepler" "Maxwell")
# This list will be used for CUDA_ARCH_NAME = Common option (enabled by default)
set(CUDA_COMMON_GPU_ARCHITECTURES "5.0")
# This list is used to filter CUDA archs when autodetecting
set(CUDA_ALL_GPU_ARCHITECTURES "5.0")
if(CUDA_VERSION VERSION_GREATER "10.5")
list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Ampere")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "8.0")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "8.0")
if(CUDA_VERSION VERSION_LESS "11.1")
set(CUDA_LIMIT_GPU_ARCHITECTURE "8.0")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "8.0+PTX")
endif()
endif()
if(NOT CUDA_VERSION VERSION_LESS "11.1")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "8.6")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "8.6")
set(CUDA_LIMIT_GPU_ARCHITECUTRE "8.6")
if(CUDA_VERSION VERSION_LESS "11.8")
set(CUDA_LIMIT_GPU_ARCHITECTURE "8.9")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "8.6+PTX")
endif()
endif()
if(NOT CUDA_VERSION VERSION_LESS "11.8")
list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Ada")
list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Hopper")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "8.9")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "9.0")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "8.9")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "9.0")
endif()
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "9.0a")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "9.0a")
if(CUDA_VERSION VERSION_GREATER "12.6")
list(APPEND CUDA_KNOWN_GPU_ARCHITECTURES "Blackwell")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "10.0")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "10.0a")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "10.1a")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "12.0")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "12.0a")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "10.0")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "10.0a")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "10.1a")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "12.0")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "12.0a")
if(NOT CUDA_VERSION VERSION_LESS "13.0")
list(REMOVE_ITEM CUDA_COMMON_GPU_ARCHITECTURES "10.1a")
list(REMOVE_ITEM CUDA_ALL_GPU_ARCHITECTURES "10.1a")
list(APPEND CUDA_COMMON_GPU_ARCHITECTURES "11.0a")
list(APPEND CUDA_ALL_GPU_ARCHITECTURES "11.0a")
endif()
endif()
################################################################################################
# A function for automatic detection of GPUs installed (if autodetection is enabled)
# Usage:
# CUDA_DETECT_INSTALLED_GPUS(OUT_VARIABLE)
#
function(CUDA_DETECT_INSTALLED_GPUS OUT_VARIABLE)
if(NOT CUDA_GPU_DETECT_OUTPUT)
if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language
set(file "${PROJECT_BINARY_DIR}/detect_cuda_compute_capabilities.cu")
else()
set(file "${PROJECT_BINARY_DIR}/detect_cuda_compute_capabilities.cpp")
endif()
file(WRITE ${file} ""
"#include <cuda_runtime.h>\n"
"#include <cstdio>\n"
"int main()\n"
"{\n"
" int count = 0;\n"
" if (cudaSuccess != cudaGetDeviceCount(&count)) return -1;\n"
" if (count == 0) return -1;\n"
" for (int device = 0; device < count; ++device)\n"
" {\n"
" cudaDeviceProp prop;\n"
" if (cudaSuccess == cudaGetDeviceProperties(&prop, device))\n"
" std::printf(\"%d.%d \", prop.major, prop.minor);\n"
" }\n"
" return 0;\n"
"}\n")
if(CMAKE_CUDA_COMPILER_LOADED) # CUDA as a language
try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file}
RUN_OUTPUT_VARIABLE compute_capabilities)
else()
try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CUDA_INCLUDE_DIRS}"
LINK_LIBRARIES ${CUDA_LIBRARIES}
RUN_OUTPUT_VARIABLE compute_capabilities)
endif()
# Filter unrelated content out of the output.
string(REGEX MATCHALL "[0-9]+\\.[0-9]+" compute_capabilities "${compute_capabilities}")
if(run_result EQUAL 0)
string(REPLACE "2.1" "2.1(2.0)" compute_capabilities "${compute_capabilities}")
set(CUDA_GPU_DETECT_OUTPUT ${compute_capabilities}
CACHE INTERNAL "Returned GPU architectures from detect_gpus tool" FORCE)
endif()
endif()
if(NOT CUDA_GPU_DETECT_OUTPUT)
message(STATUS "Automatic GPU detection failed. Building for common architectures.")
set(${OUT_VARIABLE} ${CUDA_COMMON_GPU_ARCHITECTURES} PARENT_SCOPE)
else()
# Filter based on CUDA version supported archs
set(CUDA_GPU_DETECT_OUTPUT_FILTERED "")
separate_arguments(CUDA_GPU_DETECT_OUTPUT)
foreach(ITEM IN ITEMS ${CUDA_GPU_DETECT_OUTPUT})
if(CUDA_LIMIT_GPU_ARCHITECTURE AND (ITEM VERSION_GREATER CUDA_LIMIT_GPU_ARCHITECTURE OR
ITEM VERSION_EQUAL CUDA_LIMIT_GPU_ARCHITECTURE))
list(GET CUDA_COMMON_GPU_ARCHITECTURES -1 NEWITEM)
string(APPEND CUDA_GPU_DETECT_OUTPUT_FILTERED " ${NEWITEM}")
else()
string(APPEND CUDA_GPU_DETECT_OUTPUT_FILTERED " ${ITEM}")
endif()
endforeach()
set(${OUT_VARIABLE} ${CUDA_GPU_DETECT_OUTPUT_FILTERED} PARENT_SCOPE)
endif()
endfunction()
################################################################################################
# Function for selecting GPU arch flags for nvcc based on CUDA architectures from parameter list
# Usage:
# SELECT_NVCC_ARCH_FLAGS(out_variable [list of CUDA compute archs])
function(CUDA_SELECT_NVCC_ARCH_FLAGS out_variable)
set(CUDA_ARCH_LIST "${ARGN}")
if("X${CUDA_ARCH_LIST}" STREQUAL "X" )
set(CUDA_ARCH_LIST "Auto")
endif()
set(cuda_arch_bin)
set(cuda_arch_ptx)
if("${CUDA_ARCH_LIST}" STREQUAL "All")
set(CUDA_ARCH_LIST ${CUDA_KNOWN_GPU_ARCHITECTURES})
elseif("${CUDA_ARCH_LIST}" STREQUAL "Common")
set(CUDA_ARCH_LIST ${CUDA_COMMON_GPU_ARCHITECTURES})
elseif("${CUDA_ARCH_LIST}" STREQUAL "Auto")
CUDA_DETECT_INSTALLED_GPUS(CUDA_ARCH_LIST)
message(STATUS "Autodetected CUDA architecture(s): ${CUDA_ARCH_LIST}")
endif()
# Now process the list and look for names
string(REGEX REPLACE "[ \t]+" ";" CUDA_ARCH_LIST "${CUDA_ARCH_LIST}")
list(REMOVE_DUPLICATES CUDA_ARCH_LIST)
foreach(arch_name ${CUDA_ARCH_LIST})
set(arch_bin)
set(arch_ptx)
set(add_ptx FALSE)
# Check to see if we are compiling PTX
if(arch_name MATCHES "(.*)\\+PTX$")
set(add_ptx TRUE)
set(arch_name ${CMAKE_MATCH_1})
endif()
if(arch_name MATCHES "^([0-9]+\\.[0-9][af]?(\\([0-9]+\\.[0-9]\\))?)$")
set(arch_bin ${CMAKE_MATCH_1})
set(arch_ptx ${arch_bin})
else()
# Look for it in our list of known architectures
if(${arch_name} STREQUAL "Kepler+Tesla")
set(arch_bin 3.7)
elseif(${arch_name} STREQUAL "Kepler")
set(arch_bin 3.5)
set(arch_ptx 3.5)
elseif(${arch_name} STREQUAL "Maxwell+Tegra")
set(arch_bin 5.3)
elseif(${arch_name} STREQUAL "Maxwell")
set(arch_bin 5.0 5.2)
set(arch_ptx 5.2)
elseif(${arch_name} STREQUAL "Pascal")
set(arch_bin 6.0 6.1)
set(arch_ptx 6.1)
elseif(${arch_name} STREQUAL "Volta+Tegra")
set(arch_bin 7.2)
elseif(${arch_name} STREQUAL "Volta")
set(arch_bin 7.0 7.0)
set(arch_ptx 7.0)
elseif(${arch_name} STREQUAL "Turing")
set(arch_bin 7.5)
set(arch_ptx 7.5)
elseif(${arch_name} STREQUAL "Ampere+Tegra")
set(arch_bin 8.7)
elseif(${arch_name} STREQUAL "Ampere")
set(arch_bin 8.0 8.6)
set(arch_ptx 8.0 8.6)
elseif(${arch_name} STREQUAL "Ada")
set(arch_bin 8.9)
set(arch_ptx 8.9)
elseif(${arch_name} STREQUAL "Hopper")
set(arch_bin 9.0)
set(arch_ptx 9.0)
elseif(${arch_name} STREQUAL "Blackwell+Tegra")
set(arch_bin 10.1)
elseif(${arch_name} STREQUAL "Blackwell")
set(arch_bin 10.0 12.0)
set(arch_ptx 10.0 12.0)
else()
message(SEND_ERROR "Found Unknown CUDA Architecture Name in CUDA_SELECT_NVCC_ARCH_FLAGS: ${arch_name} ")
endif()
endif()
if(NOT arch_bin)
message(SEND_ERROR "arch_bin wasn't set for some reason")
endif()
list(APPEND cuda_arch_bin ${arch_bin})
if(add_ptx)
if (NOT arch_ptx)
set(arch_ptx ${arch_bin})
endif()
list(APPEND cuda_arch_ptx ${arch_ptx})
endif()
endforeach()
# remove dots and convert to lists
string(REGEX REPLACE "\\." "" cuda_arch_bin "${cuda_arch_bin}")
string(REGEX REPLACE "\\." "" cuda_arch_ptx "${cuda_arch_ptx}")
string(REGEX MATCHALL "[0-9()]+[af]?" cuda_arch_bin "${cuda_arch_bin}")
string(REGEX MATCHALL "[0-9]+[af]?" cuda_arch_ptx "${cuda_arch_ptx}")
if(cuda_arch_bin)
list(REMOVE_DUPLICATES cuda_arch_bin)
endif()
if(cuda_arch_ptx)
list(REMOVE_DUPLICATES cuda_arch_ptx)
endif()
set(nvcc_flags "")
set(nvcc_archs_readable "")
# Tell NVCC to add binaries for the specified GPUs
foreach(arch ${cuda_arch_bin})
if(arch MATCHES "([0-9]+)\\(([0-9]+)\\)")
# User explicitly specified ARCH for the concrete CODE
list(APPEND nvcc_flags -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1})
list(APPEND nvcc_archs_readable sm_${CMAKE_MATCH_1})
else()
# User didn't explicitly specify ARCH for the concrete CODE, we assume ARCH=CODE
list(APPEND nvcc_flags -gencode arch=compute_${arch},code=sm_${arch})
list(APPEND nvcc_archs_readable sm_${arch})
endif()
endforeach()
# Tell NVCC to add PTX intermediate code for the specified architectures
foreach(arch ${cuda_arch_ptx})
list(APPEND nvcc_flags -gencode arch=compute_${arch},code=compute_${arch})
list(APPEND nvcc_archs_readable compute_${arch})
endforeach()
string(REPLACE ";" " " nvcc_archs_readable "${nvcc_archs_readable}")
set(${out_variable} ${nvcc_flags} PARENT_SCOPE)
set(${out_variable}_readable ${nvcc_archs_readable} PARENT_SCOPE)
endfunction()
@@ -0,0 +1,47 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
#.rst:
# FindPackageMessage
# ------------------
#
#
#
# FIND_PACKAGE_MESSAGE(<name> "message for user" "find result details")
#
# This macro is intended to be used in FindXXX.cmake modules files. It
# will print a message once for each unique find result. This is useful
# for telling the user where a package was found. The first argument
# specifies the name (XXX) of the package. The second argument
# specifies the message to display. The third argument lists details
# about the find result so that if they change the message will be
# displayed again. The macro also obeys the QUIET argument to the
# find_package command.
#
# Example:
#
# ::
#
# if(X11_FOUND)
# FIND_PACKAGE_MESSAGE(X11 "Found X11: ${X11_X11_LIB}"
# "[${X11_X11_LIB}][${X11_INCLUDE_DIR}]")
# else()
# ...
# endif()
function(FIND_PACKAGE_MESSAGE pkg msg details)
# Avoid printing a message repeatedly for the same find result.
if(NOT ${pkg}_FIND_QUIETLY)
string(REPLACE "\n" "" details "${details}")
set(DETAILS_VAR FIND_PACKAGE_MESSAGE_DETAILS_${pkg})
if(NOT "${details}" STREQUAL "${${DETAILS_VAR}}")
# The message has not yet been printed.
message(STATUS "${msg}")
# Save the find details in the cache to avoid printing the same
# message again.
set("${DETAILS_VAR}" "${details}"
CACHE INTERNAL "Details about finding ${pkg}")
endif()
endif()
endfunction()
@@ -0,0 +1,287 @@
set(PYTORCH_FOUND_HIP FALSE)
# If ROCM_PATH is set, assume intention is to compile with
# ROCm support and error out if the ROCM_PATH does not exist.
# Else ROCM_PATH does not exist, try to get it from rocm-sdk,
# or assume a default of /opt/rocm
# In the latter case, if /opt/rocm does not exist emit status
# message and return.
if(DEFINED ENV{ROCM_PATH})
file(TO_CMAKE_PATH "$ENV{ROCM_PATH}" ROCM_PATH)
if(NOT EXISTS ${ROCM_PATH})
message(FATAL_ERROR
"ROCM_PATH environment variable is set to ${ROCM_PATH} but does not exist.\n"
"Set a valid ROCM_PATH or unset ROCM_PATH environment variable to fix.")
endif()
else()
# Try to get ROCM_PATH from rocm-sdk if available
find_program(ROCM_SDK_EXECUTABLE rocm-sdk)
if(ROCM_SDK_EXECUTABLE)
execute_process(
COMMAND ${ROCM_SDK_EXECUTABLE} path --root
OUTPUT_VARIABLE ROCM_SDK_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE ROCM_SDK_RESULT
ERROR_QUIET
)
if(ROCM_SDK_RESULT EQUAL 0 AND EXISTS "${ROCM_SDK_PATH}")
set(ROCM_PATH "${ROCM_SDK_PATH}")
message(STATUS "Found ROCm installation via rocm-sdk at: ${ROCM_PATH}")
endif()
endif()
# Fall back to default paths if rocm-sdk did not work
if(NOT DEFINED ROCM_PATH OR NOT EXISTS ${ROCM_PATH})
if(UNIX)
set(ROCM_PATH /opt/rocm)
else() # Win32
set(ROCM_PATH C:/opt/rocm)
endif()
endif()
if(NOT EXISTS ${ROCM_PATH})
message(STATUS
"ROCM_PATH environment variable is not set and ${ROCM_PATH} does not exist.\n"
"Building without ROCm support.")
return()
endif()
endif()
# MAGMA_HOME
if(NOT DEFINED ENV{MAGMA_HOME})
set(MAGMA_HOME ${ROCM_PATH}/magma)
set(ENV{MAGMA_HOME} ${ROCM_PATH}/magma)
else()
file(TO_CMAKE_PATH "$ENV{MAGMA_HOME}" MAGMA_HOME)
endif()
# MIOpen isn't a part of HIP-SDK for Windows and hence, may have a different
# installation directory.
if(WIN32)
if(NOT DEFINED ENV{MIOPEN_PATH})
set(miopen_DIR C:/opt/miopen/lib/cmake/miopen)
else()
set(miopen_DIR $ENV{MIOPEN_PATH}/lib/cmake/miopen)
endif()
endif()
torch_hip_get_arch_list(PYTORCH_ROCM_ARCH)
if(PYTORCH_ROCM_ARCH STREQUAL "")
message(FATAL_ERROR "No GPU arch specified for ROCm build. Please use PYTORCH_ROCM_ARCH environment variable to specify GPU archs to build for.")
endif()
message("Building PyTorch for GPU arch: ${PYTORCH_ROCM_ARCH}")
# Add HIP to the CMAKE Module Path
# needed because the find_package call to this module uses the Module mode search
# https://cmake.org/cmake/help/latest/command/find_package.html#search-modes
if(UNIX)
set(CMAKE_MODULE_PATH ${ROCM_PATH}/lib/cmake/hip;${ROCM_PATH}/lib/${CMAKE_LIBRARY_ARCHITECTURE}/cmake/hip ${CMAKE_MODULE_PATH})
else() # Win32
set(CMAKE_MODULE_PATH ${ROCM_PATH}/cmake/ ${CMAKE_MODULE_PATH})
endif()
# Add ROCM_PATH to CMAKE_PREFIX_PATH, needed because the find_package
# call to individual ROCM components uses the Config mode search
list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH})
macro(find_package_and_print_version PACKAGE_NAME)
find_package("${PACKAGE_NAME}" ${ARGN})
if(NOT ${PACKAGE_NAME}_FOUND)
message("Optional package ${PACKAGE_NAME} not found")
else()
message("${PACKAGE_NAME} VERSION: ${${PACKAGE_NAME}_VERSION}")
if(${PACKAGE_NAME}_INCLUDE_DIR)
list(APPEND ROCM_INCLUDE_DIRS ${${PACKAGE_NAME}_INCLUDE_DIR})
endif()
endif()
endmacro()
# Find the HIP Package
# MODULE argument is added for clarity that CMake is searching
# for FindHIP.cmake in Module mode
find_package_and_print_version(HIP 1.0 MODULE)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
enable_language(HIP)
endif()
if(HIP_FOUND)
set(PYTORCH_FOUND_HIP TRUE)
find_package_and_print_version(hip REQUIRED CONFIG)
if(HIP_VERSION)
# Check if HIP_VERSION contains a dash (e.g., "7.1.25421-32f9fa6ca5")
# and strip everything after it to get clean numeric version
string(FIND "${HIP_VERSION}" "-" DASH_POS)
if(NOT DASH_POS EQUAL -1)
string(SUBSTRING "${HIP_VERSION}" 0 ${DASH_POS} HIP_VERSION_CLEAN)
set(HIP_VERSION "${HIP_VERSION_CLEAN}")
else()
set(HIP_VERSION_CLEAN "${HIP_VERSION}")
endif()
message("HIP version: ${HIP_VERSION}")
else()
set(HIP_VERSION_CLEAN "")
endif()
# The rocm-core package was only introduced in ROCm 6.4, so we make it optional.
find_package(rocm-core CONFIG)
# Some old consumer HIP SDKs do not distribute rocm_version.h, so we allow
# falling back to the hip version, which everyone should have.
# rocm_version.h lives in the rocm-core package and hip_version.h lives in the
# hip (lower-case) package. Both are probed above and will be in
# ROCM_INCLUDE_DIRS if available.
find_file(ROCM_VERSION_HEADER_PATH
NAMES rocm-core/rocm_version.h hip/hip_version.h
NO_DEFAULT_PATH
PATHS ${ROCM_INCLUDE_DIRS}
)
if(ROCM_VERSION_HEADER_PATH MATCHES "rocm-core/rocm_version.h$")
set(ROCM_LIB_NAME "ROCM")
else()
set(ROCM_LIB_NAME "HIP")
endif()
if(NOT ROCM_VERSION_HEADER_PATH)
message(FATAL_ERROR "Could not find hip/hip_version.h or rocm-core/rocm_version.h in ${ROCM_INCLUDE_DIRS}")
endif()
get_filename_component(ROCM_HEADER_NAME ${ROCM_VERSION_HEADER_PATH} NAME)
if(EXISTS ${ROCM_VERSION_HEADER_PATH})
set(ROCM_HEADER_FILE ${ROCM_VERSION_HEADER_PATH})
else()
message(FATAL_ERROR "********************* ${ROCM_HEADER_NAME} could not be found ******************\n")
endif()
# Read the ROCM headerfile into a variable
message(STATUS "Reading ROCM version from: ${ROCM_HEADER_FILE}")
message(STATUS "Content: ${ROCM_HEADER_CONTENT}")
file(READ "${ROCM_HEADER_FILE}" ROCM_HEADER_CONTENT)
# Below we use a RegEx to find ROCM version numbers.
# Note that CMake does not support \s for blank space. That is
# why in the regular expressions below we have a blank space in
# the square brackets.
# There are three steps:
# 1. Match regular expression
# 2. Strip the non-numerical part of the string
# 3. Strip leading and trailing spaces
string(REGEX MATCH "${ROCM_LIB_NAME}_VERSION_MAJOR[ ]+[0-9]+" TEMP1 ${ROCM_HEADER_CONTENT})
string(REPLACE "${ROCM_LIB_NAME}_VERSION_MAJOR" "" TEMP2 ${TEMP1})
string(STRIP ${TEMP2} ROCM_VERSION_DEV_MAJOR)
string(REGEX MATCH "${ROCM_LIB_NAME}_VERSION_MINOR[ ]+[0-9]+" TEMP1 ${ROCM_HEADER_CONTENT})
string(REPLACE "${ROCM_LIB_NAME}_VERSION_MINOR" "" TEMP2 ${TEMP1})
string(STRIP ${TEMP2} ROCM_VERSION_DEV_MINOR)
string(REGEX MATCH "${ROCM_LIB_NAME}_VERSION_PATCH[ ]+[0-9]+" TEMP1 ${ROCM_HEADER_CONTENT})
string(REPLACE "${ROCM_LIB_NAME}_VERSION_PATCH" "" TEMP2 ${TEMP1})
string(STRIP ${TEMP2} ROCM_VERSION_DEV_PATCH)
# Create ROCM_VERSION_DEV_INT which is later used as a preprocessor macros
set(ROCM_VERSION_DEV "${ROCM_VERSION_DEV_MAJOR}.${ROCM_VERSION_DEV_MINOR}.${ROCM_VERSION_DEV_PATCH}")
math(EXPR ROCM_VERSION_DEV_INT "(${ROCM_VERSION_DEV_MAJOR}*10000) + (${ROCM_VERSION_DEV_MINOR}*100) + ${ROCM_VERSION_DEV_PATCH}")
message("\n***** ROCm version from ${ROCM_HEADER_NAME} ****\n")
message("ROCM_VERSION_DEV: ${ROCM_VERSION_DEV}")
message("ROCM_VERSION_DEV_MAJOR: ${ROCM_VERSION_DEV_MAJOR}")
message("ROCM_VERSION_DEV_MINOR: ${ROCM_VERSION_DEV_MINOR}")
message("ROCM_VERSION_DEV_PATCH: ${ROCM_VERSION_DEV_PATCH}")
message("ROCM_VERSION_DEV_INT: ${ROCM_VERSION_DEV_INT}")
math(EXPR TORCH_HIP_VERSION "(${HIP_VERSION_MAJOR} * 100) + ${HIP_VERSION_MINOR}")
message("HIP_VERSION_MAJOR: ${HIP_VERSION_MAJOR}")
message("HIP_VERSION_MINOR: ${HIP_VERSION_MINOR}")
message("TORCH_HIP_VERSION: ${TORCH_HIP_VERSION}")
# Find ROCM components using Config mode
# These components will be searced for recursively in ${ROCM_PATH}
message("\n***** Library versions from cmake find_package *****\n")
find_package_and_print_version(amd_comgr REQUIRED)
find_package_and_print_version(rocrand REQUIRED)
find_package_and_print_version(hiprand REQUIRED)
find_package_and_print_version(rocblas REQUIRED)
find_package_and_print_version(hipblas REQUIRED)
find_package_and_print_version(miopen REQUIRED)
find_package_and_print_version(hipfft REQUIRED)
find_package_and_print_version(hipsparse REQUIRED)
find_package_and_print_version(rocprim REQUIRED)
find_package_and_print_version(hipcub REQUIRED)
find_package_and_print_version(rocthrust REQUIRED)
find_package_and_print_version(hipsolver REQUIRED)
find_package_and_print_version(rocsolver REQUIRED)
find_package_and_print_version(rocshmem)
# workaround cmake 4 build issue
if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.0.0")
message(WARNING "Work around hiprtc cmake failure for cmake >= 4")
set(CMAKE_POLICY_VERSION_MINIMUM 3.5)
find_package_and_print_version(hiprtc REQUIRED)
unset(CMAKE_POLICY_VERSION_MINIMUM)
else()
find_package_and_print_version(hiprtc REQUIRED)
endif()
find_package_and_print_version(hipblaslt REQUIRED)
if(UNIX)
find_package_and_print_version(rccl)
find_package_and_print_version(hsa-runtime64 REQUIRED)
find_package_and_print_version(rocm_smi REQUIRED)
endif()
# Optional components.
find_package_and_print_version(hipsparselt) # Will be required when ready.
list(REMOVE_DUPLICATES ROCM_INCLUDE_DIRS)
if(UNIX)
# roctx is part of roctracer
find_library(ROCM_ROCTX_LIB roctx64 HINTS ${ROCM_PATH}/lib)
set(PROJECT_RANDOM_BINARY_DIR "${PROJECT_BINARY_DIR}")
if(ROCM_VERSION_DEV VERSION_GREATER_EQUAL "5.7.0")
# check whether hipblaslt provides HIPBLASLT_MATMUL_MATRIX_SCALE_OUTER_VEC_32F
set(file "${PROJECT_BINARY_DIR}/hipblaslt_test_outer_vec.cc")
file(WRITE ${file} ""
"#define LEGACY_HIPBLAS_DIRECT\n"
"#include <hipblaslt/hipblaslt.h>\n"
"int main() {\n"
" hipblasLtMatmulMatrixScale_t attr = HIPBLASLT_MATMUL_MATRIX_SCALE_OUTER_VEC_32F;\n"
" return 0;\n"
"}\n"
)
try_compile(hipblaslt_compile_result_outer_vec ${PROJECT_RANDOM_BINARY_DIR} ${file}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${ROCM_INCLUDE_DIRS}"
COMPILE_DEFINITIONS -D__HIP_PLATFORM_AMD__ -D__HIP_PLATFORM_HCC__
OUTPUT_VARIABLE hipblaslt_compile_output_outer_vec)
# check whether hipblaslt provides HIPBLASLT_MATMUL_DESC_A_SCALE_POINTER_VEC_EXT
set(file "${PROJECT_BINARY_DIR}/hipblaslt_test_vec_ext.cc")
file(WRITE ${file} ""
"#define LEGACY_HIPBLAS_DIRECT\n"
"#include <hipblaslt/hipblaslt.h>\n"
"int main() {\n"
" hipblasLtMatmulDescAttributes_t attr = HIPBLASLT_MATMUL_DESC_A_SCALE_POINTER_VEC_EXT;\n"
" return 0;\n"
"}\n"
)
try_compile(hipblaslt_compile_result_vec_ext ${PROJECT_RANDOM_BINARY_DIR} ${file}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${ROCM_INCLUDE_DIRS}"
COMPILE_DEFINITIONS -D__HIP_PLATFORM_AMD__ -D__HIP_PLATFORM_HCC__
OUTPUT_VARIABLE hipblaslt_compile_output_vec_ext)
if(hipblaslt_compile_result_outer_vec)
set(HIPBLASLT_OUTER_VEC ON)
set(HIPBLASLT_VEC_EXT OFF)
message("hipblaslt is using scale pointer outer vec")
elseif(hipblaslt_compile_result_vec_ext)
set(HIPBLASLT_OUTER_VEC OFF)
set(HIPBLASLT_VEC_EXT ON)
message("hipblaslt is using scale pointer vec ext")
else()
set(HIPBLASLT_OUTER_VEC OFF)
set(HIPBLASLT_VEC_EXT OFF)
message("hipblaslt is NOT using scale pointer outer vec: ${hipblaslt_compile_output_outer_vec}")
message("hipblaslt is NOT using scale pointer vec ext: ${hipblaslt_compile_output_vec_ext}")
endif()
endif()
endif()
endif()
@@ -0,0 +1,404 @@
# ---[ cuda
# Poor man's include guard
if(TARGET torch::cudart)
return()
endif()
# sccache is only supported in CMake master and not in the newest official
# release (3.11.3) yet. Hence we need our own Modules_CUDA_fix to enable sccache.
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../Modules_CUDA_fix)
# We don't want to statically link cudart, because we rely on it's dynamic linkage in
# python (follow along torch/cuda/__init__.py and usage of cudaGetErrorName).
# Technically, we can link cudart here statically, and link libtorch_python.so
# to a dynamic libcudart.so, but that's just wasteful.
# However, on Windows, if this one gets switched off, the error "cuda: unknown error"
# will be raised when running the following code:
# >>> import torch
# >>> torch.cuda.is_available()
# >>> torch.cuda.current_device()
# More details can be found in the following links.
# https://github.com/pytorch/pytorch/issues/20635
# https://github.com/pytorch/pytorch/issues/17108
if(NOT MSVC)
set(CUDA_USE_STATIC_CUDA_RUNTIME OFF CACHE INTERNAL "")
endif()
# Find CUDA.
find_package(CUDA)
if(NOT CUDA_FOUND)
# If user explicitly set USE_CUDA=1, error out instead of falling back
if(_USE_CUDA_EXPLICITLY_SET AND USE_CUDA)
message(FATAL_ERROR
"PyTorch: CUDA was explicitly requested (USE_CUDA=1) but cannot be found. "
"Please check your CUDA installation, ensure CUDA toolkit is installed, "
"and that CUDA_HOME or CMAKE_CUDA_COMPILER is set correctly. "
"If you want to build without CUDA, please set USE_CUDA=0.")
endif()
message(WARNING
"PyTorch: CUDA cannot be found. Depending on whether you are building "
"PyTorch or a PyTorch dependent library, the next warning / error will "
"give you more info.")
set(CAFFE2_USE_CUDA OFF)
return()
endif()
# Enable CUDA language support
set(CUDAToolkit_ROOT "${CUDA_TOOLKIT_ROOT_DIR}")
# Pass clang as host compiler, which according to the docs
# Must be done before CUDA language is enabled, see
# https://cmake.org/cmake/help/v3.15/variable/CMAKE_CUDA_HOST_COMPILER.html
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CUDA_HOST_COMPILER "${CMAKE_CXX_COMPILER}")
endif()
enable_language(CUDA)
if("X${CMAKE_CUDA_STANDARD}" STREQUAL "X" )
set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD})
endif()
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
# CMP0074 - find_package will respect <PackageName>_ROOT variables
cmake_policy(PUSH)
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.12.0)
cmake_policy(SET CMP0074 NEW)
endif()
find_package(CUDAToolkit REQUIRED)
cmake_policy(POP)
if(NOT CMAKE_CUDA_COMPILER_VERSION VERSION_EQUAL CUDAToolkit_VERSION)
message(FATAL_ERROR "Found two conflicting CUDA versions:\n"
"V${CMAKE_CUDA_COMPILER_VERSION} in '${CUDA_INCLUDE_DIRS}' and\n"
"V${CUDAToolkit_VERSION} in '${CUDAToolkit_INCLUDE_DIRS}'")
endif()
message(STATUS "PyTorch: CUDA detected: " ${CUDA_VERSION})
message(STATUS "PyTorch: CUDA nvcc is: " ${CUDA_NVCC_EXECUTABLE})
message(STATUS "PyTorch: CUDA toolkit directory: " ${CUDA_TOOLKIT_ROOT_DIR})
if(CUDA_VERSION VERSION_LESS 12.1)
message(FATAL_ERROR "PyTorch requires CUDA 12.1 or above.")
endif()
if(CUDA_FOUND)
# Sometimes, we may mismatch nvcc with the CUDA headers we are
# compiling with, e.g., if a ccache nvcc is fed to us by CUDA_NVCC_EXECUTABLE
# but the PATH is not consistent with CUDA_HOME. It's better safe
# than sorry: make sure everything is consistent.
if(MSVC AND CMAKE_GENERATOR MATCHES "Visual Studio")
# When using Visual Studio, it attempts to lock the whole binary dir when
# `try_run` is called, which will cause the build to fail.
string(RANDOM BUILD_SUFFIX)
set(PROJECT_RANDOM_BINARY_DIR "${PROJECT_BINARY_DIR}/${BUILD_SUFFIX}")
else()
set(PROJECT_RANDOM_BINARY_DIR "${PROJECT_BINARY_DIR}")
endif()
set(file "${PROJECT_BINARY_DIR}/detect_cuda_version.cc")
file(WRITE ${file} ""
"#include <cuda.h>\n"
"#include <cstdio>\n"
"int main() {\n"
" printf(\"%d.%d\", CUDA_VERSION / 1000, (CUDA_VERSION / 10) % 100);\n"
" return 0;\n"
"}\n"
)
if(NOT CMAKE_CROSSCOMPILING)
try_run(run_result compile_result ${PROJECT_RANDOM_BINARY_DIR} ${file}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CUDA_INCLUDE_DIRS}"
LINK_LIBRARIES ${CUDA_LIBRARIES}
RUN_OUTPUT_VARIABLE cuda_version_from_header
COMPILE_OUTPUT_VARIABLE output_var
)
if(NOT compile_result)
message(FATAL_ERROR "PyTorch: Couldn't determine version from header: " ${output_var})
endif()
message(STATUS "PyTorch: Header version is: " ${cuda_version_from_header})
if(NOT cuda_version_from_header STREQUAL ${CUDA_VERSION_STRING})
# Force CUDA to be processed for again next time
# TODO: I'm not sure if this counts as an implementation detail of
# FindCUDA
set(cuda_version_from_findcuda ${CUDA_VERSION_STRING})
unset(CUDA_TOOLKIT_ROOT_DIR_INTERNAL CACHE)
# Not strictly necessary, but for good luck.
unset(CUDA_VERSION CACHE)
# Error out
message(FATAL_ERROR "FindCUDA says CUDA version is ${cuda_version_from_findcuda} (usually determined by nvcc), "
"but the CUDA headers say the version is ${cuda_version_from_header}. This often occurs "
"when you set both CUDA_HOME and CUDA_NVCC_EXECUTABLE to "
"non-standard locations, without also setting PATH to point to the correct nvcc. "
"Perhaps, try re-running this command again with PATH=${CUDA_TOOLKIT_ROOT_DIR}/bin:$PATH. "
"See above log messages for more diagnostics, and see https://github.com/pytorch/pytorch/issues/8092 for more details.")
endif()
endif()
endif()
# ---[ CUDA libraries wrapper
# find lbnvrtc.so
set(CUDA_NVRTC_LIB "${CUDA_nvrtc_LIBRARY}" CACHE FILEPATH "")
if(CUDA_NVRTC_LIB AND NOT CUDA_NVRTC_SHORTHASH)
find_package(Python COMPONENTS Interpreter)
execute_process(
COMMAND "${Python_EXECUTABLE}" -c
"import hashlib;hash=hashlib.sha256();hash.update(open('${CUDA_NVRTC_LIB}','rb').read());print(hash.hexdigest()[:8])"
RESULT_VARIABLE _retval
OUTPUT_VARIABLE CUDA_NVRTC_SHORTHASH)
if(NOT _retval EQUAL 0)
message(WARNING "Failed to compute shorthash for libnvrtc.so")
set(CUDA_NVRTC_SHORTHASH "XXXXXXXX")
else()
string(STRIP "${CUDA_NVRTC_SHORTHASH}" CUDA_NVRTC_SHORTHASH)
message(STATUS "${CUDA_NVRTC_LIB} shorthash is ${CUDA_NVRTC_SHORTHASH}")
endif()
endif()
# Create new style imported libraries.
# Several of these libraries have a hardcoded path if CAFFE2_STATIC_LINK_CUDA
# is set. This path is where sane CUDA installations have their static
# libraries installed. This flag should only be used for binary builds, so
# end-users should never have this flag set.
# cuda
add_library(caffe2::cuda INTERFACE IMPORTED)
set_property(
TARGET caffe2::cuda PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::cuda_driver)
# cudart
add_library(torch::cudart INTERFACE IMPORTED)
if(CAFFE2_STATIC_LINK_CUDA)
set_property(
TARGET torch::cudart PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::cudart_static)
else()
set_property(
TARGET torch::cudart PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::cudart)
endif()
# cublas
add_library(caffe2::cublas INTERFACE IMPORTED)
if(CAFFE2_STATIC_LINK_CUDA AND NOT WIN32)
set_property(
TARGET caffe2::cublas PROPERTY INTERFACE_LINK_LIBRARIES
# NOTE: cublas is always linked dynamically
CUDA::cublas CUDA::cublasLt)
set_property(
TARGET caffe2::cublas APPEND PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::cudart_static rt)
else()
set_property(
TARGET caffe2::cublas PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::cublas CUDA::cublasLt)
endif()
# cudnn interface
# static linking is handled by USE_STATIC_CUDNN environment variable
if(CAFFE2_USE_CUDNN)
if(USE_STATIC_CUDNN)
set(CUDNN_STATIC ON CACHE BOOL "")
else()
set(CUDNN_STATIC OFF CACHE BOOL "")
endif()
find_package(CUDNN)
if(NOT CUDNN_FOUND)
message(WARNING
"Cannot find cuDNN library. Turning the option off")
set(CAFFE2_USE_CUDNN OFF)
else()
if(CUDNN_VERSION VERSION_LESS "8.1.0")
message(FATAL_ERROR "PyTorch requires cuDNN 8.1 and above.")
endif()
endif()
add_library(torch::cudnn INTERFACE IMPORTED)
target_include_directories(torch::cudnn INTERFACE ${CUDNN_INCLUDE_PATH})
if(CUDNN_STATIC AND NOT WIN32)
target_link_options(torch::cudnn INTERFACE
"-Wl,--exclude-libs,libcudnn_static.a")
else()
target_link_libraries(torch::cudnn INTERFACE ${CUDNN_LIBRARY_PATH})
endif()
else()
message(STATUS "USE_CUDNN is set to 0. Compiling without cuDNN support")
endif()
if(CAFFE2_USE_CUSPARSELT)
find_package(CUSPARSELT)
if(NOT CUSPARSELT_FOUND)
message(WARNING
"Cannot find cuSPARSELt library. Turning the option off")
set(CAFFE2_USE_CUSPARSELT OFF)
else()
add_library(torch::cusparselt INTERFACE IMPORTED)
target_include_directories(torch::cusparselt INTERFACE ${CUSPARSELT_INCLUDE_PATH})
target_link_libraries(torch::cusparselt INTERFACE ${CUSPARSELT_LIBRARY_PATH})
endif()
else()
message(STATUS "USE_CUSPARSELT is set to 0. Compiling without cuSPARSELt support")
endif()
if(USE_CUDSS)
find_package(CUDSS)
if(NOT CUDSS_FOUND)
message(WARNING
"Cannot find CUDSS library. Turning the option off")
set(USE_CUDSS OFF)
else()
add_library(torch::cudss INTERFACE IMPORTED)
target_include_directories(torch::cudss INTERFACE ${CUDSS_INCLUDE_PATH})
target_link_libraries(torch::cudss INTERFACE ${CUDSS_LIBRARY_PATH})
endif()
else()
message(STATUS "USE_CUDSS is set to 0. Compiling without cuDSS support")
endif()
# cufile
if(CAFFE2_USE_CUFILE)
add_library(torch::cufile INTERFACE IMPORTED)
if(CAFFE2_STATIC_LINK_CUDA AND NOT WIN32)
set_property(
TARGET torch::cufile PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::cuFile_static)
else()
set_property(
TARGET torch::cufile PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::cuFile)
endif()
else()
message(STATUS "USE_CUFILE is set to 0. Compiling without cuFile support")
endif()
# curand
add_library(caffe2::curand INTERFACE IMPORTED)
if(CAFFE2_STATIC_LINK_CUDA AND NOT WIN32)
set_property(
TARGET caffe2::curand PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::curand_static)
else()
set_property(
TARGET caffe2::curand PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::curand)
endif()
# cufft
add_library(caffe2::cufft INTERFACE IMPORTED)
if(CAFFE2_STATIC_LINK_CUDA AND NOT WIN32)
if(CUDA_VERSION VERSION_LESS_EQUAL 12.9)
set_property(
TARGET caffe2::cufft PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::cufft_static_nocallback)
else()
set_property(
TARGET caffe2::cufft PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::cufft_static)
endif()
else()
set_property(
TARGET caffe2::cufft PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::cufft)
endif()
# nvrtc
# cuDNN frontend needs libnvrtc symbols, but linking through CUDA::nvrtc pulls
# CUDA::cuda_driver transitively. Keep a driver-free target for cuDNN users and
# reserve caffe2::nvrtc for the stub library that actually needs the driver API.
add_library(caffe2::nvrtc_runtime INTERFACE IMPORTED)
set_property(
TARGET caffe2::nvrtc_runtime PROPERTY INTERFACE_LINK_LIBRARIES
"${CUDA_NVRTC_LIB}")
add_library(caffe2::nvrtc INTERFACE IMPORTED)
set_property(
TARGET caffe2::nvrtc PROPERTY INTERFACE_LINK_LIBRARIES
CUDA::nvrtc caffe2::cuda)
# Add onnx namespace definition to nvcc
if(ONNX_NAMESPACE)
list(APPEND CUDA_NVCC_FLAGS "-DONNX_NAMESPACE=${ONNX_NAMESPACE}")
else()
list(APPEND CUDA_NVCC_FLAGS "-DONNX_NAMESPACE=onnx_c2")
endif()
# Don't activate VC env again for Ninja generators with MSVC on Windows if CUDAHOSTCXX is not defined
# by adding --use-local-env.
if(MSVC AND CMAKE_GENERATOR STREQUAL "Ninja" AND NOT DEFINED ENV{CUDAHOSTCXX})
list(APPEND CUDA_NVCC_FLAGS "--use-local-env")
endif()
# setting nvcc arch flags
torch_cuda_get_nvcc_gencode_flag(NVCC_FLAGS_EXTRA)
# CMake 3.18 adds integrated support for architecture selection, but we can't rely on it
if(DEFINED CMAKE_CUDA_ARCHITECTURES)
message(WARNING
"pytorch is not compatible with `CMAKE_CUDA_ARCHITECTURES` and will ignore its value. "
"Please configure `TORCH_CUDA_ARCH_LIST` instead.")
set(CMAKE_CUDA_ARCHITECTURES OFF)
endif()
list(APPEND CUDA_NVCC_FLAGS ${NVCC_FLAGS_EXTRA})
message(STATUS "Added CUDA NVCC flags for: ${NVCC_FLAGS_EXTRA}")
# disable some nvcc diagnostic that appears in boost, glog, glags, opencv, etc.
foreach(diag cc_clobber_ignored
field_without_dll_interface
base_class_has_different_dll_interface
dll_interface_conflict_none_assumed
dll_interface_conflict_dllexport_assumed
bad_friend_decl)
list(APPEND SUPPRESS_WARNING_FLAGS --diag_suppress=${diag})
endforeach()
string(REPLACE ";" "," SUPPRESS_WARNING_FLAGS "${SUPPRESS_WARNING_FLAGS}")
list(APPEND CUDA_NVCC_FLAGS -Xcudafe ${SUPPRESS_WARNING_FLAGS})
set(CUDA_PROPAGATE_HOST_FLAGS_BLOCKLIST "-Werror")
if(MSVC)
list(APPEND CUDA_NVCC_FLAGS "--Werror" "cross-execution-space-call")
list(APPEND CUDA_NVCC_FLAGS "--no-host-device-move-forward")
endif()
# Debug and Release symbol support
if(MSVC)
if(${CAFFE2_USE_MSVC_STATIC_RUNTIME})
string(APPEND CMAKE_CUDA_FLAGS_DEBUG " -Xcompiler /MTd")
string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL " -Xcompiler /MT")
string(APPEND CMAKE_CUDA_FLAGS_RELEASE " -Xcompiler /MT")
string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO " -Xcompiler /MT")
else()
string(APPEND CMAKE_CUDA_FLAGS_DEBUG " -Xcompiler /MDd")
string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL " -Xcompiler /MD")
string(APPEND CMAKE_CUDA_FLAGS_RELEASE " -Xcompiler /MD")
string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO " -Xcompiler /MD")
endif()
if(CUDA_NVCC_FLAGS MATCHES "Zi")
list(APPEND CUDA_NVCC_FLAGS "-Xcompiler" "-FS")
endif()
elseif(CUDA_DEVICE_DEBUG)
list(APPEND CUDA_NVCC_FLAGS "-g" "-G") # -G enables device code debugging symbols
endif()
# needed for compat with newer versions of clang that use C++20 mangling rules
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 18)
list(APPEND CUDA_NVCC_FLAGS "-Xcompiler=-fclang-abi-compat=17")
endif()
# Set expt-relaxed-constexpr to suppress Eigen warnings
list(APPEND CUDA_NVCC_FLAGS "--expt-relaxed-constexpr")
# Set expt-extended-lambda to support lambda on device
list(APPEND CUDA_NVCC_FLAGS "--expt-extended-lambda")
foreach(FLAG ${CUDA_NVCC_FLAGS})
string(FIND "${FLAG}" " " flag_space_position)
if(NOT flag_space_position EQUAL -1)
message(FATAL_ERROR "Found spaces in CUDA_NVCC_FLAGS entry '${FLAG}'")
endif()
string(APPEND CMAKE_CUDA_FLAGS " ${FLAG}")
endforeach()
@@ -0,0 +1,83 @@
# ---[ gflags
# We will try to use the config mode first, and then manual find.
find_package(gflags CONFIG QUIET)
if(NOT TARGET gflags)
find_package(gflags MODULE QUIET)
endif()
if(TARGET gflags)
message(STATUS "Caffe2: Found gflags with new-style gflags target.")
elseif(GFLAGS_FOUND)
message(STATUS "Caffe2: Found gflags with old-style gflag starget.")
add_library(gflags UNKNOWN IMPORTED)
set_property(
TARGET gflags PROPERTY IMPORTED_LOCATION ${GFLAGS_LIBRARY})
set_property(
TARGET gflags PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${GFLAGS_INCLUDE_DIR})
else()
message(STATUS
"Caffe2: Cannot find gflags automatically. Using legacy find.")
# - Try to find GFLAGS in the legacy way.
#
# The following variables are optionally searched for defaults
# GFLAGS_ROOT_DIR: Base directory where all GFLAGS components are found
#
# The following are set after configuration is done:
# GFLAGS_FOUND
# GFLAGS_INCLUDE_DIRS
# GFLAGS_LIBRARIES
# GFLAGS_LIBRARYRARY_DIRS
include(FindPackageHandleStandardArgs)
set(GFLAGS_ROOT_DIR "" CACHE PATH "Folder contains Gflags")
# We are testing only a couple of files in the include directories
if(WIN32)
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR}/src/windows)
else()
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR})
endif()
if(WIN32)
find_library(GFLAGS_LIBRARY_RELEASE
NAMES libgflags
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Release)
find_library(GFLAGS_LIBRARY_DEBUG
NAMES libgflags-debug
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Debug)
set(GFLAGS_LIBRARY optimized ${GFLAGS_LIBRARY_RELEASE} debug ${GFLAGS_LIBRARY_DEBUG})
else()
find_library(GFLAGS_LIBRARY gflags)
endif()
find_package_handle_standard_args(
gflags DEFAULT_MSG GFLAGS_INCLUDE_DIR GFLAGS_LIBRARY)
if(GFLAGS_FOUND)
message(
STATUS
"Caffe2: Found gflags (include: ${GFLAGS_INCLUDE_DIR}, "
"library: ${GFLAGS_LIBRARY})")
add_library(gflags UNKNOWN IMPORTED)
set_property(
TARGET gflags PROPERTY IMPORTED_LOCATION ${GFLAGS_LIBRARY})
set_property(
TARGET gflags PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${GFLAGS_INCLUDE_DIR})
endif()
endif()
# After above, we should have the gflags target now.
if(NOT TARGET gflags)
message(WARNING
"Caffe2: gflags cannot be found. Depending on whether you are building "
"Caffe2 or a Caffe2 dependent library, the next warning / error will "
"give you more info.")
endif()
@@ -0,0 +1,70 @@
# ---[ glog
# We will try to use the config mode first, and then manual find.
find_package(glog CONFIG QUIET)
if(NOT TARGET glog::glog)
find_package(glog MODULE QUIET)
endif()
if(TARGET glog::glog)
message(STATUS "Caffe2: Found glog with new-style glog target.")
elseif(GLOG_FOUND)
message(
STATUS
"Caffe2: Found glog with old-style glog starget. Glog never shipped "
"old style glog targets, so somewhere in your cmake path there might "
"be a custom Findglog.cmake file that got triggered. We will make a "
"best effort to create the new style glog target for you.")
add_library(glog::glog UNKNOWN IMPORTED)
set_property(
TARGET glog::glog PROPERTY IMPORTED_LOCATION ${GLOG_LIBRARY})
set_property(
TARGET glog::glog PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${GLOG_INCLUDE_DIR})
else()
message(STATUS "Caffe2: Cannot find glog automatically. Using legacy find.")
# - Try to find Glog
#
# The following variables are optionally searched for defaults
# GLOG_ROOT_DIR: Base directory where all GLOG components are found
#
# The following are set after configuration is done:
# GLOG_FOUND
# GLOG_INCLUDE_DIRS
# GLOG_LIBRARIES
# GLOG_LIBRARYRARY_DIRS
include(FindPackageHandleStandardArgs)
set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")
if(NOT WIN32)
find_path(GLOG_INCLUDE_DIR glog/logging.h
PATHS ${GLOG_ROOT_DIR})
endif()
find_library(GLOG_LIBRARY glog
PATHS ${GLOG_ROOT_DIR}
PATH_SUFFIXES lib lib64)
find_package_handle_standard_args(glog DEFAULT_MSG GLOG_INCLUDE_DIR GLOG_LIBRARY)
if(GLOG_FOUND)
message(STATUS
"Caffe2: Found glog (include: ${GLOG_INCLUDE_DIR}, "
"library: ${GLOG_LIBRARY})")
add_library(glog::glog UNKNOWN IMPORTED)
set_property(
TARGET glog::glog PROPERTY IMPORTED_LOCATION ${GLOG_LIBRARY})
set_property(
TARGET glog::glog PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${GLOG_INCLUDE_DIR})
endif()
endif()
# After above, we should have the glog::glog target now.
if(NOT TARGET glog::glog)
message(WARNING
"Caffe2: glog cannot be found. Depending on whether you are building "
"Caffe2 or a Caffe2 dependent library, the next warning / error will "
"give you more info.")
endif()
@@ -0,0 +1,40 @@
find_package(MKL QUIET)
if(TARGET caffe2::mkl)
return()
endif()
add_library(caffe2::mkl INTERFACE IMPORTED)
target_include_directories(caffe2::mkl INTERFACE ${MKL_INCLUDE_DIR})
target_link_libraries(caffe2::mkl INTERFACE ${MKL_LIBRARIES})
foreach(MKL_LIB IN LISTS MKL_LIBRARIES)
if(EXISTS "${MKL_LIB}")
get_filename_component(MKL_LINK_DIR "${MKL_LIB}" DIRECTORY)
if(IS_DIRECTORY "${MKL_LINK_DIR}")
target_link_directories(caffe2::mkl INTERFACE "${MKL_LINK_DIR}")
endif()
endif()
endforeach()
# TODO: This is a hack, it will not pick up architecture dependent
# MKL libraries correctly; see https://github.com/pytorch/pytorch/issues/73008
set_property(
TARGET caffe2::mkl PROPERTY INTERFACE_LINK_DIRECTORIES
${MKL_ROOT}/lib ${MKL_ROOT}/lib/intel64 ${MKL_ROOT}/lib/intel64_win ${MKL_ROOT}/lib/win-x64)
if(UNIX)
if(USE_STATIC_MKL)
foreach(MKL_LIB_PATH IN LISTS MKL_LIBRARIES)
if(NOT EXISTS "${MKL_LIB_PATH}")
continue()
endif()
get_filename_component(MKL_LIB_NAME "${MKL_LIB_PATH}" NAME)
# Match archive libraries starting with "libmkl_"
if(MKL_LIB_NAME MATCHES "^libmkl_" AND MKL_LIB_NAME MATCHES ".a$")
target_link_options(caffe2::mkl INTERFACE "-Wl,--exclude-libs,${MKL_LIB_NAME}")
endif()
endforeach()
endif()
endif()
@@ -0,0 +1,18 @@
set(MKLDNN_USE_NATIVE_ARCH ${USE_NATIVE_ARCH})
if(CPU_AARCH64)
include(${CMAKE_CURRENT_LIST_DIR}/ComputeLibrary.cmake)
endif()
find_package(MKLDNN QUIET)
if(NOT TARGET caffe2::mkldnn)
add_library(caffe2::mkldnn INTERFACE IMPORTED)
endif()
set_property(
TARGET caffe2::mkldnn PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${MKLDNN_INCLUDE_DIR})
set_property(
TARGET caffe2::mkldnn PROPERTY INTERFACE_LINK_LIBRARIES
${MKLDNN_LIBRARIES})
@@ -0,0 +1,92 @@
# ---[ Protobuf
# We will try to use the config mode first, and then manual find.
find_package(Protobuf CONFIG QUIET)
if(NOT Protobuf_FOUND)
find_package(Protobuf MODULE QUIET)
endif()
if((TARGET protobuf::libprotobuf OR TARGET protobuf::libprotobuf-lite) AND TARGET protobuf::protoc)
# Hooray. This is the most ideal situation, meaning that you either have a
# Protobuf config file installed (like on Windows), or you are using a
# modern CMake that ships with a FindProtobuf.cmake file that produces
# modern targets.
message(STATUS "Caffe2: Found protobuf with new-style protobuf targets.")
elseif(Protobuf_FOUND OR PROTOBUF_FOUND)
# If the modern targets are not present, we will generate them for you for
# backward compatibility. This is backported from CMake's new FindProtobuf.cmake
# content.
if((NOT PROTOBUF_LIBRARY) AND (NOT PROTOBUF_LITE_LIBRARY))
message(FATAL_ERROR
"Caffe2: Found protobuf with old style targets, but could not find targets."
" PROTOBUF_LIBRARY: " ${PROTOBUF_LIBRARY}
" PROTOBUF_LITE_LIBRARY: " ${PROTOBUF_LITE_LIBRARY}
" Protobuf_LIBRARY: " ${Protobuf_LIBRARY}
" Protobuf_LITE_LIBRARY: " ${Protobuf_LITE_LIBRARY})
endif()
message(STATUS "Caffe2: Found protobuf with old-style protobuf targets.")
if(PROTOBUF_LIBRARY)
if(NOT TARGET protobuf::libprotobuf)
add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
set_target_properties(protobuf::libprotobuf PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${PROTOBUF_INCLUDE_DIRS}")
endif()
if(EXISTS "${PROTOBUF_LIBRARY}")
set_target_properties(protobuf::libprotobuf PROPERTIES
IMPORTED_LOCATION "${PROTOBUF_LIBRARY}")
endif()
if(EXISTS "${PROTOBUF_LIBRARY_RELEASE}")
set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(protobuf::libprotobuf PROPERTIES
IMPORTED_LOCATION_RELEASE "${PROTOBUF_LIBRARY_RELEASE}")
endif()
if(EXISTS "${PROTOBUF_LIBRARY_DEBUG}")
set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(protobuf::libprotobuf PROPERTIES
IMPORTED_LOCATION_DEBUG "${PROTOBUF_LIBRARY_DEBUG}")
endif()
endif()
if(PROTOBUF_LITE_LIBRARY)
if(NOT TARGET protobuf::libprotobuf-lite)
add_library(protobuf::libprotobuf-lite UNKNOWN IMPORTED)
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${PROTOBUF_INCLUDE_DIRS}")
endif()
if(EXISTS "${PROTOBUF_LITE_LIBRARY}")
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
IMPORTED_LOCATION "${PROTOBUF_LITE_LIBRARY}")
endif()
if(EXISTS "${PROTOBUF_LITE_LIBRARY_RELEASE}")
set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
IMPORTED_LOCATION_RELEASE "${PROTOBUF_LITE_LIBRARY_RELEASE}")
endif()
if(EXISTS "${PROTOBUF_LITE_LIBRARY_DEBUG}")
set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(protobuf::libprotobuf-lite PROPERTIES
IMPORTED_LOCATION_DEBUG "${PROTOBUF_LITE_LIBRARY_DEBUG}")
endif()
endif()
if(PROTOBUF_PROTOC_EXECUTABLE)
if(NOT TARGET protobuf::protoc)
add_executable(protobuf::protoc IMPORTED)
endif()
set_property(TARGET protobuf::protoc PROPERTY
IMPORTED_LOCATION ${PROTOBUF_PROTOC_EXECUTABLE})
endif()
endif()
# After above, we should have the protobuf related target now.
if((NOT TARGET protobuf::libprotobuf) AND (NOT TARGET protobuf::libprotobuf-lite))
message(WARNING
"Protobuf cannot be found. Depending on whether you are building Caffe2 "
"or a Caffe2 dependent library, the next warning / error will give you "
"more info.")
endif()
@@ -0,0 +1,568 @@
################################################################################################
# Exclude and prepend functionalities
function(exclude OUTPUT INPUT)
set(EXCLUDES ${ARGN})
foreach(EXCLUDE ${EXCLUDES})
list(REMOVE_ITEM INPUT "${EXCLUDE}")
endforeach()
set(${OUTPUT} ${INPUT} PARENT_SCOPE)
endfunction(exclude)
function(prepend OUTPUT PREPEND)
set(OUT "")
foreach(ITEM ${ARGN})
list(APPEND OUT "${PREPEND}${ITEM}")
endforeach()
set(${OUTPUT} ${OUT} PARENT_SCOPE)
endfunction(prepend)
################################################################################################
# Parses a version string that might have values beyond major, minor, and patch
# and set version variables for the library.
# Usage:
# caffe2_parse_version_str(<library_name> <version_string>)
function(caffe2_parse_version_str LIBNAME VERSIONSTR)
string(REGEX REPLACE "^([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MAJOR "${VERSIONSTR}")
string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MINOR "${VERSIONSTR}")
string(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_PATCH "${VERSIONSTR}")
set(${LIBNAME}_VERSION_MAJOR ${${LIBNAME}_VERSION_MAJOR} ${ARGN} PARENT_SCOPE)
set(${LIBNAME}_VERSION_MINOR ${${LIBNAME}_VERSION_MINOR} ${ARGN} PARENT_SCOPE)
set(${LIBNAME}_VERSION_PATCH ${${LIBNAME}_VERSION_PATCH} ${ARGN} PARENT_SCOPE)
set(${LIBNAME}_VERSION "${${LIBNAME}_VERSION_MAJOR}.${${LIBNAME}_VERSION_MINOR}.${${LIBNAME}_VERSION_PATCH}" PARENT_SCOPE)
endfunction()
###
# Removes common indentation from a block of text to produce code suitable for
# setting to `python -c`, or using with pycmd. This allows multiline code to be
# nested nicely in the surrounding code structure.
#
# This function respsects Python_EXECUTABLE if it defined, otherwise it uses
# `python` and hopes for the best. An error will be thrown if it is not found.
#
# Args:
# outvar : variable that will hold the stdout of the python command
# text : text to remove indentation from
#
function(dedent outvar text)
# Use Python_EXECUTABLE if it is defined, otherwise default to python
if("${Python_EXECUTABLE}" STREQUAL "")
set(_python_exe "python3")
else()
set(_python_exe "${Python_EXECUTABLE}")
endif()
set(_fixup_cmd "import sys; from textwrap import dedent; print(dedent(sys.stdin.read()))")
file(WRITE "${CMAKE_BINARY_DIR}/indented.txt" "${text}")
execute_process(
COMMAND "${_python_exe}" -c "${_fixup_cmd}"
INPUT_FILE "${CMAKE_BINARY_DIR}/indented.txt"
RESULT_VARIABLE _dedent_exitcode
OUTPUT_VARIABLE _dedent_text)
if(NOT _dedent_exitcode EQUAL 0)
message(ERROR " Failed to remove indentation from: \n\"\"\"\n${text}\n\"\"\"
Python dedent failed with error code: ${_dedent_exitcode}")
message(FATAL_ERROR " Python dedent failed with error code: ${_dedent_exitcode}")
endif()
# Remove supurflous newlines (artifacts of print)
string(STRIP "${_dedent_text}" _dedent_text)
set(${outvar} "${_dedent_text}" PARENT_SCOPE)
endfunction()
function(pycmd_no_exit outvar exitcode cmd)
# Use Python_EXECUTABLE if it is defined, otherwise default to python
if("${Python_EXECUTABLE}" STREQUAL "")
set(_python_exe "python")
else()
set(_python_exe "${Python_EXECUTABLE}")
endif()
# run the actual command
execute_process(
COMMAND "${_python_exe}" -c "${cmd}"
RESULT_VARIABLE _exitcode
OUTPUT_VARIABLE _output)
# Remove supurflous newlines (artifacts of print)
string(STRIP "${_output}" _output)
set(${outvar} "${_output}" PARENT_SCOPE)
set(${exitcode} "${_exitcode}" PARENT_SCOPE)
endfunction()
###
# Helper function to run `python -c "<cmd>"` and capture the results of stdout
#
# Runs a python command and populates an outvar with the result of stdout.
# Common indentation in the text of `cmd` is removed before the command is
# executed, so the caller does not need to worry about indentation issues.
#
# This function respsects Python_EXECUTABLE if it defined, otherwise it uses
# `python` and hopes for the best. An error will be thrown if it is not found.
#
# Args:
# outvar : variable that will hold the stdout of the python command
# cmd : text representing a (possibly multiline) block of python code
#
function(pycmd outvar cmd)
dedent(_dedent_cmd "${cmd}")
pycmd_no_exit(_output _exitcode "${_dedent_cmd}")
if(NOT _exitcode EQUAL 0)
message(ERROR " Failed when running python code: \"\"\"\n${_dedent_cmd}\n\"\"\"")
message(FATAL_ERROR " Python command failed with error code: ${_exitcode}")
endif()
# Remove supurflous newlines (artifacts of print)
string(STRIP "${_output}" _output)
set(${outvar} "${_output}" PARENT_SCOPE)
endfunction()
##############################################################################
# Macro to update cached options.
macro(caffe2_update_option variable value)
if(CAFFE2_CMAKE_BUILDING_WITH_MAIN_REPO)
get_property(__help_string CACHE ${variable} PROPERTY HELPSTRING)
set(${variable} ${value} CACHE BOOL ${__help_string} FORCE)
else()
set(${variable} ${value})
endif()
endmacro()
##############################################################################
# Add an interface library definition that is dependent on the source.
#
# It's probably easiest to explain why this macro exists, by describing
# what things would look like if we didn't have this macro.
#
# Let's suppose we want to statically link against torch. We've defined
# a library in cmake called torch, and we might think that we just
# target_link_libraries(my-app PUBLIC torch). This will result in a
# linker argument 'libtorch.a' getting passed to the linker.
#
# Unfortunately, this link command is wrong! We have static
# initializers in libtorch.a that would get improperly pruned by
# the default link settings. What we actually need is for you
# to do -Wl,--whole-archive,libtorch.a -Wl,--no-whole-archive to ensure
# that we keep all symbols, even if they are (seemingly) not used.
#
# What caffe2_interface_library does is create an interface library
# that indirectly depends on the real library, but sets up the link
# arguments so that you get all of the extra link settings you need.
# The result is not a "real" library, and so we have to manually
# copy over necessary properties from the original target.
#
# (The discussion above is about static libraries, but a similar
# situation occurs for dynamic libraries: if no symbols are used from
# a dynamic library, it will be pruned unless you are --no-as-needed)
macro(caffe2_interface_library SRC DST)
add_library(${DST} INTERFACE)
add_dependencies(${DST} ${SRC})
# Depending on the nature of the source library as well as the compiler,
# determine the needed compilation flags.
get_target_property(__src_target_type ${SRC} TYPE)
# Depending on the type of the source library, we will set up the
# link command for the specific SRC library.
if(${__src_target_type} STREQUAL "STATIC_LIBRARY")
# In the case of static library, we will need to add whole-static flags.
target_link_libraries(${DST} INTERFACE $<LINK_LIBRARY:WHOLE_ARCHIVE,${SRC}>)
# Link all interface link libraries of the src target as well.
# For static library, we need to explicitly depend on all the libraries
# that are the dependent library of the source library. Note that we cannot
# use the populated INTERFACE_LINK_LIBRARIES property, because if one of the
# dependent library is not a target, cmake creates a $<LINK_ONLY:src> wrapper
# and then one is not able to find target "src". For more discussions, check
# https://cmake.org/Bug/print_bug_page.php?bug_id=15415
# https://cmake.org/pipermail/cmake-developers/2013-May/019019.html
# Specifically the following quote
#
# """
# For STATIC libraries we can define that the PUBLIC/PRIVATE/INTERFACE keys
# are ignored for linking and that it always populates both LINK_LIBRARIES
# LINK_INTERFACE_LIBRARIES. Note that for STATIC libraries the
# LINK_LIBRARIES property will not be used for anything except build-order
# dependencies.
# """
target_link_libraries(${DST} INTERFACE
$<TARGET_PROPERTY:${SRC},LINK_LIBRARIES>)
elseif(${__src_target_type} STREQUAL "SHARED_LIBRARY")
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
target_link_libraries(${DST} INTERFACE
"-Wl,--no-as-needed,\"$<TARGET_FILE:${SRC}>\" -Wl,--as-needed")
else()
target_link_libraries(${DST} INTERFACE ${SRC})
endif()
# Link all interface link libraries of the src target as well.
# For shared libraries, we can simply depend on the INTERFACE_LINK_LIBRARIES
# property of the target.
target_link_libraries(${DST} INTERFACE
$<TARGET_PROPERTY:${SRC},INTERFACE_LINK_LIBRARIES>)
else()
message(FATAL_ERROR
"You made a CMake build file error: target " ${SRC}
" must be of type either STATIC_LIBRARY or SHARED_LIBRARY. However, "
"I got " ${__src_target_type} ".")
endif()
# For all other interface properties, manually inherit from the source target.
set_target_properties(${DST} PROPERTIES
INTERFACE_COMPILE_DEFINITIONS
$<TARGET_PROPERTY:${SRC},INTERFACE_COMPILE_DEFINITIONS>
INTERFACE_COMPILE_OPTIONS
$<TARGET_PROPERTY:${SRC},INTERFACE_COMPILE_OPTIONS>
INTERFACE_INCLUDE_DIRECTORIES
$<TARGET_PROPERTY:${SRC},INTERFACE_INCLUDE_DIRECTORIES>
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
$<TARGET_PROPERTY:${SRC},INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>)
endmacro()
##############################################################################
# Creating a Caffe2 binary target with sources specified with relative path.
# Usage:
# caffe2_binary_target(target_name_or_src <src1> [<src2>] [<src3>] ...)
# If only target_name_or_src is specified, this target is build with one single
# source file and the target name is autogen from the filename. Otherwise, the
# target name is given by the first argument and the rest are the source files
# to build the target.
function(caffe2_binary_target target_name_or_src)
# https://cmake.org/cmake/help/latest/command/function.html
# Checking that ARGC is greater than # is the only way to ensure
# that ARGV# was passed to the function as an extra argument.
if(ARGC GREATER 1)
set(__target ${target_name_or_src})
prepend(__srcs "${CMAKE_CURRENT_SOURCE_DIR}/" "${ARGN}")
else()
get_filename_component(__target ${target_name_or_src} NAME_WE)
prepend(__srcs "${CMAKE_CURRENT_SOURCE_DIR}/" "${target_name_or_src}")
endif()
add_executable(${__target} ${__srcs})
target_link_libraries(${__target} torch_library)
# If we have Caffe2_MODULES defined, we will also link with the modules.
if(DEFINED Caffe2_MODULES)
target_link_libraries(${__target} ${Caffe2_MODULES})
endif()
install(TARGETS ${__target} DESTINATION bin)
endfunction()
function(caffe2_hip_binary_target target_name_or_src)
if(ARGC GREATER 1)
set(__target ${target_name_or_src})
prepend(__srcs "${CMAKE_CURRENT_SOURCE_DIR}/" "${ARGN}")
else()
get_filename_component(__target ${target_name_or_src} NAME_WE)
prepend(__srcs "${CMAKE_CURRENT_SOURCE_DIR}/" "${target_name_or_src}")
endif()
caffe2_binary_target(${target_name_or_src})
target_compile_options(${__target} PRIVATE ${HIP_CXX_FLAGS})
target_include_directories(${__target} PRIVATE ${Caffe2_HIP_INCLUDE})
endfunction()
##############################################################################
# Multiplex between adding libraries for CUDA versus HIP (AMD Software Stack).
# Usage:
# torch_cuda_based_add_library(cuda_target)
#
macro(torch_cuda_based_add_library cuda_target)
if(USE_ROCM)
hip_add_library(${cuda_target} ${ARGN})
elseif(USE_CUDA)
add_library(${cuda_target} ${ARGN})
else()
endif()
endmacro()
##############################################################################
# Get the HIP arch flags specified by PYTORCH_ROCM_ARCH.
# Usage:
# torch_hip_get_arch_list(variable_to_store_flags)
#
macro(torch_hip_get_arch_list store_var)
if(DEFINED ENV{PYTORCH_ROCM_ARCH})
set(_TMP $ENV{PYTORCH_ROCM_ARCH})
else()
# Use arch of installed GPUs as default
execute_process(COMMAND "rocm_agent_enumerator" COMMAND bash "-c" "grep -v gfx000 | sort -u | xargs | tr -d '\n'"
RESULT_VARIABLE ROCM_AGENT_ENUMERATOR_RESULT
OUTPUT_VARIABLE ROCM_ARCH_INSTALLED)
if(NOT ROCM_AGENT_ENUMERATOR_RESULT EQUAL 0)
message(FATAL_ERROR " Could not detect ROCm arch for GPUs on machine. Result: '${ROCM_AGENT_ENUMERATOR_RESULT}'")
endif()
set(_TMP ${ROCM_ARCH_INSTALLED})
endif()
string(REPLACE " " ";" ${store_var} "${_TMP}")
endmacro()
##############################################################################
# Get the XPU arch flags specified by TORCH_XPU_ARCH_LIST.
# Usage:
# torch_xpu_get_arch_list(variable_to_store_flags)
#
macro(torch_xpu_get_arch_list store_var)
if(DEFINED ENV{TORCH_XPU_ARCH_LIST})
set(${store_var} $ENV{TORCH_XPU_ARCH_LIST})
endif()
endmacro()
##############################################################################
# Get the NVCC arch flags specified by TORCH_CUDA_ARCH_LIST and CUDA_ARCH_NAME.
# Usage:
# torch_cuda_get_nvcc_gencode_flag(variable_to_store_flags)
#
macro(torch_cuda_get_nvcc_gencode_flag store_var)
# setting nvcc arch flags
# We need to support the explicitly and conveniently defined TORCH_CUDA_ARCH_LIST
if((NOT DEFINED TORCH_CUDA_ARCH_LIST) AND (DEFINED ENV{TORCH_CUDA_ARCH_LIST}))
set(TORCH_CUDA_ARCH_LIST $ENV{TORCH_CUDA_ARCH_LIST})
endif()
if(DEFINED CUDA_ARCH_NAME)
message(WARNING
"CUDA_ARCH_NAME is no longer used. Use TORCH_CUDA_ARCH_LIST instead. "
"Right now, CUDA_ARCH_NAME is ${CUDA_ARCH_NAME} and "
"TORCH_CUDA_ARCH_LIST is ${TORCH_CUDA_ARCH_LIST}.")
if(NOT TORCH_CUDA_ARCH_LIST)
set(TORCH_CUDA_ARCH_LIST ${CUDA_ARCH_NAME})
else()
list(APPEND TORCH_CUDA_ARCH_LIST ${CUDA_ARCH_NAME})
endif()
endif()
# Invoke cuda_select_nvcc_arch_flags from proper cmake FindCUDA.
cuda_select_nvcc_arch_flags(${store_var} ${TORCH_CUDA_ARCH_LIST})
endmacro()
##############################################################################
# Add standard compile options.
# Usage:
# torch_compile_options(lib_name)
function(torch_compile_options libname)
set_property(TARGET ${libname} PROPERTY CXX_STANDARD 20)
# until they can be unified, keep these lists synced with setup.py
if(MSVC)
if(MSVC_Z7_OVERRIDE)
set(MSVC_DEBINFO_OPTION "/Z7")
else()
set(MSVC_DEBINFO_OPTION "/Zi")
endif()
if(${MSVC_TOOLSET_VERSION} GREATER_EQUAL 142)
# Add /permissive- flag for conformance mode to the compiler.
# This will force more strict check to the code standard.
# 1. From MS official doc: https://learn.microsoft.com/en-us/cpp/build/reference/permissive-standards-conformance?view=msvc-170#remarks
# By default, the /permissive- option is set in new projects created by Visual Studio 2017 version 15.5 and later versions.
# We set the /permissive- flag from VS 2019 (MSVC_TOOLSET_VERSION 142) to avoid compiling issues for old toolkit.
# 2. For MSVC VERSION: https://cmake.org/cmake/help/latest/variable/MSVC_TOOLSET_VERSION.html
target_compile_options(${libname} PUBLIC $<$<COMPILE_LANGUAGE:CXX>:/permissive->)
endif()
# This option enables a token-based preprocessor that conforms to C99 and C++11 and later standards.
# This option is available since VS 2017.
# For MS official doc: https://learn.microsoft.com/en-us/cpp/build/reference/zc-preprocessor
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:preprocessor" PARENT_SCOPE)
target_compile_options(${libname} PUBLIC
$<$<COMPILE_LANGUAGE:CXX>:
${MSVC_RUNTIME_LIBRARY_OPTION}
$<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:${MSVC_DEBINFO_OPTION}>
/EHsc
/bigobj>
)
else()
set(private_compile_options
-Wall
-Wextra
-Wdeprecated
-Wunused
-Wno-unused-parameter
-Wno-missing-field-initializers
-Wno-array-bounds
-Wno-unknown-pragmas
-Wno-strict-overflow
-Wno-strict-aliasing
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
list(APPEND private_compile_options -Wredundant-move)
# -Wno-interference-size only exists in GCC 12+
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 12)
list(APPEND private_compile_options -Wno-interference-size)
endif()
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(NOT USE_CUDA)
# NS: One can not compile CUDA code with extra-semi flag as nvcc generates code like
# namespace MemoryOps_cu_d8602b38_109889 __attribute__((visibility("hidden"))) { };
list(APPEND private_compile_options -Wextra-semi)
else()
# NVCC + clang15 reports deprecated copies from GPU lambda instantiations
list(APPEND private_compile_options -Wno-deprecated-copy)
# NVCC + clang18 reports spurious deprecated deprecated literal operator declaration when there were none
# I.e. failures look like torch/headeronly/util/complex.h:334:40: error: identifier '_if' preceded by whitespace in a literal operator declaration is deprecated
# but if one to look at the source code, there are no space there
list(APPEND private_compile_options -Wno-deprecated-literal-operator)
endif()
list(APPEND private_compile_options -Wmove)
else()
list(APPEND private_compile_options
# Considered to be flaky. See the discussion at
# https://github.com/pytorch/pytorch/pull/9608
-Wno-maybe-uninitialized)
endif()
if(WERROR)
list(APPEND private_compile_options
-Werror
-Werror=ignored-attributes
-Werror=inconsistent-missing-override
-Werror=inconsistent-missing-destructor-override
-Werror=pedantic
-Werror=unused
-Wno-error=unused-parameter
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
list(APPEND private_compile_options -Werror=unused-but-set-variable -Werror=cpp)
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
list(APPEND private_compile_options -Werror=macro-redefined -Werror=deprecated-copy-with-dtor)
endif()
endif()
endif()
target_compile_options(${libname} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>:${private_compile_options}>)
if(USE_CUDA)
foreach(option IN LISTS private_compile_options)
if(CMAKE_CUDA_HOST_COMPILER_ID STREQUAL "GNU")
if("${option}" STREQUAL "-Wextra-semi")
continue()
endif()
if("${option}" STREQUAL "-Wunused-private-field")
continue()
endif()
endif()
target_compile_options(${libname} PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler ${option}>)
endforeach()
endif()
if(NOT WIN32 AND NOT USE_ASAN)
# Enable hidden visibility by default to make it easier to debug issues with
# TORCH_API annotations. Hidden visibility with selective default visibility
# behaves close enough to Windows' dllimport/dllexport.
#
# Unfortunately, hidden visibility messes up some ubsan warnings because
# templated classes crossing library boundary get duplicated (but identical)
# definitions. It's easier to just disable it.
target_compile_options(${libname} PRIVATE
$<$<COMPILE_LANGUAGE:CXX>: -fvisibility=hidden>)
endif()
endfunction()
##############################################################################
# Set old-style FindCuda.cmake compile flags from modern CMake cuda flags.
# Usage:
# torch_update_find_cuda_flags()
function(torch_update_find_cuda_flags)
# Convert -O2 -Xcompiler="-O2 -Wall" to "-O2;-Xcompiler=-O2,-Wall"
if(USE_CUDA)
separate_arguments(FLAGS UNIX_COMMAND "${CMAKE_CUDA_FLAGS}")
string(REPLACE " " "," FLAGS "${FLAGS}")
set(CUDA_NVCC_FLAGS ${FLAGS} PARENT_SCOPE)
separate_arguments(FLAGS_DEBUG UNIX_COMMAND "${CMAKE_CUDA_FLAGS_DEBUG}")
string(REPLACE " " "," FLAGS_DEBUG "${FLAGS_DEBUG}")
set(CUDA_NVCC_FLAGS_DEBUG "${FLAGS_DEBUG}" PARENT_SCOPE)
separate_arguments(FLAGS_RELEASE UNIX_COMMAND "${CMAKE_CUDA_FLAGS_RELEASE}")
string(REPLACE " " "," FLAGS_RELEASE "${FLAGS_RELEASE}")
set(CUDA_NVCC_FLAGS_RELEASE "${FLAGS_RELEASE}" PARENT_SCOPE)
separate_arguments(FLAGS_MINSIZEREL UNIX_COMMAND "${CMAKE_CUDA_FLAGS_MINSIZEREL}")
string(REPLACE " " "," FLAGS_MINSIZEREL "${FLAGS_MINSIZEREL}")
set(CUDA_NVCC_FLAGS_MINSIZEREL "${FLAGS_MINSIZEREL}" PARENT_SCOPE)
separate_arguments(FLAGS_RELWITHDEBINFO UNIX_COMMAND "${CMAKE_CUDA_FLAGS_RELWITHDEBINFO}")
string(REPLACE " " "," FLAGS_RELWITHDEBINFO "${FLAGS_RELWITHDEBINFO}")
set(CUDA_NVCC_FLAGS_RELWITHDEBINFO "${FLAGS_RELWITHDEBINFO}" PARENT_SCOPE)
message(STATUS "Converting CMAKE_CUDA_FLAGS to CUDA_NVCC_FLAGS:\n"
" CUDA_NVCC_FLAGS = ${FLAGS}\n"
" CUDA_NVCC_FLAGS_DEBUG = ${FLAGS_DEBUG}\n"
" CUDA_NVCC_FLAGS_RELEASE = ${FLAGS_RELEASE}\n"
" CUDA_NVCC_FLAGS_RELWITHDEBINFO = ${FLAGS_RELWITHDEBINFO}\n"
" CUDA_NVCC_FLAGS_MINSIZEREL = ${FLAGS_MINSIZEREL}")
endif()
endfunction()
include(CheckCXXCompilerFlag)
include(CheckCCompilerFlag)
include(CheckLinkerFlag)
##############################################################################
# CHeck if given flag is supported and append it to provided outputvar
# Also define HAS_UPPER_CASE_FLAG_NAME variable
# Usage:
# append_cxx_flag_if_supported("-Werror" CMAKE_CXX_FLAGS)
function(append_cxx_flag_if_supported flag outputvar)
string(TOUPPER "HAS${flag}" _FLAG_NAME)
string(REGEX REPLACE "[=-]" "_" _FLAG_NAME "${_FLAG_NAME}")
# GCC silents unknown -Wno-XXX flags, so we detect the corresponding -WXXX.
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
string(REGEX REPLACE "Wno-" "W" new_flag "${flag}")
else()
set(new_flag ${flag})
endif()
check_cxx_compiler_flag("${new_flag}" ${_FLAG_NAME})
if(${_FLAG_NAME})
string(APPEND ${outputvar} " ${flag}")
set(${outputvar} "${${outputvar}}" PARENT_SCOPE)
endif()
endfunction()
function(append_c_flag_if_supported flag outputvar)
string(TOUPPER "HAS${flag}" _FLAG_NAME)
string(REGEX REPLACE "[=-]" "_" _FLAG_NAME "${_FLAG_NAME}")
# GCC silences unknown -Wno-XXX flags, so test the corresponding -WXXX.
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
string(REGEX REPLACE "^Wno-" "W" new_flag "${flag}")
else()
set(new_flag "${flag}")
endif()
check_c_compiler_flag("${new_flag}" ${_FLAG_NAME})
if(${_FLAG_NAME})
string(APPEND ${outputvar} " ${flag}")
set(${outputvar} "${${outputvar}}" PARENT_SCOPE)
endif()
endfunction()
function(target_compile_options_if_supported target flag)
set(_compile_options "")
append_cxx_flag_if_supported("${flag}" _compile_options)
if(NOT "${_compile_options}" STREQUAL "")
target_compile_options(${target} PRIVATE ${flag})
endif()
endfunction()
# Check if a global link option is supported
function(add_link_options_if_supported flag)
check_linker_flag(C "LINKER:${flag}" _supported)
if("${_supported}")
add_link_options("LINKER:${flag}")
else()
message(WARNING "Attempted to use unsupported link option : ${flag}.")
endif()
endfunction()
function(target_link_options_if_supported tgt flag)
check_linker_flag(C "LINKER:${flag}" _supported)
if("${_supported}")
target_link_options("${tgt}" PRIVATE "LINKER:${flag}")
else()
message(WARNING "Attempted to use unsupported link option : ${flag}.")
endif()
endfunction()
@@ -0,0 +1,61 @@
# ---[ xpu
# Poor man's include guard
if(TARGET torch::xpurt)
return()
endif()
set(XPU_HOST_CXX_FLAGS)
# Find SYCL library.
find_package(SYCLToolkit REQUIRED)
if(NOT SYCL_FOUND)
set(PYTORCH_FOUND_XPU FALSE)
# Exit early to avoid populating XPU_HOST_CXX_FLAGS.
return()
endif()
set(PYTORCH_FOUND_XPU TRUE)
# SYCL library interface
add_library(torch::sycl INTERFACE IMPORTED)
set_property(
TARGET torch::sycl PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${SYCL_INCLUDE_DIR})
set_property(
TARGET torch::sycl PROPERTY INTERFACE_LINK_LIBRARIES
${SYCL_LIBRARY})
# xpurt
add_library(torch::xpurt INTERFACE IMPORTED)
set_property(
TARGET torch::xpurt PROPERTY INTERFACE_LINK_LIBRARIES
torch::sycl)
# setting xpu arch flags
torch_xpu_get_arch_list(XPU_ARCH_FLAGS)
# propagate to torch-xpu-ops
set(TORCH_XPU_ARCH_LIST ${XPU_ARCH_FLAGS})
# Ensure SYCL device code compiles with C++20 (matching CMAKE_CXX_STANDARD).
# SYCL_FLAGS flows into SYCL_COMPILE_FLAGS in torch-xpu-ops' BuildFlags.cmake
# and is passed directly to icpx on the device compilation command line.
list(APPEND SYCL_FLAGS -std=c++20)
# Ensure USE_XPU is enabled.
string(APPEND XPU_HOST_CXX_FLAGS " -DUSE_XPU")
string(APPEND XPU_HOST_CXX_FLAGS " -DSYCL_COMPILER_VERSION=${SYCL_COMPILER_VERSION}")
if(DEFINED ENV{XPU_ENABLE_KINETO})
set(XPU_ENABLE_KINETO TRUE)
else()
set(XPU_ENABLE_KINETO FALSE)
endif()
if(WIN32)
if(${SYCL_COMPILER_VERSION} GREATER_EQUAL 20250101)
set(XPU_ENABLE_KINETO TRUE)
endif()
else()
set(XPU_ENABLE_KINETO TRUE)
endif()