1 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
4 #[=======================================================================[.rst:
10 This script locates the NVIDIA CUDA toolkit and the associated libraries, but
11 does not require the ``CUDA`` language be enabled for a given project. This
12 module does not search for the NVIDIA CUDA Samples.
14 .. versionadded:: 3.19
20 The CUDA Toolkit search behavior uses the following order:
22 1. If the ``CUDA`` language has been enabled we will use the directory
23 containing the compiler as the first search location for ``nvcc``.
25 2. If the ``CUDAToolkit_ROOT`` cmake configuration variable (e.g.,
26 ``-DCUDAToolkit_ROOT=/some/path``) *or* environment variable is defined, it
27 will be searched. If both an environment variable **and** a
28 configuration variable are specified, the *configuration* variable takes
31 The directory specified here must be such that the executable ``nvcc`` or
32 the appropriate ``version.txt`` file can be found underneath the specified
35 3. If the CUDA_PATH environment variable is defined, it will be searched
38 4. The user's path is searched for ``nvcc`` using :command:`find_program`. If
39 this is found, no subsequent search attempts are performed. Users are
40 responsible for ensuring that the first ``nvcc`` to show up in the path is
41 the desired path in the event that multiple CUDA Toolkits are installed.
43 5. On Unix systems, if the symbolic link ``/usr/local/cuda`` exists, this is
44 used. No subsequent search attempts are performed. No default symbolic link
45 location exists for the Windows platform.
47 6. The platform specific default install locations are searched. If exactly one
48 candidate is found, this is used. The default CUDA Toolkit install locations
51 +-------------+-------------------------------------------------------------+
52 | Platform | Search Pattern |
53 +=============+=============================================================+
54 | macOS | ``/Developer/NVIDIA/CUDA-X.Y`` |
55 +-------------+-------------------------------------------------------------+
56 | Other Unix | ``/usr/local/cuda-X.Y`` |
57 +-------------+-------------------------------------------------------------+
58 | Windows | ``C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y`` |
59 +-------------+-------------------------------------------------------------+
61 Where ``X.Y`` would be a specific version of the CUDA Toolkit, such as
62 ``/usr/local/cuda-9.0`` or
63 ``C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.0``
67 When multiple CUDA Toolkits are installed in the default location of a
68 system (e.g., both ``/usr/local/cuda-9.0`` and ``/usr/local/cuda-10.0``
69 exist but the ``/usr/local/cuda`` symbolic link does **not** exist), this
70 package is marked as **not** found.
72 There are too many factors involved in making an automatic decision in
73 the presence of multiple CUDA Toolkits being installed. In this
74 situation, users are encouraged to either (1) set ``CUDAToolkit_ROOT`` or
75 (2) ensure that the correct ``nvcc`` executable shows up in ``$PATH`` for
76 :command:`find_program` to find.
82 The ``[<version>]`` argument requests a version with which the package found
83 should be compatible. See :ref:`find_package version format <FIND_PACKAGE_VERSION_FORMAT>`
90 If specified, configuration will error if a suitable CUDA Toolkit is not
94 If specified, the search for a suitable CUDA Toolkit will not produce any
98 If specified, the CUDA Toolkit is considered found only if the exact
99 ``VERSION`` specified is recovered.
104 An :ref:`imported target <Imported targets>` named ``CUDA::toolkit`` is provided.
106 This module defines :prop_tgt:`IMPORTED` targets for each
107 of the following libraries that are part of the CUDAToolkit:
109 - :ref:`CUDA Runtime Library<cuda_toolkit_rt_lib>`
110 - :ref:`CUDA Driver Library<cuda_toolkit_driver_lib>`
111 - :ref:`cuBLAS<cuda_toolkit_cuBLAS>`
112 - :ref:`cuFFT<cuda_toolkit_cuFFT>`
113 - :ref:`cuRAND<cuda_toolkit_cuRAND>`
114 - :ref:`cuSOLVER<cuda_toolkit_cuSOLVER>`
115 - :ref:`cuSPARSE<cuda_toolkit_cuSPARSE>`
116 - :ref:`cuPTI<cuda_toolkit_cupti>`
117 - :ref:`NPP<cuda_toolkit_NPP>`
118 - :ref:`nvBLAS<cuda_toolkit_nvBLAS>`
119 - :ref:`nvGRAPH<cuda_toolkit_nvGRAPH>`
120 - :ref:`nvJPEG<cuda_toolkit_nvJPEG>`
121 - :ref:`nvidia-ML<cuda_toolkit_nvML>`
122 - :ref:`nvRTC<cuda_toolkit_nvRTC>`
123 - :ref:`nvToolsExt<cuda_toolkit_nvToolsExt>`
124 - :ref:`OpenCL<cuda_toolkit_opencl>`
125 - :ref:`cuLIBOS<cuda_toolkit_cuLIBOS>`
127 .. _`cuda_toolkit_rt_lib`:
132 The CUDA Runtime library (cudart) are what most applications will typically
133 need to link against to make any calls such as `cudaMalloc`, and `cudaFree`.
138 - ``CUDA::cudart_static``
140 .. _`cuda_toolkit_driver_lib`:
145 The CUDA Driver library (cuda) are used by applications that use calls
146 such as `cuMemAlloc`, and `cuMemFree`.
150 - ``CUDA::cuda_driver``
152 .. _`cuda_toolkit_cuBLAS`:
157 The `cuBLAS <https://docs.nvidia.com/cuda/cublas/index.html>`_ library.
162 - ``CUDA::cublas_static``
163 - ``CUDA::cublasLt`` starting in CUDA 10.1
164 - ``CUDA::cublasLt_static`` starting in CUDA 10.1
166 .. _`cuda_toolkit_cuFFT`:
171 The `cuFFT <https://docs.nvidia.com/cuda/cufft/index.html>`_ library.
177 - ``CUDA::cufft_static``
178 - ``CUDA::cufft_static_nocallback`` starting in CUDA 9.2, requires CMake 3.23+
179 - ``CUDA::cufftw_static``
184 The `cuRAND <https://docs.nvidia.com/cuda/curand/index.html>`_ library.
189 - ``CUDA::curand_static``
191 .. _`cuda_toolkit_cuSOLVER`:
196 The `cuSOLVER <https://docs.nvidia.com/cuda/cusolver/index.html>`_ library.
201 - ``CUDA::cusolver_static``
203 .. _`cuda_toolkit_cuSPARSE`:
208 The `cuSPARSE <https://docs.nvidia.com/cuda/cusparse/index.html>`_ library.
213 - ``CUDA::cusparse_static``
215 .. _`cuda_toolkit_cupti`:
220 The `NVIDIA CUDA Profiling Tools Interface <https://developer.nvidia.com/CUPTI>`_.
225 - ``CUDA::cupti_static``
227 .. _`cuda_toolkit_NPP`:
232 The `NPP <https://docs.nvidia.com/cuda/npp/index.html>`_ libraries.
239 - ``CUDA::nppc_static``
241 - `nppial`: Arithmetic and logical operation functions in `nppi_arithmetic_and_logical_operations.h`
244 - ``CUDA::nppial_static``
246 - `nppicc`: Color conversion and sampling functions in `nppi_color_conversion.h`
249 - ``CUDA::nppicc_static``
251 - `nppicom`: JPEG compression and decompression functions in `nppi_compression_functions.h`
252 Removed starting in CUDA 11.0, use :ref:`nvJPEG<cuda_toolkit_nvJPEG>` instead.
255 - ``CUDA::nppicom_static``
257 - `nppidei`: Data exchange and initialization functions in `nppi_data_exchange_and_initialization.h`
260 - ``CUDA::nppidei_static``
262 - `nppif`: Filtering and computer vision functions in `nppi_filter_functions.h`
265 - ``CUDA::nppif_static``
267 - `nppig`: Geometry transformation functions found in `nppi_geometry_transforms.h`
270 - ``CUDA::nppig_static``
272 - `nppim`: Morphological operation functions found in `nppi_morphological_operations.h`
275 - ``CUDA::nppim_static``
277 - `nppist`: Statistics and linear transform in `nppi_statistics_functions.h` and `nppi_linear_transforms.h`
280 - ``CUDA::nppist_static``
282 - `nppisu`: Memory support functions in `nppi_support_functions.h`
285 - ``CUDA::nppisu_static``
287 - `nppitc`: Threshold and compare operation functions in `nppi_threshold_and_compare_operations.h`
290 - ``CUDA::nppitc_static``
295 - ``CUDA::npps_static``
297 .. _`cuda_toolkit_nvBLAS`:
302 The `nvBLAS <https://docs.nvidia.com/cuda/nvblas/index.html>`_ libraries.
303 This is a shared library only.
309 .. _`cuda_toolkit_nvGRAPH`:
314 The `nvGRAPH <https://docs.nvidia.com/cuda/nvgraph/index.html>`_ library.
315 Removed starting in CUDA 11.0
320 - ``CUDA::nvgraph_static``
323 .. _`cuda_toolkit_nvJPEG`:
328 The `nvJPEG <https://docs.nvidia.com/cuda/nvjpeg/index.html>`_ library.
329 Introduced in CUDA 10.
334 - ``CUDA::nvjpeg_static``
336 .. _`cuda_toolkit_nvRTC`:
341 The `nvRTC <https://docs.nvidia.com/cuda/nvrtc/index.html>`_ (Runtime Compilation) library.
342 This is a shared library only.
348 .. _`cuda_toolkit_nvml`:
353 The `NVIDIA Management Library <https://developer.nvidia.com/nvidia-management-library-nvml>`_.
354 This is a shared library only.
360 .. _`cuda_toolkit_nvToolsExt`:
365 The `NVIDIA Tools Extension <https://docs.nvidia.com/gameworks/content/gameworkslibrary/nvtx/nvidia_tools_extension_library_nvtx.htm>`_.
366 This is a shared library only.
370 - ``CUDA::nvToolsExt``
372 .. _`cuda_toolkit_opencl`:
377 The `NVIDIA OpenCL Library <https://developer.nvidia.com/opencl>`_.
378 This is a shared library only.
384 .. _`cuda_toolkit_cuLIBOS`:
389 The cuLIBOS library is a backend thread abstraction layer library which is
390 static only. The ``CUDA::cublas_static``, ``CUDA::cusparse_static``,
391 ``CUDA::cufft_static``, ``CUDA::curand_static``, and (when implemented) NPP
392 libraries all automatically have this dependency linked.
398 **Note**: direct usage of this target by consumers should not be necessary.
400 .. _`cuda_toolkit_cuRAND`:
407 ``CUDAToolkit_FOUND``
408 A boolean specifying whether or not the CUDA Toolkit was found.
410 ``CUDAToolkit_VERSION``
411 The exact version of the CUDA Toolkit found (as reported by
412 ``nvcc --version`` or ``version.txt``).
414 ``CUDAToolkit_VERSION_MAJOR``
415 The major version of the CUDA Toolkit.
417 ``CUDAToolkit_VERSION_MINOR``
418 The minor version of the CUDA Toolkit.
420 ``CUDAToolkit_VERSION_PATCH``
421 The patch version of the CUDA Toolkit.
423 ``CUDAToolkit_BIN_DIR``
424 The path to the CUDA Toolkit library directory that contains the CUDA
427 ``CUDAToolkit_INCLUDE_DIRS``
428 The path to the CUDA Toolkit ``include`` folder containing the header files
429 required to compile a project linking against CUDA.
431 ``CUDAToolkit_LIBRARY_DIR``
432 The path to the CUDA Toolkit library directory that contains the CUDA
433 Runtime library ``cudart``.
435 ``CUDAToolkit_LIBRARY_ROOT``
436 .. versionadded:: 3.18
438 The path to the CUDA Toolkit directory containing the nvvm directory and
441 ``CUDAToolkit_TARGET_DIR``
442 The path to the CUDA Toolkit directory including the target architecture
443 when cross-compiling. When not cross-compiling this will be equivalent to
444 the parent directory of ``CUDAToolkit_BIN_DIR``.
446 ``CUDAToolkit_NVCC_EXECUTABLE``
447 The path to the NVIDIA CUDA compiler ``nvcc``. Note that this path may
448 **not** be the same as
449 :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>`. ``nvcc`` must be
450 found to determine the CUDA Toolkit version as well as determining other
451 features of the Toolkit. This variable is set for the convenience of
452 modules that depend on this one.
455 #]=======================================================================]
457 # NOTE: much of this was simply extracted from FindCUDA.cmake.
459 # James Bigler, NVIDIA Corp (nvidia.com - jbigler)
460 # Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html
462 # Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
464 # Copyright (c) 2007-2009
465 # Scientific Computing and Imaging Institute, University of Utah
467 # This code is licensed under the MIT License. See the FindCUDA.cmake script
468 # for the text of the license.
472 # License for the specific language governing rights and limitations under
473 # Permission is hereby granted, free of charge, to any person obtaining a
474 # copy of this software and associated documentation files (the "Software"),
475 # to deal in the Software without restriction, including without limitation
476 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
477 # and/or sell copies of the Software, and to permit persons to whom the
478 # Software is furnished to do so, subject to the following conditions:
480 # The above copyright notice and this permission notice shall be included
481 # in all copies or substantial portions of the Software.
483 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
484 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
485 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
486 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
487 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
488 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
489 # DEALINGS IN THE SOFTWARE.
491 ###############################################################################
493 # The toolkit is located during compiler detection for CUDA and stored in CMakeCUDACompiler.cmake as
494 # CMAKE_CUDA_COMPILER_TOOLKIT_ROOT and CMAKE_CUDA_COMPILER_LIBRARY_ROOT.
495 # We compute the rest based on those here to avoid re-searching and to avoid finding a possibly
496 # different installation.
497 if(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT)
498 set(CUDAToolkit_ROOT_DIR "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}")
499 set(CUDAToolkit_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_LIBRARY_ROOT}")
500 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_ROOT_DIR}/bin")
501 set(CUDAToolkit_NVCC_EXECUTABLE "${CUDAToolkit_BIN_DIR}/nvcc${CMAKE_EXECUTABLE_SUFFIX}")
502 set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_TOOLKIT_VERSION}")
504 if(CUDAToolkit_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
505 set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
506 set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
507 set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
510 function(_CUDAToolkit_find_root_dir )
511 cmake_parse_arguments(arg "" "" "SEARCH_PATHS;FIND_FLAGS" ${ARGN})
513 if(NOT CUDAToolkit_BIN_DIR)
514 if(NOT CUDAToolkit_SENTINEL_FILE)
515 find_program(CUDAToolkit_NVCC_EXECUTABLE
517 PATHS ${arg_SEARCH_PATHS}
522 if(NOT CUDAToolkit_NVCC_EXECUTABLE)
523 find_file(CUDAToolkit_SENTINEL_FILE
525 PATHS ${arg_SEARCH_PATHS}
530 if(EXISTS "${CUDAToolkit_NVCC_EXECUTABLE}")
531 # If NVCC exists then invoke it to find the toolkit location.
532 # This allows us to support wrapper scripts (e.g. ccache or colornvcc), CUDA Toolkit,
533 # NVIDIA HPC SDK, and distro's splayed layouts
534 execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda"
535 OUTPUT_VARIABLE _CUDA_NVCC_OUT ERROR_VARIABLE _CUDA_NVCC_OUT)
536 if(_CUDA_NVCC_OUT MATCHES "\\#\\$ TOP=([^\r\n]*)")
537 get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_MATCH_1}/bin" ABSOLUTE)
539 get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
541 unset(_CUDA_NVCC_OUT)
543 mark_as_advanced(CUDAToolkit_BIN_DIR)
544 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
547 if(CUDAToolkit_SENTINEL_FILE)
548 get_filename_component(CUDAToolkit_BIN_DIR ${CUDAToolkit_SENTINEL_FILE} DIRECTORY ABSOLUTE)
549 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}/bin")
551 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
552 mark_as_advanced(CUDAToolkit_BIN_DIR)
556 if(CUDAToolkit_BIN_DIR)
557 get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE)
558 set(CUDAToolkit_ROOT_DIR "${CUDAToolkit_ROOT_DIR}" PARENT_SCOPE)
563 function(_CUDAToolkit_find_version_file result_variable)
564 # We first check for a non-scattered installation to prefer it over a scattered installation.
565 if(CUDAToolkit_ROOT AND EXISTS "${CUDAToolkit_ROOT}/version.txt")
566 set(${result_variable} "${CUDAToolkit_ROOT}/version.txt" PARENT_SCOPE)
567 elseif(CUDAToolkit_ROOT_DIR AND EXISTS "${CUDAToolkit_ROOT_DIR}/version.txt")
568 set(${result_variable} "${CUDAToolkit_ROOT_DIR}/version.txt" PARENT_SCOPE)
569 elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt")
570 set(${result_variable} "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt" PARENT_SCOPE)
571 elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt")
572 set(${result_variable} "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt" PARENT_SCOPE)
576 # For NVCC we can easily deduce the SDK binary directory from the compiler path.
577 if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
578 get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_CUDA_COMPILER}" DIRECTORY)
579 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "")
580 # Try language provided path first.
581 _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_BIN_DIR}" FIND_FLAGS NO_DEFAULT_PATH)
582 mark_as_advanced(CUDAToolkit_BIN_DIR)
585 # Try user provided path
586 if(NOT CUDAToolkit_ROOT_DIR AND CUDAToolkit_ROOT)
587 _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_ROOT}" FIND_FLAGS PATH_SUFFIXES bin NO_DEFAULT_PATH)
589 if(NOT CUDAToolkit_ROOT_DIR)
590 _CUDAToolkit_find_root_dir(FIND_FLAGS PATHS ENV CUDA_PATH PATH_SUFFIXES bin)
593 # If the user specified CUDAToolkit_ROOT but the toolkit could not be found, this is an error.
594 if(NOT CUDAToolkit_ROOT_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
595 # Declare error messages now, print later depending on find_package args.
596 set(fail_base "Could not find nvcc executable in path specified by")
597 set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
598 set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}")
600 if(CUDAToolkit_FIND_REQUIRED)
601 if(DEFINED CUDAToolkit_ROOT)
602 message(FATAL_ERROR ${cuda_root_fail})
603 elseif(DEFINED ENV{CUDAToolkit_ROOT})
604 message(FATAL_ERROR ${env_cuda_root_fail})
607 if(NOT CUDAToolkit_FIND_QUIETLY)
608 if(DEFINED CUDAToolkit_ROOT)
609 message(STATUS ${cuda_root_fail})
610 elseif(DEFINED ENV{CUDAToolkit_ROOT})
611 message(STATUS ${env_cuda_root_fail})
614 set(CUDAToolkit_FOUND FALSE)
616 unset(cuda_root_fail)
617 unset(env_cuda_root_fail)
622 # CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults.
624 # - Linux: /usr/local/cuda-X.Y
625 # - macOS: /Developer/NVIDIA/CUDA-X.Y
626 # - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y
628 # We will also search the default symlink location /usr/local/cuda first since
629 # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
630 # directory is the desired location.
631 if(NOT CUDAToolkit_ROOT_DIR)
634 set(platform_base "/usr/local/cuda-")
636 set(platform_base "/Developer/NVIDIA/CUDA-")
639 set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v")
642 # Build out a descending list of possible cuda installations, e.g.
643 file(GLOB possible_paths "${platform_base}*")
644 # Iterate the glob results and create a descending list.
646 foreach(p ${possible_paths})
647 # Extract version number from end of string
648 string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p})
649 if(IS_DIRECTORY ${p} AND p_version)
650 list(APPEND versions ${p_version})
654 # Sort numerically in descending order, so we try the newest versions first.
655 list(SORT versions COMPARE NATURAL ORDER DESCENDING)
657 # With a descending list of versions, populate possible paths to search.
659 foreach(v ${versions})
660 list(APPEND search_paths "${platform_base}${v}")
663 # Force the global default /usr/local/cuda to the front on Unix.
665 list(INSERT search_paths 0 "/usr/local/cuda")
668 # Now search for the toolkit again using the platform default search paths.
669 _CUDAToolkit_find_root_dir(SEARCH_PATHS "${search_paths}" FIND_FLAGS PATH_SUFFIXES bin)
671 # We are done with these variables now, cleanup for caller.
673 unset(possible_paths)
677 if(NOT CUDAToolkit_ROOT_DIR)
678 if(CUDAToolkit_FIND_REQUIRED)
679 message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.")
680 elseif(NOT CUDAToolkit_FIND_QUIETLY)
681 message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.")
684 set(CUDAToolkit_FOUND FALSE)
689 _CUDAToolkit_find_version_file( _CUDAToolkit_version_file )
690 if(_CUDAToolkit_version_file)
691 # CUDAToolkit_LIBRARY_ROOT contains the device library and version file.
692 get_filename_component(CUDAToolkit_LIBRARY_ROOT "${_CUDAToolkit_version_file}" DIRECTORY ABSOLUTE)
694 unset(_CUDAToolkit_version_file)
696 if(CUDAToolkit_NVCC_EXECUTABLE AND
697 CMAKE_CUDA_COMPILER_VERSION AND
698 CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER)
699 # Need to set these based off the already computed CMAKE_CUDA_COMPILER_VERSION value
700 # This if statement will always match, but is used to provide variables for MATCH 1,2,3...
701 if(CMAKE_CUDA_COMPILER_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
702 set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
703 set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
704 set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
705 set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_VERSION}")
707 elseif(CUDAToolkit_NVCC_EXECUTABLE)
708 # Compute the version by invoking nvcc
709 execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
710 if(NVCC_OUT MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=])
711 set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
712 set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
713 set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
714 set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
718 _CUDAToolkit_find_version_file(version_file)
720 file(READ "${version_file}" VERSION_INFO)
721 if(VERSION_INFO MATCHES [=[CUDA Version ([0-9]+)\.([0-9]+)\.([0-9]+)]=])
722 set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
723 set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
724 set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
725 set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
731 # Find target directory when crosscompiling.
732 if(CMAKE_CROSSCOMPILING)
733 if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a")
735 set(CUDAToolkit_TARGET_NAME "armv7-linux-androideabi")
736 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
737 set(CUDAToolkit_TARGET_NAME "armv7-linux-gnueabihf")
738 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
739 if(ANDROID_ARCH_NAME STREQUAL "arm64")
740 set(CUDAToolkit_TARGET_NAME "aarch64-linux-androideabi")
741 elseif (CMAKE_SYSTEM_NAME STREQUAL "QNX")
742 set(CUDAToolkit_TARGET_NAME "aarch64-qnx")
744 set(CUDAToolkit_TARGET_NAME "aarch64-linux")
745 endif(ANDROID_ARCH_NAME STREQUAL "arm64")
746 elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
747 set(CUDAToolkit_TARGET_NAME "x86_64-linux")
750 if(EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
751 set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
752 # add known CUDA target root path to the set of directories we search for programs, libraries and headers
753 list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}")
755 # Mark that we need to pop the root search path changes after we have
756 # found all cuda libraries so that searches for our cross-compilation
757 # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or
759 set(_CUDAToolkit_Pop_ROOT_PATH True)
763 # If not already set we can simply use the toolkit root or it's a scattered installation.
764 if(NOT CUDAToolkit_TARGET_DIR)
765 # Not cross compiling
766 set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}")
767 # Now that we have the real ROOT_DIR, find components inside it.
768 list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR})
770 # Mark that we need to pop the prefix path changes after we have
771 # found the cudart library.
772 set(_CUDAToolkit_Pop_Prefix True)
775 # CUDAToolkit_TARGET_DIR always points to the directory containing the include directory.
776 # On a scattered installation /usr, on a non-scattered something like /usr/local/cuda or /usr/local/cuda-10.2/targets/aarch64-linux.
777 if(EXISTS "${CUDAToolkit_TARGET_DIR}/include/cuda_runtime.h")
778 set(CUDAToolkit_INCLUDE_DIR "${CUDAToolkit_TARGET_DIR}/include")
779 elseif(NOT CUDAToolkit_FIND_QUIETLY)
780 message(STATUS "Unable to find cuda_runtime.h in \"${CUDAToolkit_TARGET_DIR}/include\" for CUDAToolkit_INCLUDE_DIR.")
783 # The NVHPC layout moves math library headers and libraries to a sibling directory.
784 # Create a separate variable so this directory can be selectively added to math targets.
785 if(NOT EXISTS "${CUDAToolkit_INCLUDE_DIR}/cublas_v2.h")
786 set(CUDAToolkit_MATH_INCLUDE_DIR "${CUDAToolkit_TARGET_DIR}/../../math_libs/include")
787 cmake_path(NORMAL_PATH CUDAToolkit_MATH_INCLUDE_DIR)
788 if(NOT EXISTS "${CUDAToolkit_MATH_INCLUDE_DIR}/cublas_v2.h")
789 if(NOT CUDAToolkit_FIND_QUIETLY)
790 message(STATUS "Unable to find cublas_v2.h in either \"${CUDAToolkit_INCLUDE_DIR}\" or \"${CUDAToolkit_MATH_INCLUDE_DIR}\"")
792 unset(CUDAToolkit_MATH_INCLUDE_DIR)
796 # Find the CUDA Runtime Library libcudart
797 find_library(CUDA_CUDART
799 PATH_SUFFIXES lib64 lib/x64
801 find_library(CUDA_CUDART
803 PATH_SUFFIXES lib64/stubs lib/x64/stubs
806 if(NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY)
807 message(STATUS "Unable to find cudart library.")
810 if(_CUDAToolkit_Pop_Prefix)
811 list(REMOVE_AT CMAKE_PREFIX_PATH -1)
812 unset(_CUDAToolkit_Pop_Prefix)
815 #-----------------------------------------------------------------------------
816 # Perform version comparison and validate all required variables are set.
817 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
818 find_package_handle_standard_args(CUDAToolkit
820 CUDAToolkit_INCLUDE_DIR
827 unset(CUDAToolkit_ROOT_DIR)
828 mark_as_advanced(CUDA_CUDART
829 CUDAToolkit_INCLUDE_DIR
830 CUDAToolkit_NVCC_EXECUTABLE
831 CUDAToolkit_SENTINEL_FILE
834 #-----------------------------------------------------------------------------
835 # Construct result variables
836 if(CUDAToolkit_FOUND)
837 set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR})
838 get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE)
841 #-----------------------------------------------------------------------------
842 # Construct import targets
843 if(CUDAToolkit_FOUND)
845 function(_CUDAToolkit_find_and_add_import_lib lib_name)
846 cmake_parse_arguments(arg "" "" "ALT;DEPS;EXTRA_PATH_SUFFIXES;EXTRA_INCLUDE_DIRS" ${ARGN})
848 set(search_names ${lib_name} ${arg_ALT})
850 find_library(CUDA_${lib_name}_LIBRARY
851 NAMES ${search_names}
852 HINTS ${CUDAToolkit_LIBRARY_DIR}
854 PATH_SUFFIXES nvidia/current lib64 lib/x64 lib
855 ${arg_EXTRA_PATH_SUFFIXES}
857 # Don't try any stub directories until we have exhausted all other
859 find_library(CUDA_${lib_name}_LIBRARY
860 NAMES ${search_names}
861 HINTS ${CUDAToolkit_LIBRARY_DIR}
863 PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
864 # Support NVHPC splayed math library layout
865 ../../math_libs/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64
866 ../../math_libs/lib64
869 mark_as_advanced(CUDA_${lib_name}_LIBRARY)
871 if (NOT TARGET CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY)
872 add_library(CUDA::${lib_name} UNKNOWN IMPORTED)
873 target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
874 if(DEFINED CUDAToolkit_MATH_INCLUDE_DIR)
875 string(FIND ${CUDA_${lib_name}_LIBRARY} "math_libs" math_libs)
876 if(NOT ${math_libs} EQUAL -1)
877 target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_MATH_INCLUDE_DIR}")
880 set_property(TARGET CUDA::${lib_name} PROPERTY IMPORTED_LOCATION "${CUDA_${lib_name}_LIBRARY}")
881 foreach(dep ${arg_DEPS})
882 if(TARGET CUDA::${dep})
883 target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dep})
886 if(arg_EXTRA_INCLUDE_DIRS)
887 target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${arg_EXTRA_INCLUDE_DIRS}")
892 if(NOT TARGET CUDA::toolkit)
893 add_library(CUDA::toolkit IMPORTED INTERFACE)
894 target_include_directories(CUDA::toolkit SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
895 target_link_directories(CUDA::toolkit INTERFACE "${CUDAToolkit_LIBRARY_DIR}")
898 _CUDAToolkit_find_and_add_import_lib(cuda_driver ALT cuda)
900 _CUDAToolkit_find_and_add_import_lib(cudart)
901 _CUDAToolkit_find_and_add_import_lib(cudart_static)
903 # setup dependencies that are required for cudart_static when building
904 # on linux. These are generally only required when using the CUDA toolkit
905 # when CUDA language is disabled
906 if(NOT TARGET CUDA::cudart_static_deps
907 AND TARGET CUDA::cudart_static)
909 add_library(CUDA::cudart_static_deps IMPORTED INTERFACE)
910 target_link_libraries(CUDA::cudart_static INTERFACE CUDA::cudart_static_deps)
912 if(UNIX AND (CMAKE_C_COMPILER OR CMAKE_CXX_COMPILER))
913 find_package(Threads REQUIRED)
914 target_link_libraries(CUDA::cudart_static_deps INTERFACE Threads::Threads ${CMAKE_DL_LIBS})
917 if(UNIX AND NOT APPLE AND NOT (CMAKE_SYSTEM_NAME STREQUAL "QNX"))
918 # On Linux, you must link against librt when using the static cuda runtime.
919 find_library(CUDAToolkit_rt_LIBRARY rt)
920 mark_as_advanced(CUDAToolkit_rt_LIBRARY)
921 if(NOT CUDAToolkit_rt_LIBRARY)
922 message(WARNING "Could not find librt library, needed by CUDA::cudart_static")
924 target_link_libraries(CUDA::cudart_static_deps INTERFACE ${CUDAToolkit_rt_LIBRARY})
929 _CUDAToolkit_find_and_add_import_lib(culibos) # it's a static library
930 foreach (cuda_lib cublasLt cufft curand cusparse nppc nvjpeg)
931 _CUDAToolkit_find_and_add_import_lib(${cuda_lib})
932 _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS culibos)
935 if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.0.0)
936 # cublas depends on cublasLt
937 # https://docs.nvidia.com/cuda/archive/11.0/cublas/index.html#static-library
938 _CUDAToolkit_find_and_add_import_lib(cublas DEPS cublasLt culibos)
939 _CUDAToolkit_find_and_add_import_lib(cublas_static DEPS cublasLt_static culibos)
941 _CUDAToolkit_find_and_add_import_lib(cublas DEPS culibos)
942 _CUDAToolkit_find_and_add_import_lib(cublas_static DEPS culibos)
945 # cuFFTW depends on cuFFT
946 _CUDAToolkit_find_and_add_import_lib(cufftw DEPS cufft)
947 _CUDAToolkit_find_and_add_import_lib(cufftw_static DEPS cufft_static)
948 if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 9.2)
949 _CUDAToolkit_find_and_add_import_lib(cufft_static_nocallback DEPS culibos)
952 # cuSOLVER depends on cuBLAS, and cuSPARSE
953 set(cusolver_deps cublas cusparse)
954 set(cusolver_static_deps cublas_static cusparse_static culibos)
955 if(CUDAToolkit_VERSION VERSION_GREATER 11.2.1)
956 # cusolver depends on libcusolver_metis and cublasLt
957 # https://docs.nvidia.com/cuda/archive/11.2.2/cusolver/index.html#link-dependency
958 list(APPEND cusolver_deps cublasLt)
959 _CUDAToolkit_find_and_add_import_lib(cusolver_metis_static ALT metis_static) # implementation detail static lib
960 list(APPEND cusolver_static_deps cusolver_metis_static cublasLt_static)
962 if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.1.2)
963 # cusolver depends on liblapack_static.a starting with CUDA 10.1 update 2,
964 # https://docs.nvidia.com/cuda/archive/11.5.0/cusolver/index.html#static-link-lapack
965 _CUDAToolkit_find_and_add_import_lib(cusolver_lapack_static ALT lapack_static) # implementation detail static lib
966 list(APPEND cusolver_static_deps cusolver_lapack_static)
968 _CUDAToolkit_find_and_add_import_lib(cusolver DEPS ${cusolver_deps})
969 _CUDAToolkit_find_and_add_import_lib(cusolver_static DEPS ${cusolver_static_deps})
971 unset(cusolver_static_deps)
973 # nvGRAPH depends on cuRAND, and cuSOLVER.
974 _CUDAToolkit_find_and_add_import_lib(nvgraph DEPS curand cusolver)
975 _CUDAToolkit_find_and_add_import_lib(nvgraph_static DEPS curand_static cusolver_static)
977 # Process the majority of the NPP libraries.
978 foreach (cuda_lib nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu)
979 _CUDAToolkit_find_and_add_import_lib(${cuda_lib} DEPS nppc)
980 _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS nppc_static)
983 find_path(CUDAToolkit_CUPTI_INCLUDE_DIR cupti.h PATHS
984 "${CUDAToolkit_ROOT_DIR}/extras/CUPTI/include"
985 "${CUDAToolkit_INCLUDE_DIR}/../extras/CUPTI/include"
986 "${CUDAToolkit_INCLUDE_DIR}"
989 if(CUDAToolkit_CUPTI_INCLUDE_DIR)
990 _CUDAToolkit_find_and_add_import_lib(cupti
991 EXTRA_PATH_SUFFIXES ../extras/CUPTI/lib64/
993 EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}")
994 _CUDAToolkit_find_and_add_import_lib(cupti_static
995 EXTRA_PATH_SUFFIXES ../extras/CUPTI/lib64/
997 EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}")
1000 _CUDAToolkit_find_and_add_import_lib(nvrtc DEPS cuda_driver)
1002 _CUDAToolkit_find_and_add_import_lib(nvml ALT nvidia-ml nvml)
1005 # nvtools can be installed outside the CUDA toolkit directory
1006 # so prefer the NVTOOLSEXT_PATH windows only environment variable
1007 # In addition on windows the most common name is nvToolsExt64_1
1008 find_library(CUDA_nvToolsExt_LIBRARY
1009 NAMES nvToolsExt64_1 nvToolsExt64 nvToolsExt
1010 PATHS ENV NVTOOLSEXT_PATH
1012 PATH_SUFFIXES lib/x64 lib
1015 _CUDAToolkit_find_and_add_import_lib(nvToolsExt ALT nvToolsExt64)
1017 _CUDAToolkit_find_and_add_import_lib(OpenCL)
1020 if(_CUDAToolkit_Pop_ROOT_PATH)
1021 list(REMOVE_AT CMAKE_FIND_ROOT_PATH 0)
1022 unset(_CUDAToolkit_Pop_ROOT_PATH)