From 12d324e55d0b47f442a147d8c2f93b1e6d7c2216 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 9 Dec 2019 09:12:39 -0500 Subject: CUDA: Persist SIZEOF_VOID_P and PLATFORM_ABI The CUDA language failed to persist CMAKE_SIZEOF_VOID_P and CMAKE_INTERNAL_PLATFORM_ABI, causing find_ calls to fail when the only enabled language was CUDA. This specifically occurred when having to locate libraries inside `lib64` directories. --- Modules/CMakeCUDACompiler.cmake.in | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Modules/CMakeCUDACompiler.cmake.in b/Modules/CMakeCUDACompiler.cmake.in index ea491a9..4a615a3 100644 --- a/Modules/CMakeCUDACompiler.cmake.in +++ b/Modules/CMakeCUDACompiler.cmake.in @@ -11,7 +11,9 @@ set(CMAKE_CUDA14_COMPILE_FEATURES "@CMAKE_CUDA14_COMPILE_FEATURES@") set(CMAKE_CUDA17_COMPILE_FEATURES "@CMAKE_CUDA17_COMPILE_FEATURES@") set(CMAKE_CUDA20_COMPILE_FEATURES "@CMAKE_CUDA20_COMPILE_FEATURES@") +set(CMAKE_CUDA_PLATFORM_ID "@CMAKE_CUDA_PLATFORM_ID@") set(CMAKE_CUDA_SIMULATE_ID "@CMAKE_CUDA_SIMULATE_ID@") +set(CMAKE_CUDA_COMPILER_FRONTEND_VARIANT "@CMAKE_CUDA_COMPILER_FRONTEND_VARIANT@") set(CMAKE_CUDA_SIMULATE_VERSION "@CMAKE_CUDA_SIMULATE_VERSION@") @SET_MSVC_CUDA_ARCHITECTURE_ID@ @@ -24,7 +26,18 @@ set(CMAKE_CUDA_SOURCE_FILE_EXTENSIONS cu) set(CMAKE_CUDA_LINKER_PREFERENCE 15) set(CMAKE_CUDA_LINKER_PREFERENCE_PROPAGATES 1) +set(CMAKE_CUDA_SIZEOF_DATA_PTR "@CMAKE_CUDA_SIZEOF_DATA_PTR@") +set(CMAKE_CUDA_COMPILER_ABI "@CMAKE_CUDA_COMPILER_ABI@") set(CMAKE_CUDA_LIBRARY_ARCHITECTURE "@CMAKE_CUDA_LIBRARY_ARCHITECTURE@") + +if(CMAKE_CUDA_SIZEOF_DATA_PTR) + set(CMAKE_SIZEOF_VOID_P "${CMAKE_CUDA_SIZEOF_DATA_PTR}") +endif() + +if(CMAKE_CUDA_COMPILER_ABI) + set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CUDA_COMPILER_ABI}") +endif() + if(CMAKE_CUDA_LIBRARY_ARCHITECTURE) set(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_CUDA_LIBRARY_ARCHITECTURE@") endif() -- cgit v0.12 From 2c0ff263b436050bac388485238360d5eec4a9d4 Mon Sep 17 00:00:00 2001 From: Stephen McDowell Date: Mon, 25 Feb 2019 00:21:39 -0800 Subject: FindCUDAToolkit: Add module to find the CUDA Toolkit --- Help/manual/cmake-modules.7.rst | 1 + Help/module/FindCUDAToolkit.rst | 1 + Help/release/dev/FindCUDAToolkit-module.rst | 4 + Modules/FindCUDAToolkit.cmake | 374 ++++++++++++++++++++++++++++ 4 files changed, 380 insertions(+) create mode 100644 Help/module/FindCUDAToolkit.rst create mode 100644 Help/release/dev/FindCUDAToolkit-module.rst create mode 100644 Modules/FindCUDAToolkit.cmake diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index c60dc40..be64112 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -122,6 +122,7 @@ They are normally called through the :command:`find_package` command. /module/FindCABLE /module/FindCoin3D /module/FindCups + /module/FindCUDAToolkit /module/FindCURL /module/FindCurses /module/FindCVS diff --git a/Help/module/FindCUDAToolkit.rst b/Help/module/FindCUDAToolkit.rst new file mode 100644 index 0000000..5f01d68 --- /dev/null +++ b/Help/module/FindCUDAToolkit.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/FindCUDAToolkit.cmake diff --git a/Help/release/dev/FindCUDAToolkit-module.rst b/Help/release/dev/FindCUDAToolkit-module.rst new file mode 100644 index 0000000..53a69c6 --- /dev/null +++ b/Help/release/dev/FindCUDAToolkit-module.rst @@ -0,0 +1,4 @@ +FindCUDAToolkit-module +---------------------- + +* The :module:`FindCUDAToolkit` module was added to find the CUDA Toolkit without enabling CUDA as a language. diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake new file mode 100644 index 0000000..6eed463 --- /dev/null +++ b/Modules/FindCUDAToolkit.cmake @@ -0,0 +1,374 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +#[=======================================================================[.rst: +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. + +Search Behavior +^^^^^^^^^^^^^^^ + +Finding the CUDA Toolkit requires finding the ``nvcc`` executable, which is +searched for in the following order: + +1. If the ``CUDAToolkit_ROOT`` cmake configuration variable (e.g., + ``-DCUDAToolkit_ROOT=/some/path``) *or* environment variable is defined, it + will be searched first. If both an environment variable **and** a + configuration variable are specified, the *configuration* variable takes + precedence. + + The directory specified here must be such that the executable ``nvcc`` can be + found underneath the directory specified by ``CUDAToolkit_ROOT``. If + ``CUDAToolkit_ROOT`` is specified, but no ``nvcc`` is found underneath, this + package is marked as **not** found. No subsequent search attempts are + performed. + +2. The user's path is searched for ``nvcc`` using :command:`find_program`. If + this is found, no subsequent search attempts are performed. Users are + responsible for ensuring that the first ``nvcc`` to show up in the path is + the desired path in the event that multiple CUDA Toolkits are installed. + +3. On Unix systems, if the symbolic link ``/usr/local/cuda`` exists, this is + used. No subsequent search attempts are performed. No default symbolic link + location exists for the Windows platform. + +4. The platform specific default install locations are searched. If exactly one + candidate is found, this is used. The default CUDA Toolkit install locations + searched are: + + +-------------+-------------------------------------------------------------+ + | Platform | Search Pattern | + +=============+=============================================================+ + | macOS | ``/Developer/NVIDIA/CUDA-X.Y`` | + +-------------+-------------------------------------------------------------+ + | Other Unix | ``/usr/local/cuda-X.Y`` | + +-------------+-------------------------------------------------------------+ + | Windows | ``C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y`` | + +-------------+-------------------------------------------------------------+ + + Where ``X.Y`` would be a specific version of the CUDA Toolkit, such as + ``/usr/local/cuda-9.0`` or + ``C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0`` + + .. note:: + + When multiple CUDA Toolkits are installed in the default location of a + system (e.g., both ``/usr/local/cuda-9.0`` and ``/usr/local/cuda-10.0`` + exist but the ``/usr/local/cuda`` symbolic link does **not** exist), this + package is marked as **not** found. + + There are too many factors involved in making an automatic decision in + the presence of multiple CUDA Toolkits being installed. In this + situation, users are encouraged to either (1) set ``CUDAToolkit_ROOT`` or + (2) ensure that the correct ``nvcc`` executable shows up in ``$PATH`` for + :command:`find_program` to find. + +Options +^^^^^^^ + +``VERSION`` + If specified, describes the version of the CUDA Toolkit to search for. + +``REQUIRED`` + If specified, configuration will error if a suitable CUDA Toolkit is not + found. + +``QUIET`` + If specified, the search for a suitable CUDA Toolkit will not produce any + messages. + +``EXACT`` + If specified, the CUDA Toolkit is considered found only if the exact + ``VERSION`` specified is recovered. + +Output Variables +^^^^^^^^^^^^^^^^ + +``CUDAToolkit_FOUND`` + A boolean specifying whether or not the CUDA Toolkit was found. + +``CUDAToolkit_VERSION`` + 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_INCLUDE_DIRS`` + The path to the CUDA Toolkit ``include`` folder containing the header files + required to compile a project linking against CUDA. + +``CUDAToolkit_LIBRARY_DIR`` + The path to the CUDA Toolkit library directory that contains the CUDA + Runtime library ``cudart``. + +``CUDAToolkit_NVCC_EXECUTABLE`` + The path to the NVIDIA CUDA compiler ``nvcc``. Note that this path may not + **not** be the same as + :variable:`CMAKE_CUDA_COMPILER _COMPILER>`. ``nvcc`` must be + found to determine the CUDA Toolkit version as well as determining other + 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. + +# 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. +# +############################################################################### + +# Attempt 1: try user provided paths first. +find_path(CUDAToolkit_ROOT_DIR + NAMES nvcc nvcc.exe + PATHS + ${CUDAToolkit_ROOT} + ENV CUDAToolkit_ROOT + PATH_SUFFIXES bin bin64 + 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})) + # 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}") + set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}") + + if (CUDAToolkit_FIND_REQUIRED) + if (DEFINED CUDAToolkit_ROOT) + message(FATAL_ERROR ${cuda_root_fail}) + elseif (DEFINED ENV{CUDAToolkit_ROOT}) + message(FATAL_ERROR ${env_cuda_root_fail}) + endif() + else() + if (NOT CUDAToolkit_FIND_QUIETLY) + if (DEFINED CUDAToolkit_ROOT) + message(STATUS ${cuda_root_fail}) + elseif (DEFINED ENV{CUDAToolkit_ROOT}) + message(STATUS ${env_cuda_root_fail}) + endif() + endif() + set(CUDAToolkit_FOUND FALSE) + unset(fail_base) + unset(cuda_root_fail) + unset(env_cuda_root_fail) + return() + endif() +endif() + +# CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults. +# +# - Linux: /usr/local/cuda-X.Y +# - macOS: /Developer/NVIDIA/CUDA-X.Y +# - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y +# +# 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 (UNIX) + if (NOT APPLE) + set(platform_base "/usr/local/cuda-") + else() + set(platform_base "/Developer/NVIDIA/CUDA-") + endif() + else() + set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v") + endif() + + # Build out a descending list of possible cuda installations, e.g. + file(GLOB possible_paths "${platform_base}*") + # Iterate the glob results and create a descending list. + set(possible_versions) + foreach (p ${possible_paths}) + # Extract version number from end of string + string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p}) + if (IS_DIRECTORY ${p} AND p_version) + list(APPEND possible_versions ${p_version}) + endif() + endforeach() + + # Cannot use list(SORT) because that is alphabetical, we need numerical. + # NOTE: this is not an efficient sorting strategy. But even if a user had + # every possible version of CUDA installed, this wouldn't create any + # significant overhead. + set(versions) + foreach (v ${possible_versions}) + list(LENGTH versions num_versions) + # First version, nothing to compare with so just append. + if (num_versions EQUAL 0) + list(APPEND versions ${v}) + else() + # Loop through list. Insert at an index when comparison is + # VERSION_GREATER since we want a descending list. Duplicates will not + # happen since this came from a glob list of directories. + set(i 0) + set(early_terminate FALSE) + while (i LESS num_versions) + list(GET versions ${i} curr) + if (v VERSION_GREATER curr) + list(INSERT versions ${i} ${v}) + set(early_terminate TRUE) + break() + endif() + math(EXPR i "${i} + 1") + endwhile() + # If it did not get inserted, place it at the end. + if (NOT early_terminate) + list(APPEND versions ${v}) + endif() + endif() + endforeach() + + # With a descending list of versions, populate possible paths to search. + set(search_paths) + foreach (v ${versions}) + list(APPEND search_paths "${platform_base}${v}") + endforeach() + + # Force the global default /usr/local/cuda to the front on Unix. + if (UNIX) + list(INSERT search_paths 0 "/usr/local/cuda") + endif() + + # Now search for nvcc again using the platform default search paths. + find_path(CUDAToolkit_ROOT_DIR + NAMES nvcc nvcc.exe + PATHS ${search_paths} + PATH_SUFFIXES bin bin64 + NO_DEFAULT_PATH + ) + + # We are done with these variables now, cleanup for caller. + unset(platform_base) + unset(possible_paths) + unset(possible_versions) + unset(versions) + unset(i) + unset(early_terminate) + unset(search_paths) + + if (NOT CUDAToolkit_ROOT_DIR) + if (CUDAToolkit_FIND_REQUIRED) + message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.") + elseif(NOT CUDAToolkit_FIND_QUIETLY) + message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.") + endif() + + set(CUDAToolkit_FOUND FALSE) + return() + 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} + NO_DEFAULT_PATH +) +# Compute the version. +execute_process( + COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" + OUTPUT_VARIABLE NVCC_OUT +) +string( + REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\1" + CUDAToolkit_VERSION_MAJOR ${NVCC_OUT} +) +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." +) +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) + +# Now that we have the real ROOT_DIR, find the include/ directory +find_path(CUDAToolkit_INCLUDE_DIRS + cuda_runtime.h + # TODO: FindCUDA.cmake has special TARGET_DIR for cross compiling, is that needed? + PATHS ${CUDAToolkit_ROOT_DIR} + PATH_SUFFIXES include + NO_DEFAULT_PATH +) + +# And find the CUDA Runtime Library libcudart +find_library(libcudart + 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) +endif() +unset(libcudart) + +# 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_NVCC_EXECUTABLE + VERSION_VAR + CUDAToolkit_VERSION +) -- cgit v0.12 From 29560bf07b49aee326f555aec53b091e3520294b Mon Sep 17 00:00:00 2001 From: Stephen McDowell Date: Wed, 4 Dec 2019 16:14:50 -0500 Subject: FindCUDAToolkit: Import targets for toolkit libraries --- Modules/FindCUDAToolkit.cmake | 389 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 345 insertions(+), 44 deletions(-) diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index 6eed463..384f734 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -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` +- :ref:`cuBLAS` +- :ref:`cuFFT` +- :ref:`cuLIBOS` +- :ref:`cuRAND` +- :ref:`cuSOLVER` +- :ref:`cuSPARSE` +- :ref:`NPP` +- :ref:`nvBLAS` +- :ref:`nvGRAPH` +- :ref:`nvJPEG` +- :ref:`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 `_ library. + +Targets Created: + +- ``CUDA::cublas`` +- ``CUDA::cublas_static`` + +.. _`cuda_toolkit_cuFFT`: + +cuFFT +""""" + +The `cuFFT `_ 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 `_ library. + +Targets Created: + +- ``CUDA::curand`` +- ``CUDA::curand_static`` + +.. _`cuda_toolkit_cuSOLVER`: + +cuSOLVER +"""""""" + +The `cuSOLVER `_ library. + +Targets Created: + +- ``CUDA::cusolver`` +- ``CUDA::cusolver_static`` + +.. _`cuda_toolkit_cuSPARSE`: + +cuSPARSE +"""""""" + +The `cuSPARSE `_ library. + +Targets Created: + +- ``CUDA::cusparse`` +- ``CUDA::cusparse_static`` + +.. _`cuda_toolkit_NPP`: + +NPP +""" + +The `NPP `_ 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 `_ libraries. +This is a shared library only. + +Targets Created: + +- ``CUDA::nvblas`` + +.. _`cuda_toolkit_nvGRAPH`: + +nvGRAPH +""""""" + +The `nvGRAPH `_ library. + +Targets Created: + +- ``CUDA::nvgraph`` +- ``CUDA::nvgraph_static`` + + +.. _`cuda_toolkit_nvJPEG`: + +nvJPEG +""""""" + +The `nvJPEG `_ library. + +Targets Created: + +- ``CUDA::nvjpeg`` +- ``CUDA::nvjpeg_static`` + +.. _`cuda_toolkit_nvRTC`: + +nvRTC +""""" + +The `nvRTC `_ (Runtime Compilation) library. +This is a shared library only. + +Targets Created: + +- ``CUDA::nvrtc`` + +.. _`cuda_toolkit_nvToolsExt`: + +nvToolsExt +"""""""""" + +The `NVIDIA Tools Extension `_. +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() -- cgit v0.12 From e2a5d8374f94c7893109e11173fc770cec8a4683 Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Mon, 25 Nov 2019 16:03:15 -0500 Subject: FindCUDAToolkit: Improve usage, library set, and tests Refined the initial design of FindCUDAToolkit and improve it by adding more library support, more toolkit information and tests. --- Modules/FindCUDA.cmake | 11 +- Modules/FindCUDAToolkit.cmake | 219 +++++++++++++++++-------- Tests/Cuda/CMakeLists.txt | 3 +- Tests/Cuda/IncludePathNoToolkit/CMakeLists.txt | 11 ++ Tests/Cuda/IncludePathNoToolkit/main.cpp | 8 + Tests/Cuda/Toolkit/CMakeLists.txt | 45 +++++ Tests/Cuda/Toolkit/main.cpp | 8 + Tests/Cuda/ToolkitInclude/CMakeLists.txt | 11 -- Tests/Cuda/ToolkitInclude/main.cpp | 8 - Tests/CudaOnly/CMakeLists.txt | 1 + Tests/CudaOnly/Toolkit/CMakeLists.txt | 54 ++++++ Tests/CudaOnly/Toolkit/main.cu | 8 + 12 files changed, 298 insertions(+), 89 deletions(-) create mode 100644 Tests/Cuda/IncludePathNoToolkit/CMakeLists.txt create mode 100644 Tests/Cuda/IncludePathNoToolkit/main.cpp create mode 100644 Tests/Cuda/Toolkit/CMakeLists.txt create mode 100644 Tests/Cuda/Toolkit/main.cpp delete mode 100644 Tests/Cuda/ToolkitInclude/CMakeLists.txt delete mode 100644 Tests/Cuda/ToolkitInclude/main.cpp create mode 100644 Tests/CudaOnly/Toolkit/CMakeLists.txt create mode 100644 Tests/CudaOnly/Toolkit/main.cu diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake index ad7fe99..0e2f551 100644 --- a/Modules/FindCUDA.cmake +++ b/Modules/FindCUDA.cmake @@ -5,17 +5,22 @@ FindCUDA .. deprecated:: 3.10 Superseded by first-class support for the CUDA language in CMake. + Superseded by the :module:`FindCUDAToolkit` for CUDA toolkit libraries. Replacement ^^^^^^^^^^^ -It is no longer necessary to use this module or call ``find_package(CUDA)``. -Instead, list ``CUDA`` among the languages named in the top-level -call to the :command:`project` command, or call the +It is no longer necessary to use this module or call ``find_package(CUDA)`` +for compiling CUDA code. Instead, list ``CUDA`` among the languages named +in the top-level call to the :command:`project` command, or call the :command:`enable_language` command with ``CUDA``. Then one can add CUDA (``.cu``) sources to programs directly in calls to :command:`add_library` and :command:`add_executable`. +To find and use the CUDA toolkit libraries the :module:`FindCUDAToolkit` +module has superseded this module. It works whether or not the ``CUDA`` +language is enabled. + Documentation of Deprecated Usage ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index 384f734..c3ce38a 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -15,9 +15,12 @@ Search Behavior Finding the CUDA Toolkit requires finding the ``nvcc`` executable, which is searched for in the following order: -1. If the ``CUDAToolkit_ROOT`` cmake configuration variable (e.g., +1. If the ``CUDA`` language has been enabled we will use the directory + containing the compiler as the first search location for ``nvcc``. + +2. If the ``CUDAToolkit_ROOT`` cmake configuration variable (e.g., ``-DCUDAToolkit_ROOT=/some/path``) *or* environment variable is defined, it - will be searched first. If both an environment variable **and** a + will be searched. If both an environment variable **and** a configuration variable are specified, the *configuration* variable takes precedence. @@ -27,16 +30,16 @@ searched for in the following order: package is marked as **not** found. No subsequent search attempts are performed. -2. The user's path is searched for ``nvcc`` using :command:`find_program`. If +3. The user's path is searched for ``nvcc`` using :command:`find_program`. If this is found, no subsequent search attempts are performed. Users are responsible for ensuring that the first ``nvcc`` to show up in the path is the desired path in the event that multiple CUDA Toolkits are installed. -3. On Unix systems, if the symbolic link ``/usr/local/cuda`` exists, this is +4. On Unix systems, if the symbolic link ``/usr/local/cuda`` exists, this is used. No subsequent search attempts are performed. No default symbolic link location exists for the Windows platform. -4. The platform specific default install locations are searched. If exactly one +5. The platform specific default install locations are searched. If exactly one candidate is found, this is used. The default CUDA Toolkit install locations searched are: @@ -88,13 +91,15 @@ Options Imported targets ^^^^^^^^^^^^^^^^ +An :ref:`imported target ` named ``CUDA::toolkit`` is provided. + This module defines :prop_tgt:`IMPORTED` targets for each of the following libraries that are part of the CUDAToolkit: -- :ref:`CUDA Runtime Libraries` +- :ref:`CUDA Runtime Library` +- :ref:`CUDA Driver Library` - :ref:`cuBLAS` - :ref:`cuFFT` -- :ref:`cuLIBOS` - :ref:`cuRAND` - :ref:`cuSOLVER` - :ref:`cuSPARSE` @@ -102,15 +107,19 @@ of the following libraries that are part of the CUDAToolkit: - :ref:`nvBLAS` - :ref:`nvGRAPH` - :ref:`nvJPEG` +- :ref:`nvidia-ML` +- :ref:`nvRTC` - :ref:`nvToolsExt` +- :ref:`OpenCL` +- :ref:`cuLIBOS` -.. _`cuda_toolkit_rt_libs`: +.. _`cuda_toolkit_rt_lib`: -CUDA Runtime Libraries -"""""""""""""""""""""" +CUDA Runtime Library +"""""""""""""""""""" -The CUDA Runtime libraries (cudart) are what most applications will typically -need to link against to make any calls such as `cudaMalloc` and `cudaFree`. +The CUDA Runtime library (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: @@ -118,6 +127,20 @@ Targets Created: - ``CUDA::cudart`` - ``CUDA::cudart_static`` +.. _`cuda_toolkit_driver_lib`: + +CUDA Driver Library +"""""""""""""""""""" + +The CUDA Driver library (cuda) are used by applications that use calls +such as `cuMemAlloc`, and `cuMemFree`. This is generally used by advanced + + +Targets Created: + +- ``CUDA::cuda_driver`` +- ``CUDA::cuda_driver`` + .. _`cuda_toolkit_cuBLAS`: cuBLAS @@ -144,24 +167,6 @@ Targets Created: - ``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 """""" @@ -293,9 +298,10 @@ Targets Created: .. _`cuda_toolkit_nvJPEG`: nvJPEG -""""""" +"""""" The `nvJPEG `_ library. +Introduced in CUDA 10. Targets Created: @@ -314,6 +320,20 @@ Targets Created: - ``CUDA::nvrtc`` +.. _`cuda_toolkit_nvml`: + +nvidia-ML +""""""""" + +The `NVIDIA Management Library `_. +This is a shared library only. + +Targets Created: + +- ``CUDA::nvml`` + +.. _`cuda_toolkit_opencl`: + .. _`cuda_toolkit_nvToolsExt`: nvToolsExt @@ -326,6 +346,35 @@ Targets Created: - ``CUDA::nvToolsExt`` +OpenCL +"""""" + +The `NVIDIA OpenCL Library `_. +This is a shared library only. + +Targets Created: + +- ``CUDA::OpenCL`` + +.. _`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`: + + Result variables ^^^^^^^^^^^^^^^^ @@ -337,6 +386,15 @@ Result variables The exact version of the CUDA Toolkit found (as reported by ``nvcc --version``). +``CUDAToolkit_VERSION_MAJOR`` + The major version of the CUDA Toolkit. + +``CUDAToolkit_VERSION_MAJOR`` + The minor version of the CUDA Toolkit. + +``CUDAToolkit_VERSION_PATCH`` + The patch version of the CUDA Toolkit. + ``CUDAToolkit_BIN_DIR`` The path to the CUDA Toolkit library directory that contains the CUDA executable ``nvcc``. @@ -350,7 +408,7 @@ Result variables Runtime library ``cudart``. ``CUDAToolkit_NVCC_EXECUTABLE`` - The path to the NVIDIA CUDA compiler ``nvcc``. Note that this path may not + The path to the NVIDIA CUDA compiler ``nvcc``. Note that this path may **not** be the same as :variable:`CMAKE_CUDA_COMPILER _COMPILER>`. ``nvcc`` must be found to determine the CUDA Toolkit version as well as determining other @@ -396,15 +454,21 @@ Result variables # ############################################################################### -# Attempt 1: try user provided paths first. -find_path(CUDAToolkit_BIN_DIR - NAMES nvcc nvcc.exe - PATHS - ${CUDAToolkit_ROOT} - ENV CUDAToolkit_ROOT - PATH_SUFFIXES bin bin64 - NO_DEFAULT_PATH -) +if(CMAKE_CUDA_COMPILER) + get_filename_component(cuda_dir "${CMAKE_CUDA_COMPILER}" DIRECTORY) + # use the already detected cuda compiler + set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "") +else() + # Try user provided paths first. + find_path(CUDAToolkit_BIN_DIR + NAMES nvcc nvcc.exe + PATHS + ${CUDAToolkit_ROOT} + ENV CUDAToolkit_ROOT + PATH_SUFFIXES bin bin64 + NO_DEFAULT_PATH + ) +endif() # If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error. if (NOT CUDAToolkit_BIN_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT})) @@ -544,21 +608,27 @@ find_program(CUDAToolkit_NVCC_EXECUTABLE PATHS ${CUDAToolkit_BIN_DIR} NO_DEFAULT_PATH ) -# Compute the version. -execute_process( - COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" - OUTPUT_VARIABLE NVCC_OUT -) -string( - REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\1" - CUDAToolkit_VERSION_MAJOR ${NVCC_OUT} -) -string( - REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" - CUDAToolkit_VERSION_MINOR ${NVCC_OUT} -) -set(CUDAToolkit_VERSION "${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}") -unset(NVCC_OUT) +if(CUDAToolkit_NVCC_EXECUTABLE AND + CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER) + # Need to set these based off the already computed CMAKE_CUDA_COMPILER_VERSION value + # This if statement will always match, but is used to provide variables for MATCH 1,2,3... + if(CMAKE_CUDA_COMPILER_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=]) + set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}") + set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}") + set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}") + set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_VERSION}") + endif() +else() + # Compute the version by invoking nvcc + execute_process (COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT) + if(NVCC_OUT MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=]) + set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}") + set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}") + set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}") + set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + endif() + unset(NVCC_OUT) +endif() get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE) @@ -599,27 +669,33 @@ find_package_handle_standard_args(CUDAToolkit #----------------------------------------------------------------------------- # Construct result variables -if(CUDAToolkit) - set(CUDAToolkit_ROOT_DIR ) +if(CUDAToolkit_FOUND) set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR}) get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE) endif() #----------------------------------------------------------------------------- # Construct import targets -if(CUDAToolkit) +if(CUDAToolkit_FOUND) 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(ARGC GREATER 1) + set(search_names ${ARGN}) + else() + set(search_names ${lib_name}) + endif() + + find_library(CUDA_${lib_name}_LIBRARY + NAMES ${search_names} + PATHS ${CUDAToolkit_LIBRARY_DIR} + ) - if (NOT CUDA::${lib_name} AND CUDA_${LIB_NAME}) + if (NOT CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY) 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}}") + target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}") + target_link_libraries(CUDA::${lib_name} INTERFACE "${CUDA_${lib_name}_LIBRARY}") endif() - endfunction() function(add_cuda_link_dependency lib_name) @@ -628,6 +704,13 @@ if(CUDAToolkit) endforeach() endfunction() + add_library(CUDA::toolkit IMPORTED INTERFACE) + target_include_directories(CUDA::toolkit SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}") + target_link_directories(CUDA::toolkit INTERFACE "${CUDAToolkit_LIBRARY_DIR}") + + + find_and_add_cuda_import_lib(cuda_driver cuda) + find_and_add_cuda_import_lib(cudart) find_and_add_cuda_import_lib(cudart_static) @@ -662,11 +745,15 @@ if(CUDAToolkit) endforeach() find_and_add_cuda_import_lib(nvrtc) - add_cuda_link_dependency(nvrtc cuda) + add_cuda_link_dependency(nvrtc cuda_driver) + + find_and_add_cuda_import_lib(nvml nvidia-ml nvml) find_and_add_cuda_import_lib(nvToolsExt) add_cuda_link_dependency(nvToolsExt cudart) + find_and_add_cuda_import_lib(OpenCL) + find_and_add_cuda_import_lib(culibos) foreach (cuda_lib cublas cufft cusparse curand nvjpeg) add_cuda_link_dependency(${cuda_lib}_static culibos) diff --git a/Tests/Cuda/CMakeLists.txt b/Tests/Cuda/CMakeLists.txt index 3b6a611..35b9022 100644 --- a/Tests/Cuda/CMakeLists.txt +++ b/Tests/Cuda/CMakeLists.txt @@ -9,7 +9,8 @@ ADD_TEST_MACRO(Cuda.MixedStandardLevels3 MixedStandardLevels3) ADD_TEST_MACRO(Cuda.MixedStandardLevels4 MixedStandardLevels4) ADD_TEST_MACRO(Cuda.MixedStandardLevels5 MixedStandardLevels5) ADD_TEST_MACRO(Cuda.NotEnabled CudaNotEnabled) -ADD_TEST_MACRO(Cuda.ToolkitInclude CudaToolkitInclude) +ADD_TEST_MACRO(Cuda.Toolkit Toolkit) +ADD_TEST_MACRO(Cuda.IncludePathNoToolkit IncludePathNoToolkit) ADD_TEST_MACRO(Cuda.ProperDeviceLibraries ProperDeviceLibraries) ADD_TEST_MACRO(Cuda.ProperLinkFlags ProperLinkFlags) ADD_TEST_MACRO(Cuda.WithC CudaWithC) diff --git a/Tests/Cuda/IncludePathNoToolkit/CMakeLists.txt b/Tests/Cuda/IncludePathNoToolkit/CMakeLists.txt new file mode 100644 index 0000000..7be1561 --- /dev/null +++ b/Tests/Cuda/IncludePathNoToolkit/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.8) +project (IncludePathNoToolkit CXX CUDA) + +#Goal for this example: +# Validate that between the CXX implicit include directories and the +# CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES directories we can find +# the cuda runtime headers + +add_executable(IncludePathNoToolkit main.cpp) +target_include_directories(IncludePathNoToolkit PRIVATE + ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) diff --git a/Tests/Cuda/IncludePathNoToolkit/main.cpp b/Tests/Cuda/IncludePathNoToolkit/main.cpp new file mode 100644 index 0000000..c8d5c6b --- /dev/null +++ b/Tests/Cuda/IncludePathNoToolkit/main.cpp @@ -0,0 +1,8 @@ +// Only thing we care about is that these headers are found +#include +#include + +int main() +{ + return 0; +} diff --git a/Tests/Cuda/Toolkit/CMakeLists.txt b/Tests/Cuda/Toolkit/CMakeLists.txt new file mode 100644 index 0000000..45b700b --- /dev/null +++ b/Tests/Cuda/Toolkit/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.15) +project(Toolkit CXX) + +#Goal for this example: +# Validate that we can use CUDAToolkit to find cuda include paths +find_package(CUDAToolkit REQUIRED) + +message(STATUS "CUDAToolkit_VERSION: ${CUDAToolkit_VERSION}") +message(STATUS "CUDAToolkit_VERSION_MAJOR: ${CUDAToolkit_VERSION_MAJOR}") +message(STATUS "CUDAToolkit_VERSION_MINOR: ${CUDAToolkit_VERSION_MINOR}") +message(STATUS "CUDAToolkit_VERSION_PATCH: ${CUDAToolkit_VERSION_PATCH}") +message(STATUS "CUDAToolkit_BIN_DIR: ${CUDAToolkit_BIN_DIR}") +message(STATUS "CUDAToolkit_INCLUDE_DIRS: ${CUDAToolkit_INCLUDE_DIRS}") +message(STATUS "CUDAToolkit_LIBRARY_DIR: ${CUDAToolkit_LIBRARY_DIR}") +message(STATUS "CUDAToolkit_NVCC_EXECUTABLE ${CUDAToolkit_NVCC_EXECUTABLE}") + +# Verify that all the CUDA:: targets exist even when the CUDA language isn't enabled + +foreach (cuda_lib cudart cuda_driver cublas cufft cufftw curand cusolver cusparse nvgraph) + if(NOT TARGET CUDA::${cuda_lib}) + message(FATAL_ERROR "The CUDA::${cuda_lib} target was expected but couldn't be found") + endif() +endforeach() + +foreach (cuda_lib nppc nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu) + if(NOT TARGET CUDA::${cuda_lib}) + message(FATAL_ERROR "The CUDA::${cuda_lib} target was expected but couldn't be found") + endif() +endforeach() + +foreach (cuda_lib nvrtc nvToolsExt OpenCL culibos) + if(NOT TARGET CUDA::${cuda_lib}) + message(FATAL_ERROR "The CUDA::${cuda_lib} target was expected but couldn't be found") + endif() +endforeach() + +#libraries added CUDA 10 +if(CUDAToolkit_VERSION_MAJOR VERSION_GREATER 9) + if(NOT TARGET CUDA::nvjpeg) + message(FATAL_ERROR "The CUDA::nvjpeg target was expected but couldn't be found") + endif() +endif() + +add_executable(Toolkit main.cpp) +target_link_libraries(Toolkit PRIVATE CUDA::toolkit) diff --git a/Tests/Cuda/Toolkit/main.cpp b/Tests/Cuda/Toolkit/main.cpp new file mode 100644 index 0000000..c8d5c6b --- /dev/null +++ b/Tests/Cuda/Toolkit/main.cpp @@ -0,0 +1,8 @@ +// Only thing we care about is that these headers are found +#include +#include + +int main() +{ + return 0; +} diff --git a/Tests/Cuda/ToolkitInclude/CMakeLists.txt b/Tests/Cuda/ToolkitInclude/CMakeLists.txt deleted file mode 100644 index f246b54..0000000 --- a/Tests/Cuda/ToolkitInclude/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -cmake_minimum_required(VERSION 3.8) -project (ToolkitInclude CXX CUDA) - -#Goal for this example: -# Validate that between the CXX implicit include directories and the -# CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES directories we can find -# the cuda runtime headers - -add_executable(CudaToolkitInclude main.cpp) -target_include_directories(CudaToolkitInclude PRIVATE - ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) diff --git a/Tests/Cuda/ToolkitInclude/main.cpp b/Tests/Cuda/ToolkitInclude/main.cpp deleted file mode 100644 index c8d5c6b..0000000 --- a/Tests/Cuda/ToolkitInclude/main.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// Only thing we care about is that these headers are found -#include -#include - -int main() -{ - return 0; -} diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt index 0dd3309..a0575cd 100644 --- a/Tests/CudaOnly/CMakeLists.txt +++ b/Tests/CudaOnly/CMakeLists.txt @@ -6,6 +6,7 @@ ADD_TEST_MACRO(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag) ADD_TEST_MACRO(CudaOnly.ResolveDeviceSymbols CudaOnlyResolveDeviceSymbols) ADD_TEST_MACRO(CudaOnly.SeparateCompilation CudaOnlySeparateCompilation) ADD_TEST_MACRO(CudaOnly.Standard98 CudaOnlyStandard98) +ADD_TEST_MACRO(CudaOnly.Toolkit CudaOnlyToolkit) ADD_TEST_MACRO(CudaOnly.WithDefs CudaOnlyWithDefs) add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND diff --git a/Tests/CudaOnly/Toolkit/CMakeLists.txt b/Tests/CudaOnly/Toolkit/CMakeLists.txt new file mode 100644 index 0000000..682e56e --- /dev/null +++ b/Tests/CudaOnly/Toolkit/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.15) +project(CudaOnlyToolkit CUDA) +find_package(CUDAToolkit REQUIRED) + +message(STATUS "CUDAToolkit_VERSION: ${CUDAToolkit_VERSION}") +message(STATUS "CUDAToolkit_VERSION_MAJOR: ${CUDAToolkit_VERSION_MAJOR}") +message(STATUS "CUDAToolkit_VERSION_MINOR: ${CUDAToolkit_VERSION_MINOR}") +message(STATUS "CUDAToolkit_VERSION_PATCH: ${CUDAToolkit_VERSION_PATCH}") +message(STATUS "CUDAToolkit_BIN_DIR: ${CUDAToolkit_BIN_DIR}") +message(STATUS "CUDAToolkit_INCLUDE_DIRS: ${CUDAToolkit_INCLUDE_DIRS}") +message(STATUS "CUDAToolkit_LIBRARY_DIR: ${CUDAToolkit_LIBRARY_DIR}") +message(STATUS "CUDAToolkit_NVCC_EXECUTABLE ${CUDAToolkit_NVCC_EXECUTABLE}") + +# Verify that all the CUDA:: targets and variables exist +foreach (cuda_lib cudart cuda_driver cublas cufft cufftw curand cusolver cusparse nvgraph) + if(NOT CUDA_${cuda_lib}_LIBRARY) + message(FATAL_ERROR "expected CUDAToolkit variable CUDA_${cuda_lib}_LIBRARY not found") + endif() + if(NOT TARGET CUDA::${cuda_lib}) + message(FATAL_ERROR "expected CUDAToolkit target CUDA::${cuda_lib} not found") + endif() +endforeach() + +foreach (cuda_lib nppc nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu) + if(NOT CUDA_${cuda_lib}_LIBRARY) + message(FATAL_ERROR "expected CUDAToolkit variable CUDA_${cuda_lib}_LIBRARY not found") + endif() + if(NOT TARGET CUDA::${cuda_lib}) + message(FATAL_ERROR "expected CUDAToolkit target CUDA::${cuda_lib} not found") + endif() +endforeach() + +foreach (cuda_lib nvrtc nvToolsExt OpenCL culibos) + if(NOT CUDA_${cuda_lib}_LIBRARY) + message(FATAL_ERROR "expected CUDAToolkit variable CUDA_${cuda_lib}_LIBRARY not found") + endif() + + if(NOT TARGET CUDA::${cuda_lib}) + message(FATAL_ERROR "expected CUDAToolkit target CUDA::${cuda_lib} not found") + endif() +endforeach() + +#libraries added as CUDA 10 +if(CUDAToolkit_VERSION_MAJOR VERSION_GREATER 9) + if(NOT CUDA_nvjpeg_LIBRARY) + message(FATAL_ERROR "expected CUDAToolkit variable CUDA_nvjpeg_LIBRARY not found") + endif() + if(NOT TARGET CUDA::nvjpeg) + message(FATAL_ERROR "The CUDA::nvjpeg target was expected but couldn't be found") + endif() +endif() + +add_executable(CudaOnlyToolkit main.cu) +target_link_libraries(CudaOnlyToolkit PRIVATE CUDA::toolkit) diff --git a/Tests/CudaOnly/Toolkit/main.cu b/Tests/CudaOnly/Toolkit/main.cu new file mode 100644 index 0000000..0f3ccdc --- /dev/null +++ b/Tests/CudaOnly/Toolkit/main.cu @@ -0,0 +1,8 @@ +// Only thing we care about is that these headers are found +#include +#include + +int main(int argc, char** argv) +{ + return 0; +} -- cgit v0.12 From d484a3c4d8f0bed1da42e17126bac8f7840463ef Mon Sep 17 00:00:00 2001 From: Robert Maynard Date: Thu, 12 Dec 2019 13:07:36 -0500 Subject: FindCUDAToolkit: correct searches for Toolkit components --- Modules/FindCUDAToolkit.cmake | 99 +++++++++++++++++++++-------------- Tests/Cuda/Toolkit/CMakeLists.txt | 9 +--- Tests/CudaOnly/Toolkit/CMakeLists.txt | 12 +---- 3 files changed, 63 insertions(+), 57 deletions(-) diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake index c3ce38a..1837694 100644 --- a/Modules/FindCUDAToolkit.cmake +++ b/Modules/FindCUDAToolkit.cmake @@ -30,16 +30,18 @@ searched for in the following order: package is marked as **not** found. No subsequent search attempts are performed. -3. The user's path is searched for ``nvcc`` using :command:`find_program`. If +3. If the CUDA_PATH environment variable is defined, it will be searched. + +4. The user's path is searched for ``nvcc`` using :command:`find_program`. If this is found, no subsequent search attempts are performed. Users are responsible for ensuring that the first ``nvcc`` to show up in the path is the desired path in the event that multiple CUDA Toolkits are installed. -4. On Unix systems, if the symbolic link ``/usr/local/cuda`` exists, this is +5. On Unix systems, if the symbolic link ``/usr/local/cuda`` exists, this is used. No subsequent search attempts are performed. No default symbolic link location exists for the Windows platform. -5. The platform specific default install locations are searched. If exactly one +6. The platform specific default install locations are searched. If exactly one candidate is found, this is used. The default CUDA Toolkit install locations searched are: @@ -454,24 +456,31 @@ Result variables # ############################################################################### -if(CMAKE_CUDA_COMPILER) +if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR) get_filename_component(cuda_dir "${CMAKE_CUDA_COMPILER}" DIRECTORY) # use the already detected cuda compiler set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "") -else() - # Try user provided paths first. - find_path(CUDAToolkit_BIN_DIR + unset(cuda_dir) +endif() + +# Try language- or user-provided path first. +if(CUDAToolkit_BIN_DIR) + find_program(CUDAToolkit_NVCC_EXECUTABLE NAMES nvcc nvcc.exe - PATHS - ${CUDAToolkit_ROOT} - ENV CUDAToolkit_ROOT - PATH_SUFFIXES bin bin64 + PATHS ${CUDAToolkit_BIN_DIR} NO_DEFAULT_PATH - ) + ) endif() +# Search using CUDAToolkit_ROOT +find_program(CUDAToolkit_NVCC_EXECUTABLE + NAMES nvcc nvcc.exe + PATHS ENV CUDA_PATH + PATH_SUFFIXES bin +) + # If the user specified CUDAToolkit_ROOT but nvcc could not be found, this is an error. -if (NOT CUDAToolkit_BIN_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT})) +if (NOT CUDAToolkit_NVCC_EXECUTABLE 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}") @@ -508,7 +517,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_BIN_DIR) +if (NOT CUDAToolkit_NVCC_EXECUTABLE) if (UNIX) if (NOT APPLE) set(platform_base "/usr/local/cuda-") @@ -575,11 +584,10 @@ if (NOT CUDAToolkit_BIN_DIR) endif() # Now search for nvcc again using the platform default search paths. - find_path(CUDAToolkit_BIN_DIR + find_program(CUDAToolkit_NVCC_EXECUTABLE NAMES nvcc nvcc.exe PATHS ${search_paths} - PATH_SUFFIXES bin bin64 - NO_DEFAULT_PATH + PATH_SUFFIXES bin ) # We are done with these variables now, cleanup for caller. @@ -591,7 +599,7 @@ if (NOT CUDAToolkit_BIN_DIR) unset(early_terminate) unset(search_paths) - if (NOT CUDAToolkit_BIN_DIR) + if (NOT CUDAToolkit_NVCC_EXECUTABLE) if (CUDAToolkit_FIND_REQUIRED) message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.") elseif(NOT CUDAToolkit_FIND_QUIETLY) @@ -603,11 +611,12 @@ if (NOT CUDAToolkit_BIN_DIR) endif() endif() -find_program(CUDAToolkit_NVCC_EXECUTABLE - NAMES nvcc nvcc.exe - PATHS ${CUDAToolkit_BIN_DIR} - NO_DEFAULT_PATH -) +if(NOT CUDAToolkit_BIN_DIR AND CUDAToolkit_NVCC_EXECUTABLE) + get_filename_component(cuda_dir "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY) + set(CUDAToolkit_BIN_DIR "${cuda_dir}" CACHE PATH "" FORCE) + unset(cuda_dir) +endif() + if(CUDAToolkit_NVCC_EXECUTABLE AND CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER) # Need to set these based off the already computed CMAKE_CUDA_COMPILER_VERSION value @@ -633,27 +642,25 @@ endif() get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE) -# Now that we have the real ROOT_DIR, find the include/ directory +# Now that we have the real ROOT_DIR, find components inside it. +list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR}) + +# Find the include/ directory 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} - PATH_SUFFIXES include - NO_DEFAULT_PATH + NAMES cuda_runtime.h ) # And find the CUDA Runtime Library libcudart find_library(CUDA_CUDART - cudart - PATHS ${CUDAToolkit_ROOT_DIR} - PATH_SUFFIXES lib lib64 - NO_DEFAULT_PATH + NAMES cudart + PATH_SUFFIXES lib64 lib/x64 ) if (NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY) - message(STATUS "Unable to find cudart library under ${CUDAToolkit_ROOT_DIR}/lib[64].") + message(STATUS "Unable to find cudart library.") endif() unset(CUDAToolkit_ROOT_DIR) +list(REMOVE_AT CMAKE_PREFIX_PATH -1) #----------------------------------------------------------------------------- # Perform version comparison and validate all required variables are set. @@ -689,6 +696,8 @@ if(CUDAToolkit_FOUND) find_library(CUDA_${lib_name}_LIBRARY NAMES ${search_names} PATHS ${CUDAToolkit_LIBRARY_DIR} + ENV CUDA_PATH + PATH_SUFFIXES nvidia/current lib64 lib/x64 lib ) if (NOT CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY) @@ -749,14 +758,28 @@ if(CUDAToolkit_FOUND) find_and_add_cuda_import_lib(nvml nvidia-ml nvml) - find_and_add_cuda_import_lib(nvToolsExt) + if(WIN32) + # nvtools can be installed outside the CUDA toolkit directory + # so prefer the NVTOOLSEXT_PATH windows only environment variable + # In addition on windows the most common name is nvToolsExt64_1 + find_library(CUDA_nvToolsExt_LIBRARY + NAMES nvToolsExt64_1 nvToolsExt64 nvToolsExt + PATHS ENV NVTOOLSEXT_PATH + ENV CUDA_PATH + PATH_SUFFIXES lib/x64 lib + ) + endif() + find_and_add_cuda_import_lib(nvToolsExt nvToolsExt nvToolsExt64) + add_cuda_link_dependency(nvToolsExt cudart) find_and_add_cuda_import_lib(OpenCL) find_and_add_cuda_import_lib(culibos) - foreach (cuda_lib cublas cufft cusparse curand nvjpeg) - add_cuda_link_dependency(${cuda_lib}_static culibos) - endforeach() + if(TARGET CUDA::culibos) + foreach (cuda_lib cublas cufft cusparse curand nvjpeg) + add_cuda_link_dependency(${cuda_lib}_static culibos) + endforeach() + endif() endif() diff --git a/Tests/Cuda/Toolkit/CMakeLists.txt b/Tests/Cuda/Toolkit/CMakeLists.txt index 45b700b..86b4652 100644 --- a/Tests/Cuda/Toolkit/CMakeLists.txt +++ b/Tests/Cuda/Toolkit/CMakeLists.txt @@ -28,18 +28,11 @@ foreach (cuda_lib nppc nppial nppicc nppidei nppif nppig nppim nppist nppitc npp endif() endforeach() -foreach (cuda_lib nvrtc nvToolsExt OpenCL culibos) +foreach (cuda_lib nvrtc nvToolsExt OpenCL) if(NOT TARGET CUDA::${cuda_lib}) message(FATAL_ERROR "The CUDA::${cuda_lib} target was expected but couldn't be found") endif() endforeach() -#libraries added CUDA 10 -if(CUDAToolkit_VERSION_MAJOR VERSION_GREATER 9) - if(NOT TARGET CUDA::nvjpeg) - message(FATAL_ERROR "The CUDA::nvjpeg target was expected but couldn't be found") - endif() -endif() - add_executable(Toolkit main.cpp) target_link_libraries(Toolkit PRIVATE CUDA::toolkit) diff --git a/Tests/CudaOnly/Toolkit/CMakeLists.txt b/Tests/CudaOnly/Toolkit/CMakeLists.txt index 682e56e..0d5d574 100644 --- a/Tests/CudaOnly/Toolkit/CMakeLists.txt +++ b/Tests/CudaOnly/Toolkit/CMakeLists.txt @@ -30,7 +30,7 @@ foreach (cuda_lib nppc nppial nppicc nppidei nppif nppig nppim nppist nppitc npp endif() endforeach() -foreach (cuda_lib nvrtc nvToolsExt OpenCL culibos) +foreach (cuda_lib nvrtc nvToolsExt OpenCL) if(NOT CUDA_${cuda_lib}_LIBRARY) message(FATAL_ERROR "expected CUDAToolkit variable CUDA_${cuda_lib}_LIBRARY not found") endif() @@ -40,15 +40,5 @@ foreach (cuda_lib nvrtc nvToolsExt OpenCL culibos) endif() endforeach() -#libraries added as CUDA 10 -if(CUDAToolkit_VERSION_MAJOR VERSION_GREATER 9) - if(NOT CUDA_nvjpeg_LIBRARY) - message(FATAL_ERROR "expected CUDAToolkit variable CUDA_nvjpeg_LIBRARY not found") - endif() - if(NOT TARGET CUDA::nvjpeg) - message(FATAL_ERROR "The CUDA::nvjpeg target was expected but couldn't be found") - endif() -endif() - add_executable(CudaOnlyToolkit main.cu) target_link_libraries(CudaOnlyToolkit PRIVATE CUDA::toolkit) -- cgit v0.12