FindCUDAToolkit: Import targets for toolkit libraries

This commit is contained in:
Stephen McDowell
2019-12-04 16:14:50 -05:00
committed by Robert Maynard
parent 2c0ff263b4
commit 29560bf07b

View File

@@ -5,10 +5,9 @@
FindCUDAToolkit
---------------
This script locates the NVIDIA CUDA toolkit, but does not require the ``CUDA``
language be enabled for a given project. This module does not search for the
NVIDIA CUDA Samples or any specific CUDA libraries. This module only searches
for the CUDA Toolkit root directory.
This script locates the NVIDIA CUDA toolkit and the associated libraries, but
does not require the ``CUDA`` language be enabled for a given project. This
module does not search for the NVIDIA CUDA Samples.
Search Behavior
^^^^^^^^^^^^^^^
@@ -86,7 +85,249 @@ Options
If specified, the CUDA Toolkit is considered found only if the exact
``VERSION`` specified is recovered.
Output Variables
Imported targets
^^^^^^^^^^^^^^^^
This module defines :prop_tgt:`IMPORTED` targets for each
of the following libraries that are part of the CUDAToolkit:
- :ref:`CUDA Runtime Libraries<cuda_toolkit_rt_libs>`
- :ref:`cuBLAS<cuda_toolkit_cuBLAS>`
- :ref:`cuFFT<cuda_toolkit_cuFFT>`
- :ref:`cuLIBOS<cuda_toolkit_cuLIBOS>`
- :ref:`cuRAND<cuda_toolkit_cuRAND>`
- :ref:`cuSOLVER<cuda_toolkit_cuSOLVER>`
- :ref:`cuSPARSE<cuda_toolkit_cuSPARSE>`
- :ref:`NPP<cuda_toolkit_NPP>`
- :ref:`nvBLAS<cuda_toolkit_nvBLAS>`
- :ref:`nvGRAPH<cuda_toolkit_nvGRAPH>`
- :ref:`nvJPEG<cuda_toolkit_nvJPEG>`
- :ref:`nvToolsExt<cuda_toolkit_nvToolsExt>`
.. _`cuda_toolkit_rt_libs`:
CUDA Runtime Libraries
""""""""""""""""""""""
The CUDA Runtime libraries (cudart) are what most applications will typically
need to link against to make any calls such as `cudaMalloc` and `cudaFree`.
They are an explicit dependency of almost every library.
Targets Created:
- ``CUDA::cudart``
- ``CUDA::cudart_static``
.. _`cuda_toolkit_cuBLAS`:
cuBLAS
""""""
The `cuBLAS <https://docs.nvidia.com/cuda/cublas/index.html>`_ library.
Targets Created:
- ``CUDA::cublas``
- ``CUDA::cublas_static``
.. _`cuda_toolkit_cuFFT`:
cuFFT
"""""
The `cuFFT <https://docs.nvidia.com/cuda/cufft/index.html>`_ library.
Targets Created:
- ``CUDA::cufft``
- ``CUDA::cufftw``
- ``CUDA::cufft_static``
- ``CUDA::cufftw_static``
.. _`cuda_toolkit_cuLIBOS`:
cuLIBOS
"""""""
The cuLIBOS library is a backend thread abstraction layer library which is
static only. The ``CUDA::cublas_static``, ``CUDA::cusparse_static``,
``CUDA::cufft_static``, ``CUDA::curand_static``, and (when implemented) NPP
libraries all automatically have this dependency linked.
Target Created:
- ``CUDA::culibos``
**Note**: direct usage of this target by consumers should not be necessary.
.. _`cuda_toolkit_cuRAND`:
cuRAND
""""""
The `cuRAND <https://docs.nvidia.com/cuda/curand/index.html>`_ library.
Targets Created:
- ``CUDA::curand``
- ``CUDA::curand_static``
.. _`cuda_toolkit_cuSOLVER`:
cuSOLVER
""""""""
The `cuSOLVER <https://docs.nvidia.com/cuda/cusolver/index.html>`_ library.
Targets Created:
- ``CUDA::cusolver``
- ``CUDA::cusolver_static``
.. _`cuda_toolkit_cuSPARSE`:
cuSPARSE
""""""""
The `cuSPARSE <https://docs.nvidia.com/cuda/cusparse/index.html>`_ library.
Targets Created:
- ``CUDA::cusparse``
- ``CUDA::cusparse_static``
.. _`cuda_toolkit_NPP`:
NPP
"""
The `NPP <https://docs.nvidia.com/cuda/npp/index.html>`_ libraries.
Targets Created:
- `nppc`:
- ``CUDA::nppc``
- ``CUDA::nppc_static``
- `nppial`: Arithmetic and logical operation functions in `nppi_arithmetic_and_logical_operations.h`
- ``CUDA::nppial``
- ``CUDA::nppial_static``
- `nppicc`: Color conversion and sampling functions in `nppi_color_conversion.h`
- ``CUDA::nppicc``
- ``CUDA::nppicc_static``
- `nppicom`: JPEG compression and decompression functions in `nppi_compression_functions.h`
- ``CUDA::nppicom``
- ``CUDA::nppicom_static``
- `nppidei`: Data exchange and initialization functions in `nppi_data_exchange_and_initialization.h`
- ``CUDA::nppidei``
- ``CUDA::nppidei_static``
- `nppif`: Filtering and computer vision functions in `nppi_filter_functions.h`
- ``CUDA::nppif``
- ``CUDA::nppif_static``
- `nppig`: Geometry transformation functions found in `nppi_geometry_transforms.h`
- ``CUDA::nppig``
- ``CUDA::nppig_static``
- `nppim`: Morphological operation functions found in `nppi_morphological_operations.h`
- ``CUDA::nppim``
- ``CUDA::nppim_static``
- `nppist`: Statistics and linear transform in `nppi_statistics_functions.h` and `nppi_linear_transforms.h`
- ``CUDA::nppist``
- ``CUDA::nppist_static``
- `nppisu`: Memory support functions in `nppi_support_functions.h`
- ``CUDA::nppisu``
- ``CUDA::nppisu_static``
- `nppitc`: Threshold and compare operation functions in `nppi_threshold_and_compare_operations.h`
- ``CUDA::nppitc``
- ``CUDA::nppitc_static``
- `npps`:
- ``CUDA::npps``
- ``CUDA::npps_static``
.. _`cuda_toolkit_nvBLAS`:
nvBLAS
""""""
The `nvBLAS <https://docs.nvidia.com/cuda/nvblas/index.html>`_ libraries.
This is a shared library only.
Targets Created:
- ``CUDA::nvblas``
.. _`cuda_toolkit_nvGRAPH`:
nvGRAPH
"""""""
The `nvGRAPH <https://docs.nvidia.com/cuda/nvgraph/index.html>`_ library.
Targets Created:
- ``CUDA::nvgraph``
- ``CUDA::nvgraph_static``
.. _`cuda_toolkit_nvJPEG`:
nvJPEG
"""""""
The `nvJPEG <https://docs.nvidia.com/cuda/nvjpeg/index.html>`_ library.
Targets Created:
- ``CUDA::nvjpeg``
- ``CUDA::nvjpeg_static``
.. _`cuda_toolkit_nvRTC`:
nvRTC
"""""
The `nvRTC <https://docs.nvidia.com/cuda/nvrtc/index.html>`_ (Runtime Compilation) library.
This is a shared library only.
Targets Created:
- ``CUDA::nvrtc``
.. _`cuda_toolkit_nvToolsExt`:
nvToolsExt
""""""""""
The `NVIDIA Tools Extension <https://docs.nvidia.com/gameworks/content/gameworkslibrary/nvtx/nvidia_tools_extension_library_nvtx.htm>`_.
This is a shared library only.
Targets Created:
- ``CUDA::nvToolsExt``
Result variables
^^^^^^^^^^^^^^^^
``CUDAToolkit_FOUND``
@@ -96,10 +337,9 @@ Output Variables
The exact version of the CUDA Toolkit found (as reported by
``nvcc --version``).
``CUDAToolkit_ROOT_DIR``
The root directory of the CUDA Toolkit found. Note that this variable will
be the same as ``CUDAToolkit_ROOT`` when specified *and* a suitable toolkit was
found.
``CUDAToolkit_BIN_DIR``
The path to the CUDA Toolkit library directory that contains the CUDA
executable ``nvcc``.
``CUDAToolkit_INCLUDE_DIRS``
The path to the CUDA Toolkit ``include`` folder containing the header files
@@ -117,6 +357,7 @@ Output Variables
features of the Toolkit. This variable is set for the convenience of
modules that depend on this one.
#]=======================================================================]
# NOTE: much of this was simply extracted from FindCUDA.cmake.
@@ -156,7 +397,7 @@ Output Variables
###############################################################################
# Attempt 1: try user provided paths first.
find_path(CUDAToolkit_ROOT_DIR
find_path(CUDAToolkit_BIN_DIR
NAMES nvcc nvcc.exe
PATHS
${CUDAToolkit_ROOT}
@@ -165,10 +406,8 @@ find_path(CUDAToolkit_ROOT_DIR
NO_DEFAULT_PATH
)
message(FATAL_ERROR "CUDAToolkit_ROOT_DIR: ${CUDAToolkit_ROOT_DIR}")
# If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error.
if (NOT CUDAToolkit_ROOT_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
if (NOT CUDAToolkit_BIN_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
# Declare error messages now, print later depending on find_package args.
set(fail_base "Could not find nvcc executable in path specified by")
set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
@@ -205,7 +444,7 @@ endif()
# We will also search the default symlink location /usr/local/cuda first since
# if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
# directory is the desired location.
if (NOT CUDAToolkit_ROOT_DIR)
if (NOT CUDAToolkit_BIN_DIR)
if (UNIX)
if (NOT APPLE)
set(platform_base "/usr/local/cuda-")
@@ -272,7 +511,7 @@ if (NOT CUDAToolkit_ROOT_DIR)
endif()
# Now search for nvcc again using the platform default search paths.
find_path(CUDAToolkit_ROOT_DIR
find_path(CUDAToolkit_BIN_DIR
NAMES nvcc nvcc.exe
PATHS ${search_paths}
PATH_SUFFIXES bin bin64
@@ -288,7 +527,7 @@ if (NOT CUDAToolkit_ROOT_DIR)
unset(early_terminate)
unset(search_paths)
if (NOT CUDAToolkit_ROOT_DIR)
if (NOT CUDAToolkit_BIN_DIR)
if (CUDAToolkit_FIND_REQUIRED)
message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.")
elseif(NOT CUDAToolkit_FIND_QUIETLY)
@@ -300,13 +539,9 @@ if (NOT CUDAToolkit_ROOT_DIR)
endif()
endif()
# TODO: why does FindCUDA.cmake go through effor tof `cuda_find_host_program`
# when CMAKE_CROSSCOMPILING // is that still relevant?
# https://gitlab.kitware.com/cmake/cmake/issues/16509
# NOTE: search before trimming bin / bin64 from CUDAToolkit_ROOT_DIR
find_program(CUDAToolkit_NVCC_EXECUTABLE
NAMES nvcc nvcc.exe
PATHS ${CUDAToolkit_ROOT_DIR}
PATHS ${CUDAToolkit_BIN_DIR}
NO_DEFAULT_PATH
)
# Compute the version.
@@ -322,21 +557,14 @@ string(
REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2"
CUDAToolkit_VERSION_MINOR ${NVCC_OUT}
)
set(
CUDAToolkit_VERSION "${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}"
CACHE STRING "Version of CUDA as computed from nvcc."
)
set(CUDAToolkit_VERSION "${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}")
unset(NVCC_OUT)
# CUDAToolkit_ROOT_DIR should have the path to the bin or bin64 folder from the
# find_path calls above. Failure to find nvcc should have had an early return.
# So now we need to remove bin / bin64, as well as reset the cache entry that
# find_path creates.
string(REGEX REPLACE "[/\\\\]?bin[64]*[/\\\\]?$" "" CUDAToolkit_ROOT_DIR ${CUDAToolkit_ROOT_DIR})
set(CUDAToolkit_ROOT_DIR ${CUDAToolkit_ROOT_DIR} CACHE PATH "Toolkit location." FORCE)
get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE)
# Now that we have the real ROOT_DIR, find the include/ directory
find_path(CUDAToolkit_INCLUDE_DIRS
find_path(CUDAToolkit_INCLUDE_DIR
cuda_runtime.h
# TODO: FindCUDA.cmake has special TARGET_DIR for cross compiling, is that needed?
PATHS ${CUDAToolkit_ROOT_DIR}
@@ -345,30 +573,103 @@ find_path(CUDAToolkit_INCLUDE_DIRS
)
# And find the CUDA Runtime Library libcudart
find_library(libcudart
find_library(CUDA_CUDART
cudart
PATHS ${CUDAToolkit_ROOT_DIR}
PATH_SUFFIXES lib lib64
NO_DEFAULT_PATH
)
if (libcudart)
get_filename_component(CUDAToolkit_LIBRARY_DIR ${libcudart} DIRECTORY ABSOLUTE)
else()
if (NOT CUDAToolkit_FIND_QUIETLY)
message(STATUS "Unable to find cudart library under ${CUDAToolkit_ROOT_DIR}/lib[64].")
endif()
set(CUDAToolkit_LIBRARY_DIR CUDAToolkit_LIBRARY_DIR-NOTFOUND)
if (NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY)
message(STATUS "Unable to find cudart library under ${CUDAToolkit_ROOT_DIR}/lib[64].")
endif()
unset(libcudart)
unset(CUDAToolkit_ROOT_DIR)
#-----------------------------------------------------------------------------
# Perform version comparison and validate all required variables are set.
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(CUDAToolkit
REQUIRED_VARS
CUDAToolkit_ROOT_DIR
CUDAToolkit_INCLUDE_DIRS
CUDAToolkit_LIBRARY_DIR
CUDAToolkit_INCLUDE_DIR
CUDA_CUDART
CUDAToolkit_NVCC_EXECUTABLE
VERSION_VAR
CUDAToolkit_VERSION
)
#-----------------------------------------------------------------------------
# Construct result variables
if(CUDAToolkit)
set(CUDAToolkit_ROOT_DIR )
set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR})
get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE)
endif()
#-----------------------------------------------------------------------------
# Construct import targets
if(CUDAToolkit)
function(find_and_add_cuda_import_lib lib_name)
string(TOUPPER ${lib_name} LIB_NAME)
find_library(CUDA_${LIB_NAME} ${lib_name} PATHS ${CUDAToolkit_LIBRARY_DIR})
if (NOT CUDA::${lib_name} AND CUDA_${LIB_NAME})
add_library(CUDA::${lib_name} IMPORTED INTERFACE)
target_include_directories(CUDA::${lib_name} INTERFACE "${CUDA_INCLUDE_DIRS}")
target_link_libraries(CUDA::${lib_name} INTERFACE "${CUDA_${LIB_NAME}}")
endif()
endfunction()
function(add_cuda_link_dependency lib_name)
foreach(dependency IN LISTS ${ARGN})
target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dependency})
endforeach()
endfunction()
find_and_add_cuda_import_lib(cudart)
find_and_add_cuda_import_lib(cudart_static)
foreach (cuda_lib cublas cufft cufftw curand cusolver cusparse nvgraph nvjpeg)
find_and_add_cuda_import_lib(${cuda_lib})
add_cuda_link_dependency(${cuda_lib} cudart)
find_and_add_cuda_import_lib(${cuda_lib}_static)
add_cuda_link_dependency(${cuda_lib}_static cudart_static)
endforeach()
# cuSOLVER depends on cuBLAS, and cuSPARSE
add_cuda_link_dependency(cusolver cublas cusparse)
add_cuda_link_dependency(cusolver_static cublas_static cusparse)
# nvGRAPH depends on cuRAND, and cuSOLVER.
add_cuda_link_dependency(nvgraph curand cusolver)
add_cuda_link_dependency(nvgraph_static curand_static cusolver_static)
find_and_add_cuda_import_lib(nppc)
find_and_add_cuda_import_lib(nppc_static)
add_cuda_link_dependency(nppc cudart)
add_cuda_link_dependency(nppc_static cudart_static culibos)
# Process the majority of the NPP libraries.
foreach (cuda_lib nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu)
find_and_add_cuda_import_lib(${cuda_lib})
find_and_add_cuda_import_lib(${cuda_lib}_static)
add_cuda_link_dependency(${cuda_lib} nppc)
add_cuda_link_dependency(${cuda_lib}_static nppc_static)
endforeach()
find_and_add_cuda_import_lib(nvrtc)
add_cuda_link_dependency(nvrtc cuda)
find_and_add_cuda_import_lib(nvToolsExt)
add_cuda_link_dependency(nvToolsExt cudart)
find_and_add_cuda_import_lib(culibos)
foreach (cuda_lib cublas cufft cusparse curand nvjpeg)
add_cuda_link_dependency(${cuda_lib}_static culibos)
endforeach()
endif()