-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathcuda.cmake
377 lines (345 loc) · 13.7 KB
/
cuda.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# ---[ cuda
# sccache is only supported in CMake master and not in the newest official
# release (3.11.3) yet. Hence we need our own Modules_CUDA_fix to enable sccache.
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../Modules_CUDA_fix)
# Find CUDA.
find_package(CUDA 7.0)
if(NOT CUDA_FOUND)
message(WARNING
"Caffe2: CUDA cannot be found. Depending on whether you are building "
"Caffe2 or a Caffe2 dependent library, the next warning / error will "
"give you more info.")
set(CAFFE2_USE_CUDA OFF)
return()
endif()
message(STATUS "Caffe2: CUDA detected: " ${CUDA_VERSION})
message(STATUS "Caffe2: CUDA nvcc is: " ${CUDA_NVCC_EXECUTABLE})
message(STATUS "Caffe2: CUDA toolkit directory: " ${CUDA_TOOLKIT_ROOT_DIR})
if(CUDA_FOUND)
# Sometimes, we may mismatch nvcc with the CUDA headers we are
# compiling with, e.g., if a ccache nvcc is fed to us by CUDA_NVCC_EXECUTABLE
# but the PATH is not consistent with CUDA_HOME. It's better safe
# than sorry: make sure everything is consistent.
set(file "${PROJECT_BINARY_DIR}/detect_cuda_version.cc")
file(WRITE ${file} ""
"#include <cuda.h>\n"
"#include <cstdio>\n"
"int main() {\n"
" printf(\"%d.%d\", CUDA_VERSION / 1000, (CUDA_VERSION / 10) % 100);\n"
" return 0;\n"
"}\n"
)
try_run(run_result compile_result ${PROJECT_BINARY_DIR} ${file}
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${CUDA_INCLUDE_DIRS}"
LINK_LIBRARIES ${CUDA_LIBRARIES}
RUN_OUTPUT_VARIABLE cuda_version_from_header
COMPILE_OUTPUT_VARIABLE output_var
)
if(NOT compile_result)
message(FATAL_ERROR "Caffe2: Couldn't determine version from header: " ${output_var})
endif()
message(STATUS "Caffe2: Header version is: " ${cuda_version_from_header})
if(NOT ${cuda_version_from_header} STREQUAL ${CUDA_VERSION})
# Force CUDA to be processed for again next time
# TODO: I'm not sure if this counts as an implementation detail of
# FindCUDA
set(${cuda_version_from_findcuda} ${CUDA_VERSION})
unset(CUDA_TOOLKIT_ROOT_DIR_INTERNAL CACHE)
# Not strictly necessary, but for good luck.
unset(CUDA_VERSION CACHE)
# Error out
message(FATAL_ERROR "FindCUDA says CUDA version is ${cuda_version_from_findcuda} (usually determined by nvcc), "
"but the CUDA headers say the version is ${cuda_version_from_header}. This often occurs "
"when you set both CUDA_HOME and CUDA_NVCC_EXECUTABLE to "
"non-standard locations, without also setting PATH to point to the correct nvcc. "
"Perhaps, try re-running this command again with PATH=${CUDA_TOOLKIT_ROOT_DIR}/bin:$PATH. "
"See above log messages for more diagnostics, and see https://github.com/pytorch/pytorch/issues/8092 for more details.")
endif()
endif()
# Find cuDNN.
if(CAFFE2_STATIC_LINK_CUDA)
SET(CUDNN_LIBNAME "libcudnn_static.a")
else()
SET(CUDNN_LIBNAME "cudnn")
endif()
include(FindPackageHandleStandardArgs)
if(DEFINED ENV{CUDNN_ROOT_DIR})
set(CUDNN_ROOT_DIR $ENV{CUDNN_ROOT_DIR} CACHE PATH "Folder contains NVIDIA cuDNN")
else()
set(CUDNN_ROOT_DIR "" CACHE PATH "Folder contains NVIDIA cuDNN")
endif()
if(DEFINED ENV{CUDNN_INCLUDE_DIR})
set(CUDNN_INCLUDE_DIR $ENV{CUDNN_INCLUDE_DIR})
else()
find_path(CUDNN_INCLUDE_DIR cudnn.h
HINTS ${CUDNN_ROOT_DIR} ${CUDA_TOOLKIT_ROOT_DIR}
PATH_SUFFIXES cuda/include include)
endif()
if(DEFINED ENV{CUDNN_LIBRARY})
set(CUDNN_LIBRARY $ENV{CUDNN_LIBRARY})
else()
find_library(CUDNN_LIBRARY ${CUDNN_LIBNAME}
HINTS ${CUDNN_ROOT_DIR} ${CUDA_TOOLKIT_ROOT_DIR}
PATH_SUFFIXES lib lib64 cuda/lib cuda/lib64 lib/x64)
endif()
find_package_handle_standard_args(
CUDNN DEFAULT_MSG CUDNN_INCLUDE_DIR CUDNN_LIBRARY)
if(NOT CUDNN_FOUND)
message(WARNING
"Caffe2: Cannot find cuDNN library. Turning the option off")
set(CAFFE2_USE_CUDNN OFF)
else()
set(CAFFE2_USE_CUDNN ON)
endif()
# Optionally, find TensorRT
if(CAFFE2_USE_TENSORRT)
find_path(TENSORRT_INCLUDE_DIR NvInfer.h
HINTS ${TENSORRT_ROOT} ${CUDA_TOOLKIT_ROOT_DIR}
PATH_SUFFIXES include)
find_library(TENSORRT_LIBRARY nvinfer
HINTS ${TENSORRT_ROOT} ${CUDA_TOOLKIT_ROOT_DIR}
PATH_SUFFIXES lib lib64 lib/x64)
find_package_handle_standard_args(
TENSORRT DEFAULT_MSG TENSORRT_INCLUDE_DIR TENSORRT_LIBRARY)
if(NOT TENSORRT_FOUND)
message(WARNING
"Caffe2: Cannot find TensorRT library. Turning the option off")
set(CAFFE2_USE_TENSORRT OFF)
endif()
endif()
# ---[ Extract versions
if(CAFFE2_USE_CUDNN)
# Get cuDNN version
file(READ ${CUDNN_INCLUDE_DIR}/cudnn.h CUDNN_HEADER_CONTENTS)
string(REGEX MATCH "define CUDNN_MAJOR * +([0-9]+)"
CUDNN_VERSION_MAJOR "${CUDNN_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUDNN_MAJOR * +([0-9]+)" "\\1"
CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR}")
string(REGEX MATCH "define CUDNN_MINOR * +([0-9]+)"
CUDNN_VERSION_MINOR "${CUDNN_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUDNN_MINOR * +([0-9]+)" "\\1"
CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR}")
string(REGEX MATCH "define CUDNN_PATCHLEVEL * +([0-9]+)"
CUDNN_VERSION_PATCH "${CUDNN_HEADER_CONTENTS}")
string(REGEX REPLACE "define CUDNN_PATCHLEVEL * +([0-9]+)" "\\1"
CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH}")
# Assemble cuDNN version
if(NOT CUDNN_VERSION_MAJOR)
set(CUDNN_VERSION "?")
else()
set(CUDNN_VERSION
"${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}")
endif()
message(STATUS "Found cuDNN: v${CUDNN_VERSION} (include: ${CUDNN_INCLUDE_DIR}, library: ${CUDNN_LIBRARY})")
endif()
# ---[ CUDA libraries wrapper
# find libcuda.so and lbnvrtc.so
# For libcuda.so, we will find it under lib, lib64, and then the
# stubs folder, in case we are building on a system that does not
# have cuda driver installed. On windows, we also search under the
# folder lib/x64.
find_library(CUDA_CUDA_LIB cuda
PATHS ${CUDA_TOOLKIT_ROOT_DIR}
PATH_SUFFIXES lib lib64 lib/stubs lib64/stubs lib/x64)
find_library(CUDA_NVRTC_LIB nvrtc
PATHS ${CUDA_TOOLKIT_ROOT_DIR}
PATH_SUFFIXES lib lib64 lib/x64)
# Create new style imported libraries.
# Several of these libraries have a hardcoded path if CAFFE2_STATIC_LINK_CUDA
# is set. This path is where sane CUDA installations have their static
# libraries installed. This flag should only be used for binary builds, so
# end-users should never have this flag set.
# cuda
add_library(caffe2::cuda UNKNOWN IMPORTED)
set_property(
TARGET caffe2::cuda PROPERTY IMPORTED_LOCATION
${CUDA_CUDA_LIB})
set_property(
TARGET caffe2::cuda PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${CUDA_INCLUDE_DIRS})
# cudart. CUDA_LIBRARIES is actually a list, so we will make an interface
# library.
add_library(caffe2::cudart INTERFACE IMPORTED)
if(CAFFE2_STATIC_LINK_CUDA)
set_property(
TARGET caffe2::cudart PROPERTY INTERFACE_LINK_LIBRARIES
"${CUDA_TOOLKIT_ROOT_DIR}/lib64/libcudart_static.a")
else()
set_property(
TARGET caffe2::cudart PROPERTY INTERFACE_LINK_LIBRARIES
${CUDA_LIBRARIES})
endif()
set_property(
TARGET caffe2::cudart PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${CUDA_INCLUDE_DIRS})
# cudnn
# static linking is handled by USE_STATIC_CUDNN environment variable
if(CAFFE2_USE_CUDNN)
add_library(caffe2::cudnn UNKNOWN IMPORTED)
set_property(
TARGET caffe2::cudnn PROPERTY IMPORTED_LOCATION
${CUDNN_LIBRARY})
set_property(
TARGET caffe2::cudnn PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${CUDNN_INCLUDE_DIR})
endif()
# curand
add_library(caffe2::curand UNKNOWN IMPORTED)
if(CAFFE2_STATIC_LINK_CUDA)
set_property(
TARGET caffe2::curand PROPERTY IMPORTED_LOCATION
"${CUDA_TOOLKIT_ROOT_DIR}/lib64/libcurand_static.a")
else()
set_property(
TARGET caffe2::curand PROPERTY IMPORTED_LOCATION
${CUDA_curand_LIBRARY})
endif()
set_property(
TARGET caffe2::curand PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${CUDA_INCLUDE_DIRS})
# cufft. CUDA_CUFFT_LIBRARIES is actually a list, so we will make an
# interface library similar to cudart.
add_library(caffe2::cufft INTERFACE IMPORTED)
if(CAFFE2_STATIC_LINK_CUDA)
set_property(
TARGET caffe2::cufft PROPERTY INTERFACE_LINK_LIBRARIES
"${CUDA_TOOLKIT_ROOT_DIR}/lib64/libcufft_static.a")
else()
set_property(
TARGET caffe2::cufft PROPERTY INTERFACE_LINK_LIBRARIES
${CUDA_CUFFT_LIBRARIES})
endif()
set_property(
TARGET caffe2::cufft PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${CUDA_INCLUDE_DIRS})
# TensorRT
if(CAFFE2_USE_TENSORRT)
add_library(caffe2::tensorrt UNKNOWN IMPORTED)
set_property(
TARGET caffe2::tensorrt PROPERTY IMPORTED_LOCATION
${TENSORRT_LIBRARY})
set_property(
TARGET caffe2::tensorrt PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${TENSORRT_INCLUDE_DIR})
endif()
# cublas. CUDA_CUBLAS_LIBRARIES is actually a list, so we will make an
# interface library similar to cudart.
add_library(caffe2::cublas INTERFACE IMPORTED)
if(CAFFE2_STATIC_LINK_CUDA)
set_property(
TARGET caffe2::cublas PROPERTY INTERFACE_LINK_LIBRARIES
"${CUDA_TOOLKIT_ROOT_DIR}/lib64/libcublas_static.a")
else()
set_property(
TARGET caffe2::cublas PROPERTY INTERFACE_LINK_LIBRARIES
${CUDA_CUBLAS_LIBRARIES})
endif()
set_property(
TARGET caffe2::cublas PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${CUDA_INCLUDE_DIRS})
# nvrtc
add_library(caffe2::nvrtc UNKNOWN IMPORTED)
set_property(
TARGET caffe2::nvrtc PROPERTY IMPORTED_LOCATION
${CUDA_NVRTC_LIB})
set_property(
TARGET caffe2::nvrtc PROPERTY INTERFACE_INCLUDE_DIRECTORIES
${CUDA_INCLUDE_DIRS})
# Note: in theory, we can add similar dependent library wrappers. For
# now, Caffe2 only uses the above libraries, so we will only wrap
# these.
# Special care for windows platform: we know that 32-bit windows does not
# support cuda.
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
if(NOT (CMAKE_SIZEOF_VOID_P EQUAL 8))
message(FATAL_ERROR
"CUDA support not available with 32-bit windows. Did you "
"forget to set Win64 in the generator target?")
return()
endif()
endif()
if (${CUDA_VERSION} LESS 8.0) # CUDA 7.x
list(APPEND CUDA_NVCC_FLAGS "-D_MWAITXINTRIN_H_INCLUDED")
list(APPEND CUDA_NVCC_FLAGS "-D__STRICT_ANSI__")
elseif (${CUDA_VERSION} LESS 9.0) # CUDA 8.x
list(APPEND CUDA_NVCC_FLAGS "-D_MWAITXINTRIN_H_INCLUDED")
list(APPEND CUDA_NVCC_FLAGS "-D__STRICT_ANSI__")
# CUDA 8 may complain that sm_20 is no longer supported. Suppress the
# warning for now.
list(APPEND CUDA_NVCC_FLAGS "-Wno-deprecated-gpu-targets")
endif()
# Add onnx namepsace definition to nvcc
if (ONNX_NAMESPACE)
list(APPEND CUDA_NVCC_FLAGS "-DONNX_NAMESPACE=${ONNX_NAMESPACE}")
else()
list(APPEND CUDA_NVCC_FLAGS "-DONNX_NAMESPACE=onnx_c2")
endif()
# CUDA 9.0 & 9.1 require GCC version <= 5
# Although they support GCC 6, but a bug that wasn't fixed until 9.2 prevents
# them from compiling the std::tuple header of GCC 6.
# See Sec. 2.2.1 of
# https://developer.download.nvidia.com/compute/cuda/9.2/Prod/docs/sidebar/CUDA_Toolkit_Release_Notes.pdf
if ((CUDA_VERSION VERSION_EQUAL 9.0) OR
(CUDA_VERSION VERSION_GREATER 9.0 AND CUDA_VERSION VERSION_LESS 9.2))
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0 AND
CUDA_HOST_COMPILER STREQUAL CMAKE_C_COMPILER)
message(FATAL_ERROR
"CUDA ${CUDA_VERSION} is not compatible with std::tuple from GCC version "
">= 6. Please upgrade to CUDA 9.2 or use the following option to use "
"another version (for example): \n"
" -DCUDA_HOST_COMPILER=/usr/bin/gcc-5\n")
endif()
elseif (CUDA_VERSION VERSION_EQUAL 8.0)
# CUDA 8.0 requires GCC version <= 5
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND
NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0 AND
CUDA_HOST_COMPILER STREQUAL CMAKE_C_COMPILER)
message(FATAL_ERROR
"CUDA 8.0 is not compatible with GCC version >= 6. "
"Use the following option to use another version (for example): \n"
" -DCUDA_HOST_COMPILER=/usr/bin/gcc-5\n")
endif()
endif()
# setting nvcc arch flags
torch_cuda_get_nvcc_gencode_flag(NVCC_FLAGS_EXTRA)
list(APPEND CUDA_NVCC_FLAGS ${NVCC_FLAGS_EXTRA})
message(STATUS "Added CUDA NVCC flags for: ${NVCC_FLAGS_EXTRA}")
# disable some nvcc diagnostic that apears in boost, glog, glags, opencv, etc.
foreach(diag cc_clobber_ignored integer_sign_change useless_using_declaration set_but_not_used)
list(APPEND CUDA_NVCC_FLAGS -Xcudafe --diag_suppress=${diag})
endforeach()
# Set C++11 support
set(CUDA_PROPAGATE_HOST_FLAGS_BLACKLIST "-Werror")
if (NOT MSVC)
list(APPEND CUDA_NVCC_FLAGS "-std=c++11")
list(APPEND CUDA_NVCC_FLAGS "-Xcompiler -fPIC")
endif()
# Debug and Release symbol support
if (MSVC)
if ((${CMAKE_BUILD_TYPE} MATCHES "Release") OR (${CMAKE_BUILD_TYPE} MATCHES "RelWithDebInfo") OR (${CMAKE_BUILD_TYPE} MATCHES "MinSizeRel"))
if (${CAFFE2_USE_MSVC_STATIC_RUNTIME})
list(APPEND CUDA_NVCC_FLAGS "-Xcompiler" "-MT")
else()
list(APPEND CUDA_NVCC_FLAGS "-Xcompiler" "-MD")
endif()
elseif(${CMAKE_BUILD_TYPE} MATCHES "Debug")
message(FATAL_ERROR
"Caffe2 currently does not support the combination of MSVC, Cuda "
"and Debug mode. Either set USE_CUDA=OFF or set the build type "
"to Release")
if (${CAFFE2_USE_MSVC_STATIC_RUNTIME})
list(APPEND CUDA_NVCC_FLAGS "-Xcompiler" "-MTd")
else()
list(APPEND CUDA_NVCC_FLAGS "-Xcompiler" "-MDd")
endif()
else()
message(FATAL_ERROR "Unknown cmake build type: " ${CMAKE_BUILD_TYPE})
endif()
elseif (CUDA_DEVICE_DEBUG)
list(APPEND CUDA_NVCC_FLAGS "-g" "-G") # -G enables device code debugging symbols
endif()
# Set expt-relaxed-constexpr to suppress Eigen warnings
list(APPEND CUDA_NVCC_FLAGS "--expt-relaxed-constexpr")
# Set expt-extended-lambda to support lambda on device
list(APPEND CUDA_NVCC_FLAGS "--expt-extended-lambda")