| # This ill-named file does a number of things: | |
| # - Installs Caffe2 header files (this has nothing to do with code generation) | |
| # - Configures caffe2/core/macros.h | |
| # - Creates an ATen target for its generated C++ files and adds it | |
| # as a dependency | |
| ################################################################################ | |
| # Helper functions | |
| ################################################################################ | |
| function(filter_list output input) | |
| unset(result) | |
| foreach(filename ${${input}}) | |
| foreach(pattern ${ARGN}) | |
| if("${filename}" MATCHES "${pattern}") | |
| list(APPEND result "${filename}") | |
| endif() | |
| endforeach() | |
| endforeach() | |
| set(${output} ${result} PARENT_SCOPE) | |
| endfunction() | |
| function(filter_list_exclude output input) | |
| unset(result) | |
| foreach(filename ${${input}}) | |
| foreach(pattern ${ARGN}) | |
| if(NOT "${filename}" MATCHES "${pattern}") | |
| list(APPEND result "${filename}") | |
| endif() | |
| endforeach() | |
| endforeach() | |
| set(${output} ${result} PARENT_SCOPE) | |
| endfunction() | |
| ################################################################################ | |
| # ---[ Write the macros file | |
| configure_file( | |
| ${CMAKE_CURRENT_LIST_DIR}/../caffe2/core/macros.h.in | |
| ${CMAKE_BINARY_DIR}/caffe2/core/macros.h) | |
| # ---[ Installing the header files | |
| install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../caffe2 | |
| DESTINATION include | |
| FILES_MATCHING PATTERN "*.h") | |
| if (NOT INTERN_BUILD_ATEN_OPS) | |
| install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/core | |
| DESTINATION include/ATen | |
| FILES_MATCHING PATTERN "*.h") | |
| endif() | |
| install(FILES ${CMAKE_BINARY_DIR}/caffe2/core/macros.h | |
| DESTINATION include/caffe2/core) | |
| # ---[ ATen specific | |
| if (INTERN_BUILD_ATEN_OPS) | |
| SET(OPT_FLAG "-O3 ") | |
| IF(MSVC) | |
| SET(OPT_FLAG "/Ox /fp:strict ") | |
| ENDIF() | |
| SET(VCOMP_LIB "vcomp") | |
| IF("${CMAKE_BUILD_TYPE}" MATCHES "Debug") | |
| SET(OPT_FLAG " ") | |
| SET(VCOMP_LIB "vcompd") | |
| ENDIF() | |
| IF(C_AVX_FOUND) | |
| IF(MSVC) | |
| SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_LIST_DIR}/../aten/src/TH/vector/AVX.cpp PROPERTIES COMPILE_FLAGS "${OPT_FLAG}/arch:AVX ${CXX_AVX_FLAGS}") | |
| ELSE(MSVC) | |
| SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_LIST_DIR}/../aten/src/TH/vector/AVX.cpp PROPERTIES COMPILE_FLAGS "${OPT_FLAG} ${CXX_AVX_FLAGS}") | |
| ENDIF(MSVC) | |
| ENDIF(C_AVX_FOUND) | |
| IF(C_AVX2_FOUND) | |
| IF(MSVC) | |
| SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_LIST_DIR}/../aten/src/TH/vector/AVX2.cpp PROPERTIES COMPILE_FLAGS "${OPT_FLAG}/arch:AVX2 ${CXX_AVX2_FLAGS}") | |
| ELSE(MSVC) | |
| SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_LIST_DIR}/../aten/src/TH/vector/AVX2.cpp PROPERTIES COMPILE_FLAGS "${OPT_FLAG} ${CXX_AVX2_FLAGS}") | |
| ENDIF(MSVC) | |
| ENDIF(C_AVX2_FOUND) | |
| IF(NOT MSVC AND NOT "${CMAKE_C_COMPILER_ID}" MATCHES "Clang") | |
| SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_LIST_DIR}/../aten/src/TH/THAllocator.cpp PROPERTIES COMPILE_FLAGS "-fno-openmp") | |
| ENDIF() | |
| FILE(GLOB cpu_kernel_cpp_in "${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/native/cpu/*.cpp") | |
| LIST(APPEND CPU_CAPABILITY_NAMES "DEFAULT") | |
| LIST(APPEND CPU_CAPABILITY_FLAGS "${OPT_FLAG}") | |
| IF(CXX_AVX_FOUND) | |
| SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_AVX_CPU_DEFINITION") | |
| LIST(APPEND CPU_CAPABILITY_NAMES "AVX") | |
| IF(MSVC) | |
| LIST(APPEND CPU_CAPABILITY_FLAGS "${OPT_FLAG}/arch:AVX") | |
| ELSE(MSVC) | |
| LIST(APPEND CPU_CAPABILITY_FLAGS "${OPT_FLAG} -mavx") | |
| ENDIF(MSVC) | |
| ENDIF(CXX_AVX_FOUND) | |
| IF(CXX_AVX2_FOUND) | |
| SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_AVX2_CPU_DEFINITION") | |
| # Some versions of GCC pessimistically split unaligned load and store | |
| # instructions when using the default tuning. This is a bad choice on | |
| # new Intel and AMD processors so we disable it when compiling with AVX2. | |
| # See https://stackoverflow.com/questions/52626726/why-doesnt-gcc-resolve-mm256-loadu-pd-as-single-vmovupd#tab-top | |
| check_cxx_compiler_flag("-mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store" COMPILER_SUPPORTS_NO_AVX256_SPLIT) | |
| IF(COMPILER_SUPPORTS_NO_AVX256_SPLIT) | |
| SET(CPU_NO_AVX256_SPLIT_FLAGS "-mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store") | |
| ENDIF(COMPILER_SUPPORTS_NO_AVX256_SPLIT) | |
| LIST(APPEND CPU_CAPABILITY_NAMES "AVX2") | |
| IF(MSVC) | |
| LIST(APPEND CPU_CAPABILITY_FLAGS "${OPT_FLAG}/arch:AVX2") | |
| ELSE(MSVC) | |
| LIST(APPEND CPU_CAPABILITY_FLAGS "${OPT_FLAG} -mavx2 -mfma ${CPU_NO_AVX256_SPLIT_FLAGS}") | |
| ENDIF(MSVC) | |
| ENDIF(CXX_AVX2_FOUND) | |
| list(LENGTH CPU_CAPABILITY_NAMES NUM_CPU_CAPABILITY_NAMES) | |
| math(EXPR NUM_CPU_CAPABILITY_NAMES "${NUM_CPU_CAPABILITY_NAMES}-1") | |
| FOREACH(i RANGE ${NUM_CPU_CAPABILITY_NAMES}) | |
| FOREACH(IMPL ${cpu_kernel_cpp_in}) | |
| string(REPLACE "${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/" "" NAME ${IMPL}) | |
| LIST(GET CPU_CAPABILITY_NAMES ${i} CPU_CAPABILITY) | |
| SET(NEW_IMPL ${CMAKE_BINARY_DIR}/aten/src/ATen/${NAME}.${CPU_CAPABILITY}.cpp) | |
| CONFIGURE_FILE(${IMPL} ${NEW_IMPL} COPYONLY) | |
| SET(cpu_kernel_cpp ${NEW_IMPL} ${cpu_kernel_cpp}) # Create list of copies | |
| LIST(GET CPU_CAPABILITY_FLAGS ${i} FLAGS) | |
| IF(MSVC) | |
| SET(MACRO_FLAG "/DCPU_CAPABILITY=${CPU_CAPABILITY} /DCPU_CAPABILITY_${CPU_CAPABILITY}") | |
| ELSE(MSVC) | |
| SET(MACRO_FLAG "-DCPU_CAPABILITY=${CPU_CAPABILITY} -DCPU_CAPABILITY_${CPU_CAPABILITY}") | |
| ENDIF(MSVC) | |
| SET_SOURCE_FILES_PROPERTIES(${NEW_IMPL} PROPERTIES COMPILE_FLAGS "${FLAGS} ${MACRO_FLAG}") | |
| ENDFOREACH() | |
| ENDFOREACH() | |
| list(APPEND ATen_CPU_SRCS ${cpu_kernel_cpp}) | |
| set(cwrap_files | |
| ${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/Declarations.cwrap | |
| ${CMAKE_CURRENT_LIST_DIR}/../aten/src/THNN/generic/THNN.h | |
| ${CMAKE_CURRENT_LIST_DIR}/../aten/src/THCUNN/generic/THCUNN.h | |
| ${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/nn.yaml | |
| ${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/native/native_functions.yaml) | |
| FILE(GLOB all_python "${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/*.py") | |
| set(GEN_ROCM_FLAG) | |
| if (USE_ROCM) | |
| set(GEN_ROCM_FLAG --rocm) | |
| endif() | |
| SET(GEN_COMMAND | |
| "${PYTHON_EXECUTABLE}" ${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/gen.py | |
| --source-path ${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen | |
| --install_dir ${CMAKE_BINARY_DIR}/aten/src/ATen | |
| ${GEN_ROCM_FLAG} | |
| ${cwrap_files} | |
| ) | |
| EXECUTE_PROCESS( | |
| COMMAND ${GEN_COMMAND} | |
| --output-dependencies ${CMAKE_BINARY_DIR}/aten/src/ATen/generated_cpp.txt | |
| RESULT_VARIABLE RETURN_VALUE | |
| ) | |
| if (NOT RETURN_VALUE EQUAL 0) | |
| message(STATUS ${generated_cpp}) | |
| message(FATAL_ERROR "Failed to get generated_cpp list") | |
| endif() | |
| file(READ ${CMAKE_BINARY_DIR}/aten/src/ATen/generated_cpp.txt generated_cpp) | |
| file(READ ${CMAKE_BINARY_DIR}/aten/src/ATen/generated_cpp.txt-cuda cuda_generated_cpp) | |
| file(GLOB_RECURSE all_templates "${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/templates/*") | |
| # these are files that are generated by the script and checked in -- the script checks | |
| # that they are equivalent so it must be a dependency of the script | |
| set(core_gen_checked_inputs | |
| ${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/core/Type.h | |
| ${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/core/Tensor.h | |
| ${CMAKE_CURRENT_LIST_DIR}/../aten/src/ATen/core/TensorMethods.h) | |
| file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/aten/src/ATen) | |
| file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/aten/src/ATen/core_tmp) | |
| add_custom_command(OUTPUT ${generated_cpp} ${cuda_generated_cpp} | |
| COMMAND ${GEN_COMMAND} | |
| DEPENDS ${all_python} ${all_templates} ${cwrap_files} ${core_gen_checked_inputs}) | |
| # Generated headers used from a CUDA (.cu) file are | |
| # not tracked correctly in CMake. We make the libATen.so depend explicitly | |
| # on building the generated ATen files to workaround. | |
| add_custom_target(ATEN_CPU_FILES_GEN_TARGET DEPENDS ${generated_cpp}) | |
| add_custom_target(ATEN_CUDA_FILES_GEN_TARGET DEPENDS ${cuda_generated_cpp}) | |
| add_library(ATEN_CPU_FILES_GEN_LIB INTERFACE) | |
| add_library(ATEN_CUDA_FILES_GEN_LIB INTERFACE) | |
| add_dependencies(ATEN_CPU_FILES_GEN_LIB ATEN_CPU_FILES_GEN_TARGET) | |
| add_dependencies(ATEN_CUDA_FILES_GEN_LIB ATEN_CUDA_FILES_GEN_TARGET) | |
| endif() |