Merge topic 'cxx-checks-tolerate-unused-arguments'
[kiteware-cmake.git] / Modules / FindCUDAToolkit.cmake
blobbc17f19f103878825af51a2797636394a716550c
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:
5 FindCUDAToolkit
6 ---------------
8 .. versionadded:: 3.17
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
15   QNX support.
17 Search Behavior
18 ^^^^^^^^^^^^^^^
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
29    precedence.
31    The directory specified here must be such that the executable ``nvcc`` or
32    the appropriate ``version.txt`` or ``version.json`` file can be found
33    underneath the specified directory.
35 3. If the CUDA_PATH environment variable is defined, it will be searched
36    for ``nvcc``.
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
49    searched are:
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``
65    .. note::
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.
78 Arguments
79 ^^^^^^^^^
81 ``[<version>]``
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>`
84     for more details.
86 Options
87 ^^^^^^^
89 ``REQUIRED``
90     If specified, configuration will error if a suitable CUDA Toolkit is not
91     found.
93 ``QUIET``
94     If specified, the search for a suitable CUDA Toolkit will not produce any
95     messages.
97 ``EXACT``
98     If specified, the CUDA Toolkit is considered found only if the exact
99     ``VERSION`` specified is recovered.
101 Imported targets
102 ^^^^^^^^^^^^^^^^
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:`cuDLA<cuda_toolkit_cuDLA>`
113 - :ref:`cuFile<cuda_toolkit_cuFile>`
114 - :ref:`cuFFT<cuda_toolkit_cuFFT>`
115 - :ref:`cuRAND<cuda_toolkit_cuRAND>`
116 - :ref:`cuSOLVER<cuda_toolkit_cuSOLVER>`
117 - :ref:`cuSPARSE<cuda_toolkit_cuSPARSE>`
118 - :ref:`cuPTI<cuda_toolkit_cupti>`
119 - :ref:`NPP<cuda_toolkit_NPP>`
120 - :ref:`nvBLAS<cuda_toolkit_nvBLAS>`
121 - :ref:`nvGRAPH<cuda_toolkit_nvGRAPH>`
122 - :ref:`nvJPEG<cuda_toolkit_nvJPEG>`
123 - :ref:`nvidia-ML<cuda_toolkit_nvML>`
124 - :ref:`nvPTX Compiler<cuda_toolkit_nvptx>`
125 - :ref:`nvRTC<cuda_toolkit_nvRTC>`
126 - :ref:`nvJitLink<cuda_toolkit_nvJitLink>`
127 - :ref:`nvFatBin<cuda_toolkit_nvfatbin>`
128 - :ref:`nvToolsExt<cuda_toolkit_nvToolsExt>`
129 - :ref:`nvtx3<cuda_toolkit_nvtx3>`
130 - :ref:`OpenCL<cuda_toolkit_opencl>`
131 - :ref:`cuLIBOS<cuda_toolkit_cuLIBOS>`
133 .. _`cuda_toolkit_rt_lib`:
135 CUDA Runtime Library
136 """"""""""""""""""""
138 The CUDA Runtime library (cudart) are what most applications will typically
139 need to link against to make any calls such as `cudaMalloc`, and `cudaFree`.
141 Targets Created:
143 - ``CUDA::cudart``
144 - ``CUDA::cudart_static``
146 .. _`cuda_toolkit_driver_lib`:
148 CUDA Driver Library
149 """"""""""""""""""""
151 The CUDA Driver library (cuda) are used by applications that use calls
152 such as `cuMemAlloc`, and `cuMemFree`.
154 Targets Created:
156 - ``CUDA::cuda_driver``
158 .. _`cuda_toolkit_cuBLAS`:
160 cuBLAS
161 """"""
163 The `cuBLAS <https://docs.nvidia.com/cuda/cublas>`_ library.
165 Targets Created:
167 - ``CUDA::cublas``
168 - ``CUDA::cublas_static``
169 - ``CUDA::cublasLt`` starting in CUDA 10.1
170 - ``CUDA::cublasLt_static`` starting in CUDA 10.1
172 .. _`cuda_toolkit_cuDLA`:
174 cuDLA
175 """"""
177 .. versionadded:: 3.27
179 The NVIDIA Tegra Deep Learning Accelerator `cuDLA <https://docs.nvidia.com/cuda/cublas>`_ library.
181 Targets Created:
183 - ``CUDA::cudla`` starting in CUDA 11.6
185 .. _`cuda_toolkit_cuFile`:
187 cuFile
188 """"""
190 .. versionadded:: 3.25
192 The NVIDIA GPUDirect Storage `cuFile <https://docs.nvidia.com/gpudirect-storage/api-reference-guide>`_ library.
194 Targets Created:
196 - ``CUDA::cuFile`` starting in CUDA 11.4
197 - ``CUDA::cuFile_static`` starting in CUDA 11.4
198 - ``CUDA::cuFile_rdma`` starting in CUDA 11.4
199 - ``CUDA::cuFile_rdma_static`` starting in CUDA 11.4
201 .. _`cuda_toolkit_cuFFT`:
203 cuFFT
204 """""
206 The `cuFFT <https://docs.nvidia.com/cuda/cufft>`_ library.
208 Targets Created:
210 - ``CUDA::cufft``
211 - ``CUDA::cufftw``
212 - ``CUDA::cufft_static``
213 - ``CUDA::cufft_static_nocallback`` starting in CUDA 9.2, requires CMake 3.23+
214 - ``CUDA::cufftw_static``
216 cuRAND
217 """"""
219 The `cuRAND <https://docs.nvidia.com/cuda/curand>`_ library.
221 Targets Created:
223 - ``CUDA::curand``
224 - ``CUDA::curand_static``
226 .. _`cuda_toolkit_cuSOLVER`:
228 cuSOLVER
229 """"""""
231 The `cuSOLVER <https://docs.nvidia.com/cuda/cusolver>`_ library.
233 Targets Created:
235 - ``CUDA::cusolver``
236 - ``CUDA::cusolver_static``
238 .. _`cuda_toolkit_cuSPARSE`:
240 cuSPARSE
241 """"""""
243 The `cuSPARSE <https://docs.nvidia.com/cuda/cusparse>`_ library.
245 Targets Created:
247 - ``CUDA::cusparse``
248 - ``CUDA::cusparse_static``
250 .. _`cuda_toolkit_cupti`:
252 cupti
253 """""
255 The `NVIDIA CUDA Profiling Tools Interface <https://developer.nvidia.com/cupti>`_.
257 Targets Created:
259 - ``CUDA::cupti``
260 - ``CUDA::cupti_static``
262 .. versionadded:: 3.27
264   - ``CUDA::nvperf_host``         starting in CUDA 10.2
265   - ``CUDA::nvperf_host_static``  starting in CUDA 10.2
266   - ``CUDA::nvperf_target``       starting in CUDA 10.2
267   - ``CUDA::pcsamplingutil``      starting in CUDA 11.3
269 .. _`cuda_toolkit_NPP`:
274 The `NPP <https://docs.nvidia.com/cuda/npp>`_ libraries.
276 Targets Created:
278 - `nppc`:
280   - ``CUDA::nppc``
281   - ``CUDA::nppc_static``
283 - `nppial`: Arithmetic and logical operation functions in `nppi_arithmetic_and_logical_operations.h`
285   - ``CUDA::nppial``
286   - ``CUDA::nppial_static``
288 - `nppicc`: Color conversion and sampling functions in `nppi_color_conversion.h`
290   - ``CUDA::nppicc``
291   - ``CUDA::nppicc_static``
293 - `nppicom`: JPEG compression and decompression functions in `nppi_compression_functions.h`
294   Removed starting in CUDA 11.0, use :ref:`nvJPEG<cuda_toolkit_nvJPEG>` instead.
296   - ``CUDA::nppicom``
297   - ``CUDA::nppicom_static``
299 - `nppidei`: Data exchange and initialization functions in `nppi_data_exchange_and_initialization.h`
301   - ``CUDA::nppidei``
302   - ``CUDA::nppidei_static``
304 - `nppif`: Filtering and computer vision functions in `nppi_filter_functions.h`
306   - ``CUDA::nppif``
307   - ``CUDA::nppif_static``
309 - `nppig`: Geometry transformation functions found in `nppi_geometry_transforms.h`
311   - ``CUDA::nppig``
312   - ``CUDA::nppig_static``
314 - `nppim`: Morphological operation functions found in `nppi_morphological_operations.h`
316   - ``CUDA::nppim``
317   - ``CUDA::nppim_static``
319 - `nppist`: Statistics and linear transform in `nppi_statistics_functions.h` and `nppi_linear_transforms.h`
321   - ``CUDA::nppist``
322   - ``CUDA::nppist_static``
324 - `nppisu`: Memory support functions in `nppi_support_functions.h`
326   - ``CUDA::nppisu``
327   - ``CUDA::nppisu_static``
329 - `nppitc`: Threshold and compare operation functions in `nppi_threshold_and_compare_operations.h`
331   - ``CUDA::nppitc``
332   - ``CUDA::nppitc_static``
334 - `npps`:
336   - ``CUDA::npps``
337   - ``CUDA::npps_static``
339 .. _`cuda_toolkit_nvBLAS`:
341 nvBLAS
342 """"""
344 The `nvBLAS <https://docs.nvidia.com/cuda/nvblas>`_ libraries.
345 This is a shared library only.
347 Targets Created:
349 - ``CUDA::nvblas``
351 .. _`cuda_toolkit_nvGRAPH`:
353 nvGRAPH
354 """""""
356 The `nvGRAPH <https://web.archive.org/web/20201111171403/https://docs.nvidia.com/cuda/nvgraph/index.html>`_ library.
357 Removed starting in CUDA 11.0
359 Targets Created:
361 - ``CUDA::nvgraph``
362 - ``CUDA::nvgraph_static``
365 .. _`cuda_toolkit_nvJPEG`:
367 nvJPEG
368 """"""
370 The `nvJPEG <https://docs.nvidia.com/cuda/nvjpeg>`_ library.
371 Introduced in CUDA 10.
373 Targets Created:
375 - ``CUDA::nvjpeg``
376 - ``CUDA::nvjpeg_static``
378 .. _`cuda_toolkit_nvPTX`:
380 nvPTX Compiler
381 """"""""""""""
383 .. versionadded:: 3.25
385 The `nvPTX <https://docs.nvidia.com/cuda/ptx-compiler-api>`_ (PTX Compilation) library.
386 The PTX Compiler APIs are a set of APIs which can be used to compile a PTX program into GPU assembly code.
387 Introduced in CUDA 11.1
388 This is a static library only.
390 Targets Created:
392 - ``CUDA::nvptxcompiler_static`` starting in CUDA 11.1
394 .. _`cuda_toolkit_nvRTC`:
396 nvRTC
397 """""
399 The `nvRTC <https://docs.nvidia.com/cuda/nvrtc>`_ (Runtime Compilation) library.
401 Targets Created:
403 - ``CUDA::nvrtc``
405 .. versionadded:: 3.26
407   - ``CUDA::nvrtc_builtins``
408   - ``CUDA::nvrtc_static`` starting in CUDA 11.5
409   - ``CUDA::nvrtc_builtins_static`` starting in CUDA 11.5
411 .. _`cuda_toolkit_nvjitlink`:
413 nvJitLink
414 """""""""
416 The `nvJItLink <https://docs.nvidia.com/cuda/>`_ (Runtime LTO Linking) library.
418 Targets Created:
420 - ``CUDA::nvJitLink`` starting in CUDA 12.0
421 - ``CUDA::nvJitLink_static``  starting in CUDA 12.0
423 .. _`cuda_toolkit_nvfatbin`:
425 nvFatBin
426 """""""""
428 .. versionadded:: 3.30
430 The `nvFatBin <https://docs.nvidia.com/cuda/>`_ (Runtime fatbin creation) library.
432 Targets Created:
434 - ``CUDA::nvfatbin`` starting in CUDA 12.4
435 - ``CUDA::nvfatbin_static``  starting in CUDA 12.4
437 .. _`cuda_toolkit_nvml`:
439 nvidia-ML
440 """""""""
442 The `NVIDIA Management Library <https://developer.nvidia.com/nvidia-management-library-nvml>`_.
443 This is a shared library only.
445 Targets Created:
447 - ``CUDA::nvml``
449 .. _`cuda_toolkit_nvToolsExt`:
451 nvToolsExt
452 """"""""""
454 .. deprecated:: 3.25 With CUDA 10.0+, use :ref:`nvtx3 <cuda_toolkit_nvtx3>`.
456 The `NVIDIA Tools Extension <https://docs.nvidia.com/nvtx/>`_.
457 This is a shared library only.
459 Targets Created:
461 - ``CUDA::nvToolsExt``
463 .. _`cuda_toolkit_nvtx3`:
465 nvtx3
466 """""
468 .. versionadded:: 3.25
470 The header-only `NVIDIA Tools Extension Library <https://nvidia.github.io/NVTX/doxygen>`_.
471 Introduced in CUDA 10.0.
473 Targets created:
475 - ``CUDA::nvtx3``
477 .. _`cuda_toolkit_opencl`:
479 OpenCL
480 """"""
482 The `NVIDIA OpenCL Library <https://developer.nvidia.com/opencl>`_.
483 This is a shared library only.
485 Targets Created:
487 - ``CUDA::OpenCL``
489 .. _`cuda_toolkit_cuLIBOS`:
491 cuLIBOS
492 """""""
494 The cuLIBOS library is a backend thread abstraction layer library which is
495 static only.  The ``CUDA::cublas_static``, ``CUDA::cusparse_static``,
496 ``CUDA::cufft_static``, ``CUDA::curand_static``, and (when implemented) NPP
497 libraries all automatically have this dependency linked.
499 Target Created:
501 - ``CUDA::culibos``
503 **Note**: direct usage of this target by consumers should not be necessary.
505 .. _`cuda_toolkit_cuRAND`:
509 Result variables
510 ^^^^^^^^^^^^^^^^
512 ``CUDAToolkit_FOUND``
513     A boolean specifying whether or not the CUDA Toolkit was found.
515 ``CUDAToolkit_VERSION``
516     The exact version of the CUDA Toolkit found (as reported by
517     ``nvcc --version``, ``version.txt``, or ``version.json``).
519 ``CUDAToolkit_VERSION_MAJOR``
520     The major version of the CUDA Toolkit.
522 ``CUDAToolkit_VERSION_MINOR``
523     The minor version of the CUDA Toolkit.
525 ``CUDAToolkit_VERSION_PATCH``
526     The patch version of the CUDA Toolkit.
528 ``CUDAToolkit_BIN_DIR``
529     The path to the CUDA Toolkit library directory that contains the CUDA
530     executable ``nvcc``.
532 ``CUDAToolkit_INCLUDE_DIRS``
533     List of paths to all the CUDA Toolkit folders containing header files
534     required to compile a project linking against CUDA.
536 ``CUDAToolkit_LIBRARY_DIR``
537     The path to the CUDA Toolkit library directory that contains the CUDA
538     Runtime library ``cudart``.
540 ``CUDAToolkit_LIBRARY_ROOT``
541     .. versionadded:: 3.18
543     The path to the CUDA Toolkit directory containing the nvvm directory and
544     either version.txt or version.json.
546 ``CUDAToolkit_TARGET_DIR``
547     The path to the CUDA Toolkit directory including the target architecture
548     when cross-compiling. When not cross-compiling this will be equivalent to
549     the parent directory of ``CUDAToolkit_BIN_DIR``.
551 ``CUDAToolkit_NVCC_EXECUTABLE``
552     The path to the NVIDIA CUDA compiler ``nvcc``.  Note that this path may
553     **not** be the same as
554     :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>`.  ``nvcc`` must be
555     found to determine the CUDA Toolkit version as well as determining other
556     features of the Toolkit.  This variable is set for the convenience of
557     modules that depend on this one.
560 #]=======================================================================]
562 # NOTE: much of this was simply extracted from FindCUDA.cmake.
564 #   James Bigler, NVIDIA Corp (nvidia.com - jbigler)
565 #   Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html
567 #   Copyright (c) 2008 - 2009 NVIDIA Corporation.  All rights reserved.
569 #   Copyright (c) 2007-2009
570 #   Scientific Computing and Imaging Institute, University of Utah
572 #   This code is licensed under the MIT License.  See the FindCUDA.cmake script
573 #   for the text of the license.
575 # The MIT License
577 # License for the specific language governing rights and limitations under
578 # Permission is hereby granted, free of charge, to any person obtaining a
579 # copy of this software and associated documentation files (the "Software"),
580 # to deal in the Software without restriction, including without limitation
581 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
582 # and/or sell copies of the Software, and to permit persons to whom the
583 # Software is furnished to do so, subject to the following conditions:
585 # The above copyright notice and this permission notice shall be included
586 # in all copies or substantial portions of the Software.
588 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
589 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
590 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
591 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
592 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
593 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
594 # DEALINGS IN THE SOFTWARE.
596 ###############################################################################
598 function(_CUDAToolkit_build_include_dirs result_variable default_paths_variable)
599   set(content "${${default_paths_variable}}")
600   set(${result_variable} "${content}" PARENT_SCOPE)
601 endfunction()
603 function(_CUDAToolkit_build_library_dirs result_variable default_paths_variable)
604   set(content "${${default_paths_variable}}")
605   set(${result_variable} "${content}" PARENT_SCOPE)
606 endfunction()
608 # The toolkit is located during compiler detection for CUDA and stored in CMakeCUDACompiler.cmake as
609 # - CMAKE_CUDA_COMPILER_TOOLKIT_ROOT
610 # - CMAKE_CUDA_COMPILER_LIBRARY_ROOT
611 # - CMAKE_CUDA_COMPILER_LIBRARY_DIRECTORIES_FROM_IMPLICIT_LIBRARIES
612 # - CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
613 # We compute the rest based on those here to avoid re-searching and to avoid finding a possibly
614 # different installation.
615 if(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT)
616   set(CUDAToolkit_ROOT_DIR "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}")
617   set(CUDAToolkit_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_LIBRARY_ROOT}")
618   _CUDAToolkit_build_library_dirs(CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES)
619   _CUDAToolkit_build_include_dirs(CUDAToolkit_INCLUDE_DIRECTORIES CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES)
620   set(CUDAToolkit_BIN_DIR "${CUDAToolkit_ROOT_DIR}/bin")
621   set(CUDAToolkit_NVCC_EXECUTABLE "${CUDAToolkit_BIN_DIR}/nvcc${CMAKE_EXECUTABLE_SUFFIX}")
622   set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_TOOLKIT_VERSION}")
624   if(CUDAToolkit_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
625     set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
626     set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
627     set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
628   endif()
629 else()
630   function(_CUDAToolkit_find_root_dir )
631     cmake_parse_arguments(arg "" "" "SEARCH_PATHS;FIND_FLAGS" ${ARGN})
633     if(NOT CUDAToolkit_BIN_DIR)
634       if(NOT CUDAToolkit_SENTINEL_FILE)
635         find_program(CUDAToolkit_NVCC_EXECUTABLE
636           NAMES nvcc nvcc.exe
637           PATHS ${arg_SEARCH_PATHS}
638           ${arg_FIND_FLAGS}
639         )
640       endif()
642       if(NOT CUDAToolkit_NVCC_EXECUTABLE)
643         find_file(CUDAToolkit_SENTINEL_FILE
644           NAMES version.txt version.json
645           PATHS ${arg_SEARCH_PATHS}
646           NO_DEFAULT_PATH
647         )
648       endif()
650       if(EXISTS "${CUDAToolkit_NVCC_EXECUTABLE}")
651         # If NVCC exists  then invoke it to find the toolkit location.
652         # This allows us to support wrapper scripts (e.g. ccache or colornvcc), CUDA Toolkit,
653         # NVIDIA HPC SDK, and distro's splayed layouts
654         execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda"
655           OUTPUT_VARIABLE _CUDA_NVCC_OUT ERROR_VARIABLE _CUDA_NVCC_OUT)
656         message(CONFIGURE_LOG
657           "Executed nvcc to extract CUDAToolkit information:\n${_CUDA_NVCC_OUT}\n\n")
658         if(_CUDA_NVCC_OUT MATCHES "\\#\\$ TOP=([^\r\n]*)")
659           get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_MATCH_1}/bin" ABSOLUTE)
660           message(CONFIGURE_LOG
661             "Parsed CUDAToolkit nvcc location:\n${CUDAToolkit_BIN_DIR}\n\n")
662         else()
663           get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
664         endif()
665         if(_CUDA_NVCC_OUT MATCHES "\\#\\$ INCLUDES=([^\r\n]*)")
666           separate_arguments(_nvcc_output NATIVE_COMMAND "${CMAKE_MATCH_1}")
667           foreach(line IN LISTS _nvcc_output)
668             string(REGEX REPLACE "^-I" "" line "${line}")
669             get_filename_component(line "${line}" ABSOLUTE)
670             list(APPEND _cmake_CUDAToolkit_include_directories "${line}")
671           endforeach()
672           message(CONFIGURE_LOG
673             "Parsed CUDAToolkit nvcc implicit include information:\n${_cmake_CUDAToolkit_include_directories}\n\n")
675           set(_cmake_CUDAToolkit_include_directories "${_cmake_CUDAToolkit_include_directories}" CACHE INTERNAL "CUDAToolkit internal list of include directories")
676         endif()
677         if(_CUDA_NVCC_OUT MATCHES "\\#\\$ LIBRARIES=([^\r\n]*)")
678           include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
679           set(_nvcc_link_line "cuda-fake-ld ${CMAKE_MATCH_1}")
680           CMAKE_PARSE_IMPLICIT_LINK_INFO("${_nvcc_link_line}"
681                                    _cmake_CUDAToolkit_implicit_link_libs
682                                    _cmake_CUDAToolkit_implicit_link_directories
683                                    _cmake_CUDAToolkit_implicit_frameworks
684                                    _nvcc_log
685                                    "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}"
686                                    LANGUAGE CUDA)
687           message(CONFIGURE_LOG
688           "Parsed CUDAToolkit nvcc implicit link information:\n${_nvcc_log}\n${_cmake_CUDAToolkit_implicit_link_directories}\n\n")
689           unset(_nvcc_link_line)
690           unset(_cmake_CUDAToolkit_implicit_link_libs)
691           unset(_cmake_CUDAToolkit_implicit_frameworks)
693           set(_cmake_CUDAToolkit_implicit_link_directories "${_cmake_CUDAToolkit_implicit_link_directories}" CACHE INTERNAL "CUDAToolkit internal list of implicit link directories")
694         endif()
695         unset(_CUDA_NVCC_OUT)
697         set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
698         mark_as_advanced(CUDAToolkit_BIN_DIR)
699       endif()
701       if(CUDAToolkit_SENTINEL_FILE)
702         get_filename_component(CUDAToolkit_BIN_DIR ${CUDAToolkit_SENTINEL_FILE} DIRECTORY ABSOLUTE)
703         set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}/bin")
705         set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
706         mark_as_advanced(CUDAToolkit_BIN_DIR)
707       endif()
708     endif()
710     if(DEFINED _cmake_CUDAToolkit_include_directories)
711       _CUDAToolkit_build_include_dirs(_cmake_CUDAToolkit_contents _cmake_CUDAToolkit_include_directories)
712       set(CUDAToolkit_INCLUDE_DIRECTORIES "${_cmake_CUDAToolkit_contents}" PARENT_SCOPE)
713     endif()
714     if(DEFINED _cmake_CUDAToolkit_implicit_link_directories)
715       _CUDAToolkit_build_library_dirs(_cmake_CUDAToolkit_contents _cmake_CUDAToolkit_implicit_link_directories)
716       set(CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES "${_cmake_CUDAToolkit_contents}" PARENT_SCOPE)
717     endif()
719     if(CUDAToolkit_BIN_DIR)
720       get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE)
721       set(CUDAToolkit_ROOT_DIR "${CUDAToolkit_ROOT_DIR}" PARENT_SCOPE)
722     endif()
724   endfunction()
726   function(_CUDAToolkit_find_version_file result_variable)
727     # We first check for a non-scattered installation to prefer it over a scattered installation.
728     set(version_files version.txt version.json)
729     foreach(vf IN LISTS version_files)
730       if(CUDAToolkit_ROOT AND EXISTS "${CUDAToolkit_ROOT}/${vf}")
731         set(${result_variable} "${CUDAToolkit_ROOT}/${vf}" PARENT_SCOPE)
732         break()
733       elseif(CUDAToolkit_ROOT_DIR AND EXISTS "${CUDAToolkit_ROOT_DIR}/${vf}")
734         set(${result_variable} "${CUDAToolkit_ROOT_DIR}/${vf}" PARENT_SCOPE)
735         break()
736       elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/${vf}")
737         set(${result_variable} "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/${vf}" PARENT_SCOPE)
738         break()
739       elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/${vf}")
740         set(${result_variable} "${CMAKE_SYSROOT}/usr/lib/cuda/${vf}" PARENT_SCOPE)
741         break()
742       endif()
743     endforeach()
744   endfunction()
746   function(_CUDAToolkit_parse_version_file version_file)
747     if(version_file)
748       file(READ "${version_file}" file_conents)
749       cmake_path(GET version_file EXTENSION LAST_ONLY version_ext)
750       if(version_ext STREQUAL ".json")
751         string(JSON cuda_version_info GET "${file_conents}" "cuda" "version")
752         set(cuda_version_match_regex [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
753       elseif(version_ext STREQUAL ".txt")
754         set(cuda_version_info "${file_conents}")
755         set(cuda_version_match_regex [=[CUDA Version ([0-9]+)\.([0-9]+)\.([0-9]+)]=])
756       endif()
758       if(cuda_version_info MATCHES "${cuda_version_match_regex}")
759         set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE)
760         set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE)
761         set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}" PARENT_SCOPE)
762         set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" PARENT_SCOPE)
763         message(STATUS "_CUDAToolkit_parse_version_file")
764       endif()
765     endif()
766   endfunction()
768   # For NVCC we can easily deduce the SDK binary directory from the compiler path.
769   if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
770     get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_CUDA_COMPILER}" DIRECTORY)
771     set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "")
772     # Try language provided path first.
773     _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_BIN_DIR}" FIND_FLAGS NO_DEFAULT_PATH)
774     mark_as_advanced(CUDAToolkit_BIN_DIR)
775   endif()
777   # Try user provided path
778   if(NOT CUDAToolkit_ROOT_DIR AND CUDAToolkit_ROOT)
779     _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_ROOT}" FIND_FLAGS PATH_SUFFIXES bin NO_DEFAULT_PATH)
780   endif()
781   if(NOT CUDAToolkit_ROOT_DIR)
782     _CUDAToolkit_find_root_dir(FIND_FLAGS PATHS ENV CUDA_PATH PATH_SUFFIXES bin)
783   endif()
785   # If the user specified CUDAToolkit_ROOT but the toolkit could not be found, this is an error.
786   if(NOT CUDAToolkit_ROOT_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
787     # Declare error messages now, print later depending on find_package args.
788     set(fail_base "Could not find nvcc executable in path specified by")
789     set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
790     set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}")
792     if(CUDAToolkit_FIND_REQUIRED)
793       if(DEFINED CUDAToolkit_ROOT)
794         message(FATAL_ERROR ${cuda_root_fail})
795       elseif(DEFINED ENV{CUDAToolkit_ROOT})
796         message(FATAL_ERROR ${env_cuda_root_fail})
797       endif()
798     else()
799       if(NOT CUDAToolkit_FIND_QUIETLY)
800         if(DEFINED CUDAToolkit_ROOT)
801           message(STATUS ${cuda_root_fail})
802         elseif(DEFINED ENV{CUDAToolkit_ROOT})
803           message(STATUS ${env_cuda_root_fail})
804         endif()
805       endif()
806       set(CUDAToolkit_FOUND FALSE)
807       unset(fail_base)
808       unset(cuda_root_fail)
809       unset(env_cuda_root_fail)
810       return()
811     endif()
812   endif()
814   # CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults.
815   #
816   # - Linux: /usr/local/cuda-X.Y
817   # - macOS: /Developer/NVIDIA/CUDA-X.Y
818   # - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y
819   #
820   # We will also search the default symlink location /usr/local/cuda first since
821   # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
822   # directory is the desired location.
823   if(NOT CUDAToolkit_ROOT_DIR)
824     if(UNIX)
825       if(NOT APPLE)
826         set(platform_base "/usr/local/cuda-")
827       else()
828         set(platform_base "/Developer/NVIDIA/CUDA-")
829       endif()
830     else()
831       set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v")
832     endif()
834     # Build out a descending list of possible cuda installations, e.g.
835     file(GLOB possible_paths "${platform_base}*")
836     # Iterate the glob results and create a descending list.
837     set(versions)
838     foreach(p ${possible_paths})
839       # Extract version number from end of string
840       string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p})
841       if(IS_DIRECTORY ${p} AND p_version)
842         list(APPEND versions ${p_version})
843       endif()
844     endforeach()
846     # Sort numerically in descending order, so we try the newest versions first.
847     list(SORT versions COMPARE NATURAL ORDER DESCENDING)
849     # With a descending list of versions, populate possible paths to search.
850     set(search_paths)
851     foreach(v ${versions})
852       list(APPEND search_paths "${platform_base}${v}")
853     endforeach()
855     # Force the global default /usr/local/cuda to the front on Unix.
856     if(UNIX)
857       list(INSERT search_paths 0 "/usr/local/cuda")
858     endif()
860     # Now search for the toolkit again using the platform default search paths.
861     _CUDAToolkit_find_root_dir(SEARCH_PATHS "${search_paths}" FIND_FLAGS PATH_SUFFIXES bin)
863     # We are done with these variables now, cleanup for caller.
864     unset(platform_base)
865     unset(possible_paths)
866     unset(versions)
867     unset(search_paths)
869     if(NOT CUDAToolkit_ROOT_DIR)
870       if(CUDAToolkit_FIND_REQUIRED)
871         message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.")
872       elseif(NOT CUDAToolkit_FIND_QUIETLY)
873         message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.")
874       endif()
876       set(CUDAToolkit_FOUND FALSE)
877       return()
878     endif()
879   endif()
881   _CUDAToolkit_find_version_file( _CUDAToolkit_version_file )
882   if(_CUDAToolkit_version_file)
883     # CUDAToolkit_LIBRARY_ROOT contains the device library and version file.
884     get_filename_component(CUDAToolkit_LIBRARY_ROOT "${_CUDAToolkit_version_file}" DIRECTORY ABSOLUTE)
885   endif()
886   unset(_CUDAToolkit_version_file)
888   if(CUDAToolkit_NVCC_EXECUTABLE AND
889      CMAKE_CUDA_COMPILER_VERSION AND
890      CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER)
891     # Need to set these based off the already computed CMAKE_CUDA_COMPILER_VERSION value
892     # This if statement will always match, but is used to provide variables for MATCH 1,2,3...
893     if(CMAKE_CUDA_COMPILER_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
894       set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
895       set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
896       set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
897       set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_VERSION}")
898     endif()
899   elseif(CUDAToolkit_NVCC_EXECUTABLE)
900     # Compute the version by invoking nvcc
901     execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
902     if(NVCC_OUT MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=])
903       set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
904       set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
905       set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
906       set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
907     endif()
908     unset(NVCC_OUT)
909   else()
910     _CUDAToolkit_find_version_file(version_file)
911     _CUDAToolkit_parse_version_file("${version_file}")
912   endif()
913 endif()
915 # Find target directory when crosscompiling.
916 if(CMAKE_CROSSCOMPILING)
917   if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a")
918     # Support for NVPACK
919     set(CUDAToolkit_TARGET_NAMES "armv7-linux-androideabi")
920   elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
921     set(CUDAToolkit_TARGET_NAMES "armv7-linux-gnueabihf")
922   elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
923     if(ANDROID_ARCH_NAME STREQUAL "arm64")
924       set(CUDAToolkit_TARGET_NAMES "aarch64-linux-androideabi")
925     elseif (CMAKE_SYSTEM_NAME STREQUAL "QNX")
926       set(CUDAToolkit_TARGET_NAMES "aarch64-qnx")
927     else()
928       set(CUDAToolkit_TARGET_NAMES "aarch64-linux" "sbsa-linux")
929     endif()
930   elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
931     set(CUDAToolkit_TARGET_NAMES "x86_64-linux")
932   endif()
934   foreach(CUDAToolkit_TARGET_NAME IN LISTS CUDAToolkit_TARGET_NAMES)
935     if(EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
936       set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
937       # add known CUDA target root path to the set of directories we search for programs, libraries and headers
938       list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}")
940       # Mark that we need to pop the root search path changes after we have
941       # found all cuda libraries so that searches for our cross-compilation
942       # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or
943       # PATh
944       set(_CUDAToolkit_Pop_ROOT_PATH True)
945       break()
946     endif()
947   endforeach()
948 endif()
950 # If not already set we can simply use the toolkit root or it's a scattered installation.
951 if(NOT CUDAToolkit_TARGET_DIR)
952   # Not cross compiling
953   set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}")
954   # Now that we have the real ROOT_DIR, find components inside it.
955   list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR})
957   # Mark that we need to pop the prefix path changes after we have
958   # found the cudart library.
959   set(_CUDAToolkit_Pop_Prefix True)
960 endif()
963 # We don't need to verify the cuda_runtime header when we are using `nvcc` include paths
964 # as the compiler being enabled means the header was found
965 if(NOT CUDAToolkit_INCLUDE_DIRECTORIES)
966   # Otherwise use CUDAToolkit_TARGET_DIR to guess where the `cuda_runtime.h` is located
967   # On a scattered installation /usr, on a non-scattered something like /usr/local/cuda or /usr/local/cuda-10.2/targets/aarch64-linux.
968   if(EXISTS "${CUDAToolkit_TARGET_DIR}/include/cuda_runtime.h")
969     set(CUDAToolkit_INCLUDE_DIRECTORIES "${CUDAToolkit_TARGET_DIR}/include")
970   else()
971     message(STATUS "Unable to find cuda_runtime.h in \"${CUDAToolkit_TARGET_DIR}/include\" for CUDAToolkit_INCLUDE_DIRECTORIES.")
972   endif()
973 endif()
975 # The NVHPC layout moves math library headers and libraries to a sibling directory and it could be nested under
976 # the version of the CUDA toolchain
977 # Create a separate variable so this directory can be selectively added to math targets.
978 find_path(CUDAToolkit_CUBLAS_INCLUDE_DIR cublas_v2.h PATHS
979   ${CUDAToolkit_INCLUDE_DIRECTORIES}
980   NO_DEFAULT_PATH)
982 if(NOT CUDAToolkit_CUBLAS_INCLUDE_DIR)
983   file(REAL_PATH "${CUDAToolkit_TARGET_DIR}" CUDAToolkit_MATH_INCLUDE_DIR)
984   cmake_path(APPEND CUDAToolkit_MATH_INCLUDE_DIR "../../math_libs/")
985   if(EXISTS "${CUDAToolkit_MATH_INCLUDE_DIR}/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/")
986     cmake_path(APPEND CUDAToolkit_MATH_INCLUDE_DIR "${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/")
987   endif()
988   cmake_path(APPEND CUDAToolkit_MATH_INCLUDE_DIR "include")
989   cmake_path(NORMAL_PATH CUDAToolkit_MATH_INCLUDE_DIR)
991   find_path(CUDAToolkit_CUBLAS_INCLUDE_DIR cublas_v2.h PATHS
992     ${CUDAToolkit_INCLUDE_DIRECTORIES}
993     )
994   if(CUDAToolkit_CUBLAS_INCLUDE_DIR)
995     list(APPEND CUDAToolkit_INCLUDE_DIRECTORIES "${CUDAToolkit_CUBLAS_INCLUDE_DIR}")
996   endif()
997 endif()
998 unset(CUDAToolkit_CUBLAS_INCLUDE_DIR CACHE)
999 unset(CUDAToolkit_CUBLAS_INCLUDE_DIR)
1001 # Find the CUDA Runtime Library libcudart
1002 find_library(CUDA_CUDART
1003   NAMES cudart
1004   PATHS ${CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES}
1005   PATH_SUFFIXES lib64 lib/x64
1007 find_library(CUDA_CUDART
1008   NAMES cudart
1009   PATHS ${CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES}
1010   PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
1013 if(NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY)
1014   message(STATUS "Unable to find cudart library.")
1015 endif()
1017 if(_CUDAToolkit_Pop_Prefix)
1018   list(REMOVE_AT CMAKE_PREFIX_PATH -1)
1019   unset(_CUDAToolkit_Pop_Prefix)
1020 endif()
1022 #-----------------------------------------------------------------------------
1023 # Perform version comparison and validate all required variables are set.
1024 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
1025 find_package_handle_standard_args(CUDAToolkit
1026   REQUIRED_VARS
1027     CUDAToolkit_INCLUDE_DIRECTORIES
1028     CUDA_CUDART
1029     CUDAToolkit_BIN_DIR
1030   VERSION_VAR
1031     CUDAToolkit_VERSION
1034 unset(CUDAToolkit_ROOT_DIR)
1035 mark_as_advanced(CUDA_CUDART
1036                  CUDAToolkit_NVCC_EXECUTABLE
1037                  CUDAToolkit_SENTINEL_FILE
1038                  )
1040 #-----------------------------------------------------------------------------
1041 # Construct result variables
1042 if(CUDAToolkit_FOUND)
1043   set(CUDAToolkit_INCLUDE_DIRS "${CUDAToolkit_INCLUDE_DIRECTORIES}")
1044   get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE)
1046   # Build search paths without any symlinks
1047   file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}" _cmake_search_dir)
1048   set(CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
1050   # Detect we are in a splayed nvhpc toolkit layout and add extra
1051   # search paths without symlinks
1052   if(CUDAToolkit_LIBRARY_DIR  MATCHES ".*/cuda/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64$")
1053     # Search location for math_libs/
1054     block(SCOPE_FOR POLICIES)
1055       cmake_policy(SET CMP0152 NEW)
1056       file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../../../../../" _cmake_search_dir)
1057       list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
1059       # Search location for extras like cupti
1060       file(REAL_PATH "${CUDAToolkit_LIBRARY_DIR}/../../../" _cmake_search_dir)
1061       list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${_cmake_search_dir}")
1062     endblock()
1063   endif()
1065   if(DEFINED CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES)
1066     list(APPEND CUDAToolkit_LIBRARY_SEARCH_DIRS "${CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES}")
1067   endif()
1069   # If no `CUDAToolkit_LIBRARY_ROOT` exists set it based on CUDAToolkit_LIBRARY_DIR
1070   if(NOT DEFINED CUDAToolkit_LIBRARY_ROOT)
1071     foreach(CUDAToolkit_search_loc IN LISTS CUDAToolkit_LIBRARY_DIR CUDAToolkit_BIN_DIR)
1072       get_filename_component(CUDAToolkit_possible_lib_root "${CUDAToolkit_search_loc}" DIRECTORY ABSOLUTE)
1073       if(EXISTS "${CUDAToolkit_possible_lib_root}/nvvm/")
1074         set(CUDAToolkit_LIBRARY_ROOT "${CUDAToolkit_possible_lib_root}")
1075         break()
1076       endif()
1077     endforeach()
1078     unset(CUDAToolkit_search_loc)
1079     unset(CUDAToolkit_possible_lib_root)
1080   endif()
1081 endif()
1082 unset(CUDAToolkit_IMPLICIT_LIBRARY_DIRECTORIES)
1083 unset(CUDAToolkit_INCLUDE_DIRECTORIES)
1085 #-----------------------------------------------------------------------------
1086 # Construct import targets
1087 if(CUDAToolkit_FOUND)
1089   function(_CUDAToolkit_find_and_add_import_lib lib_name)
1090     cmake_parse_arguments(arg "" "" "ALT;DEPS;EXTRA_PATH_SUFFIXES;EXTRA_INCLUDE_DIRS" ${ARGN})
1092     set(search_names ${lib_name} ${arg_ALT})
1094     find_library(CUDA_${lib_name}_LIBRARY
1095       NAMES ${search_names}
1096       HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS}
1097             ENV CUDA_PATH
1098       PATH_SUFFIXES nvidia/current lib64 lib/x64 lib
1099                     # Support NVHPC splayed math library layout
1100                     math_libs/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64
1101                     math_libs/lib64
1102                     ${arg_EXTRA_PATH_SUFFIXES}
1103     )
1104     # Don't try any stub directories until we have exhausted all other
1105     # search locations.
1106     set(CUDA_IMPORT_PROPERTY IMPORTED_LOCATION)
1107     set(CUDA_IMPORT_TYPE     UNKNOWN)
1108     if(NOT CUDA_${lib_name}_LIBRARY)
1109       find_library(CUDA_${lib_name}_LIBRARY
1110         NAMES ${search_names}
1111         HINTS ${CUDAToolkit_LIBRARY_SEARCH_DIRS}
1112               ENV CUDA_PATH
1113         PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
1114       )
1115     endif()
1116     if(CUDA_${lib_name}_LIBRARY MATCHES "/stubs/" AND NOT WIN32)
1117       # Use a SHARED library with IMPORTED_IMPLIB, but not IMPORTED_LOCATION,
1118       # to indicate that the stub is for linkers but not dynamic loaders.
1119       # It will not contribute any RPATH entry.  When encountered as
1120       # a private transitive dependency of another shared library,
1121       # it will be passed explicitly to linkers so they can find it
1122       # even when the runtime library file does not exist on disk.
1123       set(CUDA_IMPORT_PROPERTY IMPORTED_IMPLIB)
1124       set(CUDA_IMPORT_TYPE     SHARED)
1125     endif()
1127     mark_as_advanced(CUDA_${lib_name}_LIBRARY)
1129     if (NOT TARGET CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY)
1130       add_library(CUDA::${lib_name} ${CUDA_IMPORT_TYPE} IMPORTED)
1131       target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
1132       if(DEFINED CUDAToolkit_MATH_INCLUDE_DIR)
1133         string(FIND ${CUDA_${lib_name}_LIBRARY} "math_libs" math_libs)
1134         if(NOT ${math_libs} EQUAL -1)
1135           target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_MATH_INCLUDE_DIR}")
1136         endif()
1137       endif()
1138       set_property(TARGET CUDA::${lib_name} PROPERTY ${CUDA_IMPORT_PROPERTY} "${CUDA_${lib_name}_LIBRARY}")
1139       foreach(dep ${arg_DEPS})
1140         if(TARGET CUDA::${dep})
1141           target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dep})
1142         endif()
1143       endforeach()
1144       if(arg_EXTRA_INCLUDE_DIRS)
1145         target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${arg_EXTRA_INCLUDE_DIRS}")
1146       endif()
1147     endif()
1148   endfunction()
1150   if(NOT TARGET CUDA::toolkit)
1151     add_library(CUDA::toolkit IMPORTED INTERFACE)
1152     target_include_directories(CUDA::toolkit SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
1153     target_link_directories(CUDA::toolkit INTERFACE "${CUDAToolkit_LIBRARY_DIR}")
1154   endif()
1156   # setup dependencies that are required for cudart/cudart_static when building
1157   # on linux. These are generally only required when using the CUDA toolkit
1158   # when CUDA language is disabled
1159   if(NOT TARGET CUDA::cudart_static_deps)
1160     add_library(CUDA::cudart_static_deps IMPORTED INTERFACE)
1161     if(UNIX AND (CMAKE_C_COMPILER OR CMAKE_CXX_COMPILER))
1162       find_package(Threads REQUIRED)
1163       target_link_libraries(CUDA::cudart_static_deps INTERFACE Threads::Threads ${CMAKE_DL_LIBS})
1164     endif()
1166     if(UNIX AND NOT APPLE AND NOT (CMAKE_SYSTEM_NAME STREQUAL "QNX"))
1167       # On Linux, you must link against librt when using the static cuda runtime.
1168       find_library(CUDAToolkit_rt_LIBRARY rt)
1169       mark_as_advanced(CUDAToolkit_rt_LIBRARY)
1170       if(NOT CUDAToolkit_rt_LIBRARY)
1171         message(WARNING "Could not find librt library, needed by CUDA::cudart_static")
1172       else()
1173         target_link_libraries(CUDA::cudart_static_deps INTERFACE ${CUDAToolkit_rt_LIBRARY})
1174       endif()
1175     endif()
1176   endif()
1178   _CUDAToolkit_find_and_add_import_lib(cuda_driver ALT cuda DEPS cudart_static_deps)
1179   _CUDAToolkit_find_and_add_import_lib(cudart DEPS cudart_static_deps)
1180   _CUDAToolkit_find_and_add_import_lib(cudart_static DEPS cudart_static_deps)
1182   if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 12.0.0)
1183     _CUDAToolkit_find_and_add_import_lib(nvJitLink)
1184     _CUDAToolkit_find_and_add_import_lib(nvJitLink_static DEPS cudart_static_deps)
1185   endif()
1187   if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 12.4.0)
1188     _CUDAToolkit_find_and_add_import_lib(nvfatbin DEPS cudart_static_deps)
1189     _CUDAToolkit_find_and_add_import_lib(nvfatbin_static DEPS cudart_static_deps)
1190   endif()
1192   _CUDAToolkit_find_and_add_import_lib(culibos) # it's a static library
1193   foreach (cuda_lib cublasLt cufft nvjpeg)
1194     _CUDAToolkit_find_and_add_import_lib(${cuda_lib})
1195     _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS cudart_static_deps culibos)
1196   endforeach()
1197   foreach (cuda_lib curand nppc)
1198     _CUDAToolkit_find_and_add_import_lib(${cuda_lib})
1199     _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS culibos)
1200   endforeach()
1202   _CUDAToolkit_find_and_add_import_lib(cusparse DEPS nvJitLink)
1203   _CUDAToolkit_find_and_add_import_lib(cusparse_static DEPS nvJitLink_static culibos)
1205   if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.0.0)
1206     # cublas depends on cublasLt
1207     # https://docs.nvidia.com/cuda/archive/11.0/cublas#static-library
1208     _CUDAToolkit_find_and_add_import_lib(cublas DEPS cublasLt culibos)
1209     _CUDAToolkit_find_and_add_import_lib(cublas_static DEPS cublasLt_static culibos)
1210   else()
1211     _CUDAToolkit_find_and_add_import_lib(cublas DEPS culibos)
1212     _CUDAToolkit_find_and_add_import_lib(cublas_static DEPS culibos)
1213   endif()
1215   if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.4)
1216     _CUDAToolkit_find_and_add_import_lib(cuFile ALT cufile DEPS culibos)
1217     _CUDAToolkit_find_and_add_import_lib(cuFile_static ALT cufile_static DEPS culibos)
1219     _CUDAToolkit_find_and_add_import_lib(cuFile_rdma ALT cufile_rdma DEPS cuFile culibos)
1220     _CUDAToolkit_find_and_add_import_lib(cuFile_rdma_static ALT cufile_rdma_static DEPS cuFile_static culibos)
1221   endif()
1223     if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.6)
1224     _CUDAToolkit_find_and_add_import_lib(cudla)
1225   endif()
1228   # cuFFTW depends on cuFFT
1229   _CUDAToolkit_find_and_add_import_lib(cufftw DEPS cufft)
1230   _CUDAToolkit_find_and_add_import_lib(cufftw_static DEPS cufft_static)
1231   if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 9.2)
1232     _CUDAToolkit_find_and_add_import_lib(cufft_static_nocallback DEPS culibos)
1233   endif()
1235   # cuSOLVER depends on cuBLAS, and cuSPARSE
1236   set(cusolver_deps cublas cusparse)
1237   set(cusolver_static_deps cublas_static cusparse_static culibos)
1238   if(CUDAToolkit_VERSION VERSION_GREATER 11.2.1)
1239     # cusolver depends on libcusolver_metis and cublasLt
1240     # https://docs.nvidia.com/cuda/archive/11.2.2/cusolver#link-dependency
1241     list(APPEND cusolver_deps cublasLt)
1242     _CUDAToolkit_find_and_add_import_lib(cusolver_metis_static ALT metis_static) # implementation detail static lib
1243     list(APPEND cusolver_static_deps cusolver_metis_static cublasLt_static)
1244   endif()
1245   if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.1.2)
1246     # cusolver depends on liblapack_static.a starting with CUDA 10.1 update 2,
1247     # https://docs.nvidia.com/cuda/archive/11.5.0/cusolver#static-link-lapack
1248     _CUDAToolkit_find_and_add_import_lib(cusolver_lapack_static ALT lapack_static) # implementation detail static lib
1249     list(APPEND cusolver_static_deps cusolver_lapack_static)
1250   endif()
1251   _CUDAToolkit_find_and_add_import_lib(cusolver DEPS ${cusolver_deps})
1252   _CUDAToolkit_find_and_add_import_lib(cusolver_static DEPS ${cusolver_static_deps})
1253   unset(cusolver_deps)
1254   unset(cusolver_static_deps)
1256   # nvGRAPH depends on cuRAND, and cuSOLVER.
1257   _CUDAToolkit_find_and_add_import_lib(nvgraph DEPS curand cusolver)
1258   _CUDAToolkit_find_and_add_import_lib(nvgraph_static DEPS curand_static cusolver_static)
1260   # Process the majority of the NPP libraries.
1261   foreach (cuda_lib nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu)
1262     _CUDAToolkit_find_and_add_import_lib(${cuda_lib} DEPS nppc)
1263     _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS nppc_static)
1264   endforeach()
1266   find_path(CUDAToolkit_CUPTI_INCLUDE_DIR cupti.h PATHS
1267       "${CUDAToolkit_ROOT_DIR}/extras/CUPTI/include"
1268       ${CUDAToolkit_INCLUDE_DIRS}
1269       PATH_SUFFIXES "../extras/CUPTI/include"
1270                     "../../../extras/CUPTI/include"
1271       NO_DEFAULT_PATH)
1272   mark_as_advanced(CUDAToolkit_CUPTI_INCLUDE_DIR)
1274   if(CUDAToolkit_CUPTI_INCLUDE_DIR)
1275     set(_cmake_cupti_extra_paths extras/CUPTI/lib64/
1276                                  extras/CUPTI/lib/
1277                                  ../extras/CUPTI/lib64/
1278                                  ../extras/CUPTI/lib/)
1279     _CUDAToolkit_find_and_add_import_lib(cupti
1280                                         EXTRA_PATH_SUFFIXES ${_cmake_cupti_extra_paths}
1281                                         EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}")
1282     _CUDAToolkit_find_and_add_import_lib(cupti_static
1283                                         EXTRA_PATH_SUFFIXES ${_cmake_cupti_extra_paths}
1284                                         EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}")
1285     if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.2.0)
1286       _CUDAToolkit_find_and_add_import_lib(nvperf_host
1287                                           EXTRA_PATH_SUFFIXES ${_cmake_cupti_extra_paths}
1288                                           EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}")
1289       _CUDAToolkit_find_and_add_import_lib(nvperf_host_static
1290                                           EXTRA_PATH_SUFFIXES ${_cmake_cupti_extra_paths}
1291                                           EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}")
1292       _CUDAToolkit_find_and_add_import_lib(nvperf_target
1293                                           EXTRA_PATH_SUFFIXES ${_cmake_cupti_extra_paths}
1294                                           EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}")
1295     endif()
1296     if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.3.0)
1297       _CUDAToolkit_find_and_add_import_lib(pcsamplingutil
1298                                           EXTRA_PATH_SUFFIXES ${_cmake_cupti_extra_paths}
1299                                           EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}")
1300     endif()
1301   endif()
1303   if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.1.0)
1304     if(NOT TARGET CUDA::nvptxcompiler_static)
1305       _CUDAToolkit_find_and_add_import_lib(nvptxcompiler_static)
1306       if(TARGET CUDA::nvptxcompiler_static)
1307         target_link_libraries(CUDA::nvptxcompiler_static INTERFACE CUDA::cudart_static_deps)
1308       endif()
1309     endif()
1310   endif()
1312   _CUDAToolkit_find_and_add_import_lib(nvrtc_builtins ALT nvrtc-builtins)
1313   _CUDAToolkit_find_and_add_import_lib(nvrtc DEPS nvrtc_builtins nvJitLink)
1314   if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.5.0)
1315     _CUDAToolkit_find_and_add_import_lib(nvrtc_builtins_static ALT nvrtc-builtins_static)
1316     if(NOT TARGET CUDA::nvrtc_static)
1317       _CUDAToolkit_find_and_add_import_lib(nvrtc_static DEPS nvrtc_builtins_static nvptxcompiler_static nvJitLink_static)
1318       if(TARGET CUDA::nvrtc_static AND WIN32 AND NOT (BORLAND OR MINGW OR CYGWIN))
1319         target_link_libraries(CUDA::nvrtc_static INTERFACE Ws2_32.lib)
1320       endif()
1321     endif()
1322   endif()
1324   _CUDAToolkit_find_and_add_import_lib(nvml ALT nvidia-ml nvml)
1326   if(WIN32)
1327     # nvtools can be installed outside the CUDA toolkit directory
1328     # so prefer the NVTOOLSEXT_PATH windows only environment variable
1329     # In addition on windows the most common name is nvToolsExt64_1
1330     find_library(CUDA_nvToolsExt_LIBRARY
1331       NAMES nvToolsExt64_1 nvToolsExt64 nvToolsExt
1332       PATHS ENV NVTOOLSEXT_PATH
1333             ENV CUDA_PATH
1334       PATH_SUFFIXES lib/x64 lib
1335     )
1336   endif()
1337   _CUDAToolkit_find_and_add_import_lib(nvToolsExt ALT nvToolsExt64)
1339   if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.0)
1340     # nvToolsExt is deprecated since nvtx3 introduction.
1341     # Warn only if the project requires a sufficiently new CMake to make migration possible.
1342     if(TARGET CUDA::nvToolsExt AND CMAKE_MINIMUM_REQUIRED_VERSION VERSION_GREATER_EQUAL 3.25)
1343       set_property(TARGET CUDA::nvToolsExt PROPERTY DEPRECATION "nvToolsExt has been superseded by nvtx3 since CUDA 10.0 and CMake 3.25. Use CUDA::nvtx3 and include <nvtx3/nvToolsExt.h> instead.")
1344     endif()
1346     # Header-only variant. Uses dlopen().
1347     if(NOT TARGET CUDA::nvtx3)
1348       add_library(CUDA::nvtx3 INTERFACE IMPORTED)
1349       target_include_directories(CUDA::nvtx3 SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
1350       target_link_libraries(CUDA::nvtx3 INTERFACE ${CMAKE_DL_LIBS})
1351     endif()
1352   endif()
1354   _CUDAToolkit_find_and_add_import_lib(OpenCL)
1355 endif()
1357 if(_CUDAToolkit_Pop_ROOT_PATH)
1358   list(REMOVE_AT CMAKE_FIND_ROOT_PATH 0)
1359   unset(_CUDAToolkit_Pop_ROOT_PATH)
1360 endif()