|
| 1 | +# Detect CUDA devices in the system and set up proper NVCC flags |
| 2 | +# |
| 3 | +# Usage: |
| 4 | +# find_package(CUDADevice [X.Y] [REQUIRED]) |
| 5 | +# |
| 6 | +# This module looks for CUDA devices that support at least compute |
| 7 | +# capabilities X.Y, or all CUDA capable devices if the version is omitted. |
| 8 | +# It will gather the necessary compile flags for the minimum architecture |
| 9 | +# to support X.Y (if specified), and for all devices detected in the system. |
| 10 | +# |
| 11 | +# If no suitable CUDA devices are found and REQUIRED is used, a fatal |
| 12 | +# error is raised. |
| 13 | +# |
| 14 | +# The following variables will be set: |
| 15 | +# |
| 16 | +# CUDADEVICE_FOUND - system has CUDA device(s) |
| 17 | +# CUDADEVICE_NVCC_FLAGS - Compile flags for NVCC |
| 18 | +# |
| 19 | +# |
| 20 | +# Copyright 2016 Fraunhofer FKIE |
| 21 | +# |
| 22 | +# Redistribution and use in source and binary forms, with or without |
| 23 | +# modification, are permitted provided that the following conditions |
| 24 | +# are met: |
| 25 | +# |
| 26 | +# * Redistributions of source code must retain the above copyright |
| 27 | +# notice, this list of conditions and the following disclaimer. |
| 28 | +# * Redistributions in binary form must reproduce the above copyright |
| 29 | +# notice, this list of conditions and the following disclaimer in the |
| 30 | +# documentation and/or other materials provided with the distribution. |
| 31 | +# * Neither the name of the Fraunhofer organization nor the names of its |
| 32 | +# contributors may be used to endorse or promote products derived from |
| 33 | +# this software without specific prior written permission. |
| 34 | +# |
| 35 | +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS |
| 36 | +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
| 37 | +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
| 38 | +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 39 | +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 40 | +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
| 41 | +# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 42 | +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 43 | +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 44 | +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 45 | +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 46 | +# |
| 47 | +unset(CUDADEVICE_FOUND) |
| 48 | +unset(CUDADEVICE_NVCC_FLAGS) |
| 49 | +set(__cuda_arch_list) |
| 50 | +if(NOT CMAKE_CROSSCOMPILING) |
| 51 | + set(__cufile "${PROJECT_BINARY_DIR}/detect_cuda_arch.cu") |
| 52 | + file(WRITE "${__cufile}" "" |
| 53 | + "#include <cstdio>\n" |
| 54 | + "int main()\n" |
| 55 | + "{\n" |
| 56 | + " int count = 0;\n" |
| 57 | + " if (cudaGetDeviceCount(&count) != cudaSuccess) return 1;\n" |
| 58 | + " if (count == 0) return 1;\n" |
| 59 | + " for (int device = 0; device < count; ++device)\n" |
| 60 | + " {\n" |
| 61 | + " cudaDeviceProp prop;\n" |
| 62 | + " if (cudaGetDeviceProperties(&prop, device) == cudaSuccess)\n" |
| 63 | + " {\n" |
| 64 | + " printf(\"%d.%d \", prop.major, prop.minor);\n" |
| 65 | + " }\n" |
| 66 | + " }\n" |
| 67 | + " return 0;\n" |
| 68 | + "}\n" |
| 69 | + ) |
| 70 | + execute_process(COMMAND "${CUDA_NVCC_EXECUTABLE}" "--run" "${__cufile}" "-ccbin" "${CMAKE_CXX_COMPILER}" |
| 71 | + WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/CMakeFiles/" |
| 72 | + RESULT_VARIABLE __nvcc_result |
| 73 | + OUTPUT_VARIABLE __nvcc_out |
| 74 | + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE |
| 75 | + ) |
| 76 | + if(__nvcc_result EQUAL 0) |
| 77 | + string(REPLACE " " ";" __nvcc_out "${__nvcc_out}") |
| 78 | + if(CUDADevice_FIND_VERSION) |
| 79 | + foreach(__cuda_arch ${__nvcc_out}) |
| 80 | + if(NOT __cuda_arch VERSION_LESS "${CUDADevice_FIND_VERSION}") |
| 81 | + list(APPEND __cuda_arch_list "${__cuda_arch}") |
| 82 | + endif() |
| 83 | + endforeach() |
| 84 | + else() |
| 85 | + set(__cuda_arch_list "${__nvcc_out}") |
| 86 | + endif() |
| 87 | + if(__cuda_arch_list) |
| 88 | + set(CUDADEVICE_FOUND TRUE) |
| 89 | + if(NOT CUDADevice_FIND_QUIET) |
| 90 | + message(STATUS "Found CUDA device(s) with compute capabilities ${__cuda_arch_list}") |
| 91 | + endif() |
| 92 | + endif() |
| 93 | + endif() |
| 94 | + unset(__nvcc_result) |
| 95 | + unset(__nvcc_out) |
| 96 | + unset(__cufile) |
| 97 | +endif() |
| 98 | + |
| 99 | +if(CUDADevice_FIND_VERSION) |
| 100 | + list(APPEND __cuda_arch_list ${CUDADevice_FIND_VERSION}) |
| 101 | +endif() |
| 102 | +list(REMOVE_DUPLICATES __cuda_arch_list) |
| 103 | +foreach(__cuda_arch ${__cuda_arch_list}) |
| 104 | + if(__cuda_arch STREQUAL "2.1") |
| 105 | + list(APPEND CUDADEVICE_NVCC_FLAGS "-gencode arch=compute_20,code=sm_21") |
| 106 | + else() |
| 107 | + string(REPLACE "." "" __cuda_arch "${__cuda_arch}") |
| 108 | + list(APPEND CUDADEVICE_NVCC_FLAGS "-gencode arch=compute_${__cuda_arch},code=sm_${__cuda_arch}") |
| 109 | + endif() |
| 110 | +endforeach() |
| 111 | +string(REPLACE ";" " " CUDADEVICE_NVCC_FLAGS "${CUDADEVICE_NVCC_FLAGS}") |
| 112 | +if(CUDADEVICE_NVCC_FLAGS AND NOT CUDADevice_FIND_QUIET) |
| 113 | + message(STATUS "CUDA NVCC device flags: ${CUDADEVICE_NVCC_FLAGS}") |
| 114 | +endif() |
| 115 | +unset(__cuda_arch_list) |
| 116 | +unset(__cuda_arch) |
| 117 | + |
| 118 | +if(NOT CUDADEVICE_FOUND AND CUDADevice_FIND_REQUIRED) |
| 119 | + message(FATAL_ERROR "This computer has no CUDA device with the required compute capabilities") |
| 120 | +endif() |
| 121 | + |
0 commit comments