summaryrefslogtreecommitdiff
path: root/cmake
diff options
context:
space:
mode:
authorAnatoly Baksheev <no@email>2014-12-17 12:09:14 +0300
committerEvan Shelhamer <shelhamer@imaginarynumber.net>2015-02-16 20:48:16 -0800
commit9358247014eb8322160c7feaad46091412d75d3f (patch)
treec95feaba2700ce53350db6a0ac7a389cb5a20a60 /cmake
parent32bf5c7ad804ad683aa5ea9382209e9284451e5f (diff)
downloadcaffeonacl-9358247014eb8322160c7feaad46091412d75d3f.tar.gz
caffeonacl-9358247014eb8322160c7feaad46091412d75d3f.tar.bz2
caffeonacl-9358247014eb8322160c7feaad46091412d75d3f.zip
improve CMake build
Diffstat (limited to 'cmake')
-rw-r--r--cmake/ConfigGen.cmake86
-rw-r--r--cmake/Cuda.cmake243
-rw-r--r--cmake/Dependencies.cmake124
-rw-r--r--cmake/Misc.cmake47
-rw-r--r--cmake/Modules/FindAtlas.cmake52
-rw-r--r--cmake/Modules/FindGFlags.cmake50
-rw-r--r--cmake/Modules/FindGlog.cmake48
-rw-r--r--cmake/Modules/FindLAPACK.cmake190
-rw-r--r--cmake/Modules/FindLMDB.cmake28
-rw-r--r--cmake/Modules/FindLevelDB.cmake44
-rw-r--r--cmake/Modules/FindMKL.cmake113
-rw-r--r--cmake/Modules/FindMatlabMex.cmake48
-rw-r--r--cmake/Modules/FindNumPy.cmake58
-rw-r--r--cmake/Modules/FindOpenBLAS.cmake62
-rw-r--r--cmake/Modules/FindSnappy.cmake28
-rw-r--r--cmake/Modules/FindvecLib.cmake34
-rw-r--r--cmake/ProtoBuf.cmake90
-rw-r--r--cmake/Summary.cmake166
-rw-r--r--cmake/Targets.cmake170
-rw-r--r--cmake/Templates/CaffeConfig.cmake.in58
-rw-r--r--cmake/Templates/CaffeConfigVersion.cmake.in11
-rw-r--r--cmake/Templates/caffe_config.h.in32
-rw-r--r--cmake/Utils.cmake365
-rw-r--r--cmake/lint.cmake48
24 files changed, 2195 insertions, 0 deletions
diff --git a/cmake/ConfigGen.cmake b/cmake/ConfigGen.cmake
new file mode 100644
index 00000000..24f23e9c
--- /dev/null
+++ b/cmake/ConfigGen.cmake
@@ -0,0 +1,86 @@
+
+################################################################################################
+# Helper function to fetch caffe includes which will be passed to dependent projects
+# Usage:
+# caffe_get_current_includes(<includes_list_variable>)
+function(caffe_get_current_includes includes_variable)
+ get_property(current_includes DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
+ caffe_convert_absolute_paths(current_includes)
+
+ # remove at most one ${CMAKE_BINARY_DIR} include added for caffe_config.h
+ list(FIND current_includes ${CMAKE_BINARY_DIR} __index)
+ list(REMOVE_AT current_includes ${__index})
+
+ caffe_list_unique(current_includes)
+ set(${includes_variable} ${current_includes} PARENT_SCOPE)
+endfunction()
+
+################################################################################################
+# Helper function to get all list items that begin with given prefix
+# Usage:
+# caffe_get_items_with_prefix(<prefix> <list_variable> <output_variable>)
+function(caffe_get_items_with_prefix prefix list_variable output_variable)
+ set(__result "")
+ foreach(__e ${${list_variable}})
+ if(__e MATCHES "^${prefix}.*")
+ list(APPEND __result ${__e})
+ endif()
+ endforeach()
+ set(${output_variable} ${__result} PARENT_SCOPE)
+endfunction()
+
+################################################################################################
+# Function for generation Caffe build- and install- tree export config files
+# Usage:
+# caffe_generate_export_configs()
+function(caffe_generate_export_configs)
+ set(install_cmake_suffix "share/Caffe")
+
+ # ---[ Configure build-tree CaffeConfig.cmake file ]---
+ caffe_get_current_includes(Caffe_INCLUDE_DIRS)
+ if(NOT HAVE_CUDA)
+ set(HAVE_CUDA FALSE)
+ set(Caffe_DEFINITIONS -DCPU_ONLY)
+ endif()
+ if(NOT HAVE_CUDNN)
+ set(HAVE_CUDNN FALSE)
+ else()
+ set(Caffe_DEFINITIONS -DUSE_CUDNN)
+ endif()
+
+ configure_file("cmake/Templates/CaffeConfig.cmake.in" "${CMAKE_BINARY_DIR}/CaffeConfig.cmake" @ONLY)
+
+ # Add targets to the build-tree export set
+ export(TARGETS caffe proto FILE "${CMAKE_BINARY_DIR}/CaffeTargets.cmake")
+ export(PACKAGE Caffe)
+
+ # ---[ Configure install-tree CaffeConfig.cmake file ]---
+
+ # remove source and build dir includes
+ caffe_get_items_with_prefix(${CMAKE_SOURCE_DIR} Caffe_INCLUDE_DIRS __insource)
+ caffe_get_items_with_prefix(${CMAKE_BINARY_DIR} Caffe_INCLUDE_DIRS __inbinary)
+ list(REMOVE_ITEM Caffe_INCLUDE_DIRS ${__insource} ${__inbinary})
+
+ # add `install` include folder
+ set(lines
+ "get_filename_component(__caffe_include \"\${Caffe_CMAKE_DIR}/../../include\" ABSOLUTE)\n"
+ "list(APPEND Caffe_INCLUDE_DIRS \${__caffe_include})\n"
+ "unset(__caffe_include)\n")
+ string(REPLACE ";" "" Caffe_INSTALL_INCLUDE_DIR_APPEND_COMMAND ${lines})
+
+ configure_file("cmake/Templates/CaffeConfig.cmake.in" "${CMAKE_BINARY_DIR}/cmake/CaffeConfig.cmake" @ONLY)
+
+ # Install the CaffeConfig.cmake and export set to use wuth install-tree
+ install(FILES "${CMAKE_BINARY_DIR}/cmake/CaffeConfig.cmake" DESTINATION ${install_cmake_suffix})
+ install(EXPORT CaffeTargets DESTINATION ${install_cmake_suffix})
+
+ # ---[ Configure and install version file ]---
+
+ # TODO: Lines below are commented because Caffe does't declare its version in headers.
+ # When the declarations are added, modify `caffe_extract_caffe_version()` macro and uncomment
+
+ # configure_file(cmake/Templates/CaffeConfigVersion.cmake.in "${CMAKE_BINARY_DIR}/CaffeConfigVersion.cmake" @ONLY)
+ # install(FILES "${CMAKE_BINARY_DIR}/CaffeConfigVersion.cmake" DESTINATION ${install_cmake_suffix})
+endfunction()
+
+
diff --git a/cmake/Cuda.cmake b/cmake/Cuda.cmake
new file mode 100644
index 00000000..42a94e5a
--- /dev/null
+++ b/cmake/Cuda.cmake
@@ -0,0 +1,243 @@
+if(CPU_ONLY)
+ return()
+endif()
+
+# Known NVIDIA GPU achitectures Caffe can be compiled for.
+# This list will be used for CUDA_ARCH_NAME = All option
+set(Caffe_known_gpu_archs "20 21(20) 30 35 50")
+
+################################################################################################
+# A function for automatic detection of GPUs installed (if autodetection is enabled)
+# Usage:
+# caffe_detect_installed_gpus(out_variable)
+function(caffe_detect_installed_gpus out_variable)
+ if(NOT CUDA_gpu_detect_output)
+ set(__cufile ${CMAKE_BINARY_DIR}/detect_cuda_archs.cu)
+
+ file(WRITE ${__cufile} ""
+ "#include <cstdio>\n"
+ "int main()\n"
+ "{\n"
+ " int count = 0;\n"
+ " if (cudaSuccess != cudaGetDeviceCount(&count)) return -1;\n"
+ " if (count == 0) return -1;\n"
+ " for (int device = 0; device < count; ++device)\n"
+ " {\n"
+ " cudaDeviceProp prop;\n"
+ " if (cudaSuccess == cudaGetDeviceProperties(&prop, device))\n"
+ " std::printf(\"%d.%d \", prop.major, prop.minor);\n"
+ " }\n"
+ " return 0;\n"
+ "}\n")
+
+ execute_process(COMMAND "${CUDA_NVCC_EXECUTABLE}" "--run" "${__cufile}"
+ WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/CMakeFiles/"
+ RESULT_VARIABLE __nvcc_res OUTPUT_VARIABLE __nvcc_out
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(__nvcc_res EQUAL 0)
+ string(REPLACE "2.1" "2.1(2.0)" __nvcc_out "${__nvcc_out}")
+ set(CUDA_gpu_detect_output ${__nvcc_out} CACHE INTERNAL "Returned GPU architetures from caffe_detect_gpus tool" FORCE)
+ endif()
+ endif()
+
+ if(NOT CUDA_gpu_detect_output)
+ message(STATUS "Automatic GPU detection failed. Building for all known architectures.")
+ set(${out_variable} ${Caffe_known_gpu_archs} PARENT_SCOPE)
+ else()
+ set(${out_variable} ${CUDA_gpu_detect_output} PARENT_SCOPE)
+ endif()
+endfunction()
+
+
+################################################################################################
+# Function for selecting GPU arch flags for nvcc based on CUDA_ARCH_NAME
+# Usage:
+# caffe_select_nvcc_arch_flags(out_variable)
+function(caffe_select_nvcc_arch_flags out_variable)
+ # List of arch names
+ set(__archs_names "Fermi" "Kepler" "Maxwell" "All" "Manual")
+ set(__archs_name_default "All")
+ if(NOT CMAKE_CROSSCOMPILING)
+ list(APPEND __archs_names "Auto")
+ set(__archs_name_default "Auto")
+ endif()
+
+ # set CUDA_ARCH_NAME strings (so it will be seen as dropbox in CMake-Gui)
+ set(CUDA_ARCH_NAME ${__archs_name_default} CACHE STRING "Select target NVIDIA GPU achitecture.")
+ set_property( CACHE CUDA_ARCH_NAME PROPERTY STRINGS "" ${__archs_names} )
+ mark_as_advanced(CUDA_ARCH_NAME)
+
+ # verify CUDA_ARCH_NAME value
+ if(NOT ";${__archs_names};" MATCHES ";${CUDA_ARCH_NAME};")
+ string(REPLACE ";" ", " __archs_names "${__archs_names}")
+ message(FATAL_ERROR "Only ${__archs_names} architeture names are supported.")
+ endif()
+
+ if(${CUDA_ARCH_NAME} STREQUAL "Manual")
+ set(CUDA_ARCH_BIN ${Caffe_known_gpu_archs} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
+ set(CUDA_ARCH_PTX "50" CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")
+ mark_as_advanced(CUDA_ARCH_BIN CUDA_ARCH_PTX)
+ else()
+ unset(CUDA_ARCH_BIN CACHE)
+ unset(CUDA_ARCH_PTX CACHE)
+ endif()
+
+ if(${CUDA_ARCH_NAME} STREQUAL "Fermi")
+ set(__cuda_arch_bin "20 21(20)")
+ elseif(${CUDA_ARCH_NAME} STREQUAL "Kepler")
+ set(__cuda_arch_bin "30 35")
+ elseif(${CUDA_ARCH_NAME} STREQUAL "Maxwell")
+ set(__cuda_arch_bin "50")
+ elseif(${CUDA_ARCH_NAME} STREQUAL "All")
+ set(__cuda_arch_bin ${Caffe_known_gpu_archs})
+ elseif(${CUDA_ARCH_NAME} STREQUAL "Auto")
+ caffe_detect_installed_gpus(__cuda_arch_bin)
+ else() # (${CUDA_ARCH_NAME} STREQUAL "Manual")
+ set(__cuda_arch_bin ${CUDA_ARCH_BIN})
+ endif()
+
+ # remove dots and convert to lists
+ string(REGEX REPLACE "\\." "" __cuda_arch_bin "${__cuda_arch_bin}")
+ string(REGEX REPLACE "\\." "" __cuda_arch_ptx "${CUDA_ARCH_PTX}")
+ string(REGEX MATCHALL "[0-9()]+" __cuda_arch_bin "${__cuda_arch_bin}")
+ string(REGEX MATCHALL "[0-9]+" __cuda_arch_ptx "${__cuda_arch_ptx}")
+ caffe_list_unique(__cuda_arch_bin __cuda_arch_ptx)
+
+ set(__nvcc_flags "")
+ set(__nvcc_archs_readable "")
+
+ # Tell NVCC to add binaries for the specified GPUs
+ foreach(__arch ${__cuda_arch_bin})
+ if(__arch MATCHES "([0-9]+)\\(([0-9]+)\\)")
+ # User explicitly specified PTX for the concrete BIN
+ list(APPEND __nvcc_flags -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1})
+ list(APPEND __nvcc_archs_readable sm_${CMAKE_MATCH_1})
+ else()
+ # User didn't explicitly specify PTX for the concrete BIN, we assume PTX=BIN
+ list(APPEND __nvcc_flags -gencode arch=compute_${__arch},code=sm_${__arch})
+ list(APPEND __nvcc_archs_readable sm_${__arch})
+ endif()
+ endforeach()
+
+ # Tell NVCC to add PTX intermediate code for the specified architectures
+ foreach(__arch ${__cuda_arch_ptx})
+ list(APPEND __nvcc_flags -gencode arch=compute_${__arch},code=compute_${__arch})
+ list(APPEND __nvcc_archs_readable compute_${__arch})
+ endforeach()
+
+ string(REPLACE ";" " " __nvcc_archs_readable "${__nvcc_archs_readable}")
+ set(${out_variable} ${__nvcc_flags} PARENT_SCOPE)
+ set(${out_variable}_readable ${__nvcc_archs_readable} PARENT_SCOPE)
+endfunction()
+
+################################################################################################
+# Short command for cuda comnpilation
+# Usage:
+# caffe_cuda_compile(<objlist_variable> <cuda_files>)
+macro(caffe_cuda_compile objlist_variable)
+ foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
+ set(${var}_backup_in_cuda_compile_ "${${var}}")
+
+ # we remove /EHa as it generates warnings under windows
+ string(REPLACE "/EHa" "" ${var} "${${var}}")
+
+ endforeach()
+
+ if(UNIX OR APPLE)
+ list(APPEND CUDA_NVCC_FLAGS -Xcompiler -fPIC)
+ endif()
+
+ if(APPLE)
+ list(APPEND CUDA_NVCC_FLAGS -Xcompiler -Wno-unused-function)
+ endif()
+
+ cuda_compile(cuda_objcs ${ARGN})
+
+ foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
+ set(${var} "${${var}_backup_in_cuda_compile_}")
+ unset(${var}_backup_in_cuda_compile_)
+ endforeach()
+
+ set(${objlist_variable} ${cuda_objcs})
+endmacro()
+
+################################################################################################
+# Short command for cuDNN detection. Believe it soon will be a part of CUDA toolkit distribution.
+# That's why not FindcuDNN.cmake file, but just the macro
+# Usage:
+# detect_cuDNN()
+function(detect_cuDNN)
+ set(CUDNN_ROOT "" CACHE PATH "CUDNN root folder")
+
+ find_path(CUDNN_INCLUDE cudnn.h
+ PATHS ${CUDNN_ROOT} $ENV{CUDNN_ROOT} ${CUDA_TOOLKIT_INCLUDE}
+ DOC "Path to cuDNN include directory." )
+
+ get_filename_component(__libpath_hist ${CUDA_CUDART_LIBRARY} PATH)
+ find_library(CUDNN_LIBRARY NAMES libcudnn.so # libcudnn_static.a
+ PATHS ${CUDNN_ROOT} $ENV{CUDNN_ROOT} ${CUDNN_INCLUDE} ${__libpath_hist}
+ DOC "Path to cuDNN library.")
+
+ if(CUDNN_INCLUDE AND CUDNN_LIBRARY)
+ set(HAVE_CUDNN TRUE PARENT_SCOPE)
+ set(CUDNN_FOUND TRUE PARENT_SCOPE)
+
+ mark_as_advanced(CUDNN_INCLUDE CUDNN_LIBRARY CUDNN_ROOT)
+ message(STATUS "Found cuDNN (include: ${CUDNN_INCLUDE}, library: ${CUDNN_LIBRARY})")
+ endif()
+endfunction()
+
+
+################################################################################################
+### Non macro section
+################################################################################################
+
+find_package(CUDA 5.5 QUIET)
+
+if(NOT CUDA_FOUND)
+ return()
+endif()
+
+set(HAVE_CUDA TRUE)
+message(STATUS "CUDA detected: " ${CUDA_VERSION})
+include_directories(SYSTEM ${CUDA_INCLUDE_DIRS})
+list(APPEND Caffe_LINKER_LIBS ${CUDA_CUDART_LIBRARY}
+ ${CUDA_curand_LIBRARY} ${CUDA_CUBLAS_LIBRARIES})
+
+# cudnn detection
+if(USE_CUDNN)
+ detect_cuDNN()
+ if(HAVE_CUDNN)
+ add_definitions(-DUSE_CUDNN)
+ include_directories(SYSTEM ${CUDNN_INCLUDE})
+ list(APPEND Caffe_LINKER_LIBS ${CUDNN_LIBRARY})
+ endif()
+endif()
+
+# setting nvcc arch flags
+caffe_select_nvcc_arch_flags(NVCC_FLAGS_EXTRA)
+list(APPEND CUDA_NVCC_FLAGS ${NVCC_FLAGS_EXTRA})
+message(STATUS "Added CUDA NVCC flags for: ${NVCC_FLAGS_EXTRA_readable}")
+
+# Boost 1.55 workaround, see https://svn.boost.org/trac/boost/ticket/9392 or
+# https://github.com/ComputationalRadiationPhysics/picongpu/blob/master/src/picongpu/CMakeLists.txt
+if(Boost_VERSION EQUAL 105500)
+ message(STATUS "Cuda + Boost 1.55: Applying noinline work around")
+ # avoid warning for CMake >= 2.8.12
+ set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} \"-DBOOST_NOINLINE=__attribute__((noinline))\" ")
+endif()
+
+# disable some nvcc diagnostic that apears in boost, glog, glags, opencv, etc.
+foreach(diag cc_clobber_ignored integer_sign_change useless_using_declaration set_but_not_used)
+ list(APPEND CUDA_NVCC_FLAGS -Xcudafe --diag_suppress=${diag})
+endforeach()
+
+# setting default testing device
+if(NOT CUDA_TEST_DEVICE)
+ set(CUDA_TEST_DEVICE -1)
+endif()
+
+mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_VERBOSE_BUILD)
+mark_as_advanced(CUDA_SDK_ROOT_DIR CUDA_SEPARABLE_COMPILATION)
+
diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake
new file mode 100644
index 00000000..5de435c3
--- /dev/null
+++ b/cmake/Dependencies.cmake
@@ -0,0 +1,124 @@
+# This list is required for static linking and exported to CaffeConfig.cmake
+set(Caffe_LINKER_LIBS "")
+
+# ---[ Boost
+find_package(Boost 1.46 REQUIRED COMPONENTS system thread)
+include_directories(SYSTEM ${Boost_INCLUDE_DIR})
+list(APPEND Caffe_LINKER_LIBS ${Boost_LIBRARIES})
+
+# ---[ Threads
+find_package(Threads REQUIRED)
+list(APPEND Caffe_LINKER_LIBS ${CMAKE_THREAD_LIBS_INIT})
+
+# ---[ Google-glog
+find_package(Glog REQUIRED)
+include_directories(SYSTEM ${GLOG_INCLUDE_DIRS})
+list(APPEND Caffe_LINKER_LIBS ${GLOG_LIBRARIES})
+
+# ---[ Google-gflags
+find_package(GFlags REQUIRED)
+include_directories(SYSTEM ${GFLAGS_INCLUDE_DIRS})
+list(APPEND Caffe_LINKER_LIBS ${GFLAGS_LIBRARIES})
+
+# ---[ Google-protobuf
+include(cmake/ProtoBuf.cmake)
+
+# ---[ HDF5
+find_package(HDF5 COMPONENTS HL REQUIRED)
+include_directories(SYSTEM ${HDF5_INCLUDE_DIRS})
+list(APPEND Caffe_LINKER_LIBS ${HDF5_LIBRARIES})
+
+# ---[ LMDB
+find_package(LMDB REQUIRED)
+include_directories(SYSTEM ${LMDB_INCLUDE_DIR})
+list(APPEND Caffe_LINKER_LIBS ${LMDB_LIBRARIES})
+
+# ---[ LevelDB
+find_package(LevelDB REQUIRED)
+include_directories(SYSTEM ${LEVELDB_INCLUDE})
+list(APPEND Caffe_LINKER_LIBS ${LevelDB_LIBRARIES})
+
+# ---[ Snappy
+find_package(Snappy REQUIRED)
+include_directories(SYSTEM ${Snappy_INCLUDE_DIR})
+list(APPEND Caffe_LINKER_LIBS ${Snappy_LIBRARIES})
+
+# ---[ CUDA
+include(cmake/Cuda.cmake)
+if(NOT HAVE_CUDA)
+ if(CPU_ONLY)
+ message("-- CUDA is disabled. Building without it...")
+ else()
+ message("-- CUDA is not detected by cmake. Building without it...")
+ endif()
+
+ # TODO: remove this not cross platform define in future. Use caffe_config.h instead.
+ add_definitions(-DCPU_ONLY)
+endif()
+
+# ---[ OpenCV
+find_package(OpenCV QUIET COMPONENTS core highgui imgproc imgcodecs)
+if(NOT OpenCV_FOUND) # if not OpenCV 3.x, then imgcodecs are not found
+ find_package(OpenCV REQUIRED COMPONENTS core highgui imgproc)
+endif()
+include_directories(SYSTEM ${OpenCV_INCLUDE_DIRS})
+list(APPEND Caffe_LINKER_LIBS ${OpenCV_LIBS})
+message(STATUS "OpenCV found (${OpenCV_CONFIG_PATH})")
+
+# ---[ BLAS
+if(NOT APPLE)
+ set(BLAS "Atlas" CACHE STRING "Selected BLAS library")
+ set_property(CACHE BLAS PROPERTY STRINGS "Atlas;Open;MLK")
+
+ if(BLAS STREQUAL "Atlas" OR BLAS STREQUAL "atlas")
+ find_package(Atlas REQUIRED)
+ include_directories(SYSTEM ${Atlas_INCLUDE_DIR})
+ list(APPEND Caffe_LINKER_LIBS ${Atlas_LIBRARIES})
+ elseif(BLAS STREQUAL "Open" OR BLAS STREQUAL "open")
+ find_package(OpenBLAS REQUIRED)
+ include_directories(SYSTEM ${OpenBLAS_INCLUDE_DIR})
+ list(APPEND Caffe_LINKER_LIBS ${OpenBLAS_LIB})
+ elseif(BLAS STREQUAL "MLK" OR BLAS STREQUAL "mkl")
+ find_package(MKL REQUIRED)
+ include_directories(SYSTEM ${MKL_INCLUDE_DIR})
+ list(APPEND Caffe_LINKER_LIBS ${MKL_LIBRARIES})
+ endif()
+elseif(APPLE)
+ find_package(vecLib REQUIRED)
+ include_directories(SYSTEM ${vecLib_INCLUDE_DIR})
+ list(APPEND Caffe_LINKER_LIBS ${vecLib_LINKER_LIBS})
+endif()
+
+# ---[ Python
+if(BUILD_python)
+ # disable Python 3 search
+ find_package(PythonInterp 2.7)
+ find_package(PythonLibs 2.7)
+ find_package(NumPy 1.7.1)
+ find_package(Boost 1.46 COMPONENTS python)
+
+ if(PYTHONLIBS_FOUND AND NUMPY_FOUND AND Boost_PYTHON_FOUND)
+ set(HAVE_PYTHON TRUE)
+ endif()
+endif()
+
+# ---[ Matlab
+if(BUILD_matlab)
+ find_package(MatlabMex)
+ if(MATLABMEX_FOUND)
+ set(HAVE_MATLAB TRUE)
+ endif()
+
+ # sudo apt-get install liboctave-dev
+ find_program(Octave_compiler NAMES mkoctfile DOC "Octave C++ compiler")
+
+ if(HAVE_MATLAB AND Octave_compiler)
+ set(Matlab_build_mex_using "Matlab" CACHE STRING "Select Matlab or Octave if both detected")
+ set_property(CACHE Matlab_build_mex_using PROPERTY STRINGS "Matlab;Octave")
+ endif()
+endif()
+
+# ---[ Doxygen
+if(BUILD_docs)
+ find_package(Doxygen)
+endif()
diff --git a/cmake/Misc.cmake b/cmake/Misc.cmake
new file mode 100644
index 00000000..68e8a662
--- /dev/null
+++ b/cmake/Misc.cmake
@@ -0,0 +1,47 @@
+# ---[ Configurations types
+set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Possible configurations" FORCE)
+mark_as_advanced(CMAKE_CONFIGURATION_TYPES)
+
+if(DEFINED CMAKE_BUILD_TYPE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${CMAKE_CONFIGURATION_TYPES})
+endif()
+
+# --[ If user doesn't specify build type then assume release
+if("${CMAKE_BUILD_TYPE}" STREQUAL "")
+ set(CMAKE_BUILD_TYPE Release)
+endif()
+
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ set(CMAKE_COMPILER_IS_CLANGXX TRUE)
+endif()
+
+# ---[ Solution folders
+caffe_option(USE_PROJECT_FOLDERS "IDE Solution folders" (MSVC_IDE OR CMAKE_GENERATOR MATCHES Xcode) )
+
+if(USE_PROJECT_FOLDERS)
+ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+ set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets")
+endif()
+
+# ---[ Install options
+if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+ set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Default install path" FORCE)
+endif()
+
+# ---[ RPATH settings
+set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE CACHE BOOLEAN "Use link paths for shared library rpath")
+set(CMAKE_MACOSX_RPATH TRUE)
+
+# ---[ Funny target
+if(UNIX OR APPLE)
+ add_custom_target(simlink_to_build COMMAND "ln" "-sf" "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/build"
+ COMMENT "Adding simlink: <caffe_root>/build -> ${CMAKE_BINARY_DIR}" )
+endif()
+
+# ---[ Set debug postfix
+set(Caffe_DEBUG_POSTFIX "-d")
+
+set(CAffe_POSTFIX "")
+if(CMAKE_BUILD_TYPE MATCHES "Debug")
+ set(CAffe_POSTFIX ${Caffe_DEBUG_POSTFIX})
+endif()
diff --git a/cmake/Modules/FindAtlas.cmake b/cmake/Modules/FindAtlas.cmake
new file mode 100644
index 00000000..6e156435
--- /dev/null
+++ b/cmake/Modules/FindAtlas.cmake
@@ -0,0 +1,52 @@
+# Find the Atlas (and Lapack) libraries
+#
+# The following variables are optionally searched for defaults
+# Atlas_ROOT_DIR: Base directory where all Atlas components are found
+#
+# The following are set after configuration is done:
+# Atlas_FOUND
+# Atlas_INCLUDE_DIRS
+# Atlas_LIBRARIES
+# Atlas_LIBRARYRARY_DIRS
+
+set(Atlas_INCLUDE_SEARCH_PATHS
+ /usr/include/atlas
+ /usr/include/atlas-base
+ $ENV{Atlas_ROOT_DIR}
+ $ENV{Atlas_ROOT_DIR}/include
+)
+
+set(Atlas_LIB_SEARCH_PATHS
+ /usr/lib/atlas
+ /usr/lib/atlas-base
+ $ENV{Atlas_ROOT_DIR}
+ $ENV{Atlas_ROOT_DIR}/lib
+)
+
+find_path(Atlas_CBLAS_INCLUDE_DIR NAMES cblas.h PATHS ${Atlas_INCLUDE_SEARCH_PATHS})
+find_path(Atlas_CLAPACK_INCLUDE_DIR NAMES clapack.h PATHS ${Atlas_INCLUDE_SEARCH_PATHS})
+
+find_library(Atlas_CBLAS_LIBRARY NAMES ptcblas_r ptcblas cblas_r cblas PATHS ${Atlas_LIB_SEARCH_PATHS})
+find_library(Atlas_BLAS_LIBRARY NAMES atlas_r atlas PATHS ${Atlas_LIB_SEARCH_PATHS})
+find_library(Atlas_LAPACK_LIBRARY NAMES alapack_r alapack lapack_atlas PATHS ${Atlas_LIB_SEARCH_PATHS})
+
+set(LOOKED_FOR
+ Atlas_CBLAS_INCLUDE_DIR
+ Atlas_CLAPACK_INCLUDE_DIR
+
+ Atlas_CBLAS_LIBRARY
+ Atlas_BLAS_LIBRARY
+ Atlas_LAPACK_LIBRARY
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Atlas DEFAULT_MSG ${LOOKED_FOR})
+
+if(ATLAS_FOUND)
+ set(Atlas_INCLUDE_DIR ${Atlas_CBLAS_INCLUDE_DIR} ${Atlas_CLAPACK_INCLUDE_DIR})
+ set(Atlas_LIBRARIES ${Atlas_LAPACK_LIBRARY} ${Atlas_CBLAS_LIBRARY} ${Atlas_BLAS_LIBRARY})
+ mark_as_advanced(${LOOKED_FOR})
+
+ message(STATUS "Found Atlas (include: ${Atlas_CBLAS_INCLUDE_DIR}, library: ${Atlas_BLAS_LIBRARY})")
+endif(ATLAS_FOUND)
+
diff --git a/cmake/Modules/FindGFlags.cmake b/cmake/Modules/FindGFlags.cmake
new file mode 100644
index 00000000..146e8455
--- /dev/null
+++ b/cmake/Modules/FindGFlags.cmake
@@ -0,0 +1,50 @@
+# - Try to find GFLAGS
+#
+# The following variables are optionally searched for defaults
+# GFLAGS_ROOT_DIR: Base directory where all GFLAGS components are found
+#
+# The following are set after configuration is done:
+# GFLAGS_FOUND
+# GFLAGS_INCLUDE_DIRS
+# GFLAGS_LIBRARIES
+# GFLAGS_LIBRARYRARY_DIRS
+
+include(FindPackageHandleStandardArgs)
+
+set(GFLAGS_ROOT_DIR "" CACHE PATH "Folder contains Gflags")
+
+# We are testing only a couple of files in the include directories
+if(WIN32)
+ find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
+ PATHS ${GFLAGS_ROOT_DIR}/src/windows)
+else()
+ find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
+ PATHS ${GFLAGS_ROOT_DIR})
+endif()
+
+if(MSVC)
+ find_library(GFLAGS_LIBRARY_RELEASE
+ NAMES libgflags
+ PATHS ${GFLAGS_ROOT_DIR}
+ PATH_SUFFIXES Release)
+
+ find_library(GFLAGS_LIBRARY_DEBUG
+ NAMES libgflags-debug
+ PATHS ${GFLAGS_ROOT_DIR}
+ PATH_SUFFIXES Debug)
+
+ set(GFLAGS_LIBRARY optimized ${GFLAGS_LIBRARY_RELEASE} debug ${GFLAGS_LIBRARY_DEBUG})
+else()
+ find_library(GFLAGS_LIBRARY gflags)
+endif()
+
+find_package_handle_standard_args(GFLAGS DEFAULT_MSG GFLAGS_INCLUDE_DIR GFLAGS_LIBRARY)
+
+
+if(GFLAGS_FOUND)
+ set(GFLAGS_INCLUDE_DIRS ${GFLAGS_INCLUDE_DIR})
+ set(GFLAGS_LIBRARIES ${GFLAGS_LIBRARY})
+ message(STATUS "Found gflags (include: ${GFLAGS_INCLUDE_DIR}, library: ${GFLAGS_LIBRARY})")
+ mark_as_advanced(GFLAGS_LIBRARY_DEBUG GFLAGS_LIBRARY_RELEASE
+ GFLAGS_LIBRARY GFLAGS_INCLUDE_DIR GFLAGS_ROOT_DIR)
+endif()
diff --git a/cmake/Modules/FindGlog.cmake b/cmake/Modules/FindGlog.cmake
new file mode 100644
index 00000000..56c76434
--- /dev/null
+++ b/cmake/Modules/FindGlog.cmake
@@ -0,0 +1,48 @@
+# - Try to find Glog
+#
+# The following variables are optionally searched for defaults
+# GLOG_ROOT_DIR: Base directory where all GLOG components are found
+#
+# The following are set after configuration is done:
+# GLOG_FOUND
+# GLOG_INCLUDE_DIRS
+# GLOG_LIBRARIES
+# GLOG_LIBRARYRARY_DIRS
+
+include(FindPackageHandleStandardArgs)
+
+set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")
+
+if(WIN32)
+ find_path(GLOG_INCLUDE_DIR glog/logging.h
+ PATHS ${GLOG_ROOT_DIR}/src/windows)
+else()
+ find_path(GLOG_INCLUDE_DIR glog/logging.h
+ PATHS ${GLOG_ROOT_DIR})
+endif()
+
+if(MSVC)
+ find_library(GLOG_LIBRARY_RELEASE libglog_static
+ PATHS ${GLOG_ROOT_DIR}
+ PATH_SUFFIXES Release)
+
+ find_library(GLOG_LIBRARY_DEBUG libglog_static
+ PATHS ${GLOG_ROOT_DIR}
+ PATH_SUFFIXES Debug)
+
+ set(GLOG_LIBRARY optimized ${GLOG_LIBRARY_RELEASE} debug ${GLOG_LIBRARY_DEBUG})
+else()
+ find_library(GLOG_LIBRARY glog
+ PATHS ${GLOG_ROOT_DIR}
+ PATH_SUFFIXES lib lib64)
+endif()
+
+find_package_handle_standard_args(GLOG DEFAULT_MSG GLOG_INCLUDE_DIR GLOG_LIBRARY)
+
+if(GLOG_FOUND)
+ set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR})
+ set(GLOG_LIBRARIES ${GLOG_LIBRARY})
+ message(STATUS "Found glog (include: ${GLOG_INCLUDE_DIR}, library: ${GLOG_LIBRARY})")
+ mark_as_advanced(GLOG_ROOT_DIR GLOG_LIBRARY_RELEASE GLOG_LIBRARY_DEBUG
+ GLOG_LIBRARY GLOG_INCLUDE_DIR)
+endif()
diff --git a/cmake/Modules/FindLAPACK.cmake b/cmake/Modules/FindLAPACK.cmake
new file mode 100644
index 00000000..9641c45d
--- /dev/null
+++ b/cmake/Modules/FindLAPACK.cmake
@@ -0,0 +1,190 @@
+# - Find LAPACK library
+# This module finds an installed fortran library that implements the LAPACK
+# linear-algebra interface (see http://www.netlib.org/lapack/).
+#
+# The approach follows that taken for the autoconf macro file, acx_lapack.m4
+# (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).
+#
+# This module sets the following variables:
+# LAPACK_FOUND - set to true if a library implementing the LAPACK interface is found
+# LAPACK_LIBRARIES - list of libraries (using full path name) for LAPACK
+
+# Note: I do not think it is a good idea to mixup different BLAS/LAPACK versions
+# Hence, this script wants to find a Lapack library matching your Blas library
+
+# Do nothing if LAPACK was found before
+IF(NOT LAPACK_FOUND)
+
+SET(LAPACK_LIBRARIES)
+SET(LAPACK_INFO)
+
+IF(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+ FIND_PACKAGE(BLAS)
+ELSE(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+ FIND_PACKAGE(BLAS REQUIRED)
+ENDIF(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)
+
+# Old search lapack script
+include(CheckFortranFunctionExists)
+
+macro(Check_Lapack_Libraries LIBRARIES _prefix _name _flags _list _blas)
+ # This macro checks for the existence of the combination of fortran libraries
+ # given by _list. If the combination is found, this macro checks (using the
+ # Check_Fortran_Function_Exists macro) whether can link against that library
+ # combination using the name of a routine given by _name using the linker
+ # flags given by _flags. If the combination of libraries is found and passes
+ # the link test, LIBRARIES is set to the list of complete library paths that
+ # have been found. Otherwise, LIBRARIES is set to FALSE.
+ # N.B. _prefix is the prefix applied to the names of all cached variables that
+ # are generated internally and marked advanced by this macro.
+ set(_libraries_work TRUE)
+ set(${LIBRARIES})
+ set(_combined_name)
+ foreach(_library ${_list})
+ set(_combined_name ${_combined_name}_${_library})
+ if(_libraries_work)
+ if (WIN32)
+ find_library(${_prefix}_${_library}_LIBRARY
+ NAMES ${_library} PATHS ENV LIB PATHS ENV PATH)
+ else (WIN32)
+ if(APPLE)
+ find_library(${_prefix}_${_library}_LIBRARY
+ NAMES ${_library}
+ PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64
+ ENV DYLD_LIBRARY_PATH)
+ else(APPLE)
+ find_library(${_prefix}_${_library}_LIBRARY
+ NAMES ${_library}
+ PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64
+ ENV LD_LIBRARY_PATH)
+ endif(APPLE)
+ endif(WIN32)
+ mark_as_advanced(${_prefix}_${_library}_LIBRARY)
+ set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})
+ set(_libraries_work ${${_prefix}_${_library}_LIBRARY})
+ endif(_libraries_work)
+ endforeach(_library ${_list})
+ if(_libraries_work)
+ # Test this combination of libraries.
+ set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas})
+ if (CMAKE_Fortran_COMPILER_WORKS)
+ check_fortran_function_exists(${_name} ${_prefix}${_combined_name}_WORKS)
+ else (CMAKE_Fortran_COMPILER_WORKS)
+ check_function_exists("${_name}_" ${_prefix}${_combined_name}_WORKS)
+ endif (CMAKE_Fortran_COMPILER_WORKS)
+ set(CMAKE_REQUIRED_LIBRARIES)
+ mark_as_advanced(${_prefix}${_combined_name}_WORKS)
+ set(_libraries_work ${${_prefix}${_combined_name}_WORKS})
+ endif(_libraries_work)
+ if(NOT _libraries_work)
+ set(${LIBRARIES} FALSE)
+ endif(NOT _libraries_work)
+endmacro(Check_Lapack_Libraries)
+
+
+if(BLAS_FOUND)
+
+ # Intel MKL
+ IF((NOT LAPACK_INFO) AND (BLAS_INFO STREQUAL "mkl"))
+ IF(MKL_LAPACK_LIBRARIES)
+ SET(LAPACK_LIBRARIES ${MKL_LAPACK_LIBRARIES} ${MKL_LIBRARIES})
+ ELSE(MKL_LAPACK_LIBRARIES)
+ SET(LAPACK_LIBRARIES ${MKL_LIBRARIES})
+ ENDIF(MKL_LAPACK_LIBRARIES)
+ SET(LAPACK_INCLUDE_DIR ${MKL_INCLUDE_DIR})
+ SET(LAPACK_INFO "mkl")
+ ENDIF()
+
+ # OpenBlas
+ IF((NOT LAPACK_INFO) AND (BLAS_INFO STREQUAL "open"))
+ SET(CMAKE_REQUIRED_LIBRARIES ${BLAS_LIBRARIES})
+ check_function_exists("cheev_" OPEN_LAPACK_WORKS)
+ if(OPEN_LAPACK_WORKS)
+ SET(LAPACK_INFO "open")
+ else()
+ message(STATUS "It seems OpenBlas has not been compiled with Lapack support")
+ endif()
+ endif()
+
+ # GotoBlas
+ IF((NOT LAPACK_INFO) AND (BLAS_INFO STREQUAL "goto"))
+ SET(CMAKE_REQUIRED_LIBRARIES ${BLAS_LIBRARIES})
+ check_function_exists("cheev_" GOTO_LAPACK_WORKS)
+ if(GOTO_LAPACK_WORKS)
+ SET(LAPACK_INFO "goto")
+ else()
+ message(STATUS "It seems GotoBlas has not been compiled with Lapack support")
+ endif()
+ endif()
+
+ # ACML
+ IF((NOT LAPACK_INFO) AND (BLAS_INFO STREQUAL "acml"))
+ SET(CMAKE_REQUIRED_LIBRARIES ${BLAS_LIBRARIES})
+ check_function_exists("cheev_" ACML_LAPACK_WORKS)
+ if(ACML_LAPACK_WORKS)
+ SET(LAPACK_INFO "acml")
+ else()
+ message(STATUS "Strangely, this ACML library does not support Lapack?!")
+ endif()
+ endif()
+
+ # Accelerate
+ IF((NOT LAPACK_INFO) AND (BLAS_INFO STREQUAL "accelerate"))
+ SET(CMAKE_REQUIRED_LIBRARIES ${BLAS_LIBRARIES})
+ check_function_exists("cheev_" ACCELERATE_LAPACK_WORKS)
+ if(ACCELERATE_LAPACK_WORKS)
+ SET(LAPACK_INFO "accelerate")
+ else()
+ message(STATUS "Strangely, this Accelerate library does not support Lapack?!")
+ endif()
+ endif()
+
+ # vecLib
+ IF((NOT LAPACK_INFO) AND (BLAS_INFO STREQUAL "veclib"))
+ SET(CMAKE_REQUIRED_LIBRARIES ${BLAS_LIBRARIES})
+ check_function_exists("cheev_" VECLIB_LAPACK_WORKS)
+ if(VECLIB_LAPACK_WORKS)
+ SET(LAPACK_INFO "veclib")
+ else()
+ message(STATUS "Strangely, this vecLib library does not support Lapack?!")
+ endif()
+ endif()
+
+ # Generic LAPACK library?
+ IF((NOT LAPACK_INFO) AND (BLAS_INFO STREQUAL "generic"))
+ check_lapack_libraries(
+ LAPACK_LIBRARIES
+ LAPACK
+ cheev
+ ""
+ "lapack"
+ "${BLAS_LIBRARIES}"
+ )
+ if(LAPACK_LIBRARIES)
+ SET(LAPACK_INFO "generic")
+ endif(LAPACK_LIBRARIES)
+ endif()
+
+else(BLAS_FOUND)
+ message(STATUS "LAPACK requires BLAS")
+endif(BLAS_FOUND)
+
+if(LAPACK_INFO)
+ set(LAPACK_FOUND TRUE)
+else(LAPACK_INFO)
+ set(LAPACK_FOUND FALSE)
+endif(LAPACK_INFO)
+
+IF (NOT LAPACK_FOUND AND LAPACK_FIND_REQUIRED)
+ message(FATAL_ERROR "Cannot find a library with LAPACK API. Please specify library location.")
+ENDIF (NOT LAPACK_FOUND AND LAPACK_FIND_REQUIRED)
+IF(NOT LAPACK_FIND_QUIETLY)
+ IF(LAPACK_FOUND)
+ MESSAGE(STATUS "Found a library with LAPACK API. (${LAPACK_INFO})")
+ ELSE(LAPACK_FOUND)
+ MESSAGE(STATUS "Cannot find a library with LAPACK API. Not using LAPACK.")
+ ENDIF(LAPACK_FOUND)
+ENDIF(NOT LAPACK_FIND_QUIETLY)
+
+# Do nothing if LAPACK was found before
+ENDIF(NOT LAPACK_FOUND)
diff --git a/cmake/Modules/FindLMDB.cmake b/cmake/Modules/FindLMDB.cmake
new file mode 100644
index 00000000..8a817fd6
--- /dev/null
+++ b/cmake/Modules/FindLMDB.cmake
@@ -0,0 +1,28 @@
+# Try to find the LMBD libraries and headers
+# LMDB_FOUND - system has LMDB lib
+# LMDB_INCLUDE_DIR - the LMDB include directory
+# LMDB_LIBRARIES - Libraries needed to use LMDB
+
+# FindCWD based on FindGMP by:
+# Copyright (c) 2006, Laurent Montel, <montel@kde.org>
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+
+# Adapted from FindCWD by:
+# Copyright 2013 Conrad Steenberg <conrad.steenberg@gmail.com>
+# Aug 31, 2013
+
+find_path(LMDB_INCLUDE_DIR NAMES lmdb.h PATHS "$ENV{LMDB_DIR}/include")
+find_library(LMDB_LIBRARIES NAMES lmdb PATHS "$ENV{LMDB_DIR}/lib" )
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LMDB DEFAULT_MSG LMDB_INCLUDE_DIR LMDB_LIBRARIES)
+
+if(LMDB_FOUND)
+ message(STATUS "Found lmdb (include: ${LMDB_INCLUDE_DIR}, library: ${LMDB_LIBRARIES})")
+ mark_as_advanced(LMDB_INCLUDE_DIR LMDB_LIBRARIES)
+
+ caffe_parse_header(${LMDB_INCLUDE_DIR}/lmdb.h
+ LMDB_VERSION_LINES MDB_VERSION_MAJOR MDB_VERSION_MINOR MDB_VERSION_PATCH)
+ set(LMDB_VERSION "${MDB_VERSION_MAJOR}.${MDB_VERSION_MINOR}.${MDB_VERSION_PATCH}")
+endif()
diff --git a/cmake/Modules/FindLevelDB.cmake b/cmake/Modules/FindLevelDB.cmake
new file mode 100644
index 00000000..97f08ac9
--- /dev/null
+++ b/cmake/Modules/FindLevelDB.cmake
@@ -0,0 +1,44 @@
+# - Find LevelDB
+#
+# LevelDB_INCLUDES - List of LevelDB includes
+# LevelDB_LIBRARIES - List of libraries when using LevelDB.
+# LevelDB_FOUND - True if LevelDB found.
+
+# Look for the header file.
+find_path(LevelDB_INCLUDE NAMES leveldb/db.h
+ PATHS $ENV{LEVELDB_ROOT}/include /opt/local/include /usr/local/include /usr/include
+ DOC "Path in which the file leveldb/db.h is located." )
+
+# Look for the library.
+find_library(LevelDB_LIBRARY NAMES leveldb
+ PATHS /usr/lib $ENV{LEVELDB_ROOT}/lib
+ DOC "Path to leveldb library." )
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LevelDB DEFAULT_MSG LevelDB_INCLUDE LevelDB_LIBRARY)
+
+if(LEVELDB_FOUND)
+ message(STATUS "Found LevelDB (include: ${LevelDB_INCLUDE}, library: ${LevelDB_LIBRARY})")
+ set(LevelDB_INCLUDES ${LevelDB_INCLUDE})
+ set(LevelDB_LIBRARIES ${LevelDB_LIBRARY})
+ mark_as_advanced(LevelDB_INCLUDE LevelDB_LIBRARY)
+
+ if(EXISTS "${LevelDB_INCLUDE}/leveldb/db.h")
+ file(STRINGS "${LevelDB_INCLUDE}/leveldb/db.h" __version_lines
+ REGEX "static const int k[^V]+Version[ \t]+=[ \t]+[0-9]+;")
+
+ foreach(__line ${__version_lines})
+ if(__line MATCHES "[^k]+kMajorVersion[ \t]+=[ \t]+([0-9]+);")
+ set(LEVELDB_VERSION_MAJOR ${CMAKE_MATCH_1})
+ elseif(__line MATCHES "[^k]+kMinorVersion[ \t]+=[ \t]+([0-9]+);")
+ set(LEVELDB_VERSION_MINOR ${CMAKE_MATCH_1})
+ endif()
+ endforeach()
+
+ if(LEVELDB_VERSION_MAJOR AND LEVELDB_VERSION_MINOR)
+ set(LEVELDB_VERSION "${LEVELDB_VERSION_MAJOR}.${LEVELDB_VERSION_MINOR}")
+ endif()
+
+ caffe_clear_vars(__line __version_lines)
+ endif()
+endif()
diff --git a/cmake/Modules/FindMKL.cmake b/cmake/Modules/FindMKL.cmake
new file mode 100644
index 00000000..eb2d9f88
--- /dev/null
+++ b/cmake/Modules/FindMKL.cmake
@@ -0,0 +1,113 @@
+# - Find Intel MKL
+# Find the MKL libraries
+#
+# Options:
+#
+# MKL_STATAIC : use static linking
+# MKL_MULTI_THREADED: use multi-threading
+# MKL_SDL : Single Dynamic Library interface
+#
+# This module defines the following variables:
+#
+# MKL_FOUND : True if MKL_INCLUDE_DIR are found
+# MKL_INCLUDE_DIR : where to find mkl.h, etc.
+# MKL_INCLUDE_DIRS : set when MKL_INCLUDE_DIR found
+# MKL_LIBRARIES : the library to link against.
+
+
+include(FindPackageHandleStandardArgs)
+
+set(INTEL_ROOT "/opt/intel" CACHE PATH "Folder contains intel libs")
+set(MKL_ROOT ${INTEL_ROOT}/mkl CACHE PATH "Folder contains MKL")
+
+# Find include dir
+find_path(MKL_INCLUDE_DIR mkl.h
+ PATHS ${MKL_ROOT}/include)
+
+# Find include directory
+# There is no include folder under linux
+if(WIN32)
+ find_path(INTEL_INCLUDE_DIR omp.h
+ PATHS ${INTEL_ROOT}/include)
+ set(MKL_INCLUDE_DIR ${MKL_INCLUDE_DIR} ${INTEL_INCLUDE_DIR})
+endif()
+
+# Find libraries
+
+# Handle suffix
+set(_MKL_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+
+if(WIN32)
+ if(MKL_STATAIC)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib)
+ else()
+ set(CMAKE_FIND_LIBRARY_SUFFIXES _dll.lib)
+ endif()
+else()
+ if(MKL_STATAIC)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
+ else()
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .so)
+ endif()
+endif()
+
+
+# MKL is composed by four layers: Interface, Threading, Computational and RTL
+
+if(MKL_SDL)
+ find_library(MKL_LIBRARY mkl_rt
+ PATHS ${MKL_ROOT}/lib/ia32/)
+
+ set(MKL_MINIMAL_LIBRARY ${MKL_LIBRARY})
+else()
+ ######################### Interface layer #######################
+ if(WIN32)
+ set(MKL_INTERFACE_LIBNAME mkl_intel_c)
+ else()
+ set(MKL_INTERFACE_LIBNAME mkl_intel)
+ endif()
+
+ find_library(MKL_INTERFACE_LIBRARY ${MKL_INTERFACE_LIBNAME}
+ PATHS ${MKL_ROOT}/lib/ia32/)
+
+ ######################## Threading layer ########################
+ if(MKL_MULTI_THREADED)
+ set(MKL_THREADING_LIBNAME mkl_intel_thread)
+ else()
+ set(MKL_THREADING_LIBNAME mkl_sequential)
+ endif()
+
+ find_library(MKL_THREADING_LIBRARY ${MKL_THREADING_LIBNAME}
+ PATHS ${MKL_ROOT}/lib/ia32/)
+
+ ####################### Computational layer #####################
+ find_library(MKL_CORE_LIBRARY mkl_core
+ PATHS ${MKL_ROOT}/lib/ia32/)
+ find_library(MKL_FFT_LIBRARY mkl_cdft_core
+ PATHS ${MKL_ROOT}/lib/ia32/)
+ find_library(MKL_SCALAPACK_LIBRARY mkl_scalapack_core
+ PATHS ${MKL_ROOT}/lib/ia32/)
+
+ ############################ RTL layer ##########################
+ if(WIN32)
+ set(MKL_RTL_LIBNAME libiomp5md)
+ else()
+ set(MKL_RTL_LIBNAME libiomp5)
+ endif()
+ find_library(MKL_RTL_LIBRARY ${MKL_RTL_LIBNAME}
+ PATHS ${INTEL_RTL_ROOT}/lib)
+
+ set(MKL_LIBRARY ${MKL_INTERFACE_LIBRARY} ${MKL_THREADING_LIBRARY} ${MKL_CORE_LIBRARY} ${MKL_FFT_LIBRARY} ${MKL_SCALAPACK_LIBRARY} ${MKL_RTL_LIBRARY})
+ set(MKL_MINIMAL_LIBRARY ${MKL_INTERFACE_LIBRARY} ${MKL_THREADING_LIBRARY} ${MKL_CORE_LIBRARY} ${MKL_RTL_LIBRARY})
+endif()
+
+set(CMAKE_FIND_LIBRARY_SUFFIXES ${_MKL_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+
+find_package_handle_standard_args(MKL DEFAULT_MSG
+ MKL_INCLUDE_DIR MKL_LIBRARY MKL_MINIMAL_LIBRARY)
+
+if(MKL_FOUND)
+ set(MKL_INCLUDE_DIRS ${MKL_INCLUDE_DIR})
+ set(MKL_LIBRARIES ${MKL_LIBRARY})
+ set(MKL_MINIMAL_LIBRARIES ${MKL_LIBRARY})
+endif()
diff --git a/cmake/Modules/FindMatlabMex.cmake b/cmake/Modules/FindMatlabMex.cmake
new file mode 100644
index 00000000..28ae65e7
--- /dev/null
+++ b/cmake/Modules/FindMatlabMex.cmake
@@ -0,0 +1,48 @@
+# This module looks for MatlabMex compiler
+# Defines variables:
+# Matlab_DIR - Matlab root dir
+# Matlab_mex - path to mex compiler
+# Matlab_mexext - path to mexext
+
+if(MSVC)
+ foreach(__ver "9.30" "7.14" "7.11" "7.10" "7.9" "7.8" "7.7")
+ get_filename_component(__matlab_root "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\${__ver};MATLABROOT]" ABSOLUTE)
+ if(__matlab_root)
+ break()
+ endif()
+ endforeach()
+endif()
+
+if(APPLE)
+ foreach(__ver "R2014b" "R2014a" "R2013b" "R2013a" "R2012b" "R2012a" "R2011b" "R2011a" "R2010b" "R2010a")
+ if(EXISTS /Applications/MATLAB_${__ver}.app)
+ set(__matlab_root /Applications/MATLAB_${__ver}.app)
+ break()
+ endif()
+ endforeach()
+endif()
+
+if(UNIX)
+ execute_process(COMMAND which matlab OUTPUT_STRIP_TRAILING_WHITESPACE
+ OUTPUT_VARIABLE __out RESULT_VARIABLE __res)
+
+ if(__res MATCHES 0) # Suppress `readlink` warning if `which` returned nothing
+ execute_process(COMMAND which matlab COMMAND xargs readlink
+ COMMAND xargs dirname COMMAND xargs dirname COMMAND xargs echo -n
+ OUTPUT_VARIABLE __matlab_root OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+endif()
+
+
+find_path(Matlab_DIR NAMES bin/mex bin/mexext PATHS ${__matlab_root}
+ DOC "Matlab directory" NO_DEFAULT_PATH)
+
+find_program(Matlab_mex NAMES mex mex.bat HINTS ${Matlab_DIR} PATH_SUFFIXES bin NO_DEFAULT_PATH)
+find_program(Matlab_mexext NAMES mexext mexext.bat HINTS ${Matlab_DIR} PATH_SUFFIXES bin NO_DEFAULT_PATH)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MatlabMex DEFAULT_MSG Matlab_mex Matlab_mexext)
+
+if(MATLABMEX_FOUND)
+ mark_as_advanced(Matlab_mex Matlab_mexext)
+endif()
diff --git a/cmake/Modules/FindNumPy.cmake b/cmake/Modules/FindNumPy.cmake
new file mode 100644
index 00000000..a671494c
--- /dev/null
+++ b/cmake/Modules/FindNumPy.cmake
@@ -0,0 +1,58 @@
+# - Find the NumPy libraries
+# This module finds if NumPy is installed, and sets the following variables
+# indicating where it is.
+#
+# TODO: Update to provide the libraries and paths for linking npymath lib.
+#
+# NUMPY_FOUND - was NumPy found
+# NUMPY_VERSION - the version of NumPy found as a string
+# NUMPY_VERSION_MAJOR - the major version number of NumPy
+# NUMPY_VERSION_MINOR - the minor version number of NumPy
+# NUMPY_VERSION_PATCH - the patch version number of NumPy
+# NUMPY_VERSION_DECIMAL - e.g. version 1.6.1 is 10601
+# NUMPY_INCLUDE_DIR - path to the NumPy include files
+
+unset(NUMPY_VERSION)
+unset(NUMPY_INCLUDE_DIR)
+
+if(PYTHONINTERP_FOUND)
+ execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c"
+ "import numpy as n; print(n.__version__); print(n.get_include());"
+ RESULT_VARIABLE __result
+ OUTPUT_VARIABLE __output
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(__result MATCHES 0)
+ string(REGEX REPLACE ";" "\\\\;" __values ${__output})
+ string(REGEX REPLACE "\r?\n" ";" __values ${__values})
+ list(GET __values 0 NUMPY_VERSION)
+ list(GET __values 1 NUMPY_INCLUDE_DIR)
+
+ string(REGEX MATCH "^([0-9])+\\.([0-9])+\\.([0-9])+" __ver_check "${NUMPY_VERSION}")
+ if(NOT "${__ver_check}" STREQUAL "")
+ set(NUMPY_VERSION_MAJOR ${CMAKE_MATCH_1})
+ set(NUMPY_VERSION_MINOR ${CMAKE_MATCH_2})
+ set(NUMPY_VERSION_PATCH ${CMAKE_MATCH_3})
+ math(EXPR NUMPY_VERSION_DECIMAL
+ "(${NUMPY_VERSION_MAJOR} * 10000) + (${NUMPY_VERSION_MINOR} * 100) + ${NUMPY_VERSION_PATCH}")
+ string(REGEX REPLACE "\\\\" "/" NUMPY_INCLUDE_DIR ${NUMPY_INCLUDE_DIR})
+ else()
+ unset(NUMPY_VERSION)
+ unset(NUMPY_INCLUDE_DIR)
+ message(STATUS "Requested NumPy version and include path, but got instead:\n${__output}\n")
+ endif()
+ endif()
+else()
+ message(STATUS "To find NumPy Python interpretator is required to be found.")
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(NumPy REQUIRED_VARS NUMPY_INCLUDE_DIR NUMPY_VERSION
+ VERSION_VAR NUMPY_VERSION)
+
+if(NUMPY_FOUND)
+ message(STATUS "NumPy ver. ${NUMPY_VERSION} found (include: ${NUMPY_INCLUDE_DIR})")
+endif()
+
+caffe_clear_vars(__result __output __error_value __values __ver_check __error_value)
+
diff --git a/cmake/Modules/FindOpenBLAS.cmake b/cmake/Modules/FindOpenBLAS.cmake
new file mode 100644
index 00000000..b8434927
--- /dev/null
+++ b/cmake/Modules/FindOpenBLAS.cmake
@@ -0,0 +1,62 @@
+
+
+SET(Open_BLAS_INCLUDE_SEARCH_PATHS
+ /usr/include
+ /usr/include/openblas-base
+ /usr/local/include
+ /usr/local/include/openblas-base
+ /opt/OpenBLAS/include
+ $ENV{OpenBLAS_HOME}
+ $ENV{OpenBLAS_HOME}/include
+)
+
+SET(Open_BLAS_LIB_SEARCH_PATHS
+ /lib/
+ /lib/openblas-base
+ /lib64/
+ /usr/lib
+ /usr/lib/openblas-base
+ /usr/lib64
+ /usr/local/lib
+ /usr/local/lib64
+ /opt/OpenBLAS/lib
+ $ENV{OpenBLAS}cd
+ $ENV{OpenBLAS}/lib
+ $ENV{OpenBLAS_HOME}
+ $ENV{OpenBLAS_HOME}/lib
+ )
+
+FIND_PATH(OpenBLAS_INCLUDE_DIR NAMES cblas.h PATHS ${Open_BLAS_INCLUDE_SEARCH_PATHS})
+FIND_LIBRARY(OpenBLAS_LIB NAMES openblas PATHS ${Open_BLAS_LIB_SEARCH_PATHS})
+
+SET(OpenBLAS_FOUND ON)
+
+# Check include files
+IF(NOT OpenBLAS_INCLUDE_DIR)
+ SET(OpenBLAS_FOUND OFF)
+ MESSAGE(STATUS "Could not find OpenBLAS include. Turning OpenBLAS_FOUND off")
+ENDIF()
+
+# Check libraries
+IF(NOT OpenBLAS_LIB)
+ SET(OpenBLAS_FOUND OFF)
+ MESSAGE(STATUS "Could not find OpenBLAS lib. Turning OpenBLAS_FOUND off")
+ENDIF()
+
+IF (OpenBLAS_FOUND)
+ IF (NOT OpenBLAS_FIND_QUIETLY)
+ MESSAGE(STATUS "Found OpenBLAS libraries: ${OpenBLAS_LIB}")
+ MESSAGE(STATUS "Found OpenBLAS include: ${OpenBLAS_INCLUDE_DIR}")
+ ENDIF (NOT OpenBLAS_FIND_QUIETLY)
+ELSE (OpenBLAS_FOUND)
+ IF (OpenBLAS_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find OpenBLAS")
+ ENDIF (OpenBLAS_FIND_REQUIRED)
+ENDIF (OpenBLAS_FOUND)
+
+MARK_AS_ADVANCED(
+ OpenBLAS_INCLUDE_DIR
+ OpenBLAS_LIB
+ OpenBLAS
+)
+
diff --git a/cmake/Modules/FindSnappy.cmake b/cmake/Modules/FindSnappy.cmake
new file mode 100644
index 00000000..eff2a864
--- /dev/null
+++ b/cmake/Modules/FindSnappy.cmake
@@ -0,0 +1,28 @@
+# Find the Snappy libraries
+#
+# The following variables are optionally searched for defaults
+# Snappy_ROOT_DIR: Base directory where all Snappy components are found
+#
+# The following are set after configuration is done:
+# SNAPPY_FOUND
+# Snappy_INCLUDE_DIR
+# Snappy_LIBRARIES
+
+find_path(Snappy_INCLUDE_DIR NAMES snappy.h
+ PATHS ${SNAPPY_ROOT_DIR} ${SNAPPY_ROOT_DIR}/include)
+
+find_library(Snappy_LIBRARIES NAMES snappy
+ PATHS ${SNAPPY_ROOT_DIR} ${SNAPPY_ROOT_DIR}/lib)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Snappy DEFAULT_MSG Snappy_INCLUDE_DIR Snappy_LIBRARIES)
+
+if(SNAPPY_FOUND)
+ message(STATUS "Found Snappy (include: ${Snappy_INCLUDE_DIR}, library: ${Snappy_LIBRARIES})")
+ mark_as_advanced(Snappy_INCLUDE_DIR Snappy_LIBRARIES)
+
+ caffe_parse_header(${Snappy_INCLUDE_DIR}/snappy-stubs-public.h
+ SNAPPY_VERION_LINES SNAPPY_MAJOR SNAPPY_MINOR SNAPPY_PATCHLEVEL)
+ set(Snappy_VERSION "${SNAPPY_MAJOR}.${SNAPPY_MINOR}.${SNAPPY_PATCHLEVEL}")
+endif()
+
diff --git a/cmake/Modules/FindvecLib.cmake b/cmake/Modules/FindvecLib.cmake
new file mode 100644
index 00000000..9600da43
--- /dev/null
+++ b/cmake/Modules/FindvecLib.cmake
@@ -0,0 +1,34 @@
+# Find the vecLib libraries as part of Accelerate.framework or as standalon framework
+#
+# The following are set after configuration is done:
+# VECLIB_FOUND
+# vecLib_INCLUDE_DIR
+# vecLib_LINKER_LIBS
+
+
+if(NOT APPLE)
+ return()
+endif()
+
+set(__veclib_include_suffix "Frameworks/vecLib.framework/Versions/Current/Headers")
+
+find_path(vecLib_INCLUDE_DIR vecLib.h
+ DOC "vecLib include directory"
+ PATHS /System/Library/${__veclib_include_suffix}
+ /System/Library/Frameworks/Accelerate.framework/Versions/Current/${__veclib_include_suffix}
+ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Accelerate.framework/Versions/Current/Frameworks/vecLib.framework/Headers/)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(vecLib DEFAULT_MSG vecLib_INCLUDE_DIR)
+
+if(VECLIB_FOUND)
+ if(vecLib_INCLUDE_DIR MATCHES "^/System/Library/Frameworks/vecLib.framework.*")
+ set(vecLib_LINKER_LIBS -lcblas "-framework vecLib")
+ message(STATUS "Found standalone vecLib.framework")
+ else()
+ set(vecLib_LINKER_LIBS -lcblas "-framework Accelerate")
+ message(STATUS "Found vecLib as part of Accelerate.framework")
+ endif()
+
+ mark_as_advanced(vecLib_INCLUDE_DIR)
+endif()
diff --git a/cmake/ProtoBuf.cmake b/cmake/ProtoBuf.cmake
new file mode 100644
index 00000000..bb63c9ed
--- /dev/null
+++ b/cmake/ProtoBuf.cmake
@@ -0,0 +1,90 @@
+# Finds Google Protocol Buffers library and compilers and extends
+# the standart cmake script with version and python generation support
+
+find_package( Protobuf REQUIRED )
+include_directories(SYSTEM ${PROTOBUF_INCLUDE_DIR})
+list(APPEND Caffe_LINKER_LIBS ${PROTOBUF_LIBRARIES})
+
+# As of Ubuntu 14.04 protoc is no longer a part of libprotobuf-dev package
+# and should be installed separately as in: sudo apt-get install protobuf-compiler
+if(EXISTS ${PROTOBUF_PROTOC_EXECUTABLE})
+ message(STATUS "Found PROTOBUF Compiler: ${PROTOBUF_PROTOC_EXECUTABLE}")
+else()
+ message(FATAL_ERROR "Could not find PROTOBUF Compiler")
+endif()
+
+if(PROTOBUF_FOUND)
+ # fetches protobuf version
+ caffe_parse_header(${PROTOBUF_INCLUDE_DIR}/google/protobuf/stubs/common.h VERION_LINE GOOGLE_PROTOBUF_VERSION)
+ string(REGEX MATCH "([0-9])00([0-9])00([0-9])" PROTOBUF_VERSION ${GOOGLE_PROTOBUF_VERSION})
+ set(PROTOBUF_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
+ unset(GOOGLE_PROTOBUF_VERSION)
+endif()
+
+# place where to generate protobuf sources
+set(proto_gen_folder "${CMAKE_BINARY_DIR}/include/caffe/proto")
+include_directories(SYSTEM "${CMAKE_BINARY_DIR}/include")
+
+set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE)
+
+################################################################################################
+# Modification of standard 'protobuf_generate_cpp()' with output dir parameter and python support
+# Usage:
+# caffe_protobuf_generate_cpp_py(<output_dir> <srcs_var> <hdrs_var> <python_var> <proto_files>)
+function(caffe_protobuf_generate_cpp_py output_dir srcs_var hdrs_var python_var)
+ if(NOT ARGN)
+ message(SEND_ERROR "Error: caffe_protobuf_generate_cpp_py() called without any proto files")
+ return()
+ endif()
+
+ if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
+ # Create an include path for each file specified
+ foreach(fil ${ARGN})
+ get_filename_component(abs_fil ${fil} ABSOLUTE)
+ get_filename_component(abs_path ${abs_fil} PATH)
+ list(FIND _protoc_include ${abs_path} _contains_already)
+ if(${_contains_already} EQUAL -1)
+ list(APPEND _protoc_include -I ${abs_path})
+ endif()
+ endforeach()
+ else()
+ set(_protoc_include -I ${CMAKE_CURRENT_SOURCE_DIR})
+ endif()
+
+ if(DEFINED PROTOBUF_IMPORT_DIRS)
+ foreach(dir ${PROTOBUF_IMPORT_DIRS})
+ get_filename_component(abs_path ${dir} ABSOLUTE)
+ list(FIND _protoc_include ${abs_path} _contains_already)
+ if(${_contains_already} EQUAL -1)
+ list(APPEND _protoc_include -I ${abs_path})
+ endif()
+ endforeach()
+ endif()
+
+ set(${srcs_var})
+ set(${hdrs_var})
+ set(${python_var})
+ foreach(fil ${ARGN})
+ get_filename_component(abs_fil ${fil} ABSOLUTE)
+ get_filename_component(fil_we ${fil} NAME_WE)
+
+ list(APPEND ${srcs_var} "${output_dir}/${fil_we}.pb.cc")
+ list(APPEND ${hdrs_var} "${output_dir}/${fil_we}.pb.h")
+ list(APPEND ${python_var} "${output_dir}/${fil_we}_pb2.py")
+
+ add_custom_command(
+ OUTPUT "${output_dir}/${fil_we}.pb.cc"
+ "${output_dir}/${fil_we}.pb.h"
+ "${output_dir}/${fil_we}_pb2.py"
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${output_dir}"
+ COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --cpp_out ${output_dir} ${_protoc_include} ${abs_fil}
+ COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out ${output_dir} ${_protoc_include} ${abs_fil}
+ DEPENDS ${abs_fil}
+ COMMENT "Running C++/Python protocol buffer compiler on ${fil}" VERBATIM )
+ endforeach()
+
+ set_source_files_properties(${${srcs_var}} ${${hdrs_var}} ${${python_var}} PROPERTIES GENERATED TRUE)
+ set(${srcs_var} ${${srcs_var}} PARENT_SCOPE)
+ set(${hdrs_var} ${${hdrs_var}} PARENT_SCOPE)
+ set(${python_var} ${${python_var}} PARENT_SCOPE)
+endfunction()
diff --git a/cmake/Summary.cmake b/cmake/Summary.cmake
new file mode 100644
index 00000000..756a738c
--- /dev/null
+++ b/cmake/Summary.cmake
@@ -0,0 +1,166 @@
+################################################################################################
+# Caffe status report function.
+# Automatically align right column and selects text based on condition.
+# Usage:
+# caffe_status(<text>)
+# caffe_status(<heading> <value1> [<value2> ...])
+# caffe_status(<heading> <condition> THEN <text for TRUE> ELSE <text for FALSE> )
+function(caffe_status text)
+ set(status_cond)
+ set(status_then)
+ set(status_else)
+
+ set(status_current_name "cond")
+ foreach(arg ${ARGN})
+ if(arg STREQUAL "THEN")
+ set(status_current_name "then")
+ elseif(arg STREQUAL "ELSE")
+ set(status_current_name "else")
+ else()
+ list(APPEND status_${status_current_name} ${arg})
+ endif()
+ endforeach()
+
+ if(DEFINED status_cond)
+ set(status_placeholder_length 23)
+ string(RANDOM LENGTH ${status_placeholder_length} ALPHABET " " status_placeholder)
+ string(LENGTH "${text}" status_text_length)
+ if(status_text_length LESS status_placeholder_length)
+ string(SUBSTRING "${text}${status_placeholder}" 0 ${status_placeholder_length} status_text)
+ elseif(DEFINED status_then OR DEFINED status_else)
+ message(STATUS "${text}")
+ set(status_text "${status_placeholder}")
+ else()
+ set(status_text "${text}")
+ endif()
+
+ if(DEFINED status_then OR DEFINED status_else)
+ if(${status_cond})
+ string(REPLACE ";" " " status_then "${status_then}")
+ string(REGEX REPLACE "^[ \t]+" "" status_then "${status_then}")
+ message(STATUS "${status_text} ${status_then}")
+ else()
+ string(REPLACE ";" " " status_else "${status_else}")
+ string(REGEX REPLACE "^[ \t]+" "" status_else "${status_else}")
+ message(STATUS "${status_text} ${status_else}")
+ endif()
+ else()
+ string(REPLACE ";" " " status_cond "${status_cond}")
+ string(REGEX REPLACE "^[ \t]+" "" status_cond "${status_cond}")
+ message(STATUS "${status_text} ${status_cond}")
+ endif()
+ else()
+ message(STATUS "${text}")
+ endif()
+endfunction()
+
+
+################################################################################################
+# Function for fetching Caffe version from git and headers
+# Usage:
+# caffe_extract_caffe_version()
+function(caffe_extract_caffe_version)
+ set(Caffe_GIT_VERSION "unknown")
+ find_package(Git)
+ if(GIT_FOUND)
+ execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --always --dirty
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+ OUTPUT_VARIABLE Caffe_GIT_VERSION
+ RESULT_VARIABLE __git_result)
+ if(NOT ${__git_result} EQUAL 0)
+ set(Caffe_GIT_VERSION "unknown")
+ endif()
+ endif()
+
+ set(Caffe_GIT_VERSION ${Caffe_GIT_VERSION} PARENT_SCOPE)
+ set(Caffe_VERSION "<TODO> (Caffe doesn't declare its version in headers)" PARENT_SCOPE)
+
+ # caffe_parse_header(${Caffe_INCLUDE_DIR}/caffe/version.hpp Caffe_VERSION_LINES CAFFE_MAJOR CAFFE_MINOR CAFFE_PATCH)
+ # set(Caffe_VERSION "${CAFFE_MAJOR}.${CAFFE_MINOR}.${CAFFE_PATCH}" PARENT_SCOPE)
+
+ # or for #define Caffe_VERSION "x.x.x"
+ # caffe_parse_header_single_define(Caffe ${Caffe_INCLUDE_DIR}/caffe/version.hpp Caffe_VERSION)
+ # set(Caffe_VERSION ${Caffe_VERSION_STRING} PARENT_SCOPE)
+
+endfunction()
+
+
+################################################################################################
+# Prints accumulatd caffe configuration summary
+# Usage:
+# caffe_print_configuration_summary()
+
+function(caffe_print_configuration_summary)
+ caffe_extract_caffe_version()
+ set(Caffe_VERSION ${Caffe_VERSION} PARENT_SCOPE)
+
+ caffe_merge_flag_lists(__flags_rel CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS)
+ caffe_merge_flag_lists(__flags_deb CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS)
+
+ caffe_status("")
+ caffe_status("******************* Caffe Configuration Summary *******************")
+ caffe_status("General:")
+ caffe_status(" Version : ${Caffe_VERSION}")
+ caffe_status(" Git : ${Caffe_GIT_VERSION}")
+ caffe_status(" System : ${CMAKE_SYSTEM_NAME}")
+ caffe_status(" C++ compiler : ${CMAKE_CXX_COMPILER}")
+ caffe_status(" Release CXX flags : ${__flags_rel}")
+ caffe_status(" Debug CXX flags : ${__flags_deb}")
+ caffe_status(" BUILD_SHARED_LIBS : ${BUILD_SHARED_LIBS}")
+ caffe_status(" Build type : ${CMAKE_BUILD_TYPE}")
+ caffe_status(" BUILD_python : ${BUILD_python}")
+ caffe_status(" BUILD_matlab : ${BUILD_matlab}")
+ caffe_status(" BUILD_docs : ${BUILD_docs}")
+ caffe_status(" CPU_ONLY : ${CPU_ONLY}")
+ caffe_status("")
+ caffe_status("Dependencies:")
+ caffe_status(" BLAS : " APPLE THEN "Yes (vecLib)" ELSE "Yes (${BLAS})")
+ caffe_status(" glog : Yes")
+ caffe_status(" gflags : Yes")
+ caffe_status(" protobuf : " PROTOBUF_FOUND THEN "Yes (ver. ${PROTOBUF_VERSION})" ELSE "No" )
+ caffe_status(" lmdb : " LMDB_FOUND THEN "Yes (ver. ${LMDB_VERSION})" ELSE "No")
+ caffe_status(" Snappy : " SNAPPY_FOUND THEN "Yes (ver. ${Snappy_VERSION})" ELSE "No" )
+ caffe_status(" LevelDB : " LEVELDB_FOUND THEN "Yes (ver. ${LEVELDB_VERSION})" ELSE "No")
+ caffe_status(" OpenCV : Yes (ver. ${OpenCV_VERSION})")
+ caffe_status(" CUDA : " HAVE_CUDA THEN "Yes (ver. ${CUDA_VERSION})" ELSE "No" )
+ caffe_status("")
+ if(HAVE_CUDA)
+ caffe_status("NVIDIA CUDA:")
+ caffe_status(" Target GPU(s) : ${CUDA_ARCH_NAME}" )
+ caffe_status(" GPU arch(s) : ${NVCC_FLAGS_EXTRA_readable}")
+ if(USE_CUDNN)
+ caffe_status(" cuDNN : " HAVE_CUDNN THEN "Yes" ELSE "Not found")
+ else()
+ caffe_status(" cuDNN : Disabled")
+ endif()
+ caffe_status("")
+ endif()
+ if(HAVE_PYTHON)
+ caffe_status("Python:")
+ caffe_status(" Interpreter :" PYTHON_EXECUTABLE THEN "${PYTHON_EXECUTABLE} (ver. ${PYTHON_VERSION_STRING})" ELSE "No")
+ caffe_status(" Libraries :" PYTHONLIBS_FOUND THEN "${PYTHON_LIBRARIES} (ver ${PYTHONLIBS_VERSION_STRING})" ELSE "No")
+ caffe_status(" NumPy :" NUMPY_FOUND THEN "${NUMPY_INCLUDE_DIR} (ver ${NUMPY_VERSION})" ELSE "No")
+ caffe_status("")
+ endif()
+ if(BUILD_matlab)
+ caffe_status("Matlab:")
+ caffe_status(" Matlab :" HAVE_MATLAB THEN "Yes (${Matlab_mex}, ${Matlab_mexext}" ELSE "No")
+ caffe_status(" Octave :" Octave_compiler THEN "Yes (${Octave_compiler})" ELSE "No")
+ if(HAVE_MATLAB AND Octave_compiler)
+ caffe_status(" Build mex using : ${Matlab_build_mex_using}")
+ endif()
+ caffe_status("")
+ endif()
+ if(BUILD_docs)
+ caffe_status("Documentaion:")
+ caffe_status(" Doxygen :" DOXYGEN_FOUND THEN "${DOXYGEN_EXECUTABLE} (${DOXYGEN_VERSION})" ELSE "No")
+ caffe_status(" config_file : ${DOXYGEN_config_file}")
+
+ caffe_status("")
+ endif()
+ caffe_status("Install:")
+ caffe_status(" Install path : ${CMAKE_INSTALL_PREFIX}")
+ caffe_status("")
+endfunction()
+
diff --git a/cmake/Targets.cmake b/cmake/Targets.cmake
new file mode 100644
index 00000000..84a2aaf5
--- /dev/null
+++ b/cmake/Targets.cmake
@@ -0,0 +1,170 @@
+################################################################################################
+# Defines global Caffe_LINK flag, This flag is required to prevent linker from excluding
+# some objects which are not addressed directly but are registered via static constructors
+if(BUILD_SHARED_LIBS)
+ set(Caffe_LINK caffe)
+else()
+ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ set(Caffe_LINK -Wl,-force_load caffe)
+ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ set(Caffe_LINK -Wl,--whole-archive caffe -Wl,--no-whole-archive)
+ endif()
+endif()
+
+################################################################################################
+# Convenient command to setup source group for IDEs that support this feature (VS, XCode)
+# Usage:
+# caffe_source_group(<group> GLOB[_RECURSE] <globbing_expression>)
+function(caffe_source_group group)
+ cmake_parse_arguments(CAFFE_SOURCE_GROUP "" "" "GLOB;GLOB_RECURSE" ${ARGN})
+ if(CAFFE_SOURCE_GROUP_GLOB)
+ file(GLOB srcs1 ${CAFFE_SOURCE_GROUP_GLOB})
+ source_group(${group} FILES ${srcs1})
+ endif()
+
+ if(CAFFE_SOURCE_GROUP_GLOB_RECURSE)
+ file(GLOB_RECURSE srcs2 ${CAFFE_SOURCE_GROUP_GLOB_RECURSE})
+ source_group(${group} FILES ${srcs2})
+ endif()
+endfunction()
+
+################################################################################################
+# Collecting sources from globbing and appending to output list variable
+# Usage:
+# caffe_source_group(<output_variable> GLOB[_RECURSE] <globbing_expression>)
+function(caffe_collect_sources variable)
+ cmake_parse_arguments(CAFFE_COLLECT_SOURCES "" "" "GLOB;GLOB_RECURSE" ${ARGN})
+ if(CAFFE_COLLECT_SOURCES_GLOB)
+ file(GLOB srcs1 ${CAFFE_COLLECT_SOURCES_GLOB})
+ set(${variable} ${variable} ${srcs1})
+ endif()
+
+ if(CAFFE_COLLECT_SOURCES_GLOB_RECURSE)
+ file(GLOB_RECURSE srcs2 ${CAFFE_COLLECT_SOURCES_GLOB_RECURSE})
+ set(${variable} ${variable} ${srcs2})
+ endif()
+endfunction()
+
+################################################################################################
+# Short command getting caffe sources (assuming standard Caffe code tree)
+# Usage:
+# caffe_pickup_caffe_sources(<root>)
+function(caffe_pickup_caffe_sources root)
+ # put all files in source groups (visible as subfolder in many IDEs)
+ caffe_source_group("Include" GLOB "${root}/include/caffe/*.h*")
+ caffe_source_group("Include\\Util" GLOB "${root}/include/caffe/util/*.h*")
+ caffe_source_group("Include" GLOB "${CMAKE_BINARY_DIR}/caffe_config.h*")
+ caffe_source_group("Source" GLOB "${root}/src/caffe/*.cpp")
+ caffe_source_group("Source\\Util" GLOB "${root}/src/caffe/util/*.cpp")
+ caffe_source_group("Source\\Layers" GLOB "${root}/src/caffe/layers/*.cpp")
+ caffe_source_group("Source\\Cuda" GLOB "${root}/src/caffe/layers/*.cu")
+ caffe_source_group("Source\\Cuda" GLOB "${root}/src/caffe/util/*.cu")
+ caffe_source_group("Source\\Proto" GLOB "${root}/src/caffe/proto/*.proto")
+
+ # source groups for test target
+ caffe_source_group("Include" GLOB "${root}/include/caffe/test/test_*.h*")
+ caffe_source_group("Source" GLOB "${root}/src/caffe/test/test_*.cpp")
+ caffe_source_group("Source\\Cuda" GLOB "${root}/src/caffe/test/test_*.cu")
+
+ # collect files
+ file(GLOB test_hdrs ${root}/include/caffe/test/test_*.h*)
+ file(GLOB test_srcs ${root}/src/caffe/test/test_*.cpp)
+ file(GLOB_RECURSE hdrs ${root}/include/caffe/*.h*)
+ file(GLOB_RECURSE srcs ${root}/src/caffe/*.cpp)
+ list(REMOVE_ITEM hdrs ${test_hdrs})
+ list(REMOVE_ITEM srcs ${test_srcs})
+
+ # adding headers to make the visible in some IDEs (Qt, VS, Xcode)
+ list(APPEND srcs ${hdrs} ${CMAKE_BINARY_DIR}/caffe_config.h)
+ list(APPEND test_srcs ${test_hdrs})
+
+ # collect cuda files
+ file(GLOB test_cuda ${root}/src/caffe/test/test_*.cu)
+ file(GLOB_RECURSE cuda ${root}/src/caffe/*.cu)
+ list(REMOVE_ITEM cuda ${test_cuda})
+
+ # add proto to make them editable in IDEs too
+ file(GLOB_RECURSE proto_files ${root}/src/caffe/*.proto)
+ list(APPEND srcs ${proto_files})
+
+ # convet to absolute paths
+ caffe_convert_absolute_paths(srcs)
+ caffe_convert_absolute_paths(cuda)
+ caffe_convert_absolute_paths(test_srcs)
+ caffe_convert_absolute_paths(test_cuda)
+
+ # propogate to parent scope
+ set(srcs ${srcs} PARENT_SCOPE)
+ set(cuda ${cuda} PARENT_SCOPE)
+ set(test_srcs ${test_srcs} PARENT_SCOPE)
+ set(test_cuda ${test_cuda} PARENT_SCOPE)
+endfunction()
+
+################################################################################################
+# Short command for setting defeault target properties
+# Usage:
+# caffe_default_properties(<target>)
+function(caffe_default_properties target)
+ set_target_properties(${target} PROPERTIES
+ DEBUG_POSTFIX ${Caffe_DEBUG_POSTFIX}
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
+endfunction()
+
+################################################################################################
+# Short command for setting runtime directory for build target
+# Usage:
+# caffe_set_runtime_directory(<target> <dir>)
+function(caffe_set_runtime_directory target dir)
+ set_target_properties(${target} PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY "${dir}")
+endfunction()
+
+################################################################################################
+# Short command for setting solution folder property for target
+# Usage:
+# caffe_set_solution_folder(<target> <folder>)
+function(caffe_set_solution_folder target folder)
+ if(USE_PROJECT_FOLDERS)
+ set_target_properties(${target} PROPERTIES FOLDER "${folder}")
+ endif()
+endfunction()
+
+################################################################################################
+# Reads lines from input file, prepends source directory to each line and writes to output file
+# Usage:
+# caffe_configure_testdatafile(<testdatafile>)
+function(caffe_configure_testdatafile file)
+ file(STRINGS ${file} __lines)
+ set(result "")
+ foreach(line ${__lines})
+ set(result "${result}${CMAKE_SOURCE_DIR}/${line}\n")
+ endforeach()
+ dmsg(${result})
+ file(WRITE ${file}.gen.cmake ${result})
+endfunction()
+
+################################################################################################
+# Filter outs all files that are not inlcuded in selected list
+# Usage:
+# caffe_leave_only_selected_tests(<filelist_variable> <selected_list>)
+function(caffe_leave_only_selected_tests file_list)
+ if(NOT ARGN)
+ return() # blank list means leave all
+ endif()
+ string(REPLACE "," ";" __selected ${ARGN})
+ list(APPEND __selected caffe_main)
+
+ set(result "")
+ foreach(f ${${file_list}})
+ get_filename_component(name ${f} NAME_WE)
+ string(REGEX REPLACE "^test_" "" name ${name})
+ list(FIND __selected ${name} __index)
+ if(NOT __index EQUAL -1)
+ list(APPEND result ${f})
+ endif()
+ endforeach()
+ set(${file_list} ${result} PARENT_SCOPE)
+endfunction()
+
diff --git a/cmake/Templates/CaffeConfig.cmake.in b/cmake/Templates/CaffeConfig.cmake.in
new file mode 100644
index 00000000..a4b03d96
--- /dev/null
+++ b/cmake/Templates/CaffeConfig.cmake.in
@@ -0,0 +1,58 @@
+# Config file for the Caffe package.
+#
+# Note:
+# Caffe and this config file depends on opencv,
+# so put `find_package(OpenCV)` before searching Caffe
+# via `find_package(Caffe)`. All other lib/includes
+# dependencies are hard coded int the file
+#
+# After successful configuration the following variables
+# will be defined:
+#
+# Caffe_INCLUDE_DIRS - Caffe include directories
+# Caffe_LIBRARIES - libraries to link against
+# Caffe_DEFINITIONS - a list of definitions to pass to compiler
+#
+# Caffe_HAVE_CUDA - signals about CUDA support
+# Caffe_HAVE_CUDNN - signals about cuDNN support
+
+
+# OpenCV dependency
+
+if(NOT OpenCV_FOUND)
+ set(Caffe_OpenCV_CONFIG_PATH "@OpenCV_CONFIG_PATH@")
+ if(Caffe_OpenCV_CONFIG_PATH)
+ get_filename_component(Caffe_OpenCV_CONFIG_PATH ${Caffe_OpenCV_CONFIG_PATH} ABSOLUTE)
+
+ if(EXISTS ${Caffe_OpenCV_CONFIG_PATH} AND NOT TARGET opencv_core)
+ message(STATUS "Caffe: using OpenCV config from ${Caffe_OpenCV_CONFIG_PATH}")
+ include(${Caffe_OpenCV_CONFIG_PATH}/OpenCVModules.cmake)
+ endif()
+
+ else()
+ find_package(OpenCV REQUIRED)
+ endif()
+ unset(Caffe_OpenCV_CONFIG_PATH)
+endif()
+
+# Compute paths
+get_filename_component(Caffe_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
+set(Caffe_INCLUDE_DIRS "@Caffe_INCLUDE_DIRS@")
+
+@Caffe_INSTALL_INCLUDE_DIR_APPEND_COMMAND@
+
+# Our library dependencies
+if(NOT TARGET caffe AND NOT caffe_BINARY_DIR)
+ include("${Caffe_CMAKE_DIR}/CaffeTargets.cmake")
+endif()
+
+# List of IMPORTED libs created by CaffeTargets.cmake
+set(Caffe_LIBRARIES caffe)
+
+# Definitions
+set(Caffe_DEFINITIONS "@Caffe_DEFINITIONS@")
+
+# Cuda support variables
+set(Caffe_CPU_ONLY @CPU_ONLY@)
+set(Caffe_HAVE_CUDA @HAVE_CUDA@)
+set(Caffe_HAVE_CUDNN @HAVE_CUDNN@)
diff --git a/cmake/Templates/CaffeConfigVersion.cmake.in b/cmake/Templates/CaffeConfigVersion.cmake.in
new file mode 100644
index 00000000..cbfa514f
--- /dev/null
+++ b/cmake/Templates/CaffeConfigVersion.cmake.in
@@ -0,0 +1,11 @@
+set(PACKAGE_VERSION "@Caffe_VERSION@")
+
+# Check whether the requested PACKAGE_FIND_VERSION is compatible
+if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
+ set(PACKAGE_VERSION_COMPATIBLE FALSE)
+else()
+ set(PACKAGE_VERSION_COMPATIBLE TRUE)
+ if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
+ set(PACKAGE_VERSION_EXACT TRUE)
+ endif()
+endif()
diff --git a/cmake/Templates/caffe_config.h.in b/cmake/Templates/caffe_config.h.in
new file mode 100644
index 00000000..6aa22ed7
--- /dev/null
+++ b/cmake/Templates/caffe_config.h.in
@@ -0,0 +1,32 @@
+/* Sources directory */
+#define SOURCE_FOLDER "${CMAKE_SOURCE_DIR}"
+
+/* Binaries directory */
+#define BINARY_FOLDER "${CMAKE_BINARY_DIR}"
+
+/* NVIDA Cuda */
+#cmakedefine HAVE_CUDA
+
+/* NVIDA cuDNN */
+#cmakedefine HAVE_CUDNN
+#cmakedefine USE_CUDNN
+
+/* NVIDA cuDNN */
+#cmakedefine CPU_ONLY
+
+/* Test device */
+#define CUDA_TEST_DEVICE ${CUDA_TEST_DEVICE}
+
+/* Temporary (TODO: remove) */
+#if 1
+ #define CMAKE_SOURCE_DIR SOURCE_FOLDER "/src/"
+ #define EXAMPLES_SOURCE_DIR BINARY_FOLDER "/examples/"
+ #define CMAKE_EXT ".gen.cmake"
+#else
+ #define CMAKE_SOURCE_DIR "src/"
+ #define EXAMPLES_SOURCE_DIR "examples/"
+ #define CMAKE_EXT ""
+#endif
+
+/* Matlab */
+#cmakedefine HAVE_MATLAB
diff --git a/cmake/Utils.cmake b/cmake/Utils.cmake
new file mode 100644
index 00000000..048123db
--- /dev/null
+++ b/cmake/Utils.cmake
@@ -0,0 +1,365 @@
+################################################################################################
+# Command alias for debugging messages
+# Usage:
+# dmgs(<message>)
+function(dmsg)
+ message(STATUS ${ARGN})
+endfunction()
+
+################################################################################################
+# Removes duplicates from list(s)
+# Usage:
+# caffe_list_unique(<list_variable> [<list_variable>] [...])
+macro(caffe_list_unique)
+ foreach(__lst ${ARGN})
+ if(${__lst})
+ list(REMOVE_DUPLICATES ${__lst})
+ endif()
+ endforeach()
+endmacro()
+
+################################################################################################
+# Clears variables from lsit
+# Usage:
+# caffe_list_unique(<variables_list>)
+macro(caffe_clear_vars)
+ foreach(_var ${ARGN})
+ unset(${_var})
+ endforeach()
+endmacro()
+
+################################################################################################
+# Removes duplicates from string
+# Usage:
+# caffe_string_unique(<string_variable>)
+function(caffe_string_unique __string)
+ if(${__string})
+ set(__list ${${__string}})
+ separate_arguments(__list)
+ list(REMOVE_DUPLICATES __list)
+ foreach(__e ${__list})
+ set(__str "${__str} ${__e}")
+ endforeach()
+ set(${__string} ${__str} PARENT_SCOPE)
+ endif()
+endfunction()
+
+################################################################################################
+# Prints list element per line
+# Usage:
+# caffe_print_list(<list>)
+function(caffe_print_list)
+ foreach(e ${ARGN})
+ message(STATUS ${e})
+ endforeach()
+endfunction()
+
+################################################################################################
+# Function merging lists of compiler flags to single string.
+# Usage:
+# caffe_merge_flag_lists(out_variable <list1> [<list2>] [<list3>] ...)
+function(caffe_merge_flag_lists out_var)
+ set(__result "")
+ foreach(__list ${ARGN})
+ foreach(__flag ${${__list}})
+ string(STRIP ${__flag} __flag)
+ set(__result "${__result} ${__flag}")
+ endforeach()
+ endforeach()
+ string(STRIP ${__result} __result)
+ set(${out_var} ${__result} PARENT_SCOPE)
+endfunction()
+
+################################################################################################
+# Converts all paths in list to absolute
+# Usage:
+# caffe_convert_absolute_paths(<list_variable>)
+function(caffe_convert_absolute_paths variable)
+ set(__dlist "")
+ foreach(__s ${${variable}})
+ get_filename_component(__abspath ${__s} ABSOLUTE)
+ list(APPEND __list ${__abspath})
+ endforeach()
+ set(${variable} ${__list} PARENT_SCOPE)
+endfunction()
+
+################################################################################################
+# Reads set of version defines from the header file
+# Usage:
+# caffe_parse_header(<file> <define1> <define2> <define3> ..)
+macro(caffe_parse_header FILENAME FILE_VAR)
+ set(vars_regex "")
+ set(__parnet_scope OFF)
+ set(__add_cache OFF)
+ foreach(name ${ARGN})
+ if("${name}" STREQUAL "PARENT_SCOPE")
+ set(__parnet_scope ON)
+ elseif("${name}" STREQUAL "CACHE")
+ set(__add_cache ON)
+ elseif(vars_regex)
+ set(vars_regex "${vars_regex}|${name}")
+ else()
+ set(vars_regex "${name}")
+ endif()
+ endforeach()
+ if(EXISTS "${FILENAME}")
+ file(STRINGS "${FILENAME}" ${FILE_VAR} REGEX "#define[ \t]+(${vars_regex})[ \t]+[0-9]+" )
+ else()
+ unset(${FILE_VAR})
+ endif()
+ foreach(name ${ARGN})
+ if(NOT "${name}" STREQUAL "PARENT_SCOPE" AND NOT "${name}" STREQUAL "CACHE")
+ if(${FILE_VAR})
+ if(${FILE_VAR} MATCHES ".+[ \t]${name}[ \t]+([0-9]+).*")
+ string(REGEX REPLACE ".+[ \t]${name}[ \t]+([0-9]+).*" "\\1" ${name} "${${FILE_VAR}}")
+ else()
+ set(${name} "")
+ endif()
+ if(__add_cache)
+ set(${name} ${${name}} CACHE INTERNAL "${name} parsed from ${FILENAME}" FORCE)
+ elseif(__parnet_scope)
+ set(${name} "${${name}}" PARENT_SCOPE)
+ endif()
+ else()
+ unset(${name} CACHE)
+ endif()
+ endif()
+ endforeach()
+endmacro()
+
+################################################################################################
+# Reads single version define from the header file and parses it
+# Usage:
+# caffe_parse_header_single_define(<library_name> <file> <define_name>)
+function(caffe_parse_header_single_define LIBNAME HDR_PATH VARNAME)
+ set(${LIBNAME}_H "")
+ if(EXISTS "${HDR_PATH}")
+ file(STRINGS "${HDR_PATH}" ${LIBNAME}_H REGEX "^#define[ \t]+${VARNAME}[ \t]+\"[^\"]*\".*$" LIMIT_COUNT 1)
+ endif()
+
+ if(${LIBNAME}_H)
+ string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MAJOR "${${LIBNAME}_H}")
+ string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_MINOR "${${LIBNAME}_H}")
+ string(REGEX REPLACE "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" ${LIBNAME}_VERSION_PATCH "${${LIBNAME}_H}")
+ set(${LIBNAME}_VERSION_MAJOR ${${LIBNAME}_VERSION_MAJOR} ${ARGN} PARENT_SCOPE)
+ set(${LIBNAME}_VERSION_MINOR ${${LIBNAME}_VERSION_MINOR} ${ARGN} PARENT_SCOPE)
+ set(${LIBNAME}_VERSION_PATCH ${${LIBNAME}_VERSION_PATCH} ${ARGN} PARENT_SCOPE)
+ set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_MAJOR}.${${LIBNAME}_VERSION_MINOR}.${${LIBNAME}_VERSION_PATCH}" PARENT_SCOPE)
+
+ # append a TWEAK version if it exists:
+ set(${LIBNAME}_VERSION_TWEAK "")
+ if("${${LIBNAME}_H}" MATCHES "^.*[ \t]${VARNAME}[ \t]+\"[0-9]+\\.[0-9]+\\.[0-9]+\\.([0-9]+).*$")
+ set(${LIBNAME}_VERSION_TWEAK "${CMAKE_MATCH_1}" ${ARGN} PARENT_SCOPE)
+ endif()
+ if(${LIBNAME}_VERSION_TWEAK)
+ set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}.${${LIBNAME}_VERSION_TWEAK}" ${ARGN} PARENT_SCOPE)
+ else()
+ set(${LIBNAME}_VERSION_STRING "${${LIBNAME}_VERSION_STRING}" ${ARGN} PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
+
+########################################################################################################
+# An option that the user can select. Can accept condition to control when option is available for user.
+# Usage:
+# caffe_option(<option_variable> "doc string" <initial value or boolean expression> [IF <condition>])
+function(caffe_option variable description value)
+ set(__value ${value})
+ set(__condition "")
+ set(__varname "__value")
+ foreach(arg ${ARGN})
+ if(arg STREQUAL "IF" OR arg STREQUAL "if")
+ set(__varname "__condition")
+ else()
+ list(APPEND ${__varname} ${arg})
+ endif()
+ endforeach()
+ unset(__varname)
+ if("${__condition}" STREQUAL "")
+ set(__condition 2 GREATER 1)
+ endif()
+
+ if(${__condition})
+ if("${__value}" MATCHES ";")
+ if(${__value})
+ option(${variable} "${description}" ON)
+ else()
+ option(${variable} "${description}" OFF)
+ endif()
+ elseif(DEFINED ${__value})
+ if(${__value})
+ option(${variable} "${description}" ON)
+ else()
+ option(${variable} "${description}" OFF)
+ endif()
+ else()
+ option(${variable} "${description}" ${__value})
+ endif()
+ else()
+ unset(${variable} CACHE)
+ endif()
+endfunction()
+
+################################################################################################
+# Utility macro for comparing two lists. Used for CMake debugging purposes
+# Usage:
+# caffe_compare_lists(<list_variable> <list2_variable> [description])
+function(caffe_compare_lists list1 list2 desc)
+ set(__list1 ${${list1}})
+ set(__list2 ${${list2}})
+ list(SORT __list1)
+ list(SORT __list2)
+ list(LENGTH __list1 __len1)
+ list(LENGTH __list2 __len2)
+
+ if(NOT ${__len1} EQUAL ${__len2})
+ message(FATAL_ERROR "Lists are not equal. ${__len1} != ${__len2}. ${desc}")
+ endif()
+
+ foreach(__i RANGE 1 ${__len1})
+ math(EXPR __index "${__i}- 1")
+ list(GET __list1 ${__index} __item1)
+ list(GET __list2 ${__index} __item2)
+ if(NOT ${__item1} STREQUAL ${__item2})
+ message(FATAL_ERROR "Lists are not equal. Differ at element ${__index}. ${desc}")
+ endif()
+ endforeach()
+endfunction()
+
+################################################################################################
+# Command for disabling warnings for different platforms (see below for gcc and VisualStudio)
+# Usage:
+# caffe_warnings_disable(<CMAKE_[C|CXX]_FLAGS[_CONFIGURATION]> -Wshadow /wd4996 ..,)
+macro(caffe_warnings_disable)
+ set(_flag_vars "")
+ set(_msvc_warnings "")
+ set(_gxx_warnings "")
+
+ foreach(arg ${ARGN})
+ if(arg MATCHES "^CMAKE_")
+ list(APPEND _flag_vars ${arg})
+ elseif(arg MATCHES "^/wd")
+ list(APPEND _msvc_warnings ${arg})
+ elseif(arg MATCHES "^-W")
+ list(APPEND _gxx_warnings ${arg})
+ endif()
+ endforeach()
+
+ if(NOT _flag_vars)
+ set(_flag_vars CMAKE_C_FLAGS CMAKE_CXX_FLAGS)
+ endif()
+
+ if(MSVC AND _msvc_warnings)
+ foreach(var ${_flag_vars})
+ foreach(warning ${_msvc_warnings})
+ set(${var} "${${var}} ${warning}")
+ endforeach()
+ endforeach()
+ elseif((CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX) AND _gxx_warnings)
+ foreach(var ${_flag_vars})
+ foreach(warning ${_gxx_warnings})
+ if(NOT warning MATCHES "^-Wno-")
+ string(REPLACE "${warning}" "" ${var} "${${var}}")
+ string(REPLACE "-W" "-Wno-" warning "${warning}")
+ endif()
+ set(${var} "${${var}} ${warning}")
+ endforeach()
+ endforeach()
+ endif()
+ caffe_clear_vars(_flag_vars _msvc_warnings _gxx_warnings)
+endmacro()
+
+################################################################################################
+# Helper function get current definitions
+# Usage:
+# caffe_get_current_definitions(<definitions_variable>)
+function(caffe_get_current_definitions definitions_var)
+ get_property(current_definitions DIRECTORY PROPERTY COMPILE_DEFINITIONS)
+ set(result "")
+
+ foreach(d ${current_definitions})
+ list(APPEND result -D${d})
+ endforeach()
+
+ caffe_list_unique(result)
+ set(${definitions_var} ${result} PARENT_SCOPE)
+endfunction()
+
+################################################################################################
+# Helper function get current includes/definitions
+# Usage:
+# caffe_get_current_cflags(<cflagslist_variable>)
+function(caffe_get_current_cflags cflags_var)
+ get_property(current_includes DIRECTORY PROPERTY INCLUDE_DIRECTORIES)
+ caffe_convert_absolute_paths(current_includes)
+ caffe_get_current_definitions(cflags)
+
+ foreach(i ${current_includes})
+ list(APPEND cflags "-I${i}")
+ endforeach()
+
+ caffe_list_unique(cflags)
+ set(${cflags_var} ${cflags} PARENT_SCOPE)
+endfunction()
+
+################################################################################################
+# Helper function to parse current linker libs into link directoris, libflags and osx frameworks
+# Usage:
+# caffe_parse_linker_libs(<Caffe_LINKER_LIBS_var> <directories_var> <libflags_var> <frameworks_var>)
+function(caffe_parse_linker_libs Caffe_LINKER_LIBS_variable folders_var flags_var frameworks_var)
+
+ set(__unspec "")
+ set(__debug "")
+ set(__optimized "")
+ set(__framework "")
+ set(__varname "__unspec")
+
+ # split libs into debug, optimized, unspecified and frameworks
+ foreach(list_elem ${${Caffe_LINKER_LIBS_variable}})
+ if(list_elem STREQUAL "debug")
+ set(__varname "__debug")
+ elseif(list_elem STREQUAL "optimized")
+ set(__varname "__optimized")
+ elseif(list_elem MATCHES "^-framework[ \t]+([^ \t].*)")
+ list(APPEND __framework -framework ${CMAKE_MATCH_1})
+ else()
+ list(APPEND ${__varname} ${list_elem})
+ set(__varname "__unspec")
+ endif()
+ endforeach()
+
+ # attach debug or optimized libs to unspecified according to current configuration
+ if(CMAKE_BUILD_TYPE MATCHES "Debug")
+ set(__libs ${__unspec} ${__debug})
+ else()
+ set(__libs ${__unspec} ${__optimized})
+ endif()
+
+ set(libflags "")
+ set(folders "")
+
+ # convert linker libraries list to link flags
+ foreach(lib ${__libs})
+ if(TARGET ${lib})
+ list(APPEND folders $<TARGET_LINKER_FILE_DIR:${lib}>)
+ list(APPEND libflags -l${lib})
+ elseif(lib MATCHES "^-l.*")
+ list(APPEND libflags ${lib})
+ elseif(IS_ABSOLUTE ${lib})
+ get_filename_component(name_we ${lib} NAME_WE)
+ get_filename_component(folder ${lib} PATH)
+
+ string(REGEX MATCH "^lib(.*)" __match ${name_we})
+ list(APPEND libflags -l${CMAKE_MATCH_1})
+ list(APPEND folders ${folder})
+ else()
+ message(FATAL_ERROR "Logic error. Need to update cmake script")
+ endif()
+ endforeach()
+
+ caffe_list_unique(libflags folders)
+
+ set(${folders_var} ${folders} PARENT_SCOPE)
+ set(${flags_var} ${libflags} PARENT_SCOPE)
+ set(${frameworks_var} ${__framework} PARENT_SCOPE)
+endfunction()
diff --git a/cmake/lint.cmake b/cmake/lint.cmake
new file mode 100644
index 00000000..04df3409
--- /dev/null
+++ b/cmake/lint.cmake
@@ -0,0 +1,48 @@
+
+set(CMAKE_SOURCE_DIR ../)
+set(LINT_COMMAND ${CMAKE_SOURCE_DIR}/scripts/cpp_lint.py)
+set(SRC_FILE_EXTENSIONS h hpp hu c cpp cu cc)
+set(EXCLUDE_FILE_EXTENSTIONS pb.h pb.cc)
+set(LINT_DIRS include src/caffe examples tools python matlab)
+
+# find all files of interest
+foreach(ext ${SRC_FILE_EXTENSIONS})
+ foreach(dir ${LINT_DIRS})
+ file(GLOB_RECURSE FOUND_FILES ${CMAKE_SOURCE_DIR}/${dir}/*.${ext})
+ set(LINT_SOURCES ${LINT_SOURCES} ${FOUND_FILES})
+ endforeach()
+endforeach()
+
+# find all files that should be excluded
+foreach(ext ${EXCLUDE_FILE_EXTENSTIONS})
+ file(GLOB_RECURSE FOUND_FILES ${CMAKE_SOURCE_DIR}/*.${ext})
+ set(EXCLUDED_FILES ${EXCLUDED_FILES} ${FOUND_FILES})
+endforeach()
+
+# exclude generated pb files
+list(REMOVE_ITEM LINT_SOURCES ${EXCLUDED_FILES})
+
+execute_process(
+ COMMAND ${LINT_COMMAND} ${LINT_SOURCES}
+ ERROR_VARIABLE LINT_OUTPUT
+ ERROR_STRIP_TRAILING_WHITESPACE
+)
+
+string(REPLACE "\n" ";" LINT_OUTPUT ${LINT_OUTPUT})
+
+list(GET LINT_OUTPUT -1 LINT_RESULT)
+list(REMOVE_AT LINT_OUTPUT -1)
+string(REPLACE " " ";" LINT_RESULT ${LINT_RESULT})
+list(GET LINT_RESULT -1 NUM_ERRORS)
+if(NUM_ERRORS GREATER 0)
+ foreach(msg ${LINT_OUTPUT})
+ string(FIND ${msg} "Done" result)
+ if(result LESS 0)
+ message(STATUS ${msg})
+ endif()
+ endforeach()
+ message(FATAL_ERROR "Lint found ${NUM_ERRORS} errors!")
+else()
+ message(STATUS "Lint did not find any errors!")
+endif()
+