Commit 3cef91a3 authored by Robert Maynard's avatar Robert Maynard
Browse files

CUDA: Always extract CUDA Toolkit root from nvcc verbose output

Fixes #21750, #21763

Given that NVCC can be provided by multiple different sources (NVIDIA HPC SDK, CUDA Toolkit, distro)
each of which has a different layout, we need to extract the CUDA toolkit root from the compiler
itself, allowing us to support numerious different scattered toolkit layouts.

The NVIDIA HPC SDK specifically ships two copies of nvcc one in
`compilers/bin/` and one in `cuda/bin`. Thus when using
`compilers/bin/nvcc` the Toolkit root logic fails.
parent b06a480b
Pipeline #213338 waiting for manual action with stages
in 21 minutes and 40 seconds
......@@ -172,23 +172,21 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
endif()
endif()
# If NVCC is a symlink due to a wrapper script (e.g. ccache or colornvcc), then invoke it to find the
# real non-scattered toolkit.
if(IS_SYMLINK ${_CUDA_NVCC_EXECUTABLE})
# Given that NVCC can be provided by multiple different sources (NVIDIA HPC SDK, CUDA Toolkit, distro)
# each of which has a different layout, we need to extract the CUDA toolkit root from the compiler
# itself, allowing us to support numerous different scattered toolkit layouts
execute_process(COMMAND ${_CUDA_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda" ERROR_VARIABLE NVCC_ERR)
if(NVCC_ERR MATCHES " _HERE_=([^\r\n]*)")
set(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_MATCH_1}")
else()
message(FATAL_ERROR "Could not execute nvcc with -v.")
endif()
unset(NVCC_ERR)
if(NVCC_ERR MATCHES "TOP=([^\r\n]*)")
get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_MATCH_1}" ABSOLUTE)
else()
get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${_CUDA_NVCC_EXECUTABLE}" DIRECTORY)
get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}" DIRECTORY)
endif()
unset(NVCC_ERR)
set(CMAKE_CUDA_DEVICE_LINKER "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/bin/nvlink${CMAKE_EXECUTABLE_SUFFIX}")
set(CMAKE_CUDA_FATBINARY "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/bin/fatbinary${CMAKE_EXECUTABLE_SUFFIX}")
set(CMAKE_CUDA_DEVICE_LINKER "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/nvlink${CMAKE_EXECUTABLE_SUFFIX}")
set(CMAKE_CUDA_FATBINARY "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}/fatbinary${CMAKE_EXECUTABLE_SUFFIX}")
get_filename_component(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}" DIRECTORY)
# In a non-scattered installation the following are equivalent to CMAKE_CUDA_COMPILER_TOOLKIT_ROOT.
# We first check for a non-scattered installation to prefer it over a scattered installation.
......
......@@ -834,21 +834,18 @@ if(NOT CUDA_TOOLKIT_ROOT_DIR AND NOT CMAKE_CROSSCOMPILING)
)
if (CUDA_TOOLKIT_ROOT_DIR_NVCC)
# If NVCC is a symlink due to a wrapper script (e.g. ccache or colornvcc), then invoke it to find the
# real non-scattered toolkit.
if(IS_SYMLINK ${CUDA_TOOLKIT_ROOT_DIR_NVCC})
# Given that NVCC can be provided by multiple different sources (NVIDIA HPC SDK, CUDA Toolkit, distro)
# each of which has a different layout, we need to extract the CUDA toolkit root from the compiler
# itself, allowing us to support numerous different scattered toolkit layouts
execute_process(COMMAND ${CUDA_TOOLKIT_ROOT_DIR_NVCC} "-v" "__cmake_determine_cuda" ERROR_VARIABLE NVCC_ERR)
if(NVCC_ERR MATCHES " _HERE_=([^\r\n]*)")
set(CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR "${CMAKE_MATCH_1}")
if(NVCC_ERR MATCHES "TOP=([^\r\n]*)")
get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CMAKE_MATCH_1}" ABSOLUTE CACHE)
else()
message(FATAL_ERROR "Could not execute nvcc with -v.")
get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CUDA_TOOLKIT_ROOT_DIR_NVCC}" DIRECTORY)
get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CUDA_TOOLKIT_ROOT_DIR}" DIRECTORY CACHE)
endif()
unset(NVCC_ERR)
else()
get_filename_component(CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR "${CUDA_TOOLKIT_ROOT_DIR_NVCC}" DIRECTORY)
endif()
get_filename_component(CUDA_TOOLKIT_ROOT_DIR "${CUDA_TOOLKIT_ROOT_DIR_NVCC_PAR}" DIRECTORY CACHE)
string(REGEX REPLACE "[/\\\\]?bin[64]*[/\\\\]?$" "" CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR})
# We need to force this back into the cache.
set(CUDA_TOOLKIT_ROOT_DIR ${CUDA_TOOLKIT_ROOT_DIR} CACHE PATH "Toolkit location." FORCE)
......
......@@ -518,24 +518,23 @@ else()
)
endif()
if(CUDAToolkit_NVCC_EXECUTABLE)
# If NVCC is a symlink due to a wrapper script (e.g. ccache or colornvcc), then invoke it to find the
# real non-scattered toolkit.
if(IS_SYMLINK ${CUDAToolkit_NVCC_EXECUTABLE})
if(EXISTS "${CUDAToolkit_NVCC_EXECUTABLE}")
# If NVCC exists then invoke it to find the toolkit location.
# This allows us to support wrapper scripts (e.g. ccache or colornvcc), CUDA Toolkit,
# NVIDIA HPC SDK, and distro's splayed layouts
execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda" ERROR_VARIABLE NVCC_ERR)
if(NVCC_ERR MATCHES " _HERE_=([^\r\n]*)")
set(CUDAToolkit_BIN_DIR "${CMAKE_MATCH_1}")
else()
message(FATAL_ERROR "Could not execute nvcc with -v.")
endif()
unset(NVCC_ERR)
if(NVCC_ERR MATCHES "TOP=([^\r\n]*)")
get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_MATCH_1}/bin" ABSOLUTE)
else()
get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
endif()
unset(NVCC_ERR)
set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
mark_as_advanced(CUDAToolkit_BIN_DIR)
elseif(CUDAToolkit_SENTINEL_FILE)
set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
endif()
if(CUDAToolkit_SENTINEL_FILE)
get_filename_component(CUDAToolkit_BIN_DIR ${CUDAToolkit_SENTINEL_FILE} DIRECTORY ABSOLUTE)
set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}/bin")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment