VTKmDeviceAdapters.cmake 11.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
##============================================================================
##  Copyright (c) Kitware, Inc.
##  All rights reserved.
##  See LICENSE.txt for details.
##  This software is distributed WITHOUT ANY WARRANTY; without even
##  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
##  PURPOSE.  See the above copyright notice for more information.
##
##  Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
##  Copyright 2014 UT-Battelle, LLC.
##  Copyright 2014 Los Alamos National Security.
##
##  Under the terms of Contract DE-NA0003525 with NTESS,
##  the U.S. Government retains certain rights in this software.
##
##  Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
##  Laboratory (LANL), the U.S. Government retains certain rights in
##  this software.
##============================================================================

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#
function(vtkm_extract_real_library library real_library)
  if(NOT UNIX)
    set(${real_library} "${library}" PARENT_SCOPE)
    return()
  endif()

  #Read in the first 4 bytes and see if they are the ELF magic number
  set(_elf_magic "7f454c46")
  file(READ ${library} _hex_data OFFSET 0 LIMIT 4 HEX)
  if(_hex_data STREQUAL _elf_magic)
    #we have opened a elf binary so this is what
    #we should link too
    set(${real_library} "${library}" PARENT_SCOPE)
    return()
  endif()

  file(READ ${library} _data OFFSET 0 LIMIT 1024)
  if("${_data}" MATCHES "INPUT \\(([^(]+)\\)")
    #extract out the so name from REGEX MATCh command
    set(_proper_so_name "${CMAKE_MATCH_1}")

    #construct path to the real .so which is presumed to be in the same directory
    #as the input file
    get_filename_component(_so_dir "${library}" DIRECTORY)
    set(${real_library} "${_so_dir}/${_proper_so_name}" PARENT_SCOPE)
  else()
    #unable to determine what this library is so just hope everything works
    #add pass it unmodified.
    set(${real_library} "${library}" PARENT_SCOPE)
  endif()
endfunction()

54
55
56
if(VTKm_ENABLE_TBB AND NOT TARGET vtkm::tbb)
  find_package(TBB REQUIRED)

luz.paz's avatar
luz.paz committed
57
  # Workaround a bug in older versions of cmake prevents linking with UNKNOWN IMPORTED libraries
58
59
60
61
62
63
  # refer to CMake issue #17245
  if (CMAKE_VERSION VERSION_LESS 3.10)
    add_library(vtkm::tbb SHARED IMPORTED GLOBAL)
  else()
    add_library(vtkm::tbb UNKNOWN IMPORTED GLOBAL)
  endif()
64
65
66
67

  set_target_properties(vtkm::tbb PROPERTIES
      INTERFACE_INCLUDE_DIRECTORIES "${TBB_INCLUDE_DIRS}")

68
69
70
71
72
73
74
  if(EXISTS "${TBB_LIBRARY_RELEASE}")
    vtkm_extract_real_library("${TBB_LIBRARY_RELEASE}" real_path)
    set_property(TARGET vtkm::tbb APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
    set_target_properties(vtkm::tbb PROPERTIES
      IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
      IMPORTED_LOCATION_RELEASE "${real_path}"
      )
75
76
77
78
79
80
81
82
83
84
  elseif(EXISTS "${TBB_LIBRARY}")
    #When VTK-m is mixed with OSPray we could use the OSPray FindTBB file
    #which doesn't define TBB_LIBRARY_RELEASE but instead defined only
    #TBB_LIBRARY
    vtkm_extract_real_library("${TBB_LIBRARY}" real_path)
    set_property(TARGET vtkm::tbb APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
    set_target_properties(vtkm::tbb PROPERTIES
      IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
      IMPORTED_LOCATION_RELEASE "${real_path}"
      )
85
  endif()
86

87
88
89
90
91
92
93
94
  if(EXISTS "${TBB_LIBRARY_DEBUG}")
    vtkm_extract_real_library("${TBB_LIBRARY_DEBUG}" real_path)
    set_property(TARGET vtkm::tbb APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
    set_target_properties(vtkm::tbb PROPERTIES
      IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
      IMPORTED_LOCATION_DEBUG "${real_path}"
      )
  endif()
95
96
endif()

97

98
if(VTKm_ENABLE_OPENMP AND NOT TARGET vtkm::openmp)
99
  cmake_minimum_required(VERSION 3.9...3.12 FATAL_ERROR)
Larsen, Matthew's avatar
Larsen, Matthew committed
100
  find_package(OpenMP 4.0 REQUIRED COMPONENTS CXX QUIET)
101

102
  add_library(vtkm::openmp INTERFACE IMPORTED GLOBAL)
103
  if(OpenMP_CXX_FLAGS)
104
105
    set_property(TARGET vtkm::openmp
      APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:CXX>:${OpenMP_CXX_FLAGS}>)
106
107
108

    if(VTKm_ENABLE_CUDA)
      string(REPLACE ";" "," openmp_cuda_flags "-Xcompiler=${OpenMP_CXX_FLAGS}")
109
110
      set_property(TARGET vtkm::openmp
        APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:CUDA>:${openmp_cuda_flags}>)
111
    endif()
112
113
114
115
116
117
  endif()
  if(OpenMP_CXX_LIBRARIES)
    set_target_properties(vtkm::openmp PROPERTIES
      INTERFACE_LINK_LIBRARIES "${OpenMP_CXX_LIBRARIES}")
  endif()
endif()
118
119

if(VTKm_ENABLE_CUDA AND NOT TARGET vtkm::cuda)
120
  cmake_minimum_required(VERSION 3.9...3.12 FATAL_ERROR)
121
122
  enable_language(CUDA)

123
124
125
126
127
128
  #To work around https://gitlab.kitware.com/cmake/cmake/issues/17512
  #we need to fix the CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES variable
  if(${CMAKE_VERSION} VERSION_LESS 3.10 AND CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES)
    list(APPEND CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES "${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}")
  endif()

luz.paz's avatar
luz.paz committed
129
  # Workaround a bug in older versions of cmake prevents linking with UNKNOWN IMPORTED libraries
130
131
132
133
134
135
  # refer to CMake issue #17245
  if (CMAKE_VERSION VERSION_LESS 3.10)
    add_library(vtkm::cuda STATIC IMPORTED GLOBAL)
  else()
    add_library(vtkm::cuda UNKNOWN IMPORTED GLOBAL)
  endif()
136

137
138
139
  set_target_properties(vtkm::cuda PROPERTIES
    INTERFACE_COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:CUDA>:--expt-relaxed-constexpr>
  )
140

141
142
  # We can't have this location/lib empty, so we provide a location that is
  # valid and will have no effect on compilation
143
144
145
  if("x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
    get_filename_component(VTKM_CUDA_BIN_DIR "${CMAKE_CUDA_COMPILER}" DIRECTORY)

146
147
148
149
150
    set_target_properties(vtkm::cuda PROPERTIES
        IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
        IMPORTED_LOCATION "${VTKM_CUDA_BIN_DIR}/../lib/x64/cudadevrt.lib"
        INTERFACE_INCLUDE_DIRECTORIES "${VTKM_CUDA_BIN_DIR}/../include/"
        )
151

152
  else()
153
154
    list(GET CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES 0 VTKM_CUDA_LIBRARY)
    if(IS_ABSOLUTE "${VTKM_CUDA_LIBRARY}")
155
      set_target_properties(vtkm::cuda PROPERTIES IMPORTED_LOCATION "${VTKM_CUDA_LIBRARY}")
156
157
158
159
160
161
    else()
      find_library(cuda_lib
              NAME ${VTKM_CUDA_LIBRARY}
              PATHS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}
              )
      set(VTKM_CUDA_LIBRARY ${cuda_lib})
162
      set_target_properties(vtkm::cuda PROPERTIES IMPORTED_LOCATION "${VTKM_CUDA_LIBRARY}")
163
164
165
      unset(cuda_lib CACHE)
    endif()
    set_target_properties(vtkm::cuda PROPERTIES
166
            IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
167
            INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}")
168
  endif()
169

170
171
  # add the -gencode flags so that all cuda code
  # way compiled properly
172
173

  #---------------------------------------------------------------------------
174
  # Populates CMAKE_CUDA_FLAGS with the best set of flags to compile for a
175
176
177
178
179
180
181
182
183
184
  # given GPU architecture. The majority of developers should leave the
  # option at the default of 'native' which uses system introspection to
  # determine the smallest numerous of virtual and real architectures it
  # should target.
  #
  # The option of 'all' is provided for people generating libraries that
  # will deployed to any number of machines, it will compile all CUDA code
  # for all major virtual architectures, guaranteeing that the code will run
  # anywhere.
  #
185
186
  # The option 'none' is provided so that when being built as part of another
  # project, its own custom flags can be used.
187
188
189
190
  #
  # 1 - native
  #   - Uses system introspection to determine compile flags
  # 2 - fermi
191
  #   - Uses: --generate-code=arch=compute_20,code=sm_20
192
  # 3 - kepler
193
194
  #   - Uses: --generate-code=arch=compute_30,code=sm_30
  #   - Uses: --generate-code=arch=compute_35,code=sm_35
195
  # 4 - maxwell
196
  #   - Uses: --generate-code=arch=compute_50,code=sm_50
197
  # 5 - pascal
198
  #   - Uses: --generate-code=arch=compute_60,code=sm_60
199
  # 6 - volta
200
  #   - Uses: --generate-code=arch=compute_70,code=sm_70
201
202
203
  # 7 - turing
  #   - Uses: --generate-code=arch=compute_75code=sm_75
  # 8 - all
204
205
206
207
208
  #   - Uses: --generate-code=arch=compute_30,code=sm_30
  #   - Uses: --generate-code=arch=compute_35,code=sm_35
  #   - Uses: --generate-code=arch=compute_50,code=sm_50
  #   - Uses: --generate-code=arch=compute_60,code=sm_60
  #   - Uses: --generate-code=arch=compute_70,code=sm_70
209
  #   - Uses: --generate-code=arch=compute_75,code=sm_75
210
  # 8 - none
211
212
213
214
  #

  #specify the property
  set(VTKm_CUDA_Architecture "native" CACHE STRING "Which GPU Architecture(s) to compile for")
215
  set_property(CACHE VTKm_CUDA_Architecture PROPERTY STRINGS native fermi kepler maxwell pascal volta turing all none)
216

luz.paz's avatar
luz.paz committed
217
  #detect what the property is set too
218
219
220
221
  if(VTKm_CUDA_Architecture STREQUAL "native")

    if(VTKM_CUDA_NATIVE_EXE_PROCESS_RAN_OUTPUT)
      #Use the cached value
222
      set(arch_flags ${VTKM_CUDA_NATIVE_EXE_PROCESS_RAN_OUTPUT})
223
224
225
226
227
228
229
230
231
232
233
234
    else()

      #run execute_process to do auto_detection
      if(CMAKE_GENERATOR MATCHES "Visual Studio")
        set(args "-ccbin" "${CMAKE_CXX_COMPILER}" "--run" "${VTKm_CMAKE_MODULE_PATH}/VTKmDetectCUDAVersion.cu")
      elseif(CUDA_HOST_COMPILER)
        set(args "-ccbin" "${CUDA_HOST_COMPILER}" "--run" "${VTKm_CMAKE_MODULE_PATH}/VTKmDetectCUDAVersion.cu")
      else()
        set(args "--run" "${VTKm_CMAKE_MODULE_PATH}/VTKmDetectCUDAVersion.cu")
      endif()

      execute_process(
235
              COMMAND ${CMAKE_CUDA_COMPILER} ${args}
236
237
238
239
240
241
242
243
244
245
246
              RESULT_VARIABLE ran_properly
              OUTPUT_VARIABLE run_output
              WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})

      if(ran_properly EQUAL 0)
        #find the position of the "--generate-code" output. With some compilers such as
        #msvc we get compile output plus run output. So we need to strip out just the
        #run output
        string(FIND "${run_output}" "--generate-code" position)
        string(SUBSTRING "${run_output}" ${position} -1 run_output)

247
        set(arch_flags ${run_output})
248
249
250
        set(VTKM_CUDA_NATIVE_EXE_PROCESS_RAN_OUTPUT ${run_output} CACHE INTERNAL
                "device type(s) for cuda[native]")
      else()
251
        set(VTKm_CUDA_Architecture "kepler")
252
253
254
255
      endif()
    endif()
  endif()

256
  #since when we are native we can fail, and fall back to "kepler" these have
257
258
  #to happen after, and separately of the native check
  if(VTKm_CUDA_Architecture STREQUAL "fermi")
259
    set(arch_flags --generate-code=arch=compute_20,code=sm_20)
260
  elseif(VTKm_CUDA_Architecture STREQUAL "kepler")
261
262
    set(arch_flags --generate-code=arch=compute_30,code=sm_30
                   --generate-code=arch=compute_35,code=sm_35)
263
  elseif(VTKm_CUDA_Architecture STREQUAL "maxwell")
264
    set(arch_flags --generate-code=arch=compute_50,code=sm_50)
265
  elseif(VTKm_CUDA_Architecture STREQUAL "pascal")
266
    set(arch_flags --generate-code=arch=compute_60,code=sm_60)
267
  elseif(VTKm_CUDA_Architecture STREQUAL "volta")
268
    set(arch_flags --generate-code=arch=compute_70,code=sm_70)
269
270
  elseif(VTKm_CUDA_Architecture STREQUAL "turing")
    set(arch_flags --generate-code=arch=compute_75,code=sm_75)
271
  elseif(VTKm_CUDA_Architecture STREQUAL "all")
272
273
274
275
    set(arch_flags --generate-code=arch=compute_30,code=sm_30
                   --generate-code=arch=compute_35,code=sm_35
                   --generate-code=arch=compute_50,code=sm_50
                   --generate-code=arch=compute_60,code=sm_60
276
277
                   --generate-code=arch=compute_70,code=sm_70
                   --generate-code=arch=compute_75,code=sm_75)
278
279
  endif()

280
281
282
283
284
  string(REPLACE ";" " " arch_flags "${arch_flags}")
  set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${arch_flags}")

  set_target_properties(vtkm::cuda PROPERTIES VTKm_CUDA_Architecture_Flags "${arch_flags}")

285
endif()