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:`cuFile<cuda_toolkit_cuFile>`
113 - :ref:`cuFFT<cuda_toolkit_cuFFT>`
114 - :ref:`cuRAND<cuda_toolkit_cuRAND>`
115 - :ref:`cuSOLVER<cuda_toolkit_cuSOLVER>`
116 - :ref:`cuSPARSE<cuda_toolkit_cuSPARSE>`
117 - :ref:`cuPTI<cuda_toolkit_cupti>`
118 - :ref:`NPP<cuda_toolkit_NPP>`
119 - :ref:`nvBLAS<cuda_toolkit_nvBLAS>`
120 - :ref:`nvGRAPH<cuda_toolkit_nvGRAPH>`
121 - :ref:`nvJPEG<cuda_toolkit_nvJPEG>`
122 - :ref:`nvidia-ML<cuda_toolkit_nvML>`
123 - :ref:`nvPTX Compiler<cuda_toolkit_nvptx>`
124 - :ref:`nvRTC<cuda_toolkit_nvRTC>`
125 - :ref:`nvToolsExt<cuda_toolkit_nvToolsExt>`
126 - :ref:`nvtx3<cuda_toolkit_nvtx3>`
127 - :ref:`OpenCL<cuda_toolkit_opencl>`
128 - :ref:`cuLIBOS<cuda_toolkit_cuLIBOS>`
130 .. _`cuda_toolkit_rt_lib`:
135 The CUDA Runtime library (cudart) are what most applications will typically
136 need to link against to make any calls such as `cudaMalloc`, and `cudaFree`.
141 - ``CUDA::cudart_static``
143 .. _`cuda_toolkit_driver_lib`:
148 The CUDA Driver library (cuda) are used by applications that use calls
149 such as `cuMemAlloc`, and `cuMemFree`.
153 - ``CUDA::cuda_driver``
155 .. _`cuda_toolkit_cuBLAS`:
160 The `cuBLAS <https://docs.nvidia.com/cuda/cublas/index.html>`_ library.
165 - ``CUDA::cublas_static``
166 - ``CUDA::cublasLt`` starting in CUDA 10.1
167 - ``CUDA::cublasLt_static`` starting in CUDA 10.1
169 .. _`cuda_toolkit_cuFile`:
174 .. versionadded:: 3.25
176 The NVIDIA GPUDirect Storage `cuFile <https://docs.nvidia.com/cuda/cufile-api/index.html>`_ library.
180 - ``CUDA::cuFile`` starting in CUDA 11.4
181 - ``CUDA::cuFile_static`` starting in CUDA 11.4
182 - ``CUDA::cuFile_rdma`` starting in CUDA 11.4
183 - ``CUDA::cuFile_rdma_static`` starting in CUDA 11.4
185 .. _`cuda_toolkit_cuFFT`:
190 The `cuFFT <https://docs.nvidia.com/cuda/cufft/index.html>`_ library.
196 - ``CUDA::cufft_static``
197 - ``CUDA::cufft_static_nocallback`` starting in CUDA 9.2, requires CMake 3.23+
198 - ``CUDA::cufftw_static``
203 The `cuRAND <https://docs.nvidia.com/cuda/curand/index.html>`_ library.
208 - ``CUDA::curand_static``
210 .. _`cuda_toolkit_cuSOLVER`:
215 The `cuSOLVER <https://docs.nvidia.com/cuda/cusolver/index.html>`_ library.
220 - ``CUDA::cusolver_static``
222 .. _`cuda_toolkit_cuSPARSE`:
227 The `cuSPARSE <https://docs.nvidia.com/cuda/cusparse/index.html>`_ library.
232 - ``CUDA::cusparse_static``
234 .. _`cuda_toolkit_cupti`:
239 The `NVIDIA CUDA Profiling Tools Interface <https://developer.nvidia.com/CUPTI>`_.
244 - ``CUDA::cupti_static``
246 .. _`cuda_toolkit_NPP`:
251 The `NPP <https://docs.nvidia.com/cuda/npp/index.html>`_ libraries.
258 - ``CUDA::nppc_static``
260 - `nppial`: Arithmetic and logical operation functions in `nppi_arithmetic_and_logical_operations.h`
263 - ``CUDA::nppial_static``
265 - `nppicc`: Color conversion and sampling functions in `nppi_color_conversion.h`
268 - ``CUDA::nppicc_static``
270 - `nppicom`: JPEG compression and decompression functions in `nppi_compression_functions.h`
271 Removed starting in CUDA 11.0, use :ref:`nvJPEG<cuda_toolkit_nvJPEG>` instead.
274 - ``CUDA::nppicom_static``
276 - `nppidei`: Data exchange and initialization functions in `nppi_data_exchange_and_initialization.h`
279 - ``CUDA::nppidei_static``
281 - `nppif`: Filtering and computer vision functions in `nppi_filter_functions.h`
284 - ``CUDA::nppif_static``
286 - `nppig`: Geometry transformation functions found in `nppi_geometry_transforms.h`
289 - ``CUDA::nppig_static``
291 - `nppim`: Morphological operation functions found in `nppi_morphological_operations.h`
294 - ``CUDA::nppim_static``
296 - `nppist`: Statistics and linear transform in `nppi_statistics_functions.h` and `nppi_linear_transforms.h`
299 - ``CUDA::nppist_static``
301 - `nppisu`: Memory support functions in `nppi_support_functions.h`
304 - ``CUDA::nppisu_static``
306 - `nppitc`: Threshold and compare operation functions in `nppi_threshold_and_compare_operations.h`
309 - ``CUDA::nppitc_static``
314 - ``CUDA::npps_static``
316 .. _`cuda_toolkit_nvBLAS`:
321 The `nvBLAS <https://docs.nvidia.com/cuda/nvblas/index.html>`_ libraries.
322 This is a shared library only.
328 .. _`cuda_toolkit_nvGRAPH`:
333 The `nvGRAPH <https://docs.nvidia.com/cuda/nvgraph/index.html>`_ library.
334 Removed starting in CUDA 11.0
339 - ``CUDA::nvgraph_static``
342 .. _`cuda_toolkit_nvJPEG`:
347 The `nvJPEG <https://docs.nvidia.com/cuda/nvjpeg/index.html>`_ library.
348 Introduced in CUDA 10.
353 - ``CUDA::nvjpeg_static``
355 .. _`cuda_toolkit_nvPTX`:
360 .. versionadded:: 3.25
362 The `nvPTX <https://docs.nvidia.com/cuda/ptx-compiler-api/index.html>`_ (PTX Compilation) library.
363 The PTX Compiler APIs are a set of APIs which can be used to compile a PTX program into GPU assembly code.
364 Introduced in CUDA 11.1
365 This is a static library only.
369 - ``CUDA::nvptxcompiler_static`` starting in CUDA 11.1
371 .. _`cuda_toolkit_nvRTC`:
376 The `nvRTC <https://docs.nvidia.com/cuda/nvrtc/index.html>`_ (Runtime Compilation) library.
377 This is a shared library only.
383 .. _`cuda_toolkit_nvml`:
388 The `NVIDIA Management Library <https://developer.nvidia.com/nvidia-management-library-nvml>`_.
389 This is a shared library only.
395 .. _`cuda_toolkit_nvToolsExt`:
400 .. deprecated:: 3.25 With CUDA 10.0+, use :ref:`nvtx3 <cuda_toolkit_nvtx3>`.
402 The `NVIDIA Tools Extension <https://docs.nvidia.com/gameworks/content/gameworkslibrary/nvtx/nvidia_tools_extension_library_nvtx.htm>`_.
403 This is a shared library only.
407 - ``CUDA::nvToolsExt``
409 .. _`cuda_toolkit_nvtx3`:
414 .. versionadded:: 3.25
416 The header-only `NVIDIA Tools Extension Library <https://nvidia.github.io/NVTX/doxygen/index.html>`_.
417 Introduced in CUDA 10.0.
423 .. _`cuda_toolkit_opencl`:
428 The `NVIDIA OpenCL Library <https://developer.nvidia.com/opencl>`_.
429 This is a shared library only.
435 .. _`cuda_toolkit_cuLIBOS`:
440 The cuLIBOS library is a backend thread abstraction layer library which is
441 static only. The ``CUDA::cublas_static``, ``CUDA::cusparse_static``,
442 ``CUDA::cufft_static``, ``CUDA::curand_static``, and (when implemented) NPP
443 libraries all automatically have this dependency linked.
449 **Note**: direct usage of this target by consumers should not be necessary.
451 .. _`cuda_toolkit_cuRAND`:
458 ``CUDAToolkit_FOUND``
459 A boolean specifying whether or not the CUDA Toolkit was found.
461 ``CUDAToolkit_VERSION``
462 The exact version of the CUDA Toolkit found (as reported by
463 ``nvcc --version`` or ``version.txt``).
465 ``CUDAToolkit_VERSION_MAJOR``
466 The major version of the CUDA Toolkit.
468 ``CUDAToolkit_VERSION_MINOR``
469 The minor version of the CUDA Toolkit.
471 ``CUDAToolkit_VERSION_PATCH``
472 The patch version of the CUDA Toolkit.
474 ``CUDAToolkit_BIN_DIR``
475 The path to the CUDA Toolkit library directory that contains the CUDA
478 ``CUDAToolkit_INCLUDE_DIRS``
479 The path to the CUDA Toolkit ``include`` folder containing the header files
480 required to compile a project linking against CUDA.
482 ``CUDAToolkit_LIBRARY_DIR``
483 The path to the CUDA Toolkit library directory that contains the CUDA
484 Runtime library ``cudart``.
486 ``CUDAToolkit_LIBRARY_ROOT``
487 .. versionadded:: 3.18
489 The path to the CUDA Toolkit directory containing the nvvm directory and
492 ``CUDAToolkit_TARGET_DIR``
493 The path to the CUDA Toolkit directory including the target architecture
494 when cross-compiling. When not cross-compiling this will be equivalent to
495 the parent directory of ``CUDAToolkit_BIN_DIR``.
497 ``CUDAToolkit_NVCC_EXECUTABLE``
498 The path to the NVIDIA CUDA compiler ``nvcc``. Note that this path may
499 **not** be the same as
500 :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>`. ``nvcc`` must be
501 found to determine the CUDA Toolkit version as well as determining other
502 features of the Toolkit. This variable is set for the convenience of
503 modules that depend on this one.
506 #]=======================================================================]
508 # NOTE: much of this was simply extracted from FindCUDA.cmake.
510 # James Bigler, NVIDIA Corp (nvidia.com - jbigler)
511 # Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html
513 # Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
515 # Copyright (c) 2007-2009
516 # Scientific Computing and Imaging Institute, University of Utah
518 # This code is licensed under the MIT License. See the FindCUDA.cmake script
519 # for the text of the license.
523 # License for the specific language governing rights and limitations under
524 # Permission is hereby granted, free of charge, to any person obtaining a
525 # copy of this software and associated documentation files (the "Software"),
526 # to deal in the Software without restriction, including without limitation
527 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
528 # and/or sell copies of the Software, and to permit persons to whom the
529 # Software is furnished to do so, subject to the following conditions:
531 # The above copyright notice and this permission notice shall be included
532 # in all copies or substantial portions of the Software.
534 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
535 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
536 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
537 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
538 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
539 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
540 # DEALINGS IN THE SOFTWARE.
542 ###############################################################################
544 # The toolkit is located during compiler detection for CUDA and stored in CMakeCUDACompiler.cmake as
545 # CMAKE_CUDA_COMPILER_TOOLKIT_ROOT and CMAKE_CUDA_COMPILER_LIBRARY_ROOT.
546 # We compute the rest based on those here to avoid re-searching and to avoid finding a possibly
547 # different installation.
548 if(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT)
549 set(CUDAToolkit_ROOT_DIR "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}")
550 set(CUDAToolkit_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_LIBRARY_ROOT}")
551 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_ROOT_DIR}/bin")
552 set(CUDAToolkit_NVCC_EXECUTABLE "${CUDAToolkit_BIN_DIR}/nvcc${CMAKE_EXECUTABLE_SUFFIX}")
553 set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_TOOLKIT_VERSION}")
555 if(CUDAToolkit_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
556 set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
557 set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
558 set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
561 function(_CUDAToolkit_find_root_dir )
562 cmake_parse_arguments(arg "" "" "SEARCH_PATHS;FIND_FLAGS" ${ARGN})
564 if(NOT CUDAToolkit_BIN_DIR)
565 if(NOT CUDAToolkit_SENTINEL_FILE)
566 find_program(CUDAToolkit_NVCC_EXECUTABLE
568 PATHS ${arg_SEARCH_PATHS}
573 if(NOT CUDAToolkit_NVCC_EXECUTABLE)
574 find_file(CUDAToolkit_SENTINEL_FILE
576 PATHS ${arg_SEARCH_PATHS}
581 if(EXISTS "${CUDAToolkit_NVCC_EXECUTABLE}")
582 # If NVCC exists then invoke it to find the toolkit location.
583 # This allows us to support wrapper scripts (e.g. ccache or colornvcc), CUDA Toolkit,
584 # NVIDIA HPC SDK, and distro's splayed layouts
585 execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda"
586 OUTPUT_VARIABLE _CUDA_NVCC_OUT ERROR_VARIABLE _CUDA_NVCC_OUT)
587 if(_CUDA_NVCC_OUT MATCHES "\\#\\$ TOP=([^\r\n]*)")
588 get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_MATCH_1}/bin" ABSOLUTE)
590 get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY)
592 unset(_CUDA_NVCC_OUT)
594 mark_as_advanced(CUDAToolkit_BIN_DIR)
595 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
598 if(CUDAToolkit_SENTINEL_FILE)
599 get_filename_component(CUDAToolkit_BIN_DIR ${CUDAToolkit_SENTINEL_FILE} DIRECTORY ABSOLUTE)
600 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}/bin")
602 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE)
603 mark_as_advanced(CUDAToolkit_BIN_DIR)
607 if(CUDAToolkit_BIN_DIR)
608 get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE)
609 set(CUDAToolkit_ROOT_DIR "${CUDAToolkit_ROOT_DIR}" PARENT_SCOPE)
614 function(_CUDAToolkit_find_version_file result_variable)
615 # We first check for a non-scattered installation to prefer it over a scattered installation.
616 if(CUDAToolkit_ROOT AND EXISTS "${CUDAToolkit_ROOT}/version.txt")
617 set(${result_variable} "${CUDAToolkit_ROOT}/version.txt" PARENT_SCOPE)
618 elseif(CUDAToolkit_ROOT_DIR AND EXISTS "${CUDAToolkit_ROOT_DIR}/version.txt")
619 set(${result_variable} "${CUDAToolkit_ROOT_DIR}/version.txt" PARENT_SCOPE)
620 elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt")
621 set(${result_variable} "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt" PARENT_SCOPE)
622 elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt")
623 set(${result_variable} "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt" PARENT_SCOPE)
627 # For NVCC we can easily deduce the SDK binary directory from the compiler path.
628 if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
629 get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_CUDA_COMPILER}" DIRECTORY)
630 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "")
631 # Try language provided path first.
632 _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_BIN_DIR}" FIND_FLAGS NO_DEFAULT_PATH)
633 mark_as_advanced(CUDAToolkit_BIN_DIR)
636 # Try user provided path
637 if(NOT CUDAToolkit_ROOT_DIR AND CUDAToolkit_ROOT)
638 _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_ROOT}" FIND_FLAGS PATH_SUFFIXES bin NO_DEFAULT_PATH)
640 if(NOT CUDAToolkit_ROOT_DIR)
641 _CUDAToolkit_find_root_dir(FIND_FLAGS PATHS ENV CUDA_PATH PATH_SUFFIXES bin)
644 # If the user specified CUDAToolkit_ROOT but the toolkit could not be found, this is an error.
645 if(NOT CUDAToolkit_ROOT_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT}))
646 # Declare error messages now, print later depending on find_package args.
647 set(fail_base "Could not find nvcc executable in path specified by")
648 set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}")
649 set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}")
651 if(CUDAToolkit_FIND_REQUIRED)
652 if(DEFINED CUDAToolkit_ROOT)
653 message(FATAL_ERROR ${cuda_root_fail})
654 elseif(DEFINED ENV{CUDAToolkit_ROOT})
655 message(FATAL_ERROR ${env_cuda_root_fail})
658 if(NOT CUDAToolkit_FIND_QUIETLY)
659 if(DEFINED CUDAToolkit_ROOT)
660 message(STATUS ${cuda_root_fail})
661 elseif(DEFINED ENV{CUDAToolkit_ROOT})
662 message(STATUS ${env_cuda_root_fail})
665 set(CUDAToolkit_FOUND FALSE)
667 unset(cuda_root_fail)
668 unset(env_cuda_root_fail)
673 # CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults.
675 # - Linux: /usr/local/cuda-X.Y
676 # - macOS: /Developer/NVIDIA/CUDA-X.Y
677 # - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y
679 # We will also search the default symlink location /usr/local/cuda first since
680 # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked
681 # directory is the desired location.
682 if(NOT CUDAToolkit_ROOT_DIR)
685 set(platform_base "/usr/local/cuda-")
687 set(platform_base "/Developer/NVIDIA/CUDA-")
690 set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v")
693 # Build out a descending list of possible cuda installations, e.g.
694 file(GLOB possible_paths "${platform_base}*")
695 # Iterate the glob results and create a descending list.
697 foreach(p ${possible_paths})
698 # Extract version number from end of string
699 string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p})
700 if(IS_DIRECTORY ${p} AND p_version)
701 list(APPEND versions ${p_version})
705 # Sort numerically in descending order, so we try the newest versions first.
706 list(SORT versions COMPARE NATURAL ORDER DESCENDING)
708 # With a descending list of versions, populate possible paths to search.
710 foreach(v ${versions})
711 list(APPEND search_paths "${platform_base}${v}")
714 # Force the global default /usr/local/cuda to the front on Unix.
716 list(INSERT search_paths 0 "/usr/local/cuda")
719 # Now search for the toolkit again using the platform default search paths.
720 _CUDAToolkit_find_root_dir(SEARCH_PATHS "${search_paths}" FIND_FLAGS PATH_SUFFIXES bin)
722 # We are done with these variables now, cleanup for caller.
724 unset(possible_paths)
728 if(NOT CUDAToolkit_ROOT_DIR)
729 if(CUDAToolkit_FIND_REQUIRED)
730 message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.")
731 elseif(NOT CUDAToolkit_FIND_QUIETLY)
732 message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.")
735 set(CUDAToolkit_FOUND FALSE)
740 _CUDAToolkit_find_version_file( _CUDAToolkit_version_file )
741 if(_CUDAToolkit_version_file)
742 # CUDAToolkit_LIBRARY_ROOT contains the device library and version file.
743 get_filename_component(CUDAToolkit_LIBRARY_ROOT "${_CUDAToolkit_version_file}" DIRECTORY ABSOLUTE)
745 unset(_CUDAToolkit_version_file)
747 if(CUDAToolkit_NVCC_EXECUTABLE AND
748 CMAKE_CUDA_COMPILER_VERSION AND
749 CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER)
750 # Need to set these based off the already computed CMAKE_CUDA_COMPILER_VERSION value
751 # This if statement will always match, but is used to provide variables for MATCH 1,2,3...
752 if(CMAKE_CUDA_COMPILER_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
753 set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
754 set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
755 set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
756 set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_VERSION}")
758 elseif(CUDAToolkit_NVCC_EXECUTABLE)
759 # Compute the version by invoking nvcc
760 execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT)
761 if(NVCC_OUT MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=])
762 set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
763 set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
764 set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
765 set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
769 _CUDAToolkit_find_version_file(version_file)
771 file(READ "${version_file}" VERSION_INFO)
772 if(VERSION_INFO MATCHES [=[CUDA Version ([0-9]+)\.([0-9]+)\.([0-9]+)]=])
773 set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}")
774 set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}")
775 set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}")
776 set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
782 # Find target directory when crosscompiling.
783 if(CMAKE_CROSSCOMPILING)
784 if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a")
786 set(CUDAToolkit_TARGET_NAME "armv7-linux-androideabi")
787 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
788 set(CUDAToolkit_TARGET_NAME "armv7-linux-gnueabihf")
789 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
790 if(ANDROID_ARCH_NAME STREQUAL "arm64")
791 set(CUDAToolkit_TARGET_NAME "aarch64-linux-androideabi")
792 elseif (CMAKE_SYSTEM_NAME STREQUAL "QNX")
793 set(CUDAToolkit_TARGET_NAME "aarch64-qnx")
795 set(CUDAToolkit_TARGET_NAME "aarch64-linux")
796 endif(ANDROID_ARCH_NAME STREQUAL "arm64")
797 elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
798 set(CUDAToolkit_TARGET_NAME "x86_64-linux")
801 if(EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
802 set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}")
803 # add known CUDA target root path to the set of directories we search for programs, libraries and headers
804 list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}")
806 # Mark that we need to pop the root search path changes after we have
807 # found all cuda libraries so that searches for our cross-compilation
808 # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or
810 set(_CUDAToolkit_Pop_ROOT_PATH True)
814 # If not already set we can simply use the toolkit root or it's a scattered installation.
815 if(NOT CUDAToolkit_TARGET_DIR)
816 # Not cross compiling
817 set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}")
818 # Now that we have the real ROOT_DIR, find components inside it.
819 list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR})
821 # Mark that we need to pop the prefix path changes after we have
822 # found the cudart library.
823 set(_CUDAToolkit_Pop_Prefix True)
826 # CUDAToolkit_TARGET_DIR always points to the directory containing the include directory.
827 # On a scattered installation /usr, on a non-scattered something like /usr/local/cuda or /usr/local/cuda-10.2/targets/aarch64-linux.
828 if(EXISTS "${CUDAToolkit_TARGET_DIR}/include/cuda_runtime.h")
829 set(CUDAToolkit_INCLUDE_DIR "${CUDAToolkit_TARGET_DIR}/include")
830 elseif(NOT CUDAToolkit_FIND_QUIETLY)
831 message(STATUS "Unable to find cuda_runtime.h in \"${CUDAToolkit_TARGET_DIR}/include\" for CUDAToolkit_INCLUDE_DIR.")
834 # The NVHPC layout moves math library headers and libraries to a sibling directory.
835 # Create a separate variable so this directory can be selectively added to math targets.
836 if(NOT EXISTS "${CUDAToolkit_INCLUDE_DIR}/cublas_v2.h")
837 set(CUDAToolkit_MATH_INCLUDE_DIR "${CUDAToolkit_TARGET_DIR}/../../math_libs/include")
838 cmake_path(NORMAL_PATH CUDAToolkit_MATH_INCLUDE_DIR)
839 if(NOT EXISTS "${CUDAToolkit_MATH_INCLUDE_DIR}/cublas_v2.h")
840 if(NOT CUDAToolkit_FIND_QUIETLY)
841 message(STATUS "Unable to find cublas_v2.h in either \"${CUDAToolkit_INCLUDE_DIR}\" or \"${CUDAToolkit_MATH_INCLUDE_DIR}\"")
843 unset(CUDAToolkit_MATH_INCLUDE_DIR)
847 # Find the CUDA Runtime Library libcudart
848 find_library(CUDA_CUDART
850 PATH_SUFFIXES lib64 lib/x64
852 find_library(CUDA_CUDART
854 PATH_SUFFIXES lib64/stubs lib/x64/stubs
857 if(NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY)
858 message(STATUS "Unable to find cudart library.")
861 if(_CUDAToolkit_Pop_Prefix)
862 list(REMOVE_AT CMAKE_PREFIX_PATH -1)
863 unset(_CUDAToolkit_Pop_Prefix)
866 #-----------------------------------------------------------------------------
867 # Perform version comparison and validate all required variables are set.
868 include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
869 find_package_handle_standard_args(CUDAToolkit
871 CUDAToolkit_INCLUDE_DIR
878 unset(CUDAToolkit_ROOT_DIR)
879 mark_as_advanced(CUDA_CUDART
880 CUDAToolkit_INCLUDE_DIR
881 CUDAToolkit_NVCC_EXECUTABLE
882 CUDAToolkit_SENTINEL_FILE
885 #-----------------------------------------------------------------------------
886 # Construct result variables
887 if(CUDAToolkit_FOUND)
888 set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR})
889 get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE)
892 #-----------------------------------------------------------------------------
893 # Construct import targets
894 if(CUDAToolkit_FOUND)
896 function(_CUDAToolkit_find_and_add_import_lib lib_name)
897 cmake_parse_arguments(arg "" "" "ALT;DEPS;EXTRA_PATH_SUFFIXES;EXTRA_INCLUDE_DIRS" ${ARGN})
899 set(search_names ${lib_name} ${arg_ALT})
901 find_library(CUDA_${lib_name}_LIBRARY
902 NAMES ${search_names}
903 HINTS ${CUDAToolkit_LIBRARY_DIR}
905 PATH_SUFFIXES nvidia/current lib64 lib/x64 lib
906 ${arg_EXTRA_PATH_SUFFIXES}
908 # Don't try any stub directories until we have exhausted all other
910 find_library(CUDA_${lib_name}_LIBRARY
911 NAMES ${search_names}
912 HINTS ${CUDAToolkit_LIBRARY_DIR}
914 PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs
915 # Support NVHPC splayed math library layout
916 ../../math_libs/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64
917 ../../math_libs/lib64
920 mark_as_advanced(CUDA_${lib_name}_LIBRARY)
922 if (NOT TARGET CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY)
923 add_library(CUDA::${lib_name} UNKNOWN IMPORTED)
924 target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
925 if(DEFINED CUDAToolkit_MATH_INCLUDE_DIR)
926 string(FIND ${CUDA_${lib_name}_LIBRARY} "math_libs" math_libs)
927 if(NOT ${math_libs} EQUAL -1)
928 target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_MATH_INCLUDE_DIR}")
931 set_property(TARGET CUDA::${lib_name} PROPERTY IMPORTED_LOCATION "${CUDA_${lib_name}_LIBRARY}")
932 foreach(dep ${arg_DEPS})
933 if(TARGET CUDA::${dep})
934 target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dep})
937 if(arg_EXTRA_INCLUDE_DIRS)
938 target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${arg_EXTRA_INCLUDE_DIRS}")
943 if(NOT TARGET CUDA::toolkit)
944 add_library(CUDA::toolkit IMPORTED INTERFACE)
945 target_include_directories(CUDA::toolkit SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
946 target_link_directories(CUDA::toolkit INTERFACE "${CUDAToolkit_LIBRARY_DIR}")
949 _CUDAToolkit_find_and_add_import_lib(cuda_driver ALT cuda)
951 _CUDAToolkit_find_and_add_import_lib(cudart)
952 _CUDAToolkit_find_and_add_import_lib(cudart_static)
954 # setup dependencies that are required for cudart_static when building
955 # on linux. These are generally only required when using the CUDA toolkit
956 # when CUDA language is disabled
957 if(NOT TARGET CUDA::cudart_static_deps
958 AND TARGET CUDA::cudart_static)
960 add_library(CUDA::cudart_static_deps IMPORTED INTERFACE)
961 target_link_libraries(CUDA::cudart_static INTERFACE CUDA::cudart_static_deps)
963 if(UNIX AND (CMAKE_C_COMPILER OR CMAKE_CXX_COMPILER))
964 find_package(Threads REQUIRED)
965 target_link_libraries(CUDA::cudart_static_deps INTERFACE Threads::Threads ${CMAKE_DL_LIBS})
968 if(UNIX AND NOT APPLE AND NOT (CMAKE_SYSTEM_NAME STREQUAL "QNX"))
969 # On Linux, you must link against librt when using the static cuda runtime.
970 find_library(CUDAToolkit_rt_LIBRARY rt)
971 mark_as_advanced(CUDAToolkit_rt_LIBRARY)
972 if(NOT CUDAToolkit_rt_LIBRARY)
973 message(WARNING "Could not find librt library, needed by CUDA::cudart_static")
975 target_link_libraries(CUDA::cudart_static_deps INTERFACE ${CUDAToolkit_rt_LIBRARY})
980 _CUDAToolkit_find_and_add_import_lib(culibos) # it's a static library
981 foreach (cuda_lib cublasLt cufft curand cusparse nppc nvjpeg)
982 _CUDAToolkit_find_and_add_import_lib(${cuda_lib})
983 _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS culibos)
986 if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.0.0)
987 # cublas depends on cublasLt
988 # https://docs.nvidia.com/cuda/archive/11.0/cublas/index.html#static-library
989 _CUDAToolkit_find_and_add_import_lib(cublas DEPS cublasLt culibos)
990 _CUDAToolkit_find_and_add_import_lib(cublas_static DEPS cublasLt_static culibos)
992 _CUDAToolkit_find_and_add_import_lib(cublas DEPS culibos)
993 _CUDAToolkit_find_and_add_import_lib(cublas_static DEPS culibos)
996 if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.4)
997 _CUDAToolkit_find_and_add_import_lib(cuFile DEPS culibos)
998 _CUDAToolkit_find_and_add_import_lib(cuFile_static DEPS culibos)
1000 _CUDAToolkit_find_and_add_import_lib(cuFile_rdma DEPS cuFile culibos)
1001 _CUDAToolkit_find_and_add_import_lib(cuFile_rdma_static DEPS cuFile_static culibos)
1004 # cuFFTW depends on cuFFT
1005 _CUDAToolkit_find_and_add_import_lib(cufftw DEPS cufft)
1006 _CUDAToolkit_find_and_add_import_lib(cufftw_static DEPS cufft_static)
1007 if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 9.2)
1008 _CUDAToolkit_find_and_add_import_lib(cufft_static_nocallback DEPS culibos)
1011 # cuSOLVER depends on cuBLAS, and cuSPARSE
1012 set(cusolver_deps cublas cusparse)
1013 set(cusolver_static_deps cublas_static cusparse_static culibos)
1014 if(CUDAToolkit_VERSION VERSION_GREATER 11.2.1)
1015 # cusolver depends on libcusolver_metis and cublasLt
1016 # https://docs.nvidia.com/cuda/archive/11.2.2/cusolver/index.html#link-dependency
1017 list(APPEND cusolver_deps cublasLt)
1018 _CUDAToolkit_find_and_add_import_lib(cusolver_metis_static ALT metis_static) # implementation detail static lib
1019 list(APPEND cusolver_static_deps cusolver_metis_static cublasLt_static)
1021 if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.1.2)
1022 # cusolver depends on liblapack_static.a starting with CUDA 10.1 update 2,
1023 # https://docs.nvidia.com/cuda/archive/11.5.0/cusolver/index.html#static-link-lapack
1024 _CUDAToolkit_find_and_add_import_lib(cusolver_lapack_static ALT lapack_static) # implementation detail static lib
1025 list(APPEND cusolver_static_deps cusolver_lapack_static)
1027 _CUDAToolkit_find_and_add_import_lib(cusolver DEPS ${cusolver_deps})
1028 _CUDAToolkit_find_and_add_import_lib(cusolver_static DEPS ${cusolver_static_deps})
1029 unset(cusolver_deps)
1030 unset(cusolver_static_deps)
1032 # nvGRAPH depends on cuRAND, and cuSOLVER.
1033 _CUDAToolkit_find_and_add_import_lib(nvgraph DEPS curand cusolver)
1034 _CUDAToolkit_find_and_add_import_lib(nvgraph_static DEPS curand_static cusolver_static)
1036 # Process the majority of the NPP libraries.
1037 foreach (cuda_lib nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu)
1038 _CUDAToolkit_find_and_add_import_lib(${cuda_lib} DEPS nppc)
1039 _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS nppc_static)
1042 find_path(CUDAToolkit_CUPTI_INCLUDE_DIR cupti.h PATHS
1043 "${CUDAToolkit_ROOT_DIR}/extras/CUPTI/include"
1044 "${CUDAToolkit_INCLUDE_DIR}/../extras/CUPTI/include"
1045 "${CUDAToolkit_INCLUDE_DIR}"
1048 if(CUDAToolkit_CUPTI_INCLUDE_DIR)
1049 _CUDAToolkit_find_and_add_import_lib(cupti
1050 EXTRA_PATH_SUFFIXES ../extras/CUPTI/lib64/
1051 ../extras/CUPTI/lib/
1052 EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}")
1053 _CUDAToolkit_find_and_add_import_lib(cupti_static
1054 EXTRA_PATH_SUFFIXES ../extras/CUPTI/lib64/
1055 ../extras/CUPTI/lib/
1056 EXTRA_INCLUDE_DIRS "${CUDAToolkit_CUPTI_INCLUDE_DIR}")
1059 _CUDAToolkit_find_and_add_import_lib(nvrtc DEPS cuda_driver)
1060 if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 11.1.0)
1061 if(NOT TARGET CUDA::nvptxcompiler_static)
1062 _CUDAToolkit_find_and_add_import_lib(nvptxcompiler_static DEPS cuda_driver)
1063 target_link_libraries(CUDA::nvptxcompiler_static INTERFACE Threads::Threads)
1067 _CUDAToolkit_find_and_add_import_lib(nvml ALT nvidia-ml nvml)
1070 # nvtools can be installed outside the CUDA toolkit directory
1071 # so prefer the NVTOOLSEXT_PATH windows only environment variable
1072 # In addition on windows the most common name is nvToolsExt64_1
1073 find_library(CUDA_nvToolsExt_LIBRARY
1074 NAMES nvToolsExt64_1 nvToolsExt64 nvToolsExt
1075 PATHS ENV NVTOOLSEXT_PATH
1077 PATH_SUFFIXES lib/x64 lib
1080 _CUDAToolkit_find_and_add_import_lib(nvToolsExt ALT nvToolsExt64)
1082 if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.0)
1083 # nvToolsExt is deprecated since nvtx3 introduction.
1084 # Warn only if the project requires a sufficiently new CMake to make migration possible.
1085 if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_GREATER_EQUAL 3.25)
1086 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.")
1089 # Header-only variant. Uses dlopen().
1090 if(NOT TARGET CUDA::nvtx3)
1091 add_library(CUDA::nvtx3 INTERFACE IMPORTED)
1092 target_include_directories(CUDA::nvtx3 SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
1093 target_link_libraries(CUDA::nvtx3 INTERFACE ${CMAKE_DL_LIBS})
1097 _CUDAToolkit_find_and_add_import_lib(OpenCL)
1100 if(_CUDAToolkit_Pop_ROOT_PATH)
1101 list(REMOVE_AT CMAKE_FIND_ROOT_PATH 0)
1102 unset(_CUDAToolkit_Pop_ROOT_PATH)