diff --git a/.gitignore b/.gitignore index 7a10d94bafd..d162cb42bb0 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,8 @@ _site *.sublime-workspace *.sublime-project +# Eclipse Project settings +*.*project + +# CMake generated files +*.gen.cmake diff --git a/.travis.yml b/.travis.yml index 7721de112e3..ed021b61fda 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,8 +13,11 @@ compiler: before_install: - echo $LANG - echo $LC_ALL + - export NUM_THREADS=4 + - alias make="make --jobs=$NUM_THREADS" + - sudo add-apt-repository ppa:ubuntu-sdk-team/ppa -y - sudo apt-get -y update - - sudo apt-get -y install wget git curl python-dev python-numpy libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libboost-all-dev libhdf5-serial-dev protobuf-compiler libatlas-dev libatlas-base-dev bc + - sudo apt-get -y install wget git curl python-dev python-numpy libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libboost-dev libboost-system-dev libboost-python-dev libhdf5-serial-dev protobuf-compiler libatlas-dev libatlas-base-dev bc cmake install: - wget https://google-glog.googlecode.com/files/glog-0.3.3.tar.gz -O /tmp/glog-0.3.3.tar.gz && tar -C /tmp -xzvf /tmp/glog-0.3.3.tar.gz && rm /tmp/glog-0.3.3.tar.gz @@ -35,22 +38,39 @@ install: before_script: - mv Makefile.config.example Makefile.config - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib - - export NUM_THREADS=4 script: - # CPU-GPU: build only. + # CMake build + - mkdir build + - cd build + ## CPU-GPU: build only + - cmake -DBUILD_PYTHON=ON -DBUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=Release .. + - make --keep-going + - make clean && rm -rf * + ## CPU-only: comprehensive + - cmake -DBUILD_PYTHON=ON -DBUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=Release -DCPU_ONLY=ON .. + - make --keep-going + - make runtest + - make lint + - make clean + ## Cleanup CMake build + - cd .. + - rm -rf build + + # Make build + ## CPU-GPU: build only - export CPU_ONLY=0 - - make --keep-going --jobs=$NUM_THREADS all + - make --keep-going all - make clean - # CPU-only: comprehensive. + ## CPU-only: comprehensive - export CPU_ONLY=1 - - make --keep-going --jobs=$NUM_THREADS all test warn lint + - make --keep-going all test warn lint - make runtest - - make --jobs=$NUM_THREADS all - - make --jobs=$NUM_THREADS test - - make --jobs=$NUM_THREADS warn - - make --jobs=$NUM_THREADS lint - - make --jobs=$NUM_THREADS pycaffe + - make all + - make test + - make warn + - make lint + - make pycaffe notifications: # Emails are sent to the committer's git-configured email address by default, diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000000..64250eea0f2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,90 @@ +cmake_minimum_required(VERSION 2.8.8) +project( Caffe ) + +### Build Options ########################################################################## + +option(CPU_ONLY "Build Caffe without GPU support" OFF) +option(BUILD_PYTHON "Build Python wrapper" OFF) +option(BUILD_MATLAB "Build Matlab wrapper" OFF) +option(BUILD_EXAMPLES "Build examples" ON) +option(BUILD_SHARED_LIBS "Build SHARED libs if ON and STATIC otherwise" OFF) + +if(NOT BLAS) + set(BLAS atlas) +endif() + +if(NOT CUDA_TEST_DEVICE) + set(CUDA_TEST_DEVICE -1) +endif() + +# Install Prefix +if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set (CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "Default install path" FORCE ) +endif() + +### Configuration ########################################################################### +# Compiler Flags +set(CMAKE_CXX_COMPILER_FLAGS ${CMAKE_CXX_COMPILER_FLAGS} -Wall) +set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} )#set global flags here) +set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} )#set debug flags here) +set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} )#set release flags here) + +# Global Definitions +if(CPU_ONLY) + add_definitions(-DCPU_ONLY) +endif() + +# Include Directories +set(${PROJECT_NAME}_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/include) +include_directories(${${PROJECT_NAME}_INCLUDE_DIRS}) +include_directories(${CMAKE_SOURCE_DIR}/src) + +# CMake Scripts dir +set(CMAKE_SCRIPT_DIR ${CMAKE_SOURCE_DIR}/CMakeScripts) + +# CMake module path for custom module finding +set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SCRIPT_DIR}) + +# CUDA is required globally +if(NOT CPU_ONLY) + find_package(CUDA 5.5 REQUIRED) + include_directories(${CUDA_INCLUDE_DIRS}) +endif() + +### Subdirectories ########################################################################## + +add_subdirectory(src/gtest) +add_subdirectory(src/caffe) +add_subdirectory(tools) + +if(BUILD_EXAMPLES) + message(STATUS "Examples enabled") + add_subdirectory(examples) +endif() + +if(BUILD_PYTHON) + message(STATUS "Python enabled") + add_subdirectory(python) +endif() + +if(BUILD_MATLAB) + message(STATUS "Matlab enabled") + add_subdirectory(matlab) +endif() + +### Lint Target Setup ########################################################################## + +set(LINT_TARGET lint) +set(LINT_SCRIPT ${CMAKE_SCRIPT_DIR}/lint.cmake) +add_custom_target( + ${LINT_TARGET} + COMMAND ${CMAKE_COMMAND} -P ${LINT_SCRIPT} +) + +### Install ################################################################################# + +# Install Includes +file(GLOB folders ${${PROJECT_NAME}_INCLUDE_DIRS}/*) +install(DIRECTORY ${folders} DESTINATION include) + + diff --git a/CMakeScripts/FindAtlas.cmake b/CMakeScripts/FindAtlas.cmake new file mode 100644 index 00000000000..27657a6c7d7 --- /dev/null +++ b/CMakeScripts/FindAtlas.cmake @@ -0,0 +1,61 @@ +# 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) + + mark_as_advanced(${LOOKED_FOR}) + + set(Atlas_INCLUDE_DIR + ${Atlas_CBLAS_INCLUDE_DIR} + ${Atlas_CLAPACK_INCLUDE_DIR} + ) + + set(Atlas_LIBRARIES + ${Atlas_LAPACK_LIBRARY} + ${Atlas_CBLAS_LIBRARY} + ${Atlas_BLAS_LIBRARY} + ) + +endif(ATLAS_FOUND) + diff --git a/CMakeScripts/FindGFlags.cmake b/CMakeScripts/FindGFlags.cmake new file mode 100644 index 00000000000..f93c57136a1 --- /dev/null +++ b/CMakeScripts/FindGFlags.cmake @@ -0,0 +1,48 @@ +# - 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}) +endif() diff --git a/CMakeScripts/FindGlog.cmake b/CMakeScripts/FindGlog.cmake new file mode 100644 index 00000000000..0dc30abdbf5 --- /dev/null +++ b/CMakeScripts/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}) +endif() diff --git a/CMakeScripts/FindLAPACK.cmake b/CMakeScripts/FindLAPACK.cmake new file mode 100644 index 00000000000..9641c45d196 --- /dev/null +++ b/CMakeScripts/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/CMakeScripts/FindLMDB.cmake b/CMakeScripts/FindLMDB.cmake new file mode 100644 index 00000000000..e615f542335 --- /dev/null +++ b/CMakeScripts/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, +# +# Redistribution and use is allowed according to the terms of the BSD license. + +# Adapted from FindCWD by: +# Copyright 2013 Conrad Steenberg +# Aug 31, 2013 + +if (LMDB_INCLUDE_DIR AND LMDB_LIBRARIES) + # Already in cache, be silent + set(LMDB_FIND_QUIETLY TRUE) +endif (LMDB_INCLUDE_DIR AND LMDB_LIBRARIES) + +find_path(LMDB_INCLUDE_DIR NAMES "lmdb.h" HINTS "$ENV{LMDB_DIR}/include") +find_library(LMDB_LIBRARIES NAMES lmdb HINTS $ENV{LMDB_DIR}/lib ) +MESSAGE(STATUS "LMDB lib: " ${LMDB_LIBRARIES} ) +MESSAGE(STATUS "LMDB include: " ${LMDB_INCLUDE} ) + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(LMDB DEFAULT_MSG LMDB_INCLUDE_DIR LMDB_LIBRARIES) + +mark_as_advanced(LMDB_INCLUDE_DIR LMDB_LIBRARIES) diff --git a/CMakeScripts/FindLevelDB.cmake b/CMakeScripts/FindLevelDB.cmake new file mode 100644 index 00000000000..f3386f26dbf --- /dev/null +++ b/CMakeScripts/FindLevelDB.cmake @@ -0,0 +1,37 @@ +# - Find LevelDB +# +# LEVELDB_INCLUDE - Where to find leveldb/db.h +# LEVELDB_LIBS - List of libraries when using LevelDB. +# LEVELDB_FOUND - True if LevelDB found. + +get_filename_component(module_file_path ${CMAKE_CURRENT_LIST_FILE} PATH) + +# 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." ) +mark_as_advanced(LEVELDB_INCLUDE) + +# Look for the library. +# Does this work on UNIX systems? (LINUX) +find_library(LEVELDB_LIBS NAMES leveldb PATHS /usr/lib $ENV{LEVELDB_ROOT}/lib DOC "Path to leveldb library." ) +mark_as_advanced(LEVELDB_LIBS) + +# Copy the results to the output variables. +if (LEVELDB_INCLUDE AND LEVELDB_LIBS) + message(STATUS "Found leveldb in ${LEVELDB_INCLUDE} ${LEVELDB_LIBS}") + set(LEVELDB_FOUND 1) + include(CheckCXXSourceCompiles) + set(CMAKE_REQUIRED_LIBRARY ${LEVELDB_LIBS} pthread) + set(CMAKE_REQUIRED_INCLUDES ${LEVELDB_INCLUDE}) + else () + set(LEVELDB_FOUND 0) + endif () + + # Report the results. + if (NOT LEVELDB_FOUND) + set(LEVELDB_DIR_MESSAGE "LEVELDB was not found. Make sure LEVELDB_LIBS and LEVELDB_INCLUDE are set.") + if (LEVELDB_FIND_REQUIRED) + message(FATAL_ERROR "${LEVELDB_DIR_MESSAGE}") + elseif (NOT LEVELDB_FIND_QUIETLY) + message(STATUS "${LEVELDB_DIR_MESSAGE}") + endif () + endif () \ No newline at end of file diff --git a/CMakeScripts/FindMKL.cmake b/CMakeScripts/FindMKL.cmake new file mode 100644 index 00000000000..eb2d9f8868b --- /dev/null +++ b/CMakeScripts/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/CMakeScripts/FindOpenBLAS.cmake b/CMakeScripts/FindOpenBLAS.cmake new file mode 100644 index 00000000000..297a7b6bc43 --- /dev/null +++ b/CMakeScripts/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 ${ATLAS_POSSIBLE_INCLUDE_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/CMakeScripts/FindSnappy.cmake b/CMakeScripts/FindSnappy.cmake new file mode 100644 index 00000000000..d769b442812 --- /dev/null +++ b/CMakeScripts/FindSnappy.cmake @@ -0,0 +1,33 @@ +# 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_DIRS +# Snappy_LIBS + +find_path(SNAPPY_INCLUDE_DIR + NAMES snappy.h + HINTS ${SNAPPY_ROOT_DIR} + ${SNAPPY_ROOT_DIR}/include +) + +find_library(SNAPPY_LIBS + NAMES snappy + HINTS ${SNAPPY_ROOT_DIR} + ${SNAPPY_ROOT_DIR}/lib +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Snappy + DEFAULT_MSG + SNAPPY_LIBS + SNAPPY_INCLUDE_DIR +) + +mark_as_advanced( + SNAPPY_LIBS + SNAPPY_INCLUDE_DIR +) diff --git a/CMakeScripts/lint.cmake b/CMakeScripts/lint.cmake new file mode 100644 index 00000000000..04df3409e84 --- /dev/null +++ b/CMakeScripts/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() + diff --git a/Makefile b/Makefile index 287120a5d22..2c3ce5415bd 100644 --- a/Makefile +++ b/Makefile @@ -512,12 +512,12 @@ proto: $(PROTO_GEN_CC) $(PROTO_GEN_HEADER) $(PROTO_BUILD_DIR)/%.pb.cc $(PROTO_BUILD_DIR)/%.pb.h : \ $(PROTO_SRC_DIR)/%.proto | $(PROTO_BUILD_DIR) - protoc --proto_path=src --cpp_out=$(BUILD_DIR)/src $< + protoc --proto_path=$(PROTO_SRC_DIR) --cpp_out=$(PROTO_BUILD_DIR) $< @ echo $(PY_PROTO_BUILD_DIR)/%_pb2.py : $(PROTO_SRC_DIR)/%.proto \ $(PY_PROTO_INIT) | $(PY_PROTO_BUILD_DIR) - protoc --proto_path=src --python_out=python $< + protoc --proto_path=$(PROTO_SRC_DIR) --python_out=$(PY_PROTO_BUILD_DIR) $< @ echo $(PY_PROTO_INIT): | $(PY_PROTO_BUILD_DIR) diff --git a/docs/installation.md b/docs/installation.md index ff0760dd060..c2bd64d866e 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -210,6 +210,27 @@ Be sure to set your MATLAB and Python paths in `Makefile.config` first! Now that you have installed Caffe, check out the [MNIST demo](mnist.html) and the pretrained [ImageNet example](imagenet.html). +### Compilation using CMake (beta) + +In lieu of manually editing `Makefile.config` to tell Caffe where dependencies are located, Caffe also provides a CMake-based build system (currently in "beta"). +It requires CMake version >= 2.8.8. +The basic installation steps are as follows: + + mkdir build + cd build + cmake .. + make all + make runtest + +#### Ubuntu 12.04 + +Note that in Ubuntu 12.04, Aptitude will install version CMake 2.8.7 by default, which is not supported by Caffe's CMake build (requires at least 2.8.8). +As a workaround, if you are using Ubuntu 12.04 you can try the following steps to install (or upgrade to) CMake 2.8.9: + + sudo add-apt-repository ppa:ubuntu-sdk-team/ppa -y + sudo apt-get -y update + sudo apt-get install cmake + ## Hardware Questions **Laboratory Tested Hardware**: Berkeley Vision runs Caffe with K40s, K20s, and Titans including models at ImageNet/ILSVRC scale. We also run on GTX series cards and GPU-equipped MacBook Pros. We have not encountered any trouble in-house with devices with CUDA capability >= 3.0. All reported hardware issues thus-far have been due to GPU configuration, overheating, and the like. diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 00000000000..055f4ef0d35 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,16 @@ +project( Examples ) + +file(GLOB_RECURSE EXAMPLES_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + +foreach(source ${EXAMPLES_SOURCES}) + # get file name + get_filename_component(name ${source} NAME_WE) + + #get folder name + get_filename_component(path ${source} PATH) + get_filename_component(folder ${path} NAME_WE) + + add_executable(${name} ${source}) + target_link_libraries(${name} caffe) + set_target_properties(${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${folder}) +endforeach(source) diff --git a/include/caffe/test/test_caffe_main.hpp b/include/caffe/test/test_caffe_main.hpp index 40b9effc5f1..438acf2bf17 100644 --- a/include/caffe/test/test_caffe_main.hpp +++ b/include/caffe/test/test_caffe_main.hpp @@ -14,6 +14,15 @@ using std::cout; using std::endl; +#ifdef CMAKE_BUILD + #include +#else + #define CUDA_TEST_DEVICE -1 + #define CMAKE_SOURCE_DIR "src/" + #define EXAMPLES_SOURCE_DIR "examples/" + #define CMAKE_EXT "" +#endif + int main(int argc, char** argv); namespace caffe { diff --git a/matlab/CMakeLists.txt b/matlab/CMakeLists.txt new file mode 100644 index 00000000000..f6a03ee4625 --- /dev/null +++ b/matlab/CMakeLists.txt @@ -0,0 +1 @@ +project( Matlab ) \ No newline at end of file diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt new file mode 100644 index 00000000000..8642c39367a --- /dev/null +++ b/python/CMakeLists.txt @@ -0,0 +1,20 @@ +project( Python ) + +# Python +find_package(PythonLibs REQUIRED) +include_directories(${PYTHON_INCLUDE_DIRS}) + +# Boost.Python +find_package(Boost 1.46 COMPONENTS python REQUIRED) +include_directories(${Boost_INCLUDE_DIRS}) + +file(GLOB_RECURSE Python_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + +add_library(pycaffe SHARED ${Python_SOURCES}) +target_link_libraries(pycaffe caffe ${PYTHON_LIBRARIES} ${Boost_LIBRARIES}) + +### Install ################################################################################# + +install(DIRECTORY caffe DESTINATION python) +install(FILES requirements.txt DESTINATION python) +install(TARGETS pycaffe DESTINATION python/caffe) \ No newline at end of file diff --git a/src/caffe/CMakeLists.txt b/src/caffe/CMakeLists.txt new file mode 100644 index 00000000000..ec756bede71 --- /dev/null +++ b/src/caffe/CMakeLists.txt @@ -0,0 +1,122 @@ +project( CaffeSrc ) + +# Threads +find_package(Threads REQUIRED) + +# Google-glog +find_package(Glog REQUIRED) +include_directories(${GLOG_INCLUDE_DIRS}) + +# Google-gflags +find_package(GFlags REQUIRED) +include_directories(${GFLAGS_INCLUDE_DIRS}) + +# BLAS +if(BLAS STREQUAL "atlas") + + find_package(Atlas REQUIRED) + include_directories(${Atlas_INCLUDE_DIR}) + set(BLAS_LIBRARIES ${Atlas_LIBRARIES}) + +elseif(BLAS STREQUAL "open") + + find_package(OpenBLAS REQUIRED) + include_directories(${OpenBLAS_INCLUDE_DIR}) + set(BLAS_LIBRARIES ${OpenBLAS_LIB}) + +elseif(BLAS STREQUAL "mkl") + + find_package(MKL REQUIRED) + include_directories(${MKL_INCLUDE_DIR}) + set(BLAS_LIBRARIES ${MKL_LIBRARIES}) + +endif() + +# HDF5 +find_package(HDF5 COMPONENTS HL REQUIRED) +include_directories(${HDF5_INCLUDE_DIRS}) + +# OpenCV +find_package(OpenCV REQUIRED core highgui imgproc) +include_directories(${OpenCV_INCLUDE_DIRS}) + +# LevelDB +find_package(LevelDB REQUIRED) +include_directories(${LEVELDB_INCLUDE}) +if(LEVELDB_FOUND) + find_package(Snappy REQUIRED) + include_directories(${SNAPPY_INCLUDE_DIR}) + set(LEVELDB_LIBS + ${LEVELDB_LIBS} + ${SNAPPY_LIBS} + ) +endif() + +# LMDB +find_package(LMDB REQUIRED) +include_directories(${LMDB_INCLUDE_DIR}) + +# Boost +find_package(Boost 1.46 COMPONENTS system REQUIRED) +include_directories( ${Boost_INCLUDE_DIR} ) +link_directories( ${Boost_LIBRARY_DIRS} ) + +add_subdirectory(proto) + +# Recursively find source files +## test sources +file(GLOB_RECURSE TEST_CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test_*.cpp) + +## all cpp sources +file(GLOB_RECURSE CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + +## remove test sources from cpp sources +list(REMOVE_ITEM CPP_SOURCES ${TEST_CPP_SOURCES}) + +add_library(caffe ${CPP_SOURCES}) +# both depend on proto +add_dependencies(caffe proto) + +# CUDA +if(NOT CPU_ONLY) + set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} + -gencode arch=compute_20,code=sm_20 + -gencode arch=compute_20,code=sm_21 + -gencode arch=compute_30,code=sm_30 + -gencode arch=compute_35,code=sm_35 + ) + + # cuda sources + file(GLOB_RECURSE CU_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cu) + file(GLOB_RECURSE TEST_CU_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test_*.cu) + list(REMOVE_ITEM CU_SOURCES ${TEST_CU_SOURCES}) + cuda_add_library(caffe_cu ${CU_SOURCES}) + add_dependencies(caffe_cu proto) + target_link_libraries(caffe caffe_cu + ${CUDA_CUBLAS_LIBRARIES} + ${CUDA_curand_LIBRARY} + ) +endif() + +target_link_libraries(caffe proto + ${GLOG_LIBRARIES} + ${GFLAGS_LIBRARIES} + ${HDF5_LIBRARIES} + ${OpenCV_LIBS} + ${LEVELDB_LIBS} + ${LMDB_LIBRARIES} + ${BLAS_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} +) + +#set output directory +set_target_properties(caffe PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib +) + +add_subdirectory(test) + +### Install ################################################################################# + +install(TARGETS caffe DESTINATION lib) diff --git a/src/caffe/proto/CMakeLists.txt b/src/caffe/proto/CMakeLists.txt new file mode 100644 index 00000000000..186a856509b --- /dev/null +++ b/src/caffe/proto/CMakeLists.txt @@ -0,0 +1,37 @@ +project( Proto ) + +# Google Protocol Buffers +find_package( Protobuf REQUIRED ) + +# 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(PROTOBUF_PROTOC_EXECUTABLE) + message(STATUS "Found PROTOBUF Compiler: ${PROTOBUF_PROTOC_EXECUTABLE}") +else() + message(FATAL_ERROR "Could not find PROTOBUF Compiler") +endif() + +include_directories(${PROTOBUF_INCLUDE_DIR}) +file(GLOB ProtoFiles "${CMAKE_CURRENT_SOURCE_DIR}/*.proto") +PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders ${ProtoFiles}) + +add_library(proto + ${ProtoSources} + ${ProtoHeaders} +) + +target_link_libraries(proto ${PROTOBUF_LIBRARIES}) + +# Create proto include directory +file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/include/caffe/proto) + +# Copy proto headers to include/caffe/proto/ +foreach(header ${ProtoHeaders}) + + ADD_CUSTOM_COMMAND(TARGET proto + COMMAND cmake -E copy ${header} + ${Caffe_INCLUDE_DIRS}/caffe/proto/ + DEPENDS ${header} +) + +endforeach(header) diff --git a/src/caffe/proto/caffe_pretty_print.proto b/src/caffe/proto/caffe_pretty_print.proto index 225138a4274..6f0a5f6b8df 100644 --- a/src/caffe/proto/caffe_pretty_print.proto +++ b/src/caffe/proto/caffe_pretty_print.proto @@ -2,7 +2,7 @@ syntax = "proto2"; package caffe; -import "caffe/proto/caffe.proto"; +import "caffe.proto"; // A near-duplicate of NetParameter with fields re-numbered to beautify // automatic prototext dumps. The main practical purpose is to print inputs diff --git a/src/caffe/test/CMakeLists.txt b/src/caffe/test/CMakeLists.txt new file mode 100644 index 00000000000..ffcc58f5463 --- /dev/null +++ b/src/caffe/test/CMakeLists.txt @@ -0,0 +1,68 @@ +# +# +# All test files' names must begin with a "test_" prefix +# +# +project( Test ) + +# Configuration +set(TEST_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/test) # test executables are going to be placed there +set(TEST_EXT .testbin) # test executable extension +set(ALL_TEST test${TEST_EXT}) # name of an executable comprising of all tests +set(RUN_TEST runtest) # dummy target for running tests + +# Generate config files +add_definitions(-DCMAKE_BUILD) # definition needed in order to include CMake's generated files +set(IN_EXT .in) # generator input file extension +set(GEN_EXT .gen.cmake) # generated output file extension +set(TEST_DEFINES_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake_test_defines.hpp) +set(TEST_DATA_FILE ${CMAKE_CURRENT_SOURCE_DIR}/test_data/sample_data_list.txt) + +set(IN_FILES # generator input files + ${TEST_DEFINES_FILE} + ${TEST_DATA_FILE} +) + +foreach(in_file ${IN_FILES}) + configure_file( + ${in_file}${IN_EXT} + ${in_file}${GEN_EXT} + ) +endforeach() + +include_directories( + ${Caffe_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} +) + +set(TEST_MAIN test_caffe_main.cpp) +list(REMOVE_ITEM TEST_CPP_SOURCES ${TEST_MAIN}) + +if(NOT CPU_ONLY) + set(TEST_CPP_SOURCES ${TEST_CPP_SOURCES} ${TEST_CU_SOURCES}) +endif() + +# Build each test separately +foreach(source ${TEST_CPP_SOURCES}) + get_filename_component(name ${source} NAME_WE) + set(TEST_NAME ${name}${TEST_EXT}) + add_executable(${TEST_NAME} EXCLUDE_FROM_ALL ${TEST_MAIN} ${source} ../blob.cpp) + target_link_libraries(${TEST_NAME} gtest caffe) + # output dir + set_target_properties(${TEST_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/test) + set(TEST_TARGETS ${TEST_TARGETS} ${TEST_NAME}) +endforeach() + +# Build a compound test excluded from the ALL target +add_executable(${ALL_TEST} EXCLUDE_FROM_ALL ${TEST_CPP_SOURCES} ${TEST_MAIN}) +target_link_libraries(${ALL_TEST} gtest caffe) +add_dependencies(${ALL_TEST} ${TEST_TARGETS}) +# output dir +set_target_properties(${ALL_TEST} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${TEST_OUTPUT_DIRECTORY}) +# Test command +set(TEST_ARGS --gtest_shuffle) +if(CPU_ONLY) + set(TEST_ARGS ${TEST_ARGS} --gtest_filter="-*GPU*") +endif() + +add_custom_target(${RUN_TEST} COMMAND ${ALL_TEST} ${TEST_ARGS}) diff --git a/src/caffe/test/cmake_test_defines.hpp.in b/src/caffe/test/cmake_test_defines.hpp.in new file mode 100644 index 00000000000..870eaf5c26e --- /dev/null +++ b/src/caffe/test/cmake_test_defines.hpp.in @@ -0,0 +1,4 @@ +#define CUDA_TEST_DEVICE @CUDA_TEST_DEVICE@ +#define CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/src/" +#define EXAMPLES_SOURCE_DIR "@CMAKE_SOURCE_DIR@/examples/" +#define CMAKE_EXT ".gen.cmake" diff --git a/src/caffe/test/test_caffe_main.cpp b/src/caffe/test/test_caffe_main.cpp index df188fd319b..bff0c4ed20e 100644 --- a/src/caffe/test/test_caffe_main.cpp +++ b/src/caffe/test/test_caffe_main.cpp @@ -26,6 +26,9 @@ int main(int argc, char** argv) { device = atoi(argv[1]); cudaSetDevice(device); cout << "Setting to use device " << device << endl; + } else if (CUDA_TEST_DEVICE >= 0) { + // Use the device assigned in build configuration; but with a lower priority + device = CUDA_TEST_DEVICE; } cudaGetDevice(&device); cout << "Current device id: " << device << endl; diff --git a/src/caffe/test/test_data/sample_data_list.txt.in b/src/caffe/test/test_data/sample_data_list.txt.in new file mode 100644 index 00000000000..9860ef583ab --- /dev/null +++ b/src/caffe/test/test_data/sample_data_list.txt.in @@ -0,0 +1,2 @@ +@CMAKE_SOURCE_DIR@/src/caffe/test/test_data/sample_data.h5 +@CMAKE_SOURCE_DIR@/src/caffe/test/test_data/sample_data_2_gzip.h5 \ No newline at end of file diff --git a/src/caffe/test/test_hdf5_output_layer.cpp b/src/caffe/test/test_hdf5_output_layer.cpp index 696165cdaa2..b2a511d1d09 100644 --- a/src/caffe/test/test_hdf5_output_layer.cpp +++ b/src/caffe/test/test_hdf5_output_layer.cpp @@ -23,7 +23,8 @@ class HDF5OutputLayerTest : public MultiDeviceTest { protected: HDF5OutputLayerTest() : output_file_name_(tmpnam(NULL)), - input_file_name_("src/caffe/test/test_data/sample_data.h5"), + input_file_name_( + CMAKE_SOURCE_DIR "caffe/test/test_data/sample_data.h5"), blob_data_(new Blob()), blob_label_(new Blob()), num_(5), diff --git a/src/caffe/test/test_hdf5data_layer.cpp b/src/caffe/test/test_hdf5data_layer.cpp index f903afb736f..acca75b19b1 100644 --- a/src/caffe/test/test_hdf5data_layer.cpp +++ b/src/caffe/test/test_hdf5data_layer.cpp @@ -31,8 +31,9 @@ class HDF5DataLayerTest : public MultiDeviceTest { blob_top_vec_.push_back(blob_top_label_); // Check out generate_sample_data.py in the same directory. - filename = new string("src/caffe/test/test_data/sample_data_list.txt"); - LOG(INFO) << "Using sample HDF5 data file " << filename; + filename = new string( + CMAKE_SOURCE_DIR "caffe/test/test_data/sample_data_list.txt" CMAKE_EXT); + LOG(INFO)<< "Using sample HDF5 data file " << filename; } virtual ~HDF5DataLayerTest() { diff --git a/src/caffe/test/test_image_data_layer.cpp b/src/caffe/test/test_image_data_layer.cpp index 5232c1187c1..73be5da7b23 100644 --- a/src/caffe/test/test_image_data_layer.cpp +++ b/src/caffe/test/test_image_data_layer.cpp @@ -37,7 +37,7 @@ class ImageDataLayerTest : public MultiDeviceTest { std::ofstream outfile(filename_->c_str(), std::ofstream::out); LOG(INFO) << "Using temporary file " << *filename_; for (int i = 0; i < 5; ++i) { - outfile << "examples/images/cat.jpg " << i; + outfile << EXAMPLES_SOURCE_DIR "images/cat.jpg " << i; } outfile.close(); } diff --git a/src/gtest/CMakeLists.txt b/src/gtest/CMakeLists.txt new file mode 100644 index 00000000000..82a4120ca3f --- /dev/null +++ b/src/gtest/CMakeLists.txt @@ -0,0 +1,6 @@ +project(gtest CXX C) +cmake_minimum_required(VERSION 2.6.2) + +add_library(gtest gtest-all.cpp) +add_library(gtest_main gtest_main.cc) +target_link_libraries(gtest_main gtest) \ No newline at end of file diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 00000000000..0da19fbadc8 --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,19 @@ +project( Tools ) + +# Find all source files +file(GLOB_RECURSE TOOLS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp) + +# Build each source file independently +foreach(source ${TOOLS_SOURCES}) + get_filename_component(name ${source} NAME_WE) + add_executable(${name}.bin ${source}) + set_target_properties(${name}.bin PROPERTIES OUTPUT_NAME ${name}) + target_link_libraries(${name}.bin caffe) + +### Install ################################################################################# + + install(TARGETS ${name}.bin DESTINATION tools) + + +endforeach(source) +