-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathFindTensorFlow.cmake
359 lines (316 loc) · 16 KB
/
FindTensorFlow.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
# Patrick Wieschollek, <mail@patwie.com>
# FindTensorFlow.cmake
# https://github.com/PatWie/tensorflow-cmake/blob/master/cmake/modules/FindTensorFlow.cmake
# -------------
#
# Find TensorFlow library and includes
#
# Automatically set variables have prefix "TensorFlow_",
# while environmental variables you can specify have prefix "TENSORFLOW_"
# This module will set the following variables in your project:
#
# ``TensorFlow_VERSION``
# exact TensorFlow version obtained from runtime
# ``TensorFlow_ABI``
# ABI specification of TensorFlow library obtained from runtime
# ``TensorFlow_INCLUDE_DIR``
# where to find tensorflow header files obtained from runtime
# ``TensorFlow_LIBRARY``
# the libraries to link against to use TENSORFLOW obtained from runtime
# ``TensorFlow_FOUND TRUE``
# If false, do not try to use TENSORFLOW.
# ``TensorFlow_C_LIBRARY``
# Path to tensorflow_cc library (libtensorflow[.so,.dylib,.dll], or similar)
#
# for some examples, you will need to specify on of the following cmake variables:
# ``TensorFlow_BUILD_DIR`` Is the directory containing the tensorflow_cc library, which can be initialized
# with env-var 'TENSORFLOW_BUILD_DIR' environmental variable
# ``TensorFlow_SOURCE_DIR`` Is the path to source of TensorFlow, which can be initialized
# with env-var 'TENSORFLOW_SOURCE_DIR' environmental variable
#
#
# USAGE
# ------
# add "list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}../../path/to/this/file)" to your project
#
# "add_tensorflow_gpu_operation" is a macro to compile a custom operation
#
# add_tensorflow_gpu_operation("<op-name>") expects the following files to exists:
# - kernels/<op-name>_kernel.cc
# - kernels/<op-name>_kernel_gpu.cu.cc (kernels/<op-name>_kernel.cu is supported as well)
# - kernels/<op-name>_op.cc
# - kernels/<op-name>_op.h
# - ops/<op-name>.cc
if(APPLE)
message(WARNING "This FindTensorflow.cmake is not tested on APPLE\n"
"Please report if this works\n"
"https://github.com/PatWie/tensorflow-cmake")
endif()
if(WIN32)
message(WARNING "This FindTensorflow.cmake is not tested on WIN32\n"
"Please report if this works\n"
"https://github.com/PatWie/tensorflow-cmake")
endif()
set(PYTHON_EXECUTABLE "python3" CACHE STRING "specify the python version TensorFlow is installed on.")
if(TensorFlow_FOUND AND EXISTS "${TensorFlow_LIBRARY}" AND IS_DIRECTORY "${TensorFlow_INCLUDE_DIR}")
# reuse cached variables
message(STATUS "Reuse cached information from TensorFlow ${TensorFlow_VERSION} ")
else()
message(STATUS "Detecting TensorFlow using ${PYTHON_EXECUTABLE}"
" (use -DPYTHON_EXECUTABLE=... otherwise)")
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "import tensorflow as tf; print(tf.__version__); print(tf.__cxx11_abi_flag__); print(tf.sysconfig.get_include()); print(tf.sysconfig.get_lib());"
OUTPUT_VARIABLE TF_INFORMATION_STRING
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE retcode)
if(NOT "${retcode}" STREQUAL "0")
message(FATAL_ERROR "Detecting TensorFlow info - failed \n Did you installed TensorFlow?")
else()
message(STATUS "Detecting TensorFlow info - done")
endif()
string(REPLACE "\n" ";" TF_INFORMATION_LIST ${TF_INFORMATION_STRING})
list(GET TF_INFORMATION_LIST 0 TF_DETECTED_VERSION)
list(GET TF_INFORMATION_LIST 1 TF_DETECTED_ABI)
list(GET TF_INFORMATION_LIST 2 TF_DETECTED_INCLUDE_DIR)
list(GET TF_INFORMATION_LIST 3 TF_DETECTED_LIBRARY_PATH)
# set(TF_DETECTED_VERSION 1.8)
set(_packageName "TF")
if (DEFINED TF_DETECTED_VERSION)
string (REGEX MATCHALL "[0-9]+" _versionComponents "${TF_DETECTED_VERSION}")
list (LENGTH _versionComponents _len)
if (${_len} GREATER 0)
list(GET _versionComponents 0 TF_DETECTED_VERSION_MAJOR)
endif()
if (${_len} GREATER 1)
list(GET _versionComponents 1 TF_DETECTED_VERSION_MINOR)
endif()
if (${_len} GREATER 2)
list(GET _versionComponents 2 TF_DETECTED_VERSION_PATCH)
endif()
if (${_len} GREATER 3)
list(GET _versionComponents 3 TF_DETECTED_VERSION_TWEAK)
endif()
set (TF_DETECTED_VERSION_COUNT ${_len})
else()
set (TF_DETECTED_VERSION_COUNT 0)
endif()
# -- prevent pre 1.9 versions
# Note: TensorFlow 1.7 supported custom ops and all header files.
# TensorFlow 1.8 broke that promise and 1.9, 1.10 are fine again.
# This cmake-file is only tested against 1.9+.
if("${TF_DETECTED_VERSION}" VERSION_LESS "1.9")
message(FATAL_ERROR "Your installed TensorFlow version ${TF_DETECTED_VERSION} is too old.")
endif()
if(TF_FIND_VERSION_EXACT)
# User requested exact match of TensorFlow.
# TensorFlow release cycles are currently just depending on (major, minor)
# But we test against both.
set(_TensorFlow_TEST_VERSIONS
"${TF_FIND_VERSION_MAJOR}.${TF_FIND_VERSION_MINOR}.${TF_FIND_VERSION_PATCH}"
"${TF_FIND_VERSION_MAJOR}.${TF_FIND_VERSION_MINOR}")
else() # TF_FIND_VERSION_EXACT
# User requested not an exact TensorFlow version.
# However, only TensorFlow versions 1.9, 1.10 support all header files
# for custom ops.
set(_TensorFlow_KNOWN_VERSIONS ${TensorFlow_ADDITIONAL_VERSIONS}
"1.9" "1.9.0" "1.10" "1.10.0" "1.11" "1.11.0" "1.12" "1.12.0" "1.13" "1.13.1")
set(_TensorFlow_TEST_VERSIONS)
if(TF_FIND_VERSION)
set(_TF_FIND_VERSION_SHORT "${TF_FIND_VERSION_MAJOR}.${TF_FIND_VERSION_MINOR}")
# Select acceptable versions.
foreach(version ${_TensorFlow_KNOWN_VERSIONS})
if(NOT "${version}" VERSION_LESS "${TF_FIND_VERSION}")
# This version is high enough.
list(APPEND _TensorFlow_TEST_VERSIONS "${version}")
endif()
endforeach()
else() # TF_FIND_VERSION
# Any version is acceptable.
set(_TensorFlow_TEST_VERSIONS "${_TensorFlow_KNOWN_VERSIONS}")
endif()
endif()
#### ---- Configure TensorFlow_SOURCE_DIR
# Order of precidence is 1) CMake variable value, 2) Environmental Variable value
if(IS_DIRECTORY "${TensorFlow_SOURCE_DIR}")
set(TensorFlow_SOURCE_DIR "${TensorFlow_SOURCE_DIR}" CACHE PATH "directory containing the file 'libtensorflow_cc${CMAKE_SHARED_LIBRARY_SUFFIX}'")
else()
if(IS_DIRECTORY "$ENV{TENSORFLOW_SOURCE_DIR}")
set(TensorFlow_SOURCE_DIR "$ENV{TENSORFLOW_SOURCE_DIR}" CACHE PATH "source code for tensorflow (i.e. the git checkout directory of the source code)")
else()
set(TensorFlow_SOURCE_DIR "TensorFlow_SOURCE_DIR-NOTFOUND" CACHE PATH "source code for tensorflow (i.e. the git checkout directory of the source code)")
endif()
endif()
# Report on status of cmake cache variable for TensorFlow_SOURCE_DIR
if(IS_DIRECTORY ${TensorFlow_SOURCE_DIR})
message(STATUS "TensorFlow_SOURCE_DIR is ${TensorFlow_SOURCE_DIR}")
else()
# NOTE This is not a fatal error for backward compatibility ("custom_op test")
message(STATUS "No directory at 'TensorFlow_SOURCE_DIR:PATH=${TensorFlow_SOURCE_DIR}' detected,\n"
"please specify the path in ENV 'export TENSORFLOW_SOURCE_DIR=...'\n or cmake -DTensorFlow_SOURCE_DIR:PATH=...\n"
"to the directory containing the source code for tensorflow\n (i.e. the git checkout directory of the source code)"
)
endif()
#### ---- Configure TensorFlow_BUILD_DIR
# Order of precidence is 1) CMake variable value, 2) Environmental Variable value
if(IS_DIRECTORY "${TensorFlow_BUILD_DIR}")
set(TensorFlow_BUILD_DIR "${TensorFlow_BUILD_DIR}" CACHE PATH "directory containing the file 'libtensorflow_cc${CMAKE_SHARED_LIBRARY_SUFFIX}'")
else()
if(IS_DIRECTORY "$ENV{TENSORFLOW_BUILD_DIR}")
set(TensorFlow_BUILD_DIR "$ENV{TENSORFLOW_BUILD_DIR}" CACHE PATH "directory containing the file 'libtensorflow_cc${CMAKE_SHARED_LIBRARY_SUFFIX}'")
else()
set(TensorFlow_BUILD_DIR "TensorFlow_BUILD_DIR-NOTFOUND" CACHE PATH "directory containing the file 'libtensorflow_cc${CMAKE_SHARED_LIBRARY_SUFFIX}'")
endif()
endif()
# Report on status of cmake cache variable for TensorFlow_BUILD_DIR
if(IS_DIRECTORY ${TensorFlow_BUILD_DIR})
message(STATUS "TensorFlow_BUILD_DIR is ${TensorFlow_BUILD_DIR}")
else()
# NOTE This is not a fatal error for backward compatibility ("custom_op test")
message(STATUS "No directory at 'TensorFlow_BUILD_DIR:PATH=${TensorFlow_BUILD_DIR}' detected,\n"
"please specify the path in ENV 'export TENSORFLOW_BUILD_DIR=...'\n or cmake -DTensorFlow_BUILD_DIR:PATH=...\n"
"to the directory containing the file 'libtensorflow_cc${CMAKE_SHARED_LIBRARY_SUFFIX}'"
)
endif()
if(IS_DIRECTORY ${TensorFlow_BUILD_DIR})
file(GLOB_RECURSE TF_LIBRARY_SEARCH_PATHS
LIST_DIRECTORIES FALSE
"${TensorFlow_BUILD_DIR}/*libtensorflow_cc${CMAKE_SHARED_LIBRARY_SUFFIX}"
)
list(LENGTH TF_LIBRARY_SEARCH_PATHS TF_LIBRARY_SEARCH_PATHS_LENGTH)
if( NOT ${TF_LIBRARY_SEARCH_PATHS_LENGTH} EQUAL 1 )
message(FATAL_ERROR "Incorrect number of items matching 'libtensorflow_cc${CMAKE_SHARED_LIBRARY_SUFFIX}' in '${TF_LIBRARY_SEARCH_PATHS}'\n"
"( ${TF_LIBRARY_SEARCH_PATHS_LENGTH} != 1 ).\n"
"Change 'TensorFlow_BUILD_DIR' to have more specific path."
)
endif()
list(GET TF_LIBRARY_SEARCH_PATHS 0 TF_LIBRARY_SEARCH_ONEPATH)
get_filename_component(TensorFlow_C_LIBRARY_DIR "${TF_LIBRARY_SEARCH_ONEPATH}" DIRECTORY )
if( IS_DIRECTORY "${TensorFlow_C_LIBRARY_DIR}")
find_library(TensorFlow_C_LIBRARY
NAMES tensorflow_cc
PATHS "${TensorFlow_C_LIBRARY_DIR}"
DOC "TensorFlow CC library." )
endif()
if( TensorFlow_C_LIBRARY )
message(STATUS "TensorFlow-CC-LIBRARY is ${TensorFlow_C_LIBRARY}")
else()
# NOTE This is not a fatal error for backward compatibility ("custom_op test")
message(STATUS "No TensorFlow-CC-LIBRARY detected")
endif()
endif()
find_library( TF_DETECTED_LIBRARY
NAMES tensorflow_framework
PATHS "${TensorFlow_C_LIBRARY_DIR}" # Prefer the library from the build tree, if TensorFlow_C_LIBRARY is detected.
"${TF_DETECTED_LIBRARY_PATH}" # use copy of file from the python install tree (This often has a .so.1 extension only for installed version)
DOC "The tensorflow_framework library path."
)
if( TF_DETECTED_LIBRARY )
message(STATUS "Found: ${TF_DETECTED_LIBRARY}")
else()
message(FATAL_ERROR "Required library for tensorflow_framework not found in ${TF_DETECTED_LIBRARY_PATH}!")
endif()
# test all given versions
set(TensorFlow_FOUND FALSE)
foreach(_TensorFlow_VER ${_TensorFlow_TEST_VERSIONS})
if("${TF_DETECTED_VERSION_MAJOR}.${TF_DETECTED_VERSION_MINOR}" STREQUAL "${_TensorFlow_VER}")
# found appropriate version
set(TensorFlow_VERSION ${TF_DETECTED_VERSION})
set(TensorFlow_ABI ${TF_DETECTED_ABI})
set(TensorFlow_INCLUDE_DIR ${TF_DETECTED_INCLUDE_DIR})
set(TensorFlow_LIBRARY ${TF_DETECTED_LIBRARY})
set(TensorFlow_FOUND TRUE)
message(STATUS "Found TensorFlow: (found appropriate version \"${TensorFlow_VERSION}\")")
message(STATUS "TensorFlow-ABI is ${TensorFlow_ABI}")
message(STATUS "TensorFlow-INCLUDE_DIR is ${TensorFlow_INCLUDE_DIR}")
message(STATUS "TensorFlow-LIBRARY is ${TensorFlow_LIBRARY}")
add_definitions("-DTENSORFLOW_ABI=${TensorFlow_ABI}")
add_definitions("-DTENSORFLOW_VERSION=${TensorFlow_VERSION}")
break()
endif()
endforeach()
if(NOT TensorFlow_FOUND)
message(FATAL_ERROR "Your installed TensorFlow version ${TF_DETECTED_VERSION_MAJOR}.${TF_DETECTED_VERSION_MINOR} is not supported\n"
"We tested against ${_TensorFlow_TEST_VERSIONS}")
endif()
# test 1.11 version
if("${TF_DETECTED_VERSION}" VERSION_EQUAL "1.11")
set(TF_DISABLE_ASSERTS "TRUE")
endif()
if("${TF_DETECTED_VERSION}" VERSION_EQUAL "1.12")
set(TF_DISABLE_ASSERTS "TRUE")
endif()
if("${TF_DETECTED_VERSION}" VERSION_EQUAL "1.12.0")
set(TF_DISABLE_ASSERTS "TRUE")
endif()
if("${TF_DETECTED_VERSION}" VERSION_EQUAL "1.13")
set(TF_DISABLE_ASSERTS "TRUE")
endif()
if("${TF_DETECTED_VERSION}" VERSION_EQUAL "1.13.1")
set(TF_DISABLE_ASSERTS "TRUE")
endif()
endif() #-- End detection
if(${TF_DISABLE_ASSERTS})
message(STATUS "[WARNING] The TensorFlow version ${TF_DETECTED_VERSION} has a bug (see \#22766). We disable asserts using -DNDEBUG=True ")
add_definitions("-DNDEBUG=True")
endif()
macro(TensorFlow_REQUIRE_C_LIBRARY)
if(NOT EXISTS "${TensorFlow_C_LIBRARY}")
message(FATAL_ERROR "Project requires libtensorflow_cc${CMAKE_SHARED_LIBRARY_SUFFIX}, please specify the path in ENV 'export TENSORFLOW_BUILD_DIR=...' or cmake -DTensorFlow_BUILD_DIR:PATH=...")
endif()
endmacro()
macro(TensorFlow_REQUIRE_SOURCE)
if(NOT IS_DIRECTORY "${TensorFlow_SOURCE_DIR}")
message(FATAL_ERROR "Project requires TensorFlow source directory, please specify the path in ENV 'export TENSORFLOW_SOURCE_DIR=...' or cmake -DTensorFlow_SOURCE_DIR:PATH=...")
endif()
endmacro()
macro(add_tensorflow_cpu_operation op_name)
# Compiles a CPU-only operation without invoking NVCC
message(STATUS "will build custom TensorFlow operation \"${op_name}\" (CPU only)")
add_library(${op_name}_op SHARED kernels/${op_name}_op.cc kernels/${op_name}_kernel.cc ops/${op_name}.cc )
set_target_properties(${op_name}_op PROPERTIES PREFIX "")
target_link_libraries(${op_name}_op LINK_PUBLIC ${TensorFlow_LIBRARY})
endmacro()
macro(add_tensorflow_gpu_operation op_name)
# Compiles a CPU + GPU operation with invoking NVCC
message(STATUS "will build custom TensorFlow operation \"${op_name}\" (CPU+GPU)")
set(kernel_file "")
if(EXISTS "kernels/${op_name}_kernel.cu")
message(WARNING "you should rename your file ${op_name}_kernel.cu to ${op_name}_kernel_gpu.cu.cc")
set(kernel_file kernels/${op_name}_kernel.cu)
else()
set_source_files_properties(kernels/${op_name}_kernel_gpu.cu.cc PROPERTIES CUDA_SOURCE_PROPERTY_FORMAT OBJ)
set(kernel_file kernels/${op_name}_kernel_gpu.cu.cc)
endif()
cuda_add_library(${op_name}_op_cu SHARED ${kernel_file})
set_target_properties(${op_name}_op_cu PROPERTIES PREFIX "")
add_library(${op_name}_op SHARED kernels/${op_name}_op.cc kernels/${op_name}_kernel.cc ops/${op_name}.cc )
set_target_properties(${op_name}_op PROPERTIES PREFIX "")
set_target_properties(${op_name}_op PROPERTIES COMPILE_FLAGS "-DGOOGLE_CUDA")
target_link_libraries(${op_name}_op LINK_PUBLIC ${op_name}_op_cu ${TensorFlow_LIBRARY})
endmacro()
# simplify TensorFlow dependencies
add_library(TensorFlow_DEP INTERFACE)
target_include_directories(TensorFlow_DEP SYSTEM INTERFACE ${TensorFlow_SOURCE_DIR})
target_include_directories(TensorFlow_DEP SYSTEM INTERFACE ${TensorFlow_INCLUDE_DIR})
target_link_libraries(TensorFlow_DEP INTERFACE -Wl,--allow-multiple-definition -Wl,--whole-archive ${TensorFlow_C_LIBRARY} -Wl,--no-whole-archive)
target_link_libraries(TensorFlow_DEP INTERFACE -Wl,--allow-multiple-definition -Wl,--whole-archive ${TensorFlow_LIBRARY} -Wl,--no-whole-archive)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(
TENSORFLOW
FOUND_VAR TENSORFLOW_FOUND
REQUIRED_VARS
TensorFlow_LIBRARY
TensorFlow_INCLUDE_DIR
VERSION_VAR
TensorFlow_VERSION
)
mark_as_advanced(TF_INFORMATION_STRING TF_DETECTED_VERSION TF_DETECTED_VERSION_MAJOR TF_DETECTED_VERSION_MINOR TF_DETECTED_VERSION TF_DETECTED_ABI
TF_DETECTED_INCLUDE_DIR TF_DETECTED_LIBRARY TF_DISABLE_ASSERTS
TensorFlow_C_LIBRARY TensorFlow_LIBRARY TensorFlow_SOURCE_DIR TensorFlow_INCLUDE_DIR TensorFlow_ABI)
set(TensorFlow_INCLUDE_DIR "${TensorFlow_INCLUDE_DIR}" CACHE PATH "The path to tensorflow header files")
set(TensorFlow_VERSION "${TensorFlow_VERSION}" CACHE INTERNAL "The Tensorflow version")
set(TensorFlow_ABI "${TensorFlow_ABI}" CACHE STRING "The ABI version used by TensorFlow")
set(TensorFlow_LIBRARY "${TensorFlow_LIBRARY}" CACHE FILEPATH "The C++ library of TensorFlow")
set(TensorFlow_C_LIBRARY "${TensorFlow_C_LIBRARY}" CACHE STRING "The C library of TensorFlow")
set(TensorFlow_FOUND "${TensorFlow_FOUND}" CACHE BOOL "A flag stating if TensorFlow has been found")
set(TF_DISABLE_ASSERTS "${TF_DISABLE_ASSERTS}" CACHE BOOL "A flag to enable workarounds")