xref: /aosp_15_r20/external/pytorch/cmake/Dependencies.cmake (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1# RPATH stuff
2# see https://cmake.org/Wiki/CMake_RPATH_handling
3if(APPLE)
4  set(CMAKE_MACOSX_RPATH ON)
5  set(_rpath_portable_origin "@loader_path")
6else()
7  set(_rpath_portable_origin $ORIGIN)
8endif(APPLE)
9# Use separate rpaths during build and install phases
10set(CMAKE_SKIP_BUILD_RPATH  FALSE)
11# Don't use the install-rpath during the build phase
12set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
13set(CMAKE_INSTALL_RPATH "${_rpath_portable_origin}")
14# Automatically add all linked folders that are NOT in the build directory to
15# the rpath (per library?)
16set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
17
18 # UBSAN triggers when compiling protobuf, so we need to disable it.
19set(UBSAN_FLAG "-fsanitize=undefined")
20
21macro(disable_ubsan)
22  if(CMAKE_C_FLAGS MATCHES ${UBSAN_FLAG} OR CMAKE_CXX_FLAGS MATCHES ${UBSAN_FLAG})
23    set(CAFFE2_UBSAN_ENABLED ON)
24    string(REPLACE ${UBSAN_FLAG} "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
25    string(REPLACE ${UBSAN_FLAG} "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
26  endif()
27endmacro()
28
29macro(enable_ubsan)
30  if(CAFFE2_UBSAN_ENABLED)
31    set(CMAKE_C_FLAGS "${UBSAN_FLAG} ${CMAKE_C_FLAGS}")
32    set(CMAKE_CXX_FLAGS "${UBSAN_FLAG} ${CMAKE_CXX_FLAGS}")
33  endif()
34endmacro()
35
36# ---[ CUDA
37if(USE_CUDA)
38  # public/*.cmake uses CAFFE2_USE_*
39  set(CAFFE2_USE_CUDA ${USE_CUDA})
40  set(CAFFE2_USE_CUDNN ${USE_CUDNN})
41  set(CAFFE2_USE_CUSPARSELT ${USE_CUSPARSELT})
42  set(CAFFE2_USE_CUFILE ${USE_CUFILE})
43  set(CAFFE2_USE_NVRTC ${USE_NVRTC})
44  include(${CMAKE_CURRENT_LIST_DIR}/public/cuda.cmake)
45  if(CAFFE2_USE_CUDA)
46    # A helper variable recording the list of Caffe2 dependent libraries
47    # torch::cudart is dealt with separately, due to CUDA_ADD_LIBRARY
48    # design reason (it adds CUDA_LIBRARIES itself).
49    set(Caffe2_PUBLIC_CUDA_DEPENDENCY_LIBS )
50    if(NOT CAFFE2_USE_NVRTC)
51      caffe2_update_option(USE_NVRTC OFF)
52    endif()
53    list(APPEND Caffe2_CUDA_DEPENDENCY_LIBS caffe2::curand caffe2::cufft caffe2::cublas)
54    if(CAFFE2_USE_CUDNN)
55      list(APPEND Caffe2_CUDA_DEPENDENCY_LIBS torch::cudnn)
56    else()
57      caffe2_update_option(USE_CUDNN OFF)
58    endif()
59    if(CAFFE2_USE_CUSPARSELT)
60      list(APPEND Caffe2_CUDA_DEPENDENCY_LIBS torch::cusparselt)
61    else()
62      caffe2_update_option(USE_CUSPARSELT OFF)
63    endif()
64    if(CAFFE2_USE_CUFILE)
65      list(APPEND Caffe2_CUDA_DEPENDENCY_LIBS torch::cufile)
66    endif()
67    find_program(SCCACHE_EXECUTABLE sccache)
68    if(SCCACHE_EXECUTABLE)
69      # Using RSP/--options-file renders output noncacheable by sccache
70      # as they fall under `multiple input files` non-cacheable rule
71      set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 0)
72      set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
73      set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0)
74    endif()
75  else()
76    message(WARNING
77      "Not compiling with CUDA. Suppress this warning with "
78      "-DUSE_CUDA=OFF.")
79    caffe2_update_option(USE_CUDA OFF)
80    caffe2_update_option(USE_CUDNN OFF)
81    caffe2_update_option(USE_CUSPARSELT OFF)
82    caffe2_update_option(USE_NVRTC OFF)
83    set(CAFFE2_USE_CUDA OFF)
84    set(CAFFE2_USE_CUDNN OFF)
85    set(CAFFE2_USE_CUSPARSELT OFF)
86    set(CAFFE2_USE_CUFILE OFF)
87    set(CAFFE2_USE_NVRTC OFF)
88  endif()
89endif()
90
91# ---[ XPU
92if(USE_XPU)
93  include(${CMAKE_CURRENT_LIST_DIR}/public/xpu.cmake)
94  if(NOT PYTORCH_FOUND_XPU)
95    message(WARNING "Not compiling with XPU. Could NOT find SYCL."
96    "Suppress this warning with -DUSE_XPU=OFF.")
97    caffe2_update_option(USE_XPU OFF)
98  else()
99    if(LINUX)
100      string(APPEND CMAKE_CXX_FLAGS " -D__INTEL_PREVIEW_BREAKING_CHANGES")
101    endif()
102  endif()
103endif()
104
105# ---[ Custom Protobuf
106if(CAFFE2_CMAKE_BUILDING_WITH_MAIN_REPO AND NOT INTERN_BUILD_MOBILE)
107  disable_ubsan()
108  include(${CMAKE_CURRENT_LIST_DIR}/ProtoBuf.cmake)
109  enable_ubsan()
110endif()
111
112if(USE_ASAN OR USE_TSAN)
113  find_package(Sanitizer REQUIRED)
114  if(USE_ASAN)
115    if(TARGET Sanitizer::address)
116      list(APPEND Caffe2_DEPENDENCY_LIBS Sanitizer::address)
117    else()
118      message(WARNING "Not ASAN found. Suppress this warning with -DUSE_ASAN=OFF.")
119      caffe2_update_option(USE_ASAN OFF)
120    endif()
121    if(TARGET Sanitizer::undefined)
122      list(APPEND Caffe2_DEPENDENCY_LIBS Sanitizer::undefined)
123    endif()
124  endif()
125  if(USE_TSAN)
126    if(TARGET Sanitizer::thread)
127      list(APPEND Caffe2_DEPENDENCY_LIBS Sanitizer::thread)
128    else()
129      message(WARNING "Not TSAN found. Suppress this warning with -DUSE_TSAN=OFF.")
130      caffe2_update_option(USE_TSAN OFF)
131    endif()
132  endif()
133endif()
134
135# ---[ Threads
136find_package(Threads REQUIRED)
137if(TARGET Threads::Threads)
138  list(APPEND Caffe2_DEPENDENCY_LIBS Threads::Threads)
139else()
140  message(FATAL_ERROR
141      "Cannot find threading library. PyTorch requires Threads to compile.")
142endif()
143
144# ---[ protobuf
145if(CAFFE2_CMAKE_BUILDING_WITH_MAIN_REPO)
146  if(USE_LITE_PROTO)
147    set(CAFFE2_USE_LITE_PROTO 1)
148  endif()
149endif()
150
151# ---[ BLAS
152
153set(AT_MKLDNN_ACL_ENABLED 0)
154set(AT_MKLDNN_ENABLED 0)
155set(AT_MKL_ENABLED 0)
156# setting default preferred BLAS options if not already present.
157if(NOT INTERN_BUILD_MOBILE)
158  set(BLAS "MKL" CACHE STRING "Selected BLAS library")
159else()
160  set(BLAS "Eigen" CACHE STRING "Selected BLAS library")
161  set(AT_MKLDNN_ENABLED 0)
162  set(AT_MKL_ENABLED 0)
163endif()
164set_property(CACHE BLAS PROPERTY STRINGS "ATLAS;BLIS;Eigen;FLAME;Generic;MKL;OpenBLAS;vecLib")
165message(STATUS "Trying to find preferred BLAS backend of choice: " ${BLAS})
166
167if(BLAS STREQUAL "Eigen")
168  # Eigen is header-only and we do not have any dependent libraries
169  set(CAFFE2_USE_EIGEN_FOR_BLAS ON)
170elseif(BLAS STREQUAL "ATLAS")
171  find_package(Atlas REQUIRED)
172  include_directories(SYSTEM ${ATLAS_INCLUDE_DIRS})
173  list(APPEND Caffe2_DEPENDENCY_LIBS ${ATLAS_LIBRARIES})
174  list(APPEND Caffe2_DEPENDENCY_LIBS cblas)
175  set(BLAS_INFO "atlas")
176  set(BLAS_FOUND 1)
177  set(BLAS_LIBRARIES ${ATLAS_LIBRARIES} cblas)
178elseif(BLAS STREQUAL "OpenBLAS")
179  find_package(OpenBLAS REQUIRED)
180  include_directories(SYSTEM ${OpenBLAS_INCLUDE_DIR})
181  list(APPEND Caffe2_DEPENDENCY_LIBS ${OpenBLAS_LIB})
182  set(BLAS_INFO "open")
183  set(BLAS_FOUND 1)
184  set(BLAS_LIBRARIES ${OpenBLAS_LIB})
185elseif(BLAS STREQUAL "BLIS")
186  find_package(BLIS REQUIRED)
187  include_directories(SYSTEM ${BLIS_INCLUDE_DIR})
188  list(APPEND Caffe2_DEPENDENCY_LIBS ${BLIS_LIB})
189elseif(BLAS STREQUAL "MKL")
190  if(BLAS_SET_BY_USER)
191    find_package(MKL REQUIRED)
192  else()
193    find_package(MKL QUIET)
194  endif()
195  include(${CMAKE_CURRENT_LIST_DIR}/public/mkl.cmake)
196  if(MKL_FOUND)
197    message(STATUS "MKL libraries: ${MKL_LIBRARIES}")
198    message(STATUS "MKL include directory: ${MKL_INCLUDE_DIR}")
199    message(STATUS "MKL OpenMP type: ${MKL_OPENMP_TYPE}")
200    message(STATUS "MKL OpenMP library: ${MKL_OPENMP_LIBRARY}")
201    include_directories(AFTER SYSTEM ${MKL_INCLUDE_DIR})
202    list(APPEND Caffe2_PUBLIC_DEPENDENCY_LIBS caffe2::mkl)
203    set(CAFFE2_USE_MKL ON)
204    set(BLAS_INFO "mkl")
205    set(BLAS_FOUND 1)
206    set(BLAS_LIBRARIES ${MKL_LIBRARIES})
207  else()
208    message(WARNING "MKL could not be found. Defaulting to Eigen")
209    set(CAFFE2_USE_EIGEN_FOR_BLAS ON)
210    set(CAFFE2_USE_MKL OFF)
211  endif()
212elseif(BLAS STREQUAL "NVPL")
213  find_package(NVPL_BLAS REQUIRED)
214  list(APPEND Caffe2_DEPENDENCY_LIBS nvpl::blas_lp64_omp)
215  set(BLAS_INFO "nvpl")
216  set(BLAS_FOUND 1)
217  set(BLAS_USE_CBLAS_DOT TRUE)
218elseif(BLAS STREQUAL "vecLib")
219  find_package(vecLib REQUIRED)
220  include_directories(SYSTEM ${vecLib_INCLUDE_DIR})
221  list(APPEND Caffe2_DEPENDENCY_LIBS ${vecLib_LINKER_LIBS})
222  set(BLAS_INFO "veclib")
223  set(BLAS_FOUND 1)
224  set(BLAS_LIBRARIES ${vecLib_LINKER_LIBS})
225elseif(BLAS STREQUAL "FlexiBLAS")
226  find_package(FlexiBLAS REQUIRED)
227  include_directories(SYSTEM ${FlexiBLAS_INCLUDE_DIR})
228  list(APPEND Caffe2_DEPENDENCY_LIBS ${FlexiBLAS_LIB})
229elseif(BLAS STREQUAL "Generic")
230  # On Debian family, the CBLAS ABIs have been merged into libblas.so
231  if(ENV{GENERIC_BLAS_LIBRARIES} STREQUAL "")
232    set(GENERIC_BLAS "blas")
233  else()
234    set(GENERIC_BLAS $ENV{GENERIC_BLAS_LIBRARIES})
235  endif()
236  find_library(BLAS_LIBRARIES NAMES ${GENERIC_BLAS})
237  message("-- Using BLAS: ${BLAS_LIBRARIES}")
238  list(APPEND Caffe2_DEPENDENCY_LIBS ${BLAS_LIBRARIES})
239  set(GENERIC_BLAS_FOUND TRUE)
240  set(BLAS_INFO "generic")
241  set(BLAS_FOUND 1)
242else()
243  message(FATAL_ERROR "Unrecognized BLAS option: " ${BLAS})
244endif()
245
246if(NOT INTERN_BUILD_MOBILE)
247  set(AT_MKL_SEQUENTIAL 0)
248  set(USE_BLAS 1)
249  if(NOT (ATLAS_FOUND OR BLIS_FOUND OR GENERIC_BLAS_FOUND OR MKL_FOUND OR OpenBLAS_FOUND OR VECLIB_FOUND OR FlexiBLAS_FOUND OR NVPL_BLAS_FOUND))
250    message(WARNING "Preferred BLAS (" ${BLAS} ") cannot be found, now searching for a general BLAS library")
251    find_package(BLAS)
252    if(NOT BLAS_FOUND)
253      set(USE_BLAS 0)
254    endif()
255  endif()
256
257  if(MKL_FOUND)
258    if("${MKL_THREADING}" STREQUAL "SEQ")
259      set(AT_MKL_SEQUENTIAL 1)
260    endif()
261    set(AT_MKL_ENABLED 1)
262  endif()
263elseif(INTERN_USE_EIGEN_BLAS)
264  # Eigen BLAS for Mobile
265  set(USE_BLAS 1)
266  include(${CMAKE_CURRENT_LIST_DIR}/External/EigenBLAS.cmake)
267  list(APPEND Caffe2_DEPENDENCY_LIBS eigen_blas)
268endif()
269
270# --- [ PocketFFT
271set(AT_POCKETFFT_ENABLED 0)
272if(NOT AT_MKL_ENABLED)
273  set(POCKETFFT_INCLUDE_DIR "${Torch_SOURCE_DIR}/third_party/pocketfft/")
274  if(NOT EXISTS "${POCKETFFT_INCLUDE_DIR}")
275    message(FATAL_ERROR "pocketfft directory not found, expected ${POCKETFFT_INCLUDE_DIR}")
276  elif(NOT EXISTS "${POCKETFFT_INCLUDE_DIR}/pocketfft_hdronly.h")
277    message(FATAL_ERROR "pocketfft headers not found in ${POCKETFFT_INCLUDE_DIR}")
278  endif()
279
280  set(AT_POCKETFFT_ENABLED 1)
281  message(STATUS "Using pocketfft in directory: ${POCKETFFT_INCLUDE_DIR}")
282endif()
283
284# ---[ Dependencies
285# NNPACK and family (QNNPACK, PYTORCH_QNNPACK, and XNNPACK) can download and
286# compile their dependencies in isolation as part of their build.  These dependencies
287# are then linked statically with PyTorch.  To avoid the possibility of a version
288# mismatch between these shared dependencies, explicitly declare our intent to these
289# libraries that we are interested in using the exact same source dependencies for all.
290
291if(USE_NNPACK OR USE_PYTORCH_QNNPACK OR USE_XNNPACK)
292  set(DISABLE_NNPACK_AND_FAMILY OFF)
293
294  # Sanity checks - Can we actually build NNPACK and family given the configuration provided?
295  # Disable them and warn the user if not.
296
297  if(IOS)
298    list(LENGTH IOS_ARCH IOS_ARCH_COUNT)
299    if(IOS_ARCH_COUNT GREATER 1)
300      message(WARNING
301        "Multi-architecture (${IOS_ARCH}) builds are not supported in {Q/X}NNPACK. "
302        "Specify a single architecture in IOS_ARCH and re-configure, or "
303        "turn this warning off by USE_{Q/X}NNPACK=OFF.")
304      set(DISABLE_NNPACK_AND_FAMILY ON)
305    endif()
306    if(NOT IOS_ARCH MATCHES "^(i386|x86_64|armv7.*|arm64.*)$")
307      message(WARNING
308        "Target architecture \"${IOS_ARCH}\" is not supported in {Q/X}NNPACK. "
309        "Supported architectures are x86, x86-64, ARM, and ARM64. "
310        "Turn this warning off by USE_{Q/X}NNPACK=OFF.")
311      set(DISABLE_NNPACK_AND_FAMILY ON)
312    endif()
313  else()
314    if(NOT IOS AND NOT (CMAKE_SYSTEM_NAME MATCHES "^(Android|Linux|Darwin|Windows)$"))
315      message(WARNING
316        "Target platform \"${CMAKE_SYSTEM_NAME}\" is not supported in {Q/X}NNPACK. "
317        "Supported platforms are Android, iOS, Linux, and macOS. "
318        "Turn this warning off by USE_{Q/X}NNPACK=OFF.")
319      set(DISABLE_NNPACK_AND_FAMILY ON)
320    endif()
321    if(NOT IOS AND NOT (CMAKE_SYSTEM_PROCESSOR MATCHES "^(i686|AMD64|x86_64|armv[0-9].*|arm64|aarch64)$"))
322      message(WARNING
323        "Target architecture \"${CMAKE_SYSTEM_PROCESSOR}\" is not supported in {Q/X}NNPACK. "
324        "Supported architectures are x86, x86-64, ARM, and ARM64. "
325        "Turn this warning off by USE_{Q/X}NNPACK=OFF.")
326      set(DISABLE_NNPACK_AND_FAMILY ON)
327    endif()
328  endif()
329
330  if(DISABLE_NNPACK_AND_FAMILY)
331    caffe2_update_option(USE_NNPACK OFF)
332    caffe2_update_option(USE_PYTORCH_QNNPACK OFF)
333    caffe2_update_option(USE_XNNPACK OFF)
334  else()
335    # Disable unsupported NNPack combinations with MSVC
336    if(MSVC)
337      caffe2_update_option(USE_NNPACK OFF)
338      caffe2_update_option(USE_PYTORCH_QNNPACK OFF)
339    endif()
340
341    set(CAFFE2_THIRD_PARTY_ROOT "${PROJECT_SOURCE_DIR}/third_party")
342
343    if(NOT DEFINED CPUINFO_SOURCE_DIR)
344      set(CPUINFO_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/cpuinfo" CACHE STRING "cpuinfo source directory")
345    endif()
346    if(NOT DEFINED FP16_SOURCE_DIR)
347      set(FP16_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/FP16" CACHE STRING "FP16 source directory")
348    endif()
349    if(NOT DEFINED FXDIV_SOURCE_DIR)
350      set(FXDIV_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/FXdiv" CACHE STRING "FXdiv source directory")
351    endif()
352    if(NOT DEFINED PSIMD_SOURCE_DIR)
353      set(PSIMD_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/psimd" CACHE STRING "PSimd source directory")
354    endif()
355    if(NOT DEFINED PTHREADPOOL_SOURCE_DIR)
356      set(PTHREADPOOL_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/pthreadpool" CACHE STRING "pthreadpool source directory")
357    endif()
358  endif()
359else()
360  set(DISABLE_NNPACK_AND_FAMILY ON)
361endif()
362
363set(CONFU_DEPENDENCIES_SOURCE_DIR ${PROJECT_BINARY_DIR}/confu-srcs
364  CACHE PATH "Confu-style dependencies source directory")
365set(CONFU_DEPENDENCIES_BINARY_DIR ${PROJECT_BINARY_DIR}/confu-deps
366  CACHE PATH "Confu-style dependencies binary directory")
367
368# ---[ pthreadpool
369# Only add a dependency on pthreadpool if we are on a mobile build
370# or are building any of the libraries in the {Q/X}NNPACK family.
371if(INTERN_BUILD_MOBILE OR NOT DISABLE_NNPACK_AND_FAMILY)
372  set(USE_PTHREADPOOL ON CACHE BOOL "" FORCE)
373  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_PTHREADPOOL")
374
375  # Always use third_party/pthreadpool.
376  set(USE_INTERNAL_PTHREADPOOL_IMPL OFF CACHE BOOL "" FORCE)
377
378  if(NOT TARGET pthreadpool)
379    if(USE_SYSTEM_PTHREADPOOL)
380      add_library(pthreadpool SHARED IMPORTED)
381      find_library(PTHREADPOOL_LIBRARY pthreadpool)
382      set_property(TARGET pthreadpool PROPERTY IMPORTED_LOCATION "${PTHREADPOOL_LIBRARY}")
383      if(NOT PTHREADPOOL_LIBRARY)
384        message(FATAL_ERROR "Cannot find pthreadpool")
385      endif()
386      message("-- Found pthreadpool: ${PTHREADPOOL_LIBRARY}")
387    elseif(NOT USE_INTERNAL_PTHREADPOOL_IMPL)
388      if(NOT DEFINED PTHREADPOOL_SOURCE_DIR)
389        set(CAFFE2_THIRD_PARTY_ROOT "${PROJECT_SOURCE_DIR}/third_party")
390        set(PTHREADPOOL_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/pthreadpool" CACHE STRING "pthreadpool source directory")
391      endif()
392
393      set(PTHREADPOOL_BUILD_TESTS OFF CACHE BOOL "")
394      set(PTHREADPOOL_BUILD_BENCHMARKS OFF CACHE BOOL "")
395      set(PTHREADPOOL_LIBRARY_TYPE "static" CACHE STRING "")
396      set(PTHREADPOOL_ALLOW_DEPRECATED_API ON CACHE BOOL "")
397      add_subdirectory(
398        "${PTHREADPOOL_SOURCE_DIR}"
399        "${CONFU_DEPENDENCIES_BINARY_DIR}/pthreadpool")
400      set_property(TARGET pthreadpool PROPERTY POSITION_INDEPENDENT_CODE ON)
401    endif()
402
403    if(USE_INTERNAL_PTHREADPOOL_IMPL)
404      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_INTERNAL_PTHREADPOOL_IMPL")
405    else()
406      list(APPEND Caffe2_DEPENDENCY_LIBS pthreadpool)
407    endif()
408  endif()
409else()
410  set(USE_PTHREADPOOL OFF CACHE BOOL "" FORCE)
411endif()
412
413if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x|ppc64le)$")
414  # ---[ Caffe2 uses cpuinfo library in the thread pool
415  # ---[ But it doesn't support s390x/powerpc and thus not used on s390x/powerpc
416  if(NOT TARGET cpuinfo AND USE_SYSTEM_CPUINFO)
417    add_library(cpuinfo SHARED IMPORTED)
418    find_library(CPUINFO_LIBRARY cpuinfo)
419    if(NOT CPUINFO_LIBRARY)
420      message(FATAL_ERROR "Cannot find cpuinfo")
421    endif()
422    message("Found cpuinfo: ${CPUINFO_LIBRARY}")
423    set_target_properties(cpuinfo PROPERTIES IMPORTED_LOCATION "${CPUINFO_LIBRARY}")
424  elseif(NOT TARGET cpuinfo)
425    if(NOT DEFINED CPUINFO_SOURCE_DIR)
426      set(CPUINFO_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../third_party/cpuinfo" CACHE STRING "cpuinfo source directory")
427    endif()
428
429    set(CPUINFO_BUILD_TOOLS OFF CACHE BOOL "")
430    set(CPUINFO_BUILD_UNIT_TESTS OFF CACHE BOOL "")
431    set(CPUINFO_BUILD_MOCK_TESTS OFF CACHE BOOL "")
432    set(CPUINFO_BUILD_BENCHMARKS OFF CACHE BOOL "")
433    set(CPUINFO_LIBRARY_TYPE "static" CACHE STRING "")
434    set(CPUINFO_LOG_LEVEL "error" CACHE STRING "")
435    if(MSVC)
436      if(CAFFE2_USE_MSVC_STATIC_RUNTIME)
437        set(CPUINFO_RUNTIME_TYPE "static" CACHE STRING "")
438      else()
439        set(CPUINFO_RUNTIME_TYPE "shared" CACHE STRING "")
440      endif()
441    endif()
442    add_subdirectory(
443      "${CPUINFO_SOURCE_DIR}"
444      "${CONFU_DEPENDENCIES_BINARY_DIR}/cpuinfo")
445    # We build static version of cpuinfo but link
446    # them into a shared library for Caffe2, so they need PIC.
447    set_property(TARGET cpuinfo PROPERTY POSITION_INDEPENDENT_CODE ON)
448  endif()
449  list(APPEND Caffe2_DEPENDENCY_LIBS cpuinfo)
450endif()
451
452
453# ---[ PYTORCH_QNNPACK
454set(CAFFE2_THIRD_PARTY_ROOT "${PROJECT_SOURCE_DIR}/third_party")
455if(USE_PYTORCH_QNNPACK)
456    if(NOT DEFINED PYTORCH_QNNPACK_SOURCE_DIR)
457      set(PYTORCH_QNNPACK_SOURCE_DIR "${PROJECT_SOURCE_DIR}/aten/src/ATen/native/quantized/cpu/qnnpack" CACHE STRING "QNNPACK source directory")
458    endif()
459
460    if(NOT TARGET pytorch_qnnpack)
461      if(NOT USE_SYSTEM_PTHREADPOOL AND USE_INTERNAL_PTHREADPOOL_IMPL)
462        set(PYTORCH_QNNPACK_CUSTOM_THREADPOOL ON CACHE BOOL "")
463      endif()
464
465      set(PYTORCH_QNNPACK_BUILD_TESTS OFF CACHE BOOL "")
466      set(PYTORCH_QNNPACK_BUILD_BENCHMARKS OFF CACHE BOOL "")
467      set(PYTORCH_QNNPACK_LIBRARY_TYPE "static" CACHE STRING "")
468      add_subdirectory(
469        "${PYTORCH_QNNPACK_SOURCE_DIR}"
470        "${CONFU_DEPENDENCIES_BINARY_DIR}/pytorch_qnnpack")
471      # We build static versions of QNNPACK and pthreadpool but link
472      # them into a shared library for Caffe2, so they need PIC.
473      set_property(TARGET pytorch_qnnpack PROPERTY POSITION_INDEPENDENT_CODE ON)
474      set_property(TARGET cpuinfo PROPERTY POSITION_INDEPENDENT_CODE ON)
475      # QNNPACK depends on gemmlowp headers
476      target_include_directories(pytorch_qnnpack PRIVATE "${CAFFE2_THIRD_PARTY_ROOT}/gemmlowp")
477
478      if(PYTORCH_QNNPACK_CUSTOM_THREADPOOL)
479        target_compile_definitions(
480          pytorch_qnnpack PRIVATE
481          pthreadpool_t=legacy_pthreadpool_t
482          pthreadpool_function_1d_t=legacy_pthreadpool_function_1d_t
483          pthreadpool_function_1d_tiled_t=legacy_pthreadpool_function_1d_tiled_t
484          pthreadpool_function_2d_t=legacy_pthreadpool_function_2d_t
485          pthreadpool_function_2d_tiled_t=legacy_pthreadpool_function_2d_tiled_t
486          pthreadpool_function_3d_tiled_t=legacy_pthreadpool_function_3d_tiled_t
487          pthreadpool_function_4d_tiled_t=legacy_pthreadpool_function_4d_tiled_t
488          pthreadpool_create=legacy_pthreadpool_create
489          pthreadpool_destroy=legacy_pthreadpool_destroy
490          pthreadpool_get_threads_count=legacy_pthreadpool_get_threads_count
491          pthreadpool_compute_1d=legacy_pthreadpool_compute_1d
492          pthreadpool_parallelize_1d=legacy_pthreadpool_parallelize_1d
493          pthreadpool_compute_1d_tiled=legacy_pthreadpool_compute_1d_tiled
494          pthreadpool_compute_2d=legacy_pthreadpool_compute_2d
495          pthreadpool_compute_2d_tiled=legacy_pthreadpool_compute_2d_tiled
496          pthreadpool_compute_3d_tiled=legacy_pthreadpool_compute_3d_tiled
497          pthreadpool_compute_4d_tiled=legacy_pthreadpool_compute_4d_tiled)
498      endif()
499    endif()
500
501    list(APPEND Caffe2_DEPENDENCY_LIBS pytorch_qnnpack)
502endif()
503
504# ---[ NNPACK
505if(USE_NNPACK)
506  include(${CMAKE_CURRENT_LIST_DIR}/External/nnpack.cmake)
507  if(NNPACK_FOUND)
508    if(TARGET nnpack)
509      # ---[ NNPACK is being built together with Caffe2: explicitly specify dependency
510      list(APPEND Caffe2_DEPENDENCY_LIBS nnpack)
511    else()
512      include_directories(SYSTEM ${NNPACK_INCLUDE_DIRS})
513      list(APPEND Caffe2_DEPENDENCY_LIBS ${NNPACK_LIBRARIES})
514    endif()
515  else()
516    message(WARNING "Not compiling with NNPACK. Suppress this warning with -DUSE_NNPACK=OFF")
517    caffe2_update_option(USE_NNPACK OFF)
518  endif()
519endif()
520
521# ---[ XNNPACK
522if(USE_XNNPACK AND NOT USE_SYSTEM_XNNPACK)
523  if(NOT DEFINED XNNPACK_SOURCE_DIR)
524    set(XNNPACK_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/XNNPACK" CACHE STRING "XNNPACK source directory")
525  endif()
526
527  if(NOT DEFINED XNNPACK_INCLUDE_DIR)
528    set(XNNPACK_INCLUDE_DIR "${XNNPACK_SOURCE_DIR}/include" CACHE STRING "XNNPACK include directory")
529  endif()
530
531  if(NOT TARGET XNNPACK)
532    set(XNNPACK_LIBRARY_TYPE "static" CACHE STRING "")
533    set(XNNPACK_BUILD_BENCHMARKS OFF CACHE BOOL "")
534    set(XNNPACK_BUILD_TESTS OFF CACHE BOOL "")
535
536    # Disable ARM BF16 and FP16 vector for now; unused and causes build failures because
537    # these new ISA features may not be supported on older compilers
538    set(XNNPACK_ENABLE_ARM_BF16 OFF CACHE BOOL "")
539
540    # Disable AVXVNNI for now, older clang versions seem not to support it
541    # (clang 12 is where avx-vnni support is added)
542    set(XNNPACK_ENABLE_AVXVNNI OFF CACHE BOOL "")
543
544    # Disable I8MM For CI since clang 9 does not support neon i8mm.
545    set(XNNPACK_ENABLE_ARM_I8MM OFF CACHE BOOL "")
546
547    # Conditionally disable AVX512AMX, as it requires Clang 11 or later. Note that
548    # XNNPACK does conditionally compile this based on GCC version. Once it also does
549    # so based on Clang version, this logic can be removed.
550    IF(CMAKE_C_COMPILER_ID STREQUAL "Clang")
551      IF(CMAKE_C_COMPILER_VERSION VERSION_LESS "11")
552        set(XNNPACK_ENABLE_AVX512AMX OFF CACHE BOOL "")
553      ENDIF()
554    ENDIF()
555
556    # Setting this global PIC flag for all XNNPACK targets.
557    # This is needed for Object libraries within XNNPACK which must
558    # be PIC to successfully link this static libXNNPACK with pytorch
559    set(__caffe2_CMAKE_POSITION_INDEPENDENT_CODE_FLAG ${CMAKE_POSITION_INDEPENDENT_CODE})
560    set(CMAKE_POSITION_INDEPENDENT_CODE ON)
561
562    add_subdirectory(
563      "${XNNPACK_SOURCE_DIR}"
564      "${CONFU_DEPENDENCIES_BINARY_DIR}/XNNPACK")
565
566    # Revert to whatever it was before
567    set(CMAKE_POSITION_INDEPENDENT_CODE ${__caffe2_CMAKE_POSITION_INDEPENDENT_CODE_FLAG})
568  endif()
569
570  include_directories(SYSTEM ${XNNPACK_INCLUDE_DIR})
571  list(APPEND Caffe2_DEPENDENCY_LIBS XNNPACK)
572elseif(NOT TARGET XNNPACK AND USE_SYSTEM_XNNPACK)
573  add_library(XNNPACK SHARED IMPORTED)
574  find_library(XNNPACK_LIBRARY XNNPACK)
575  set_property(TARGET XNNPACK PROPERTY IMPORTED_LOCATION "${XNNPACK_LIBRARY}")
576  if(NOT XNNPACK_LIBRARY)
577    message(FATAL_ERROR "Cannot find XNNPACK")
578  endif()
579  message("-- Found XNNPACK: ${XNNPACK_LIBRARY}")
580  list(APPEND Caffe2_DEPENDENCY_LIBS XNNPACK)
581endif()
582
583# ---[ Vulkan deps
584if(USE_VULKAN)
585  set(Vulkan_DEFINES)
586  set(Vulkan_INCLUDES)
587  set(Vulkan_LIBS)
588  include(${CMAKE_CURRENT_LIST_DIR}/VulkanDependencies.cmake)
589  string(APPEND CMAKE_CXX_FLAGS ${Vulkan_DEFINES})
590  include_directories(SYSTEM ${Vulkan_INCLUDES})
591  list(APPEND Caffe2_DEPENDENCY_LIBS ${Vulkan_LIBS})
592endif()
593
594# ---[ gflags
595if(USE_GFLAGS)
596  include(${CMAKE_CURRENT_LIST_DIR}/public/gflags.cmake)
597  if(NOT TARGET gflags)
598    message(WARNING
599        "gflags is not found. Caffe2 will build without gflags support but "
600        "it is strongly recommended that you install gflags. Suppress this "
601        "warning with -DUSE_GFLAGS=OFF")
602    caffe2_update_option(USE_GFLAGS OFF)
603  endif()
604endif()
605
606# ---[ Google-glog
607if(USE_GLOG)
608  include(${CMAKE_CURRENT_LIST_DIR}/public/glog.cmake)
609  if(TARGET glog::glog)
610    set(CAFFE2_USE_GOOGLE_GLOG 1)
611  else()
612    message(WARNING
613        "glog is not found. Caffe2 will build without glog support but it is "
614        "strongly recommended that you install glog. Suppress this warning "
615        "with -DUSE_GLOG=OFF")
616    caffe2_update_option(USE_GLOG OFF)
617  endif()
618endif()
619
620
621# ---[ Googletest and benchmark
622if(BUILD_TEST OR BUILD_MOBILE_BENCHMARK OR BUILD_MOBILE_TEST)
623  # Preserve build options.
624  set(TEMP_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
625
626  # We will build gtest as static libs and embed it directly into the binary.
627  set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libs" FORCE)
628
629  # For gtest, we will simply embed it into our test binaries, so we won't
630  # need to install it.
631  set(INSTALL_GTEST OFF CACHE BOOL "Install gtest." FORCE)
632  set(BUILD_GMOCK ON CACHE BOOL "Build gmock." FORCE)
633  # For Windows, we will check the runtime used is correctly passed in.
634  if(NOT CAFFE2_USE_MSVC_STATIC_RUNTIME)
635      set(gtest_force_shared_crt ON CACHE BOOL "force shared crt on gtest" FORCE)
636  endif()
637  # We need to replace googletest cmake scripts too.
638  # Otherwise, it will sometimes break the build.
639  # To make the git clean after the build, we make a backup first.
640  if((MSVC AND MSVC_Z7_OVERRIDE) OR USE_CUDA)
641    execute_process(
642      COMMAND ${CMAKE_COMMAND}
643              "-DFILENAME=${CMAKE_CURRENT_LIST_DIR}/../third_party/googletest/googletest/cmake/internal_utils.cmake"
644              "-DBACKUP=${CMAKE_CURRENT_LIST_DIR}/../third_party/googletest/googletest/cmake/internal_utils.cmake.bak"
645              "-DREVERT=0"
646              "-P"
647              "${CMAKE_CURRENT_LIST_DIR}/GoogleTestPatch.cmake"
648      RESULT_VARIABLE _exitcode)
649    if(NOT _exitcode EQUAL 0)
650      message(WARNING "Patching failed for Google Test. The build may fail.")
651    endif()
652  endif()
653
654  # Add googletest subdirectory but make sure our INCLUDE_DIRECTORIES
655  # don't bleed into it. This is because libraries installed into the root conda
656  # env (e.g. MKL) add a global /opt/conda/include directory, and if there's
657  # gtest installed in conda, the third_party/googletest/**.cc source files
658  # would try to include headers from /opt/conda/include/gtest/**.h instead of
659  # its own. Once we have proper target-based include directories,
660  # this shouldn't be necessary anymore.
661  get_property(INC_DIR_temp DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
662  set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES "")
663  add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../third_party/googletest)
664  set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES ${INC_DIR_temp})
665
666  include_directories(BEFORE SYSTEM ${CMAKE_CURRENT_LIST_DIR}/../third_party/googletest/googletest/include)
667  include_directories(BEFORE SYSTEM ${CMAKE_CURRENT_LIST_DIR}/../third_party/googletest/googlemock/include)
668
669  # We will not need to test benchmark lib itself.
670  set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "Disable benchmark testing as we don't need it.")
671  # We will not need to install benchmark since we link it statically.
672  set(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL "Disable benchmark install to avoid overwriting vendor install.")
673  if(NOT USE_SYSTEM_BENCHMARK)
674    add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../third_party/benchmark)
675  else()
676    add_library(benchmark SHARED IMPORTED)
677    find_library(BENCHMARK_LIBRARY benchmark)
678    if(NOT BENCHMARK_LIBRARY)
679      message(FATAL_ERROR "Cannot find google benchmark library")
680    endif()
681    message("-- Found benchmark: ${BENCHMARK_LIBRARY}")
682    set_property(TARGET benchmark PROPERTY IMPORTED_LOCATION ${BENCHMARK_LIBRARY})
683  endif()
684  include_directories(${CMAKE_CURRENT_LIST_DIR}/../third_party/benchmark/include)
685
686  # Recover build options.
687  set(BUILD_SHARED_LIBS ${TEMP_BUILD_SHARED_LIBS} CACHE BOOL "Build shared libs" FORCE)
688
689  # To make the git clean after the build, we revert the changes here.
690  if(MSVC AND MSVC_Z7_OVERRIDE)
691    execute_process(
692      COMMAND ${CMAKE_COMMAND}
693              "-DFILENAME=${CMAKE_CURRENT_LIST_DIR}/../third_party/googletest/googletest/cmake/internal_utils.cmake"
694              "-DBACKUP=${CMAKE_CURRENT_LIST_DIR}/../third_party/googletest/googletest/cmake/internal_utils.cmake.bak"
695              "-DREVERT=1"
696              "-P"
697              "${CMAKE_CURRENT_LIST_DIR}/GoogleTestPatch.cmake"
698      RESULT_VARIABLE _exitcode)
699    if(NOT _exitcode EQUAL 0)
700      message(WARNING "Reverting changes failed for Google Test. The build may fail.")
701    endif()
702  endif()
703
704  # Cacheing variables to enable incremental build.
705  # Without this is cross compiling we end up having to blow build directory
706  # and rebuild from scratch.
707  if(CMAKE_CROSSCOMPILING)
708    if(COMPILE_HAVE_STD_REGEX)
709      set(RUN_HAVE_STD_REGEX 0 CACHE INTERNAL "Cache RUN_HAVE_STD_REGEX output for cross-compile.")
710    endif()
711  endif()
712endif()
713
714# ---[ FBGEMM
715if(USE_FBGEMM)
716  set(CAFFE2_THIRD_PARTY_ROOT "${PROJECT_SOURCE_DIR}/third_party")
717  if(NOT DEFINED FBGEMM_SOURCE_DIR)
718    set(FBGEMM_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/fbgemm" CACHE STRING "FBGEMM source directory")
719  endif()
720  if(NOT CAFFE2_COMPILER_SUPPORTS_AVX512_EXTENSIONS)
721    message(WARNING
722      "A compiler with AVX512 support is required for FBGEMM. "
723      "Not compiling with FBGEMM. "
724      "Turn this warning off by USE_FBGEMM=OFF.")
725    set(USE_FBGEMM OFF)
726  endif()
727  if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
728    message(WARNING
729      "x64 operating system is required for FBGEMM. "
730      "Not compiling with FBGEMM. "
731      "Turn this warning off by USE_FBGEMM=OFF.")
732    set(USE_FBGEMM OFF)
733  endif()
734  if(USE_FBGEMM AND NOT TARGET fbgemm)
735    set(FBGEMM_BUILD_TESTS OFF CACHE BOOL "")
736    set(FBGEMM_BUILD_BENCHMARKS OFF CACHE BOOL "")
737    if(MSVC AND BUILD_SHARED_LIBS)
738      set(FBGEMM_LIBRARY_TYPE "shared" CACHE STRING "")
739    else()
740      set(FBGEMM_LIBRARY_TYPE "static" CACHE STRING "")
741    endif()
742    if(USE_ASAN)
743      set(USE_SANITIZER "address,undefined" CACHE STRING "-fsanitize options for FBGEMM")
744    endif()
745    add_subdirectory("${FBGEMM_SOURCE_DIR}")
746    set_property(TARGET fbgemm_generic PROPERTY POSITION_INDEPENDENT_CODE ON)
747    set_property(TARGET fbgemm_avx2 PROPERTY POSITION_INDEPENDENT_CODE ON)
748    set_property(TARGET fbgemm_avx512 PROPERTY POSITION_INDEPENDENT_CODE ON)
749    set_property(TARGET fbgemm PROPERTY POSITION_INDEPENDENT_CODE ON)
750    if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 13.0.0)
751      # See https://github.com/pytorch/pytorch/issues/74352
752      target_compile_options_if_supported(asmjit -Wno-deprecated-copy)
753      target_compile_options_if_supported(asmjit -Wno-unused-but-set-variable)
754    endif()
755  endif()
756
757  if(USE_FBGEMM)
758    list(APPEND Caffe2_DEPENDENCY_LIBS fbgemm)
759  endif()
760endif()
761
762if(USE_FBGEMM)
763  caffe2_update_option(USE_FBGEMM ON)
764else()
765  caffe2_update_option(USE_FBGEMM OFF)
766  message(WARNING
767    "Turning USE_FAKELOWP off as it depends on USE_FBGEMM.")
768  caffe2_update_option(USE_FAKELOWP OFF)
769endif()
770
771if(USE_OPENCL)
772  message(INFO "USING OPENCL")
773  find_package(OpenCL REQUIRED)
774  include_directories(SYSTEM ${OpenCL_INCLUDE_DIRS})
775  list(APPEND Caffe2_DEPENDENCY_LIBS ${OpenCL_LIBRARIES})
776endif()
777
778# ---[ NUMA
779if(USE_NUMA)
780  if(LINUX)
781    find_package(Numa)
782    if(NOT NUMA_FOUND)
783      message(WARNING "Not compiling with NUMA. Suppress this warning with -DUSE_NUMA=OFF")
784      caffe2_update_option(USE_NUMA OFF)
785    endif()
786  else()
787    message(WARNING "NUMA is currently only supported under Linux.")
788    caffe2_update_option(USE_NUMA OFF)
789  endif()
790endif()
791
792if(USE_ITT)
793  find_package(ITT)
794  if(ITT_FOUND)
795    include_directories(SYSTEM ${ITT_INCLUDE_DIR})
796    list(APPEND Caffe2_DEPENDENCY_LIBS ${ITT_LIBRARIES})
797    list(APPEND TORCH_PYTHON_LINK_LIBRARIES ${ITT_LIBRARIES})
798  else()
799    message(WARNING "Not compiling with ITT. Suppress this warning with -DUSE_ITT=OFF")
800    set(USE_ITT OFF CACHE BOOL "" FORCE)
801    caffe2_update_option(USE_ITT OFF)
802  endif()
803endif()
804
805# ---[ Caffe2 depends on FP16 library for half-precision conversions
806if(NOT TARGET fp16 AND NOT USE_SYSTEM_FP16)
807  set(CAFFE2_THIRD_PARTY_ROOT "${PROJECT_SOURCE_DIR}/third_party")
808  # PSIMD is required by FP16
809  if(NOT DEFINED PSIMD_SOURCE_DIR)
810    set(PSIMD_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/psimd" CACHE STRING "PSimd source directory")
811  endif()
812  if(NOT DEFINED FP16_SOURCE_DIR)
813    set(FP16_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/FP16" CACHE STRING "FP16 source directory")
814  endif()
815
816  set(FP16_BUILD_TESTS OFF CACHE BOOL "")
817  set(FP16_BUILD_BENCHMARKS OFF CACHE BOOL "")
818  add_subdirectory(
819    "${FP16_SOURCE_DIR}"
820    "${CONFU_DEPENDENCIES_BINARY_DIR}/FP16")
821elseif(NOT TARGET fp16 AND USE_SYSTEM_FP16)
822  add_library(fp16 STATIC "/usr/include/fp16.h")
823  set_target_properties(fp16 PROPERTIES LINKER_LANGUAGE C)
824endif()
825list(APPEND Caffe2_DEPENDENCY_LIBS fp16)
826
827# ---[ EIGEN
828# Due to license considerations, we will only use the MPL2 parts of Eigen.
829set(EIGEN_MPL2_ONLY 1)
830if(USE_SYSTEM_EIGEN_INSTALL)
831  find_package(Eigen3)
832  if(EIGEN3_FOUND)
833    message(STATUS "Found system Eigen at " ${EIGEN3_INCLUDE_DIR})
834  else()
835    message(STATUS "Did not find system Eigen. Using third party subdirectory.")
836    set(EIGEN3_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/../third_party/eigen)
837    caffe2_update_option(USE_SYSTEM_EIGEN_INSTALL OFF)
838  endif()
839else()
840  message(STATUS "Using third party subdirectory Eigen.")
841  set(EIGEN3_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/../third_party/eigen)
842endif()
843include_directories(SYSTEM ${EIGEN3_INCLUDE_DIR})
844
845
846# ---[ Python Interpreter
847# If not given a Python installation, then use the current active Python
848if(NOT Python_EXECUTABLE)
849  execute_process(
850    COMMAND "which" "python3" RESULT_VARIABLE _exitcode OUTPUT_VARIABLE _py_exe)
851  if(${_exitcode} EQUAL 0)
852    if(NOT MSVC)
853      string(STRIP ${_py_exe} Python_EXECUTABLE)
854    endif()
855    message(STATUS "Setting Python to ${Python_EXECUTABLE}")
856  endif()
857endif()
858
859if(BUILD_PYTHON)
860  set(PYTHON_COMPONENTS Development.Module)
861  if(USE_NUMPY)
862    list(APPEND PYTHON_COMPONENTS NumPy)
863  endif()
864  find_package(Python COMPONENTS Interpreter OPTIONAL_COMPONENTS ${PYTHON_COMPONENTS})
865else()
866  find_package(Python COMPONENTS Interpreter)
867endif()
868
869if(NOT Python_Interpreter_FOUND)
870  message(FATAL_ERROR "Python3 could not be found.")
871endif()
872
873if(${Python_VERSION} VERSION_LESS 3.8)
874  message(FATAL_ERROR
875    "Found Python libraries version ${Python_VERSION}. Python < 3.8 is no longer supported by PyTorch.")
876endif()
877
878# ---[ Python + Numpy
879if(BUILD_PYTHON)
880  if(Python_Development.Module_FOUND)
881    if(USE_NUMPY)
882      if(NOT Python_NumPy_FOUND)
883        message(WARNING "NumPy could not be found. Not building with NumPy. Suppress this warning with -DUSE_NUMPY=OFF")
884        caffe2_update_option(USE_NUMPY OFF)
885      else()
886        caffe2_update_option(USE_NUMPY ON)
887      endif()
888    endif()
889    # Observers are required in the python build
890    caffe2_update_option(USE_OBSERVERS ON)
891  else()
892    message(WARNING "Python dependencies not met. Not compiling with python. Suppress this warning with -DBUILD_PYTHON=OFF")
893    caffe2_update_option(BUILD_PYTHON OFF)
894  endif()
895endif()
896
897# ---[ pybind11
898if(USE_SYSTEM_PYBIND11)
899  find_package(pybind11 CONFIG)
900  if(NOT pybind11_FOUND)
901    find_package(pybind11)
902  endif()
903  if(NOT pybind11_FOUND)
904    message(FATAL "Cannot find system pybind11")
905  endif()
906else()
907    message(STATUS "Using third_party/pybind11.")
908    set(pybind11_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}/../third_party/pybind11/include)
909    install(DIRECTORY ${pybind11_INCLUDE_DIRS}
910            DESTINATION ${CMAKE_INSTALL_PREFIX}
911            FILES_MATCHING PATTERN "*.h")
912endif()
913message(STATUS "pybind11 include dirs: " "${pybind11_INCLUDE_DIRS}")
914add_library(pybind::pybind11 INTERFACE IMPORTED)
915target_include_directories(pybind::pybind11 SYSTEM INTERFACE ${pybind11_INCLUDE_DIRS})
916target_link_libraries(pybind::pybind11 INTERFACE Python::Module)
917
918# ---[ OpenTelemetry API headers
919find_package(OpenTelemetryApi)
920if(NOT OpenTelemetryApi_FOUND)
921  message(STATUS "Using third_party/opentelemetry-cpp.")
922  set(OpenTelemetryApi_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}/../third_party/opentelemetry-cpp/api/include)
923endif()
924message(STATUS "opentelemetry api include dirs: " "${OpenTelemetryApi_INCLUDE_DIRS}")
925add_library(opentelemetry::api INTERFACE IMPORTED)
926target_include_directories(opentelemetry::api SYSTEM INTERFACE ${OpenTelemetryApi_INCLUDE_DIRS})
927
928# ---[ MPI
929if(USE_MPI)
930  find_package(MPI)
931  if(MPI_CXX_FOUND)
932    message(STATUS "MPI support found")
933    message(STATUS "MPI compile flags: " ${MPI_CXX_COMPILE_FLAGS})
934    message(STATUS "MPI include path: " ${MPI_CXX_INCLUDE_PATH})
935    message(STATUS "MPI LINK flags path: " ${MPI_CXX_LINK_FLAGS})
936    message(STATUS "MPI libraries: " ${MPI_CXX_LIBRARIES})
937    find_program(OMPI_INFO
938      NAMES ompi_info
939      HINTS ${MPI_CXX_LIBRARIES}/../bin)
940    if(OMPI_INFO)
941      execute_process(COMMAND ${OMPI_INFO}
942                      OUTPUT_VARIABLE _output)
943      if(_output MATCHES "smcuda")
944        message(STATUS "Found OpenMPI with CUDA support built.")
945      else()
946        message(WARNING "OpenMPI found, but it is not built with CUDA support.")
947        set(CAFFE2_FORCE_FALLBACK_CUDA_MPI 1)
948      endif()
949    endif()
950  else()
951    message(WARNING "Not compiling with MPI. Suppress this warning with -DUSE_MPI=OFF")
952    caffe2_update_option(USE_MPI OFF)
953  endif()
954endif()
955
956# ---[ OpenMP
957if(USE_OPENMP AND NOT TARGET caffe2::openmp)
958  include(${CMAKE_CURRENT_LIST_DIR}/Modules/FindOpenMP.cmake)
959  if(OPENMP_FOUND)
960    message(STATUS "Adding OpenMP CXX_FLAGS: " ${OpenMP_CXX_FLAGS})
961    if(APPLE AND USE_MPS)
962      string(APPEND CMAKE_OBJCXX_FLAGS " ${OpenMP_CXX_FLAGS}")
963    endif()
964    if(OpenMP_CXX_LIBRARIES)
965      message(STATUS "Will link against OpenMP libraries: ${OpenMP_CXX_LIBRARIES}")
966    endif()
967    add_library(caffe2::openmp INTERFACE IMPORTED)
968    target_link_libraries(caffe2::openmp INTERFACE OpenMP::OpenMP_CXX)
969    list(APPEND Caffe2_DEPENDENCY_LIBS caffe2::openmp)
970    if(MSVC AND OpenMP_CXX_LIBRARIES MATCHES ".*libiomp5md\\.lib.*")
971      target_compile_definitions(caffe2::openmp INTERFACE _OPENMP_NOFORCE_MANIFEST)
972      target_link_options(caffe2::openmp INTERFACE "/NODEFAULTLIB:vcomp")
973    endif()
974  else()
975    message(WARNING "Not compiling with OpenMP. Suppress this warning with -DUSE_OPENMP=OFF")
976    caffe2_update_option(USE_OPENMP OFF)
977  endif()
978endif()
979
980
981
982# ---[ Android specific ones
983if(ANDROID)
984  list(APPEND Caffe2_DEPENDENCY_LIBS log)
985endif()
986
987# ---[ LLVM
988if(USE_LLVM)
989  message(STATUS "Looking for LLVM in ${USE_LLVM}")
990  find_package(LLVM PATHS ${USE_LLVM} NO_DEFAULT_PATH)
991
992  if(LLVM_FOUND)
993    message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
994    message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
995
996    include_directories(${LLVM_INCLUDE_DIRS})
997    add_definitions(-DTORCH_ENABLE_LLVM)
998  endif(LLVM_FOUND)
999endif(USE_LLVM)
1000
1001# ---[ cuDNN
1002if(USE_CUDNN)
1003  if(CUDNN_VERSION VERSION_LESS 8.5)
1004    message(FATAL_ERROR "PyTorch needs CuDNN-8.5 or above, but found ${CUDNN_VERSION}. Builds are still possible with `USE_CUDNN=0`")
1005  endif()
1006  set(CUDNN_FRONTEND_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/../third_party/cudnn_frontend/include)
1007  target_include_directories(torch::cudnn INTERFACE ${CUDNN_FRONTEND_INCLUDE_DIR})
1008endif()
1009
1010# ---[ HIP
1011if(USE_ROCM)
1012  # This prevents linking in the libtinfo from /opt/conda/lib which conflicts with ROCm libtinfo.
1013  # Currently only active for Ubuntu 20.04 and greater versions.
1014  if(UNIX AND EXISTS "/etc/os-release")
1015    file(STRINGS /etc/os-release OS_RELEASE)
1016    set(DISTRO_NAME "")
1017    set(DISTRO_VERSION "")
1018    foreach(line ${OS_RELEASE})
1019      string(REGEX MATCH "^NAME=" DISTRO_NAME_MATCH ${line})
1020      if(NOT DISTRO_NAME_MATCH STREQUAL "")
1021        string(REGEX REPLACE "^NAME=\"(.*)\"" "\\1" DISTRO_NAME ${line})
1022      endif()
1023      string(REGEX MATCH "^VERSION_ID=" DISTRO_VERSION_MATCH ${line})
1024      if(NOT DISTRO_VERSION_MATCH STREQUAL "")
1025        string(REGEX REPLACE "^VERSION_ID=\"(.*)\"" "\\1" DISTRO_VERSION ${line})
1026      endif()
1027    endforeach()
1028    if(DISTRO_NAME STREQUAL "Ubuntu" AND DISTRO_VERSION VERSION_GREATER_EQUAL "20.04")
1029      find_library(LIBTINFO_LOC tinfo NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH)
1030      if(LIBTINFO_LOC)
1031        get_filename_component(LIBTINFO_LOC_PARENT ${LIBTINFO_LOC} DIRECTORY)
1032        set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,${LIBTINFO_LOC_PARENT}")
1033      endif()
1034    endif()
1035  endif()
1036
1037  include(${CMAKE_CURRENT_LIST_DIR}/public/LoadHIP.cmake)
1038  if(PYTORCH_FOUND_HIP)
1039    message(INFO "Compiling with HIP for AMD.")
1040    caffe2_update_option(USE_ROCM ON)
1041
1042    if(USE_NCCL AND NOT USE_SYSTEM_NCCL)
1043      message(INFO "Forcing USE_SYSTEM_NCCL to ON since it's required by using RCCL")
1044      caffe2_update_option(USE_SYSTEM_NCCL ON)
1045    endif()
1046
1047    list(APPEND HIP_CXX_FLAGS -fPIC)
1048    list(APPEND HIP_CXX_FLAGS -D__HIP_PLATFORM_AMD__=1)
1049    list(APPEND HIP_CXX_FLAGS -DCUDA_HAS_FP16=1)
1050    list(APPEND HIP_CXX_FLAGS -DUSE_ROCM)
1051    list(APPEND HIP_CXX_FLAGS -D__HIP_NO_HALF_OPERATORS__=1)
1052    list(APPEND HIP_CXX_FLAGS -D__HIP_NO_HALF_CONVERSIONS__=1)
1053    list(APPEND HIP_CXX_FLAGS -DTORCH_HIP_VERSION=${TORCH_HIP_VERSION})
1054    list(APPEND HIP_CXX_FLAGS -Wno-shift-count-negative)
1055    list(APPEND HIP_CXX_FLAGS -Wno-shift-count-overflow)
1056    list(APPEND HIP_CXX_FLAGS -Wno-duplicate-decl-specifier)
1057    list(APPEND HIP_CXX_FLAGS -DCAFFE2_USE_MIOPEN)
1058    list(APPEND HIP_CXX_FLAGS -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_HIP)
1059    list(APPEND HIP_CXX_FLAGS -std=c++17)
1060    list(APPEND HIP_CXX_FLAGS -DHIPBLAS_V2)
1061    if(HIP_NEW_TYPE_ENUMS)
1062      list(APPEND HIP_CXX_FLAGS -DHIP_NEW_TYPE_ENUMS)
1063    endif()
1064    add_definitions(-DROCM_VERSION=${ROCM_VERSION_DEV_INT})
1065    add_definitions(-DTORCH_HIP_VERSION=${TORCH_HIP_VERSION})
1066    message("TORCH_HIP_VERSION=${TORCH_HIP_VERSION} is added as a compiler defines")
1067
1068    if(CMAKE_BUILD_TYPE MATCHES Debug)
1069       list(APPEND HIP_CXX_FLAGS -g2)
1070       list(APPEND HIP_CXX_FLAGS -O0)
1071       list(APPEND HIP_HIPCC_FLAGS -fdebug-info-for-profiling)
1072    endif(CMAKE_BUILD_TYPE MATCHES Debug)
1073
1074    # needed for compat with newer versions of hip-clang that introduced C++20 mangling rules
1075    list(APPEND HIP_HIPCC_FLAGS -fclang-abi-compat=17)
1076
1077    set(HIP_CLANG_FLAGS ${HIP_CXX_FLAGS})
1078    # Ask hcc to generate device code during compilation so we can use
1079    # host linker to link.
1080    list(APPEND HIP_CLANG_FLAGS -fno-gpu-rdc)
1081    foreach(pytorch_rocm_arch ${PYTORCH_ROCM_ARCH})
1082      list(APPEND HIP_CLANG_FLAGS --offload-arch=${pytorch_rocm_arch})
1083    endforeach()
1084
1085    set(Caffe2_HIP_INCLUDE
1086       $<INSTALL_INTERFACE:include> ${Caffe2_HIP_INCLUDE})
1087    # This is needed for library added by hip_add_library (same for hip_add_executable)
1088    hip_include_directories(${Caffe2_HIP_INCLUDE})
1089
1090    set(Caffe2_PUBLIC_HIP_DEPENDENCY_LIBS
1091      hip::amdhip64 MIOpen hiprtc::hiprtc) # libroctx will be linked in with MIOpen
1092    list(APPEND Caffe2_PUBLIC_HIP_DEPENDENCY_LIBS roc::hipblaslt)
1093
1094    list(APPEND Caffe2_PUBLIC_HIP_DEPENDENCY_LIBS
1095      roc::hipblas hip::hipfft hip::hiprand roc::hipsparse roc::hipsolver)
1096
1097    # ---[ Kernel asserts
1098    # Kernel asserts is disabled for ROCm by default.
1099    # It can be turned on by turning on the env USE_ROCM_KERNEL_ASSERT to the build system.
1100    if(USE_ROCM_KERNEL_ASSERT)
1101      message(STATUS "Enabling Kernel Assert for ROCm")
1102    else()
1103      message(STATUS "Disabling Kernel Assert for ROCm")
1104    endif()
1105
1106  else()
1107    caffe2_update_option(USE_ROCM OFF)
1108  endif()
1109endif()
1110
1111# ---[ NCCL
1112if(USE_NCCL)
1113  if(NOT (USE_CUDA OR USE_ROCM))
1114    message(WARNING
1115        "Not using CUDA/ROCM, so disabling USE_NCCL. Suppress this warning with "
1116        "-DUSE_NCCL=OFF.")
1117    caffe2_update_option(USE_NCCL OFF)
1118  elseif(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
1119    message(WARNING "NCCL is currently only supported under Linux.")
1120    caffe2_update_option(USE_NCCL OFF)
1121  elseif(USE_CUDA)
1122    include(${CMAKE_CURRENT_LIST_DIR}/External/nccl.cmake)
1123    list(APPEND Caffe2_CUDA_DEPENDENCY_LIBS __caffe2_nccl)
1124  elseif(USE_ROCM)
1125    include(${CMAKE_CURRENT_LIST_DIR}/External/rccl.cmake)
1126    list(APPEND Caffe2_CUDA_DEPENDENCY_LIBS __caffe2_nccl)
1127  endif()
1128endif()
1129
1130# ---[ UCC
1131if(USE_UCC)
1132  if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux")
1133    message(WARNING "UCC is currently only supported under Linux.")
1134    caffe2_update_option(USE_UCC OFF)
1135  else()
1136    include(${CMAKE_CURRENT_LIST_DIR}/External/ucc.cmake)
1137  endif()
1138endif()
1139
1140# ---[ CUB
1141if(USE_CUDA)
1142  find_package(CUB)
1143  if(NOT CUB_FOUND)
1144    message(FATAL_ERROR "Cannot find CUB.")
1145  endif()
1146  include_directories(SYSTEM ${CUB_INCLUDE_DIRS})
1147endif()
1148
1149if(USE_DISTRIBUTED AND USE_TENSORPIPE)
1150  if(MSVC)
1151    message(WARNING "Tensorpipe cannot be used on Windows.")
1152  else()
1153    if(USE_CUDA)
1154      set(TP_USE_CUDA ON CACHE BOOL "" FORCE)
1155      set(TP_ENABLE_CUDA_IPC ON CACHE BOOL "" FORCE)
1156    endif()
1157    set(TP_BUILD_LIBUV ON CACHE BOOL "" FORCE)
1158    add_compile_options(-DTORCH_USE_LIBUV)
1159    include_directories(BEFORE SYSTEM ${CMAKE_CURRENT_LIST_DIR}/../third_party/tensorpipe/third_party/libuv/include)
1160    set(TP_STATIC_OR_SHARED STATIC CACHE STRING "" FORCE)
1161
1162    # Tensorpipe uses cuda_add_library
1163    torch_update_find_cuda_flags()
1164    add_subdirectory(${PROJECT_SOURCE_DIR}/third_party/tensorpipe)
1165
1166    list(APPEND Caffe2_DEPENDENCY_LIBS tensorpipe)
1167    list(APPEND Caffe2_DEPENDENCY_LIBS nlohmann)
1168    if(USE_CUDA)
1169      list(APPEND Caffe2_CUDA_DEPENDENCY_LIBS tensorpipe_cuda)
1170    elseif(USE_ROCM)
1171      message(WARNING "TensorPipe doesn't yet support ROCm")
1172      # Not yet...
1173      # list(APPEND Caffe2_HIP_DEPENDENCY_LIBS tensorpipe_hip)
1174    endif()
1175  endif()
1176endif()
1177
1178if(USE_GLOO)
1179  if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
1180    message(WARNING "Gloo can only be used on 64-bit systems.")
1181    caffe2_update_option(USE_GLOO OFF)
1182  else()
1183    # Don't install gloo
1184    set(GLOO_INSTALL OFF CACHE BOOL "" FORCE)
1185    set(GLOO_STATIC_OR_SHARED STATIC CACHE STRING "" FORCE)
1186
1187    # Temporarily override variables to avoid building Gloo tests/benchmarks
1188    set(__BUILD_TEST ${BUILD_TEST})
1189    set(__BUILD_BENCHMARK ${BUILD_BENCHMARK})
1190    set(BUILD_TEST OFF)
1191    set(BUILD_BENCHMARK OFF)
1192    if(USE_ROCM)
1193      set(ENV{GLOO_ROCM_ARCH} "${PYTORCH_ROCM_ARCH}")
1194    endif()
1195    if(NOT USE_SYSTEM_GLOO)
1196      if(USE_DISTRIBUED AND USE_TENSORPIPE)
1197        get_target_property(_include_dirs uv_a INCLUDE_DIRECTORIES)
1198        set_target_properties(uv_a PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${_include_dirs}")
1199      endif()
1200      if(USE_NCCL AND NOT USE_SYSTEM_NCCL)
1201        # Tell Gloo build system to use bundled NCCL, see
1202        # https://github.com/facebookincubator/gloo/blob/950c0e23819779a9e0c70b861db4c52b31d1d1b2/cmake/Dependencies.cmake#L123
1203        set(NCCL_EXTERNAL ON)
1204      endif()
1205      set(GLOO_USE_CUDA_TOOLKIT ON CACHE BOOL "" FORCE)
1206      add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../third_party/gloo)
1207    else()
1208      add_library(gloo SHARED IMPORTED)
1209      find_library(GLOO_LIBRARY gloo)
1210      if(NOT GLOO_LIBRARY)
1211        message(FATAL_ERROR "Cannot find gloo")
1212      endif()
1213      message("Found gloo: ${GLOO_LIBRARY}")
1214      set_target_properties(gloo PROPERTIES IMPORTED_LOCATION ${GLOO_LIBRARY})
1215    endif()
1216    # Here is a little bit hacky. We have to put PROJECT_BINARY_DIR in front
1217    # of PROJECT_SOURCE_DIR with/without conda system. The reason is that
1218    # gloo generates a new config.h in the binary diretory.
1219    include_directories(BEFORE SYSTEM ${CMAKE_CURRENT_LIST_DIR}/../third_party/gloo)
1220    include_directories(BEFORE SYSTEM ${PROJECT_BINARY_DIR}/third_party/gloo)
1221    set(BUILD_TEST ${__BUILD_TEST})
1222    set(BUILD_BENCHMARK ${__BUILD_BENCHMARK})
1223
1224    # Add explicit dependency since NCCL is built from third_party.
1225    # Without dependency, make -jN with N>1 can fail if the NCCL build
1226    # hasn't finished when CUDA targets are linked.
1227    if(NOT USE_SYSTEM_NCCL AND USE_NCCL AND NOT USE_ROCM)
1228      add_dependencies(gloo_cuda nccl_external)
1229    endif()
1230    # Pick the right dependency depending on USE_CUDA
1231    list(APPEND Caffe2_DEPENDENCY_LIBS gloo)
1232    if(USE_CUDA)
1233      list(APPEND Caffe2_CUDA_DEPENDENCY_LIBS gloo_cuda)
1234    elseif(USE_ROCM)
1235      list(APPEND Caffe2_HIP_DEPENDENCY_LIBS gloo_hip)
1236    endif()
1237    add_compile_options(-DCAFFE2_USE_GLOO)
1238  endif()
1239endif()
1240
1241# ---[ profiling
1242if(USE_PROF)
1243  find_package(htrace)
1244  if(htrace_FOUND)
1245    set(USE_PROF_HTRACE ON)
1246  else()
1247    message(WARNING "htrace not found. Caffe2 will build without htrace prof")
1248  endif()
1249endif()
1250
1251if(USE_SNPE AND ANDROID)
1252  if(SNPE_LOCATION AND SNPE_HEADERS)
1253    message(STATUS "Using SNPE location specified by -DSNPE_LOCATION: " ${SNPE_LOCATION})
1254    message(STATUS "Using SNPE headers specified by -DSNPE_HEADERS: " ${SNPE_HEADERS})
1255    include_directories(SYSTEM ${SNPE_HEADERS})
1256    add_library(snpe SHARED IMPORTED)
1257    set_property(TARGET snpe PROPERTY IMPORTED_LOCATION ${SNPE_LOCATION})
1258    list(APPEND Caffe2_DEPENDENCY_LIBS snpe)
1259  else()
1260    caffe2_update_option(USE_SNPE OFF)
1261  endif()
1262endif()
1263
1264if(USE_NNAPI AND NOT ANDROID)
1265  message(WARNING "NNApi is only used in android builds.")
1266  caffe2_update_option(USE_NNAPI OFF)
1267endif()
1268
1269# ---[ Onnx
1270if(CAFFE2_CMAKE_BUILDING_WITH_MAIN_REPO AND NOT INTERN_DISABLE_ONNX)
1271  if(EXISTS "${CAFFE2_CUSTOM_PROTOC_EXECUTABLE}")
1272    set(ONNX_CUSTOM_PROTOC_EXECUTABLE ${CAFFE2_CUSTOM_PROTOC_EXECUTABLE})
1273  endif()
1274  set(TEMP_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
1275  set(BUILD_SHARED_LIBS OFF)
1276  set(ONNX_USE_MSVC_STATIC_RUNTIME ${CAFFE2_USE_MSVC_STATIC_RUNTIME})
1277  set(ONNX_USE_LITE_PROTO ${CAFFE2_USE_LITE_PROTO})
1278  # If linking local protobuf, make sure ONNX has the same protobuf
1279  # patches as Caffe2 and Caffe proto. This forces some functions to
1280  # not be inline and instead route back to the statically-linked protobuf.
1281  if(CAFFE2_LINK_LOCAL_PROTOBUF)
1282    set(ONNX_PROTO_POST_BUILD_SCRIPT ${PROJECT_SOURCE_DIR}/cmake/ProtoBufPatch.cmake)
1283  endif()
1284  if(ONNX_ML)
1285    add_definitions(-DONNX_ML=1)
1286  endif()
1287  add_definitions(-DONNXIFI_ENABLE_EXT=1)
1288  if(NOT USE_SYSTEM_ONNX)
1289    add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../third_party/onnx EXCLUDE_FROM_ALL)
1290    if(NOT MSVC)
1291      set_target_properties(onnx_proto PROPERTIES CXX_STANDARD 17)
1292    endif()
1293  endif()
1294
1295  add_definitions(-DONNX_NAMESPACE=${ONNX_NAMESPACE})
1296  if(NOT USE_SYSTEM_ONNX)
1297    include_directories(${ONNX_INCLUDE_DIRS})
1298    # In mobile build we care about code size, and so we need drop
1299    # everything (e.g. checker) in onnx but the pb definition.
1300    if(ANDROID OR IOS)
1301      caffe2_interface_library(onnx_proto onnx_library)
1302    else()
1303      caffe2_interface_library(onnx onnx_library)
1304    endif()
1305    list(APPEND Caffe2_DEPENDENCY_WHOLE_LINK_LIBS onnx_library)
1306  else()
1307    add_library(onnx SHARED IMPORTED)
1308    find_library(ONNX_LIBRARY onnx)
1309    if(NOT ONNX_LIBRARY)
1310      message(FATAL_ERROR "Cannot find onnx")
1311    endif()
1312    set_property(TARGET onnx PROPERTY IMPORTED_LOCATION ${ONNX_LIBRARY})
1313    add_library(onnx_proto SHARED IMPORTED)
1314    find_library(ONNX_PROTO_LIBRARY onnx_proto)
1315    if(NOT ONNX_PROTO_LIBRARY)
1316      message(FATAL_ERROR "Cannot find onnx")
1317    endif()
1318    set_property(TARGET onnx_proto PROPERTY IMPORTED_LOCATION ${ONNX_PROTO_LIBRARY})
1319    message("-- Found onnx: ${ONNX_LIBRARY} ${ONNX_PROTO_LIBRARY}")
1320    list(APPEND Caffe2_DEPENDENCY_LIBS onnx_proto onnx)
1321  endif()
1322  # Recover the build shared libs option.
1323  set(BUILD_SHARED_LIBS ${TEMP_BUILD_SHARED_LIBS})
1324endif()
1325
1326# --[ ATen checks
1327set(USE_LAPACK 0)
1328
1329# we need to build all targets to be linked with PIC
1330if(USE_KINETO AND INTERN_BUILD_MOBILE AND USE_LITE_INTERPRETER_PROFILER)
1331  set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
1332endif()
1333
1334if(NOT INTERN_BUILD_MOBILE)
1335  set(TORCH_CUDA_ARCH_LIST $ENV{TORCH_CUDA_ARCH_LIST})
1336  string(APPEND CMAKE_CUDA_FLAGS " $ENV{TORCH_NVCC_FLAGS}")
1337  set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
1338
1339  # Top-level build config
1340  ############################################
1341  # Flags
1342  # When using MSVC
1343  # Detect CUDA architecture and get best NVCC flags
1344  # finding cuda must be first because other things depend on the result
1345  #
1346  # NB: We MUST NOT run this find_package if NOT USE_CUDA is set, because upstream
1347  # FindCUDA has a bug where it will still attempt to make use of NOTFOUND
1348  # compiler variables to run various probe tests.  We could try to fix
1349  # this, but since FindCUDA upstream is subsumed by first-class support
1350  # for CUDA language, it seemed not worth fixing.
1351
1352  if(MSVC)
1353    # we want to respect the standard, and we are bored of those **** .
1354    add_definitions(-D_CRT_SECURE_NO_DEPRECATE=1)
1355    string(APPEND CMAKE_CUDA_FLAGS " -Xcompiler=/wd4819,/wd4503,/wd4190,/wd4244,/wd4251,/wd4275,/wd4522")
1356  endif()
1357
1358  string(APPEND CMAKE_CUDA_FLAGS " -Wno-deprecated-gpu-targets --expt-extended-lambda")
1359
1360  # use cub in a safe manner, see:
1361  # https://github.com/pytorch/pytorch/pull/55292
1362  string(APPEND CMAKE_CUDA_FLAGS " -DCUB_WRAPPED_NAMESPACE=at_cuda_detail")
1363
1364  message(STATUS "Found CUDA with FP16 support, compiling with torch.cuda.HalfTensor")
1365  string(APPEND CMAKE_CUDA_FLAGS " -DCUDA_HAS_FP16=1"
1366                                 " -D__CUDA_NO_HALF_OPERATORS__"
1367                                 " -D__CUDA_NO_HALF_CONVERSIONS__"
1368                                 " -D__CUDA_NO_HALF2_OPERATORS__"
1369                                 " -D__CUDA_NO_BFLOAT16_CONVERSIONS__")
1370
1371  string(APPEND CMAKE_C_FLAGS_RELEASE " -DNDEBUG")
1372  string(APPEND CMAKE_CXX_FLAGS_RELEASE " -DNDEBUG")
1373  if(NOT GENERATOR_IS_MULTI_CONFIG)
1374    if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
1375      message(STATUS "Adding -DNDEBUG to compile flags")
1376      string(APPEND CMAKE_C_FLAGS " -DNDEBUG")
1377      string(APPEND CMAKE_CXX_FLAGS " -DNDEBUG")
1378    else()
1379      message(STATUS "Removing -DNDEBUG from compile flags")
1380      string(REGEX REPLACE "[-/]DNDEBUG" "" CMAKE_C_FLAGS "" ${CMAKE_C_FLAGS})
1381      string(REGEX REPLACE "[-/]DNDEBUG" "" CMAKE_CXX_FLAGS "" ${CMAKE_CXX_FLAGS})
1382    endif()
1383  endif()
1384  string(REGEX REPLACE "[-/]DNDEBUG" "" CMAKE_C_FLAGS_DEBUG "" ${CMAKE_C_FLAGS_DEBUG})
1385  string(REGEX REPLACE "[-/]DNDEBUG" "" CMAKE_CXX_FLAGS_DEBUG "" ${CMAKE_CXX_FLAGS_DEBUG})
1386
1387  set(CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE OFF)
1388
1389  if(USE_CUDA OR USE_ROCM)
1390    if(USE_MAGMA)
1391      find_package(MAGMA)
1392      if(MAGMA_FOUND)
1393        message(STATUS "Compiling with MAGMA support")
1394        message(STATUS "MAGMA INCLUDE DIRECTORIES: ${MAGMA_INCLUDE_DIR}")
1395        message(STATUS "MAGMA LIBRARIES: ${MAGMA_LIBRARIES}")
1396        message(STATUS "MAGMA V2 check: ${MAGMA_V2}")
1397      else()
1398        message(STATUS "MAGMA not found. Compiling without MAGMA support")
1399        caffe2_update_option(USE_MAGMA OFF)
1400      endif()
1401    endif()
1402  elseif(USE_MAGMA)
1403    message(WARNING
1404      "Not compiling with MAGMA. Suppress this warning with "
1405      "-DUSE_MAGMA=OFF.")
1406    caffe2_update_option(USE_MAGMA OFF)
1407  endif()
1408
1409  # ARM specific flags
1410  find_package(ARM)
1411  if(ASIMD_FOUND)
1412    message(STATUS "asimd/Neon found with compiler flag : -D__NEON__")
1413    add_compile_options(-D__NEON__)
1414  elseif(NEON_FOUND)
1415    if(APPLE)
1416      message(STATUS "Neon found with compiler flag : -D__NEON__")
1417      add_compile_options(-D__NEON__)
1418    else()
1419      message(STATUS "Neon found with compiler flag : -mfpu=neon -D__NEON__")
1420      add_compile_options(-mfpu=neon -D__NEON__)
1421    endif()
1422  endif()
1423  if(CORTEXA8_FOUND)
1424    message(STATUS "Cortex-A8 Found with compiler flag : -mcpu=cortex-a8")
1425    add_compile_options(-mcpu=cortex-a8 -fprefetch-loop-arrays)
1426  endif()
1427  if(CORTEXA9_FOUND)
1428    message(STATUS "Cortex-A9 Found with compiler flag : -mcpu=cortex-a9")
1429    add_compile_options(-mcpu=cortex-a9)
1430  endif()
1431
1432  find_package(LAPACK)
1433  if(LAPACK_FOUND)
1434    set(USE_LAPACK 1)
1435    list(APPEND Caffe2_PRIVATE_DEPENDENCY_LIBS ${LAPACK_LIBRARIES})
1436  endif()
1437
1438  if(NOT USE_CUDA)
1439    message("disabling CUDA because NOT USE_CUDA is set")
1440    set(AT_CUDA_ENABLED 0)
1441  else()
1442    set(AT_CUDA_ENABLED 1)
1443  endif()
1444
1445  if(NOT USE_ROCM)
1446    message("disabling ROCM because NOT USE_ROCM is set")
1447    message(STATUS "MIOpen not found. Compiling without MIOpen support")
1448    set(AT_ROCM_ENABLED 0)
1449  else()
1450    include_directories(BEFORE ${MIOPEN_INCLUDE_DIRS})
1451    set(AT_ROCM_ENABLED 1)
1452  endif()
1453
1454  if(USE_MKLDNN)
1455    if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
1456      message(WARNING
1457        "x64 operating system is required for MKLDNN. "
1458        "Not compiling with MKLDNN. "
1459        "Turn this warning off by USE_MKLDNN=OFF.")
1460      set(USE_MKLDNN OFF)
1461    endif()
1462    if(USE_MKLDNN_ACL)
1463      set(AT_MKLDNN_ACL_ENABLED 1)
1464    endif()
1465  endif()
1466  if(USE_MKLDNN)
1467    include(${CMAKE_CURRENT_LIST_DIR}/public/mkldnn.cmake)
1468    if(MKLDNN_FOUND)
1469      set(AT_MKLDNN_ENABLED 1)
1470      include_directories(AFTER SYSTEM ${MKLDNN_INCLUDE_DIR})
1471    else()
1472      message(WARNING "MKLDNN could not be found.")
1473      caffe2_update_option(USE_MKLDNN OFF)
1474    endif()
1475  else()
1476    message("disabling MKLDNN because USE_MKLDNN is not set")
1477  endif()
1478
1479  if(UNIX AND NOT APPLE)
1480     include(CheckLibraryExists)
1481     # https://github.com/libgit2/libgit2/issues/2128#issuecomment-35649830
1482     CHECK_LIBRARY_EXISTS(rt clock_gettime "time.h" NEED_LIBRT)
1483     if(NEED_LIBRT)
1484       list(APPEND Caffe2_DEPENDENCY_LIBS rt)
1485       set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} rt)
1486     endif(NEED_LIBRT)
1487  endif(UNIX AND NOT APPLE)
1488
1489  if(UNIX)
1490    set(CMAKE_EXTRA_INCLUDE_FILES "sys/mman.h")
1491    CHECK_FUNCTION_EXISTS(mmap HAVE_MMAP)
1492    if(HAVE_MMAP)
1493      add_definitions(-DHAVE_MMAP=1)
1494    endif(HAVE_MMAP)
1495    # done for lseek: https://www.gnu.org/software/libc/manual/html_node/File-Position-Primitive.html
1496    add_definitions(-D_FILE_OFFSET_BITS=64)
1497    CHECK_FUNCTION_EXISTS(shm_open HAVE_SHM_OPEN)
1498    if(HAVE_SHM_OPEN)
1499      add_definitions(-DHAVE_SHM_OPEN=1)
1500    endif(HAVE_SHM_OPEN)
1501    CHECK_FUNCTION_EXISTS(shm_unlink HAVE_SHM_UNLINK)
1502    if(HAVE_SHM_UNLINK)
1503      add_definitions(-DHAVE_SHM_UNLINK=1)
1504    endif(HAVE_SHM_UNLINK)
1505    CHECK_FUNCTION_EXISTS(malloc_usable_size HAVE_MALLOC_USABLE_SIZE)
1506    if(HAVE_MALLOC_USABLE_SIZE)
1507      add_definitions(-DHAVE_MALLOC_USABLE_SIZE=1)
1508    endif(HAVE_MALLOC_USABLE_SIZE)
1509  endif(UNIX)
1510
1511  add_definitions(-DUSE_EXTERNAL_MZCRC)
1512  add_definitions(-DMINIZ_DISABLE_ZIP_READER_CRC32_CHECKS)
1513
1514  find_package(ZVECTOR) # s390x simd support
1515endif()
1516
1517#
1518# End ATen checks
1519#
1520set(TEMP_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS})
1521set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared libs" FORCE)
1522add_subdirectory(${PROJECT_SOURCE_DIR}/third_party/fmt)
1523
1524# Disable compiler feature checks for `fmt`.
1525#
1526# CMake compiles a little program to check compiler features. Some of our build
1527# configurations (notably the mobile build analyzer) will populate
1528# CMAKE_CXX_FLAGS in ways that break feature checks. Since we already know
1529# `fmt` is compatible with a superset of the compilers that PyTorch is, it
1530# shouldn't be too bad to just disable the checks.
1531set_target_properties(fmt-header-only PROPERTIES INTERFACE_COMPILE_FEATURES "")
1532
1533list(APPEND Caffe2_DEPENDENCY_LIBS fmt::fmt-header-only)
1534set(BUILD_SHARED_LIBS ${TEMP_BUILD_SHARED_LIBS} CACHE BOOL "Build shared libs" FORCE)
1535
1536# ---[ Kineto
1537# edge profiler depends on KinetoProfiler but it only does cpu
1538# profiling. Thus we dont need USE_CUDA/USE_ROCM
1539if(USE_KINETO AND INTERN_BUILD_MOBILE AND NOT (BUILD_LITE_INTERPRETER AND USE_LITE_INTERPRETER_PROFILER))
1540  message(STATUS "Not using libkineto in a mobile build.")
1541  set(USE_KINETO OFF)
1542endif()
1543
1544if(USE_KINETO AND INTERN_BUILD_MOBILE AND USE_LITE_INTERPRETER_PROFILER AND (USE_CUDA OR USE_ROCM))
1545  message(FATAL_ERROR "Mobile build with profiler does not support CUDA or ROCM")
1546endif()
1547
1548if(USE_KINETO)
1549  if((NOT USE_CUDA) OR MSVC)
1550    set(LIBKINETO_NOCUPTI ON CACHE STRING "" FORCE)
1551  else()
1552    set(LIBKINETO_NOCUPTI OFF CACHE STRING "")
1553    message(STATUS "Using Kineto with CUPTI support")
1554  endif()
1555
1556  if(NOT USE_ROCM)
1557    set(LIBKINETO_NOROCTRACER ON CACHE STRING "" FORCE)
1558  else()
1559    set(LIBKINETO_NOROCTRACER OFF CACHE STRING "")
1560    message(STATUS "Using Kineto with Roctracer support")
1561  endif()
1562
1563  if((NOT USE_XPU) OR WIN32)
1564    set(LIBKINETO_NOXPUPTI ON CACHE STRING "" FORCE)
1565  else()
1566    set(LIBKINETO_NOXPUPTI OFF CACHE STRING "")
1567    message(STATUS "Using Kineto with XPUPTI support")
1568  endif()
1569
1570  if(LIBKINETO_NOCUPTI AND LIBKINETO_NOROCTRACER AND LIBKINETO_NOXPUPTI)
1571    message(STATUS "Using CPU-only version of Kineto")
1572  endif()
1573
1574  set(CAFFE2_THIRD_PARTY_ROOT "${PROJECT_SOURCE_DIR}/third_party" CACHE STRING "")
1575  set(KINETO_SOURCE_DIR "${CAFFE2_THIRD_PARTY_ROOT}/kineto/libkineto" CACHE STRING "")
1576  set(KINETO_BUILD_TESTS OFF CACHE BOOL "")
1577  set(KINETO_LIBRARY_TYPE "static" CACHE STRING "")
1578
1579  message(STATUS "Configuring Kineto dependency:")
1580  message(STATUS "  KINETO_SOURCE_DIR = ${KINETO_SOURCE_DIR}")
1581  message(STATUS "  KINETO_BUILD_TESTS = ${KINETO_BUILD_TESTS}")
1582  message(STATUS "  KINETO_LIBRARY_TYPE = ${KINETO_LIBRARY_TYPE}")
1583
1584  if(NOT LIBKINETO_NOCUPTI)
1585    set(CUDA_SOURCE_DIR "${CUDA_TOOLKIT_ROOT_DIR}" CACHE STRING "")
1586    message(STATUS "  CUDA_SOURCE_DIR = ${CUDA_SOURCE_DIR}")
1587    message(STATUS "  CUDA_INCLUDE_DIRS = ${CUDA_INCLUDE_DIRS}")
1588
1589    if(NOT MSVC)
1590      if(USE_CUPTI_SO)
1591        set(CUPTI_LIB_NAME "libcupti.so")
1592      else()
1593        set(CUPTI_LIB_NAME "libcupti_static.a")
1594      endif()
1595    else()
1596      set(CUPTI_LIB_NAME "cupti.lib")
1597    endif()
1598
1599    find_library(CUPTI_LIBRARY_PATH ${CUPTI_LIB_NAME} PATHS
1600        ${CUDA_SOURCE_DIR}
1601        ${CUDA_SOURCE_DIR}/extras/CUPTI/lib64
1602        ${CUDA_SOURCE_DIR}/lib
1603        ${CUDA_SOURCE_DIR}/lib64
1604        NO_DEFAULT_PATH)
1605
1606    find_path(CUPTI_INCLUDE_DIR cupti.h PATHS
1607        ${CUDA_SOURCE_DIR}/extras/CUPTI/include
1608        ${CUDA_INCLUDE_DIRS}
1609        ${CUDA_SOURCE_DIR}
1610        ${CUDA_SOURCE_DIR}/include
1611        NO_DEFAULT_PATH)
1612
1613    if(CUPTI_LIBRARY_PATH AND CUPTI_INCLUDE_DIR)
1614      message(STATUS "  CUPTI_INCLUDE_DIR = ${CUPTI_INCLUDE_DIR}")
1615      set(CUDA_cupti_LIBRARY ${CUPTI_LIBRARY_PATH})
1616      message(STATUS "  CUDA_cupti_LIBRARY = ${CUDA_cupti_LIBRARY}")
1617      message(STATUS "Found CUPTI")
1618      set(LIBKINETO_NOCUPTI OFF CACHE STRING "" FORCE)
1619
1620      # I've only tested this sanity check on Linux; if someone
1621      # runs into this bug on another platform feel free to
1622      # generalize it accordingly
1623      if(NOT USE_CUPTI_SO AND UNIX)
1624        include(CheckCXXSourceRuns)
1625        # rt is handled by the CMAKE_REQUIRED_LIBRARIES set above
1626        if(NOT APPLE)
1627          set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} "dl" "pthread")
1628        endif()
1629        set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--whole-archive,${CUPTI_LIBRARY_PATH},--no-whole-archive")
1630        check_cxx_source_runs("#include <stdexcept>
1631  int main() {
1632    try {
1633      throw std::runtime_error(\"error\");
1634    } catch (...) {
1635      return 0;
1636    }
1637    return 1;
1638  }" EXCEPTIONS_WORK)
1639        set(CMAKE_REQUIRED_LINK_OPTIONS "")
1640        if(NOT EXCEPTIONS_WORK)
1641          message(FATAL_ERROR "Detected that statically linking against CUPTI causes exceptions to stop working.  See https://github.com/pytorch/pytorch/issues/57744 for more details.  Perhaps try: USE_CUPTI_SO=1 python setup.py develop --cmake")
1642        endif()
1643      endif()
1644
1645    else()
1646      message(STATUS "Could not find CUPTI library, using CPU-only Kineto build")
1647      set(LIBKINETO_NOCUPTI ON CACHE STRING "" FORCE)
1648    endif()
1649  endif()
1650
1651  if(NOT LIBKINETO_NOROCTRACER)
1652    if("$ENV{ROCM_SOURCE_DIR}" STREQUAL "")
1653      set(ENV{ROCM_SOURCE_DIR} "/opt/rocm")
1654    endif()
1655  endif()
1656
1657  if(NOT TARGET kineto)
1658    add_subdirectory("${KINETO_SOURCE_DIR}")
1659    set_property(TARGET kineto PROPERTY POSITION_INDEPENDENT_CODE ON)
1660  endif()
1661  list(APPEND Caffe2_DEPENDENCY_LIBS kineto)
1662  string(APPEND CMAKE_CXX_FLAGS " -DUSE_KINETO")
1663  if(LIBKINETO_NOCUPTI)
1664    string(APPEND CMAKE_CXX_FLAGS " -DLIBKINETO_NOCUPTI")
1665  endif()
1666  if(LIBKINETO_NOROCTRACER)
1667    string(APPEND CMAKE_CXX_FLAGS " -DLIBKINETO_NOROCTRACER")
1668  endif()
1669  if(LIBKINETO_NOXPUPTI)
1670    string(APPEND CMAKE_CXX_FLAGS " -DLIBKINETO_NOXPUPTI=ON")
1671  else()
1672    string(APPEND CMAKE_CXX_FLAGS " -DLIBKINETO_NOXPUPTI=OFF")
1673  endif()
1674  if(LIBKINETO_NOCUPTI AND LIBKINETO_NOROCTRACER AND LIBKINETO_NOXPUPTI)
1675    message(STATUS "Configured Kineto (CPU)")
1676  else()
1677    message(STATUS "Configured Kineto")
1678  endif()
1679endif()
1680
1681# Include google/FlatBuffers
1682include(${CMAKE_CURRENT_LIST_DIR}/FlatBuffers.cmake)
1683
1684# Include cpp-httplib
1685add_library(httplib INTERFACE IMPORTED)
1686target_include_directories(httplib SYSTEM INTERFACE ${PROJECT_SOURCE_DIR}/third_party/cpp-httplib)
1687
1688# Include nlohmann-json
1689add_library(nlohmann INTERFACE IMPORTED)
1690include_directories(nlohmann SYSTEM INTERFACE ${PROJECT_SOURCE_DIR}/third_party/nlohmann/include)
1691