1# Distributed under the OSI-approved BSD 3-Clause License. See accompanying 2# file Copyright.txt or https://cmake.org/licensing for details. 3 4#[=======================================================================[.rst: 5FindCUDAToolkit 6--------------- 7 8.. versionadded:: 3.17 9 10This script locates the NVIDIA CUDA toolkit and the associated libraries, but 11does not require the ``CUDA`` language be enabled for a given project. This 12module does not search for the NVIDIA CUDA Samples. 13 14.. versionadded:: 3.19 15 QNX support. 16 17Search Behavior 18^^^^^^^^^^^^^^^ 19 20The CUDA Toolkit search behavior uses the following order: 21 221. If the ``CUDA`` language has been enabled we will use the directory 23 containing the compiler as the first search location for ``nvcc``. 24 252. 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. 30 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 33 directory. 34 353. If the CUDA_PATH environment variable is defined, it will be searched 36 for ``nvcc``. 37 384. 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. 42 435. 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. 46 476. 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: 50 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 +-------------+-------------------------------------------------------------+ 60 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`` 64 65 .. note:: 66 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. 71 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. 77 78Arguments 79^^^^^^^^^ 80 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. 85 86Options 87^^^^^^^ 88 89``REQUIRED`` 90 If specified, configuration will error if a suitable CUDA Toolkit is not 91 found. 92 93``QUIET`` 94 If specified, the search for a suitable CUDA Toolkit will not produce any 95 messages. 96 97``EXACT`` 98 If specified, the CUDA Toolkit is considered found only if the exact 99 ``VERSION`` specified is recovered. 100 101Imported targets 102^^^^^^^^^^^^^^^^ 103 104An :ref:`imported target <Imported targets>` named ``CUDA::toolkit`` is provided. 105 106This module defines :prop_tgt:`IMPORTED` targets for each 107of the following libraries that are part of the CUDAToolkit: 108 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>` 126 127.. _`cuda_toolkit_rt_lib`: 128 129CUDA Runtime Library 130"""""""""""""""""""" 131 132The CUDA Runtime library (cudart) are what most applications will typically 133need to link against to make any calls such as `cudaMalloc`, and `cudaFree`. 134 135Targets Created: 136 137- ``CUDA::cudart`` 138- ``CUDA::cudart_static`` 139 140.. _`cuda_toolkit_driver_lib`: 141 142CUDA Driver Library 143"""""""""""""""""""" 144 145The CUDA Driver library (cuda) are used by applications that use calls 146such as `cuMemAlloc`, and `cuMemFree`. This is generally used by advanced 147 148 149Targets Created: 150 151- ``CUDA::cuda_driver`` 152- ``CUDA::cuda_driver`` 153 154.. _`cuda_toolkit_cuBLAS`: 155 156cuBLAS 157"""""" 158 159The `cuBLAS <https://docs.nvidia.com/cuda/cublas/index.html>`_ library. 160 161Targets Created: 162 163- ``CUDA::cublas`` 164- ``CUDA::cublas_static`` 165- ``CUDA::cublasLt`` starting in CUDA 10.1 166- ``CUDA::cublasLt_static`` starting in CUDA 10.1 167 168.. _`cuda_toolkit_cuFFT`: 169 170cuFFT 171""""" 172 173The `cuFFT <https://docs.nvidia.com/cuda/cufft/index.html>`_ library. 174 175Targets Created: 176 177- ``CUDA::cufft`` 178- ``CUDA::cufftw`` 179- ``CUDA::cufft_static`` 180- ``CUDA::cufftw_static`` 181 182cuRAND 183"""""" 184 185The `cuRAND <https://docs.nvidia.com/cuda/curand/index.html>`_ library. 186 187Targets Created: 188 189- ``CUDA::curand`` 190- ``CUDA::curand_static`` 191 192.. _`cuda_toolkit_cuSOLVER`: 193 194cuSOLVER 195"""""""" 196 197The `cuSOLVER <https://docs.nvidia.com/cuda/cusolver/index.html>`_ library. 198 199Targets Created: 200 201- ``CUDA::cusolver`` 202- ``CUDA::cusolver_static`` 203 204.. _`cuda_toolkit_cuSPARSE`: 205 206cuSPARSE 207"""""""" 208 209The `cuSPARSE <https://docs.nvidia.com/cuda/cusparse/index.html>`_ library. 210 211Targets Created: 212 213- ``CUDA::cusparse`` 214- ``CUDA::cusparse_static`` 215 216.. _`cuda_toolkit_cupti`: 217 218cupti 219""""" 220 221The `NVIDIA CUDA Profiling Tools Interface <https://developer.nvidia.com/CUPTI>`_. 222 223Targets Created: 224 225- ``CUDA::cupti`` 226- ``CUDA::cupti_static`` 227 228.. _`cuda_toolkit_NPP`: 229 230NPP 231""" 232 233The `NPP <https://docs.nvidia.com/cuda/npp/index.html>`_ libraries. 234 235Targets Created: 236 237- `nppc`: 238 239 - ``CUDA::nppc`` 240 - ``CUDA::nppc_static`` 241 242- `nppial`: Arithmetic and logical operation functions in `nppi_arithmetic_and_logical_operations.h` 243 244 - ``CUDA::nppial`` 245 - ``CUDA::nppial_static`` 246 247- `nppicc`: Color conversion and sampling functions in `nppi_color_conversion.h` 248 249 - ``CUDA::nppicc`` 250 - ``CUDA::nppicc_static`` 251 252- `nppicom`: JPEG compression and decompression functions in `nppi_compression_functions.h` 253 Removed starting in CUDA 11.0, use :ref:`nvJPEG<cuda_toolkit_nvJPEG>` instead. 254 255 - ``CUDA::nppicom`` 256 - ``CUDA::nppicom_static`` 257 258- `nppidei`: Data exchange and initialization functions in `nppi_data_exchange_and_initialization.h` 259 260 - ``CUDA::nppidei`` 261 - ``CUDA::nppidei_static`` 262 263- `nppif`: Filtering and computer vision functions in `nppi_filter_functions.h` 264 265 - ``CUDA::nppif`` 266 - ``CUDA::nppif_static`` 267 268- `nppig`: Geometry transformation functions found in `nppi_geometry_transforms.h` 269 270 - ``CUDA::nppig`` 271 - ``CUDA::nppig_static`` 272 273- `nppim`: Morphological operation functions found in `nppi_morphological_operations.h` 274 275 - ``CUDA::nppim`` 276 - ``CUDA::nppim_static`` 277 278- `nppist`: Statistics and linear transform in `nppi_statistics_functions.h` and `nppi_linear_transforms.h` 279 280 - ``CUDA::nppist`` 281 - ``CUDA::nppist_static`` 282 283- `nppisu`: Memory support functions in `nppi_support_functions.h` 284 285 - ``CUDA::nppisu`` 286 - ``CUDA::nppisu_static`` 287 288- `nppitc`: Threshold and compare operation functions in `nppi_threshold_and_compare_operations.h` 289 290 - ``CUDA::nppitc`` 291 - ``CUDA::nppitc_static`` 292 293- `npps`: 294 295 - ``CUDA::npps`` 296 - ``CUDA::npps_static`` 297 298.. _`cuda_toolkit_nvBLAS`: 299 300nvBLAS 301"""""" 302 303The `nvBLAS <https://docs.nvidia.com/cuda/nvblas/index.html>`_ libraries. 304This is a shared library only. 305 306Targets Created: 307 308- ``CUDA::nvblas`` 309 310.. _`cuda_toolkit_nvGRAPH`: 311 312nvGRAPH 313""""""" 314 315The `nvGRAPH <https://docs.nvidia.com/cuda/nvgraph/index.html>`_ library. 316Removed starting in CUDA 11.0 317 318Targets Created: 319 320- ``CUDA::nvgraph`` 321- ``CUDA::nvgraph_static`` 322 323 324.. _`cuda_toolkit_nvJPEG`: 325 326nvJPEG 327"""""" 328 329The `nvJPEG <https://docs.nvidia.com/cuda/nvjpeg/index.html>`_ library. 330Introduced in CUDA 10. 331 332Targets Created: 333 334- ``CUDA::nvjpeg`` 335- ``CUDA::nvjpeg_static`` 336 337.. _`cuda_toolkit_nvRTC`: 338 339nvRTC 340""""" 341 342The `nvRTC <https://docs.nvidia.com/cuda/nvrtc/index.html>`_ (Runtime Compilation) library. 343This is a shared library only. 344 345Targets Created: 346 347- ``CUDA::nvrtc`` 348 349.. _`cuda_toolkit_nvml`: 350 351nvidia-ML 352""""""""" 353 354The `NVIDIA Management Library <https://developer.nvidia.com/nvidia-management-library-nvml>`_. 355This is a shared library only. 356 357Targets Created: 358 359- ``CUDA::nvml`` 360 361.. _`cuda_toolkit_nvToolsExt`: 362 363nvToolsExt 364"""""""""" 365 366The `NVIDIA Tools Extension <https://docs.nvidia.com/gameworks/content/gameworkslibrary/nvtx/nvidia_tools_extension_library_nvtx.htm>`_. 367This is a shared library only. 368 369Targets Created: 370 371- ``CUDA::nvToolsExt`` 372 373.. _`cuda_toolkit_opencl`: 374 375OpenCL 376"""""" 377 378The `NVIDIA OpenCL Library <https://developer.nvidia.com/opencl>`_. 379This is a shared library only. 380 381Targets Created: 382 383- ``CUDA::OpenCL`` 384 385.. _`cuda_toolkit_cuLIBOS`: 386 387cuLIBOS 388""""""" 389 390The cuLIBOS library is a backend thread abstraction layer library which is 391static only. The ``CUDA::cublas_static``, ``CUDA::cusparse_static``, 392``CUDA::cufft_static``, ``CUDA::curand_static``, and (when implemented) NPP 393libraries all automatically have this dependency linked. 394 395Target Created: 396 397- ``CUDA::culibos`` 398 399**Note**: direct usage of this target by consumers should not be necessary. 400 401.. _`cuda_toolkit_cuRAND`: 402 403 404 405Result variables 406^^^^^^^^^^^^^^^^ 407 408``CUDAToolkit_FOUND`` 409 A boolean specifying whether or not the CUDA Toolkit was found. 410 411``CUDAToolkit_VERSION`` 412 The exact version of the CUDA Toolkit found (as reported by 413 ``nvcc --version`` or ``version.txt``). 414 415``CUDAToolkit_VERSION_MAJOR`` 416 The major version of the CUDA Toolkit. 417 418``CUDAToolkit_VERSION_MINOR`` 419 The minor version of the CUDA Toolkit. 420 421``CUDAToolkit_VERSION_PATCH`` 422 The patch version of the CUDA Toolkit. 423 424``CUDAToolkit_BIN_DIR`` 425 The path to the CUDA Toolkit library directory that contains the CUDA 426 executable ``nvcc``. 427 428``CUDAToolkit_INCLUDE_DIRS`` 429 The path to the CUDA Toolkit ``include`` folder containing the header files 430 required to compile a project linking against CUDA. 431 432``CUDAToolkit_LIBRARY_DIR`` 433 The path to the CUDA Toolkit library directory that contains the CUDA 434 Runtime library ``cudart``. 435 436``CUDAToolkit_LIBRARY_ROOT`` 437 .. versionadded:: 3.18 438 439 The path to the CUDA Toolkit directory containing the nvvm directory and 440 version.txt. 441 442``CUDAToolkit_TARGET_DIR`` 443 The path to the CUDA Toolkit directory including the target architecture 444 when cross-compiling. When not cross-compiling this will be equivalent to 445 the parent directory of ``CUDAToolkit_BIN_DIR``. 446 447``CUDAToolkit_NVCC_EXECUTABLE`` 448 The path to the NVIDIA CUDA compiler ``nvcc``. Note that this path may 449 **not** be the same as 450 :variable:`CMAKE_CUDA_COMPILER <CMAKE_<LANG>_COMPILER>`. ``nvcc`` must be 451 found to determine the CUDA Toolkit version as well as determining other 452 features of the Toolkit. This variable is set for the convenience of 453 modules that depend on this one. 454 455 456#]=======================================================================] 457 458# NOTE: much of this was simply extracted from FindCUDA.cmake. 459 460# James Bigler, NVIDIA Corp (nvidia.com - jbigler) 461# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html 462# 463# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved. 464# 465# Copyright (c) 2007-2009 466# Scientific Computing and Imaging Institute, University of Utah 467# 468# This code is licensed under the MIT License. See the FindCUDA.cmake script 469# for the text of the license. 470 471# The MIT License 472# 473# License for the specific language governing rights and limitations under 474# Permission is hereby granted, free of charge, to any person obtaining a 475# copy of this software and associated documentation files (the "Software"), 476# to deal in the Software without restriction, including without limitation 477# the rights to use, copy, modify, merge, publish, distribute, sublicense, 478# and/or sell copies of the Software, and to permit persons to whom the 479# Software is furnished to do so, subject to the following conditions: 480# 481# The above copyright notice and this permission notice shall be included 482# in all copies or substantial portions of the Software. 483# 484# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 485# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 486# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 487# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 488# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 489# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 490# DEALINGS IN THE SOFTWARE. 491# 492############################################################################### 493 494# The toolkit is located during compiler detection for CUDA and stored in CMakeCUDACompiler.cmake as 495# CMAKE_CUDA_COMPILER_TOOLKIT_ROOT and CMAKE_CUDA_COMPILER_LIBRARY_ROOT. 496# We compute the rest based on those here to avoid re-searching and to avoid finding a possibly 497# different installation. 498if(CMAKE_CUDA_COMPILER_TOOLKIT_ROOT) 499 set(CUDAToolkit_ROOT_DIR "${CMAKE_CUDA_COMPILER_TOOLKIT_ROOT}") 500 set(CUDAToolkit_LIBRARY_ROOT "${CMAKE_CUDA_COMPILER_LIBRARY_ROOT}") 501 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_ROOT_DIR}/bin") 502 set(CUDAToolkit_NVCC_EXECUTABLE "${CUDAToolkit_BIN_DIR}/nvcc${CMAKE_EXECUTABLE_SUFFIX}") 503else() 504 505 function(_CUDAToolkit_find_root_dir ) 506 cmake_parse_arguments(arg "" "" "SEARCH_PATHS;FIND_FLAGS" ${ARGN}) 507 508 509 if(NOT CUDAToolkit_BIN_DIR) 510 if(NOT CUDAToolkit_SENTINEL_FILE) 511 find_program(CUDAToolkit_NVCC_EXECUTABLE 512 NAMES nvcc nvcc.exe 513 PATHS ${arg_SEARCH_PATHS} 514 ${arg_FIND_FLAGS} 515 ) 516 endif() 517 518 if(NOT CUDAToolkit_NVCC_EXECUTABLE) 519 find_file(CUDAToolkit_SENTINEL_FILE 520 NAMES version.txt 521 PATHS ${arg_SEARCH_PATHS} 522 NO_DEFAULT_PATH 523 ) 524 endif() 525 526 if(EXISTS "${CUDAToolkit_NVCC_EXECUTABLE}") 527 # If NVCC exists then invoke it to find the toolkit location. 528 # This allows us to support wrapper scripts (e.g. ccache or colornvcc), CUDA Toolkit, 529 # NVIDIA HPC SDK, and distro's splayed layouts 530 execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "-v" "__cmake_determine_cuda" 531 OUTPUT_VARIABLE _CUDA_NVCC_OUT ERROR_VARIABLE _CUDA_NVCC_OUT) 532 if(_CUDA_NVCC_OUT MATCHES "\\#\\$ TOP=([^\r\n]*)") 533 get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_MATCH_1}/bin" ABSOLUTE) 534 else() 535 get_filename_component(CUDAToolkit_BIN_DIR "${CUDAToolkit_NVCC_EXECUTABLE}" DIRECTORY) 536 endif() 537 unset(_CUDA_NVCC_OUT) 538 539 mark_as_advanced(CUDAToolkit_BIN_DIR) 540 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE) 541 endif() 542 543 if(CUDAToolkit_SENTINEL_FILE) 544 get_filename_component(CUDAToolkit_BIN_DIR ${CUDAToolkit_SENTINEL_FILE} DIRECTORY ABSOLUTE) 545 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}/bin") 546 547 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "" FORCE) 548 mark_as_advanced(CUDAToolkit_BIN_DIR) 549 endif() 550 endif() 551 552 if(CUDAToolkit_BIN_DIR) 553 get_filename_component(CUDAToolkit_ROOT_DIR ${CUDAToolkit_BIN_DIR} DIRECTORY ABSOLUTE) 554 set(CUDAToolkit_ROOT_DIR "${CUDAToolkit_ROOT_DIR}" PARENT_SCOPE) 555 endif() 556 557 endfunction() 558 559 function(_CUDAToolkit_find_version_file result_variable) 560 # We first check for a non-scattered installation to prefer it over a scattered installation. 561 if(CUDAToolkit_ROOT AND EXISTS "${CUDAToolkit_ROOT}/version.txt") 562 set(${result_variable} "${CUDAToolkit_ROOT}/version.txt" PARENT_SCOPE) 563 elseif(CUDAToolkit_ROOT_DIR AND EXISTS "${CUDAToolkit_ROOT_DIR}/version.txt") 564 set(${result_variable} "${CUDAToolkit_ROOT_DIR}/version.txt" PARENT_SCOPE) 565 elseif(CMAKE_SYSROOT_LINK AND EXISTS "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt") 566 set(${result_variable} "${CMAKE_SYSROOT_LINK}/usr/lib/cuda/version.txt" PARENT_SCOPE) 567 elseif(EXISTS "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt") 568 set(${result_variable} "${CMAKE_SYSROOT}/usr/lib/cuda/version.txt" PARENT_SCOPE) 569 endif() 570 endfunction() 571 572 # For NVCC we can easily deduce the SDK binary directory from the compiler path. 573 if(CMAKE_CUDA_COMPILER_LOADED AND NOT CUDAToolkit_BIN_DIR AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA") 574 get_filename_component(CUDAToolkit_BIN_DIR "${CMAKE_CUDA_COMPILER}" DIRECTORY) 575 set(CUDAToolkit_BIN_DIR "${CUDAToolkit_BIN_DIR}" CACHE PATH "") 576 # Try language provided path first. 577 _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_BIN_DIR}" FIND_FLAGS NO_DEFAULT_PATH) 578 mark_as_advanced(CUDAToolkit_BIN_DIR) 579 endif() 580 581 # Try user provided path 582 if(NOT CUDAToolkit_ROOT_DIR AND CUDAToolkit_ROOT) 583 _CUDAToolkit_find_root_dir(SEARCH_PATHS "${CUDAToolkit_ROOT}" FIND_FLAGS PATH_SUFFIXES bin NO_DEFAULT_PATH) 584 endif() 585 if(NOT CUDAToolkit_ROOT_DIR) 586 _CUDAToolkit_find_root_dir(FIND_FLAGS PATHS ENV CUDA_PATH PATH_SUFFIXES bin) 587 endif() 588 589 # If the user specified CUDAToolkit_ROOT but the toolkit could not be found, this is an error. 590 if(NOT CUDAToolkit_ROOT_DIR AND (DEFINED CUDAToolkit_ROOT OR DEFINED ENV{CUDAToolkit_ROOT})) 591 # Declare error messages now, print later depending on find_package args. 592 set(fail_base "Could not find nvcc executable in path specified by") 593 set(cuda_root_fail "${fail_base} CUDAToolkit_ROOT=${CUDAToolkit_ROOT}") 594 set(env_cuda_root_fail "${fail_base} environment variable CUDAToolkit_ROOT=$ENV{CUDAToolkit_ROOT}") 595 596 if(CUDAToolkit_FIND_REQUIRED) 597 if(DEFINED CUDAToolkit_ROOT) 598 message(FATAL_ERROR ${cuda_root_fail}) 599 elseif(DEFINED ENV{CUDAToolkit_ROOT}) 600 message(FATAL_ERROR ${env_cuda_root_fail}) 601 endif() 602 else() 603 if(NOT CUDAToolkit_FIND_QUIETLY) 604 if(DEFINED CUDAToolkit_ROOT) 605 message(STATUS ${cuda_root_fail}) 606 elseif(DEFINED ENV{CUDAToolkit_ROOT}) 607 message(STATUS ${env_cuda_root_fail}) 608 endif() 609 endif() 610 set(CUDAToolkit_FOUND FALSE) 611 unset(fail_base) 612 unset(cuda_root_fail) 613 unset(env_cuda_root_fail) 614 return() 615 endif() 616 endif() 617 618 # CUDAToolkit_ROOT cmake / env variable not specified, try platform defaults. 619 # 620 # - Linux: /usr/local/cuda-X.Y 621 # - macOS: /Developer/NVIDIA/CUDA-X.Y 622 # - Windows: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\vX.Y 623 # 624 # We will also search the default symlink location /usr/local/cuda first since 625 # if CUDAToolkit_ROOT is not specified, it is assumed that the symlinked 626 # directory is the desired location. 627 if(NOT CUDAToolkit_ROOT_DIR) 628 if(UNIX) 629 if(NOT APPLE) 630 set(platform_base "/usr/local/cuda-") 631 else() 632 set(platform_base "/Developer/NVIDIA/CUDA-") 633 endif() 634 else() 635 set(platform_base "C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v") 636 endif() 637 638 # Build out a descending list of possible cuda installations, e.g. 639 file(GLOB possible_paths "${platform_base}*") 640 # Iterate the glob results and create a descending list. 641 set(versions) 642 foreach(p ${possible_paths}) 643 # Extract version number from end of string 644 string(REGEX MATCH "[0-9][0-9]?\\.[0-9]$" p_version ${p}) 645 if(IS_DIRECTORY ${p} AND p_version) 646 list(APPEND versions ${p_version}) 647 endif() 648 endforeach() 649 650 # Sort numerically in descending order, so we try the newest versions first. 651 list(SORT versions COMPARE NATURAL ORDER DESCENDING) 652 653 # With a descending list of versions, populate possible paths to search. 654 set(search_paths) 655 foreach(v ${versions}) 656 list(APPEND search_paths "${platform_base}${v}") 657 endforeach() 658 659 # Force the global default /usr/local/cuda to the front on Unix. 660 if(UNIX) 661 list(INSERT search_paths 0 "/usr/local/cuda") 662 endif() 663 664 # Now search for the toolkit again using the platform default search paths. 665 _CUDAToolkit_find_root_dir(SEARCH_PATHS "${search_paths}" FIND_FLAGS PATH_SUFFIXES bin) 666 667 # We are done with these variables now, cleanup for caller. 668 unset(platform_base) 669 unset(possible_paths) 670 unset(versions) 671 unset(search_paths) 672 673 if(NOT CUDAToolkit_ROOT_DIR) 674 if(CUDAToolkit_FIND_REQUIRED) 675 message(FATAL_ERROR "Could not find nvcc, please set CUDAToolkit_ROOT.") 676 elseif(NOT CUDAToolkit_FIND_QUIETLY) 677 message(STATUS "Could not find nvcc, please set CUDAToolkit_ROOT.") 678 endif() 679 680 set(CUDAToolkit_FOUND FALSE) 681 return() 682 endif() 683 endif() 684 685 _CUDAToolkit_find_version_file( _CUDAToolkit_version_file ) 686 if(_CUDAToolkit_version_file) 687 # CUDAToolkit_LIBRARY_ROOT contains the device library and version file. 688 get_filename_component(CUDAToolkit_LIBRARY_ROOT "${_CUDAToolkit_version_file}" DIRECTORY ABSOLUTE) 689 endif() 690 unset(_CUDAToolkit_version_file) 691endif() 692 693# Find target directory when crosscompiling. 694if(CMAKE_CROSSCOMPILING) 695 if(CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7-a") 696 # Support for NVPACK 697 set(CUDAToolkit_TARGET_NAME "armv7-linux-androideabi") 698 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm") 699 set(CUDAToolkit_TARGET_NAME "armv7-linux-gnueabihf") 700 elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64") 701 if(ANDROID_ARCH_NAME STREQUAL "arm64") 702 set(CUDAToolkit_TARGET_NAME "aarch64-linux-androideabi") 703 elseif (CMAKE_SYSTEM_NAME STREQUAL "QNX") 704 set(CUDAToolkit_TARGET_NAME "aarch64-qnx") 705 else() 706 set(CUDAToolkit_TARGET_NAME "aarch64-linux") 707 endif(ANDROID_ARCH_NAME STREQUAL "arm64") 708 elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64") 709 set(CUDAToolkit_TARGET_NAME "x86_64-linux") 710 endif() 711 712 if(EXISTS "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") 713 set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}/targets/${CUDAToolkit_TARGET_NAME}") 714 # add known CUDA target root path to the set of directories we search for programs, libraries and headers 715 list(PREPEND CMAKE_FIND_ROOT_PATH "${CUDAToolkit_TARGET_DIR}") 716 717 # Mark that we need to pop the root search path changes after we have 718 # found all cuda libraries so that searches for our cross-compilation 719 # libraries work when another cuda sdk is in CMAKE_PREFIX_PATH or 720 # PATh 721 set(_CUDAToolkit_Pop_ROOT_PATH True) 722 endif() 723endif() 724 725# If not already set we can simply use the toolkit root or it's a scattered installation. 726if(NOT CUDAToolkit_TARGET_DIR) 727 # Not cross compiling 728 set(CUDAToolkit_TARGET_DIR "${CUDAToolkit_ROOT_DIR}") 729 # Now that we have the real ROOT_DIR, find components inside it. 730 list(APPEND CMAKE_PREFIX_PATH ${CUDAToolkit_ROOT_DIR}) 731 732 # Mark that we need to pop the prefix path changes after we have 733 # found the cudart library. 734 set(_CUDAToolkit_Pop_Prefix True) 735endif() 736 737# CUDAToolkit_TARGET_DIR always points to the directory containing the include directory. 738# On a scattered installation /usr, on a non-scattered something like /usr/local/cuda or /usr/local/cuda-10.2/targets/aarch64-linux. 739if(EXISTS "${CUDAToolkit_TARGET_DIR}/include/cuda_runtime.h") 740 set(CUDAToolkit_INCLUDE_DIR "${CUDAToolkit_TARGET_DIR}/include") 741elseif(NOT CUDAToolkit_FIND_QUIETLY) 742 message(STATUS "Unable to find cuda_runtime.h in \"${CUDAToolkit_TARGET_DIR}/include\" for CUDAToolkit_INCLUDE_DIR.") 743endif() 744 745# The NVHPC layout moves math library headers and libraries to a sibling directory. 746# Create a separate variable so this directory can be selectively added to math targets. 747if(NOT EXISTS "${CUDAToolkit_INCLUDE_DIR}/cublas_v2.h") 748 set(CUDAToolkit_MATH_INCLUDE_DIR "${CUDAToolkit_TARGET_DIR}/../../math_libs/include") 749 cmake_path(NORMAL_PATH CUDAToolkit_MATH_INCLUDE_DIR) 750 if(NOT EXISTS "${CUDAToolkit_MATH_INCLUDE_DIR}/cublas_v2.h") 751 if(NOT CUDAToolkit_FIND_QUIETLY) 752 message(STATUS "Unable to find cublas_v2.h in either \"${CUDAToolkit_INCLUDE_DIR}\" or \"${CUDAToolkit_MATH_INCLUDE_DIR}\"") 753 endif() 754 unset(CUDAToolkit_MATH_INCLUDE_DIR) 755 endif() 756endif() 757 758if(CUDAToolkit_NVCC_EXECUTABLE AND 759 CMAKE_CUDA_COMPILER_VERSION AND 760 CUDAToolkit_NVCC_EXECUTABLE STREQUAL CMAKE_CUDA_COMPILER) 761 # Need to set these based off the already computed CMAKE_CUDA_COMPILER_VERSION value 762 # This if statement will always match, but is used to provide variables for MATCH 1,2,3... 763 if(CMAKE_CUDA_COMPILER_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=]) 764 set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}") 765 set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}") 766 set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}") 767 set(CUDAToolkit_VERSION "${CMAKE_CUDA_COMPILER_VERSION}") 768 endif() 769elseif(CUDAToolkit_NVCC_EXECUTABLE) 770 # Compute the version by invoking nvcc 771 execute_process(COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT) 772 if(NVCC_OUT MATCHES [=[ V([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}") 777 endif() 778 unset(NVCC_OUT) 779else() 780 _CUDAToolkit_find_version_file(version_file) 781 if(version_file) 782 file(READ "${version_file}" VERSION_INFO) 783 if(VERSION_INFO MATCHES [=[CUDA Version ([0-9]+)\.([0-9]+)\.([0-9]+)]=]) 784 set(CUDAToolkit_VERSION_MAJOR "${CMAKE_MATCH_1}") 785 set(CUDAToolkit_VERSION_MINOR "${CMAKE_MATCH_2}") 786 set(CUDAToolkit_VERSION_PATCH "${CMAKE_MATCH_3}") 787 set(CUDAToolkit_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") 788 endif() 789 endif() 790endif() 791 792# Find the CUDA Runtime Library libcudart 793find_library(CUDA_CUDART 794 NAMES cudart 795 PATH_SUFFIXES lib64 lib/x64 796) 797find_library(CUDA_CUDART 798 NAMES cudart 799 PATH_SUFFIXES lib64/stubs lib/x64/stubs 800) 801 802if(NOT CUDA_CUDART AND NOT CUDAToolkit_FIND_QUIETLY) 803 message(STATUS "Unable to find cudart library.") 804endif() 805 806if(_CUDAToolkit_Pop_Prefix) 807 list(REMOVE_AT CMAKE_PREFIX_PATH -1) 808 unset(_CUDAToolkit_Pop_Prefix) 809endif() 810 811#----------------------------------------------------------------------------- 812# Perform version comparison and validate all required variables are set. 813include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) 814find_package_handle_standard_args(CUDAToolkit 815 REQUIRED_VARS 816 CUDAToolkit_INCLUDE_DIR 817 CUDA_CUDART 818 CUDAToolkit_BIN_DIR 819 VERSION_VAR 820 CUDAToolkit_VERSION 821) 822 823unset(CUDAToolkit_ROOT_DIR) 824mark_as_advanced(CUDA_CUDART 825 CUDAToolkit_INCLUDE_DIR 826 CUDAToolkit_NVCC_EXECUTABLE 827 CUDAToolkit_SENTINEL_FILE 828 ) 829 830#----------------------------------------------------------------------------- 831# Construct result variables 832if(CUDAToolkit_FOUND) 833 set(CUDAToolkit_INCLUDE_DIRS ${CUDAToolkit_INCLUDE_DIR}) 834 get_filename_component(CUDAToolkit_LIBRARY_DIR ${CUDA_CUDART} DIRECTORY ABSOLUTE) 835endif() 836 837#----------------------------------------------------------------------------- 838# Construct import targets 839if(CUDAToolkit_FOUND) 840 841 function(_CUDAToolkit_find_and_add_import_lib lib_name) 842 cmake_parse_arguments(arg "" "" "ALT;DEPS;EXTRA_PATH_SUFFIXES" ${ARGN}) 843 844 set(search_names ${lib_name} ${arg_ALT}) 845 846 find_library(CUDA_${lib_name}_LIBRARY 847 NAMES ${search_names} 848 HINTS ${CUDAToolkit_LIBRARY_DIR} 849 ENV CUDA_PATH 850 PATH_SUFFIXES nvidia/current lib64 lib/x64 lib 851 ${arg_EXTRA_PATH_SUFFIXES} 852 ) 853 # Don't try any stub directories until we have exhausted all other 854 # search locations. 855 find_library(CUDA_${lib_name}_LIBRARY 856 NAMES ${search_names} 857 HINTS ${CUDAToolkit_LIBRARY_DIR} 858 ENV CUDA_PATH 859 PATH_SUFFIXES lib64/stubs lib/x64/stubs lib/stubs stubs 860 # Support NVHPC splayed math library layout 861 ../../math_libs/${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}/lib64 862 ../../math_libs/lib64 863 ) 864 865 mark_as_advanced(CUDA_${lib_name}_LIBRARY) 866 867 if (NOT TARGET CUDA::${lib_name} AND CUDA_${lib_name}_LIBRARY) 868 add_library(CUDA::${lib_name} UNKNOWN IMPORTED) 869 target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}") 870 if(DEFINED CUDAToolkit_MATH_INCLUDE_DIR) 871 string(FIND ${CUDA_${lib_name}_LIBRARY} "math_libs" math_libs) 872 if(NOT ${math_libs} EQUAL -1) 873 target_include_directories(CUDA::${lib_name} SYSTEM INTERFACE "${CUDAToolkit_MATH_INCLUDE_DIR}") 874 endif() 875 endif() 876 set_property(TARGET CUDA::${lib_name} PROPERTY IMPORTED_LOCATION "${CUDA_${lib_name}_LIBRARY}") 877 foreach(dep ${arg_DEPS}) 878 if(TARGET CUDA::${dep}) 879 target_link_libraries(CUDA::${lib_name} INTERFACE CUDA::${dep}) 880 endif() 881 endforeach() 882 endif() 883 endfunction() 884 885 if(NOT TARGET CUDA::toolkit) 886 add_library(CUDA::toolkit IMPORTED INTERFACE) 887 target_include_directories(CUDA::toolkit SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}") 888 target_link_directories(CUDA::toolkit INTERFACE "${CUDAToolkit_LIBRARY_DIR}") 889 endif() 890 891 _CUDAToolkit_find_and_add_import_lib(cuda_driver ALT cuda) 892 893 _CUDAToolkit_find_and_add_import_lib(cudart) 894 _CUDAToolkit_find_and_add_import_lib(cudart_static) 895 896 # setup dependencies that are required for cudart_static when building 897 # on linux. These are generally only required when using the CUDA toolkit 898 # when CUDA language is disabled 899 if(NOT TARGET CUDA::cudart_static_deps 900 AND TARGET CUDA::cudart_static) 901 902 add_library(CUDA::cudart_static_deps IMPORTED INTERFACE) 903 target_link_libraries(CUDA::cudart_static INTERFACE CUDA::cudart_static_deps) 904 905 if(UNIX AND (CMAKE_C_COMPILER OR CMAKE_CXX_COMPILER)) 906 find_package(Threads REQUIRED) 907 target_link_libraries(CUDA::cudart_static_deps INTERFACE Threads::Threads ${CMAKE_DL_LIBS}) 908 endif() 909 910 if(UNIX AND NOT APPLE AND NOT (CMAKE_SYSTEM_NAME STREQUAL "QNX")) 911 # On Linux, you must link against librt when using the static cuda runtime. 912 find_library(CUDAToolkit_rt_LIBRARY rt) 913 mark_as_advanced(CUDAToolkit_rt_LIBRARY) 914 if(NOT CUDAToolkit_rt_LIBRARY) 915 message(WARNING "Could not find librt library, needed by CUDA::cudart_static") 916 else() 917 target_link_libraries(CUDA::cudart_static_deps INTERFACE ${CUDAToolkit_rt_LIBRARY}) 918 endif() 919 endif() 920 endif() 921 922 _CUDAToolkit_find_and_add_import_lib(culibos) # it's a static library 923 foreach (cuda_lib cublasLt cublas cufft curand cusparse nppc nvjpeg) 924 _CUDAToolkit_find_and_add_import_lib(${cuda_lib}) 925 _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS culibos) 926 endforeach() 927 928 # cuFFTW depends on cuFFT 929 _CUDAToolkit_find_and_add_import_lib(cufftw DEPS cufft) 930 _CUDAToolkit_find_and_add_import_lib(cufftw DEPS cufft_static) 931 932 # cuSOLVER depends on cuBLAS, and cuSPARSE 933 _CUDAToolkit_find_and_add_import_lib(cusolver DEPS cublas cusparse) 934 _CUDAToolkit_find_and_add_import_lib(cusolver_static DEPS cublas_static cusparse_static culibos) 935 936 # nvGRAPH depends on cuRAND, and cuSOLVER. 937 _CUDAToolkit_find_and_add_import_lib(nvgraph DEPS curand cusolver) 938 _CUDAToolkit_find_and_add_import_lib(nvgraph_static DEPS curand_static cusolver_static) 939 940 # Process the majority of the NPP libraries. 941 foreach (cuda_lib nppial nppicc nppidei nppif nppig nppim nppist nppitc npps nppicom nppisu) 942 _CUDAToolkit_find_and_add_import_lib(${cuda_lib} DEPS nppc) 943 _CUDAToolkit_find_and_add_import_lib(${cuda_lib}_static DEPS nppc_static) 944 endforeach() 945 946 _CUDAToolkit_find_and_add_import_lib(cupti 947 EXTRA_PATH_SUFFIXES ../extras/CUPTI/lib64/ 948 ../extras/CUPTI/lib/) 949 _CUDAToolkit_find_and_add_import_lib(cupti_static 950 EXTRA_PATH_SUFFIXES ../extras/CUPTI/lib64/ 951 ../extras/CUPTI/lib/) 952 953 _CUDAToolkit_find_and_add_import_lib(nvrtc DEPS cuda_driver) 954 955 _CUDAToolkit_find_and_add_import_lib(nvml ALT nvidia-ml nvml) 956 957 if(WIN32) 958 # nvtools can be installed outside the CUDA toolkit directory 959 # so prefer the NVTOOLSEXT_PATH windows only environment variable 960 # In addition on windows the most common name is nvToolsExt64_1 961 find_library(CUDA_nvToolsExt_LIBRARY 962 NAMES nvToolsExt64_1 nvToolsExt64 nvToolsExt 963 PATHS ENV NVTOOLSEXT_PATH 964 ENV CUDA_PATH 965 PATH_SUFFIXES lib/x64 lib 966 ) 967 endif() 968 _CUDAToolkit_find_and_add_import_lib(nvToolsExt ALT nvToolsExt64) 969 970 _CUDAToolkit_find_and_add_import_lib(OpenCL) 971endif() 972 973if(_CUDAToolkit_Pop_ROOT_PATH) 974 list(REMOVE_AT CMAKE_FIND_ROOT_PATH 0) 975 unset(_CUDAToolkit_Pop_ROOT_PATH) 976endif() 977