From 07970293d3fd166cb0be3a78d6e14f5b4f7c4331 Mon Sep 17 00:00:00 2001 From: sh1r0 Date: Mon, 28 Dec 2015 22:50:03 +0800 Subject: [PATCH] added switches for dependency on glog and hdf5 MINIGLOG is modified from [Ceres Solver](http://ceres-solver.org/) --- CMakeLists.txt | 15 + Makefile | 29 +- Makefile.config.example | 4 + cmake/ConfigGen.cmake | 8 + cmake/Dependencies.cmake | 28 +- cmake/Modules/FindProtobuf.cmake | 231 +++++++++ cmake/Summary.cmake | 6 +- cmake/Targets.cmake | 4 + cmake/Templates/caffe_config.h.in | 4 + docs/installation.md | 5 +- include/caffe/util/hdf5.hpp | 2 + include/caffe/util/math_functions.hpp | 1 + .../ceres/internal/miniglog/glog/logging.h | 443 ++++++++++++++++++ src/caffe/CMakeLists.txt | 3 + src/caffe/layers/hdf5_data_layer.cpp | 2 + src/caffe/layers/hdf5_data_layer.cu | 2 + src/caffe/layers/hdf5_output_layer.cpp | 2 + src/caffe/layers/hdf5_output_layer.cu | 2 + src/caffe/net.cpp | 11 + src/caffe/solvers/sgd_solver.cpp | 10 + src/caffe/test/test_hdf5_output_layer.cpp | 2 + src/caffe/test/test_hdf5data_layer.cpp | 2 + src/caffe/util/hdf5.cpp | 2 + src/ceres/internal/miniglog/glog/logging.cpp | 41 ++ 24 files changed, 842 insertions(+), 17 deletions(-) create mode 100644 cmake/Modules/FindProtobuf.cmake create mode 100644 include/ceres/internal/miniglog/glog/logging.h create mode 100644 src/ceres/internal/miniglog/glog/logging.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c446c608952..4f840f3a917 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,19 @@ endif() # ---[ Caffe project project(Caffe C CXX) +# Search packages for host system instead of packages for target system +# in case of cross compilation these macro should be defined by toolchain file +if(NOT COMMAND find_host_package) + macro(find_host_package) + find_package(${ARGN}) + endmacro() +endif() +if(NOT COMMAND find_host_program) + macro(find_host_program) + find_program(${ARGN}) + endmacro() +endif() + # ---[ Using cmake scripts and modules list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules) @@ -30,9 +43,11 @@ caffe_option(BUILD_matlab "Build Matlab wrapper" OFF IF UNIX OR APPLE) caffe_option(BUILD_docs "Build documentation" ON IF UNIX OR APPLE) caffe_option(BUILD_python_layer "Build the Caffe Python layer" ON) caffe_option(USE_OPENCV "Build with OpenCV support" ON) +caffe_option(USE_GLOG "Build with glog support" ON) caffe_option(USE_LEVELDB "Build with levelDB" ON) caffe_option(USE_LMDB "Build with lmdb" ON) caffe_option(ALLOW_LMDB_NOLOCK "Allow MDB_NOLOCK when reading LMDB files (only if necessary)" OFF) +caffe_option(USE_HDF5 "Build with hdf5" ON) # ---[ Dependencies include(cmake/Dependencies.cmake) diff --git a/Makefile b/Makefile index 985fffd6c0b..355b40eeb7b 100644 --- a/Makefile +++ b/Makefile @@ -33,11 +33,20 @@ LIB_BUILD_DIR := $(BUILD_DIR)/lib STATIC_NAME := $(LIB_BUILD_DIR)/lib$(PROJECT).a DYNAMIC_NAME := $(LIB_BUILD_DIR)/lib$(PROJECT).so +# toggle glog or miniglog +USE_GLOG ?= 1 +ifeq ($(USE_GLOG), 1) + LIBRARIES += glog +else + CXX_SRCS := ./src/ceres/internal/miniglog/glog/logging.cpp + INCLUDE_DIRS := ./include/ceres/internal/miniglog/ $(INCLUDE_DIRS) +endif + ############################## # Get all source files ############################## # CXX_SRCS are the source files excluding the test ones. -CXX_SRCS := $(shell find src/$(PROJECT) ! -name "test_*.cpp" -name "*.cpp") +CXX_SRCS += $(shell find src/$(PROJECT) ! -name "test_*.cpp" -name "*.cpp") # CU_SRCS are the cuda source files CU_SRCS := $(shell find src/$(PROJECT) ! -name "test_*.cu" -name "*.cu") # TEST_SRCS are the test source files @@ -170,11 +179,12 @@ ifneq ($(CPU_ONLY), 1) LIBRARIES := cudart cublas curand endif -LIBRARIES += glog gflags protobuf boost_system boost_filesystem m hdf5_hl hdf5 +LIBRARIES += gflags protobuf boost_system boost_filesystem m # handle IO dependencies USE_LEVELDB ?= 1 USE_LMDB ?= 1 +USE_HDF5 ?= 1 USE_OPENCV ?= 1 ifeq ($(USE_LEVELDB), 1) @@ -183,13 +193,16 @@ endif ifeq ($(USE_LMDB), 1) LIBRARIES += lmdb endif +ifeq ($(USE_HDF5), 1) + LIBRARIES += hdf5_hl hdf5 +endif ifeq ($(USE_OPENCV), 1) - LIBRARIES += opencv_core opencv_highgui opencv_imgproc + LIBRARIES += opencv_core opencv_highgui opencv_imgproc ifeq ($(OPENCV_VERSION), 3) LIBRARIES += opencv_imgcodecs endif - + endif PYTHON_LIBRARIES := boost_python python2.7 WARNINGS := -Wall -Wno-sign-compare @@ -309,6 +322,11 @@ ifeq ($(USE_CUDNN), 1) COMMON_FLAGS += -DUSE_CUDNN endif +# glog configuration. +ifeq ($(USE_GLOG), 1) + COMMON_FLAGS += -DUSE_GLOG +endif + # configure IO libraries ifeq ($(USE_OPENCV), 1) COMMON_FLAGS += -DUSE_OPENCV @@ -322,6 +340,9 @@ ifeq ($(ALLOW_LMDB_NOLOCK), 1) COMMON_FLAGS += -DALLOW_LMDB_NOLOCK endif endif +ifeq ($(USE_HDF5), 1) + COMMON_FLAGS += -DUSE_HDF5 +endif # CPU-only configuration ifeq ($(CPU_ONLY), 1) diff --git a/Makefile.config.example b/Makefile.config.example index 1dd6a8f7c7c..38569facc5e 100644 --- a/Makefile.config.example +++ b/Makefile.config.example @@ -11,6 +11,7 @@ # USE_OPENCV := 0 # USE_LEVELDB := 0 # USE_LMDB := 0 +# USE_HDF5 := 0 # uncomment to allow MDB_NOLOCK when reading LMDB files (only if necessary) # You should not set this flag if you will be reading LMDBs with any @@ -20,6 +21,9 @@ # Uncomment if you're using OpenCV 3 # OPENCV_VERSION := 3 +# uncomment to disable glog +# USE_GLOG := 0 + # To customize your choice of compiler, uncomment and set the following. # N.B. the default for Linux is g++ and the default for OSX is clang++ # CUSTOM_CXX := g++ diff --git a/cmake/ConfigGen.cmake b/cmake/ConfigGen.cmake index 056371110b5..ba22e8c4054 100644 --- a/cmake/ConfigGen.cmake +++ b/cmake/ConfigGen.cmake @@ -56,6 +56,10 @@ function(caffe_generate_export_configs) list(APPEND Caffe_DEFINITIONS -DCPU_ONLY) endif() + if(USE_GLOG) + list(APPEND Caffe_DEFINITIONS -DUSE_GLOG) + endif() + if(USE_OPENCV) list(APPEND Caffe_DEFINITIONS -DUSE_OPENCV) endif() @@ -71,6 +75,10 @@ function(caffe_generate_export_configs) list(APPEND Caffe_DEFINITIONS -DUSE_LEVELDB) endif() + if(USE_HDF5) + list(APPEND Caffe_DEFINITIONS -DUSE_HDF5) + endif() + if(NOT HAVE_CUDNN) set(HAVE_CUDNN FALSE) else() diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 51a803c1a73..2098439dc69 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -11,9 +11,14 @@ find_package(Threads REQUIRED) list(APPEND Caffe_LINKER_LIBS ${CMAKE_THREAD_LIBS_INIT}) # ---[ Google-glog -include("cmake/External/glog.cmake") -include_directories(SYSTEM ${GLOG_INCLUDE_DIRS}) -list(APPEND Caffe_LINKER_LIBS ${GLOG_LIBRARIES}) +if(USE_GLOG) + include("cmake/External/glog.cmake") + include_directories(SYSTEM ${GLOG_INCLUDE_DIRS}) + list(APPEND Caffe_LINKER_LIBS ${GLOG_LIBRARIES}) + add_definitions(-DUSE_GLOG) +else() + include_directories("include/ceres/internal/miniglog") +endif() # ---[ Google-gflags include("cmake/External/gflags.cmake") @@ -24,9 +29,12 @@ list(APPEND Caffe_LINKER_LIBS ${GFLAGS_LIBRARIES}) include(cmake/ProtoBuf.cmake) # ---[ HDF5 -find_package(HDF5 COMPONENTS HL REQUIRED) -include_directories(SYSTEM ${HDF5_INCLUDE_DIRS} ${HDF5_HL_INCLUDE_DIR}) -list(APPEND Caffe_LINKER_LIBS ${HDF5_LIBRARIES}) +if(USE_HDF5) + find_package(HDF5 COMPONENTS HL REQUIRED) + include_directories(SYSTEM ${HDF5_INCLUDE_DIRS} ${HDF5_HL_INCLUDE_DIR}) + list(APPEND Caffe_LINKER_LIBS ${HDF5_LIBRARIES}) + add_definitions(-DUSE_HDF5) +endif() # ---[ LMDB if(USE_LMDB) @@ -113,18 +121,18 @@ if(BUILD_python) find_package(NumPy 1.7.1) # Find the matching boost python implementation set(version ${PYTHONLIBS_VERSION_STRING}) - + STRING( REPLACE "." "" boost_py_version ${version} ) find_package(Boost 1.46 COMPONENTS "python-py${boost_py_version}") set(Boost_PYTHON_FOUND ${Boost_PYTHON-PY${boost_py_version}_FOUND}) - + while(NOT "${version}" STREQUAL "" AND NOT Boost_PYTHON_FOUND) STRING( REGEX REPLACE "([0-9.]+).[0-9]+" "\\1" version ${version} ) - + STRING( REPLACE "." "" boost_py_version ${version} ) find_package(Boost 1.46 COMPONENTS "python-py${boost_py_version}") set(Boost_PYTHON_FOUND ${Boost_PYTHON-PY${boost_py_version}_FOUND}) - + STRING( REGEX MATCHALL "([0-9.]+).[0-9]+" has_more_version ${version} ) if("${has_more_version}" STREQUAL "") break() diff --git a/cmake/Modules/FindProtobuf.cmake b/cmake/Modules/FindProtobuf.cmake new file mode 100644 index 00000000000..e8fe5299d17 --- /dev/null +++ b/cmake/Modules/FindProtobuf.cmake @@ -0,0 +1,231 @@ +# Locate and configure the Google Protocol Buffers library. +# +# The following variables can be set and are optional: +# +# PROTOBUF_SRC_ROOT_FOLDER - When compiling with MSVC, if this cache variable is set +# the protobuf-default VS project build locations +# (vsprojects/Debug & vsprojects/Release) will be searched +# for libraries and binaries. +# +# PROTOBUF_IMPORT_DIRS - List of additional directories to be searched for +# imported .proto files. (New in CMake 2.8.8) +# +# Defines the following variables: +# +# PROTOBUF_FOUND - Found the Google Protocol Buffers library (libprotobuf & header files) +# PROTOBUF_INCLUDE_DIRS - Include directories for Google Protocol Buffers +# PROTOBUF_LIBRARIES - The protobuf libraries +# [New in CMake 2.8.5] +# PROTOBUF_PROTOC_LIBRARIES - The protoc libraries +# PROTOBUF_LITE_LIBRARIES - The protobuf-lite libraries +# +# The following cache variables are also available to set or use: +# PROTOBUF_LIBRARY - The protobuf library +# PROTOBUF_PROTOC_LIBRARY - The protoc library +# PROTOBUF_INCLUDE_DIR - The include directory for protocol buffers +# PROTOBUF_PROTOC_EXECUTABLE - The protoc compiler +# [New in CMake 2.8.5] +# PROTOBUF_LIBRARY_DEBUG - The protobuf library (debug) +# PROTOBUF_PROTOC_LIBRARY_DEBUG - The protoc library (debug) +# PROTOBUF_LITE_LIBRARY - The protobuf lite library +# PROTOBUF_LITE_LIBRARY_DEBUG - The protobuf lite library (debug) +# +# ==================================================================== +# Example: +# +# find_package(Protobuf REQUIRED) +# include_directories(${PROTOBUF_INCLUDE_DIRS}) +# +# include_directories(${CMAKE_CURRENT_BINARY_DIR}) +# PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS foo.proto) +# add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS}) +# target_link_libraries(bar ${PROTOBUF_LIBRARIES}) +# +# NOTE: You may need to link against pthreads, depending +# on the platform. +# +# NOTE: The PROTOBUF_GENERATE_CPP macro & add_executable() or add_library() +# calls only work properly within the same directory. +# +# ==================================================================== +# +# PROTOBUF_GENERATE_CPP (public function) +# SRCS = Variable to define with autogenerated +# source files +# HDRS = Variable to define with autogenerated +# header files +# ARGN = proto files +# +# ==================================================================== + + +#============================================================================= +# Copyright 2009 Kitware, Inc. +# Copyright 2009-2011 Philip Lowman +# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +function(PROTOBUF_GENERATE_CPP SRCS HDRS) + if(NOT ARGN) + message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() 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 _protobuf_include_path ${ABS_PATH} _contains_already) + if(${_contains_already} EQUAL -1) + list(APPEND _protobuf_include_path -I ${ABS_PATH}) + endif() + endforeach() + else() + set(_protobuf_include_path -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 _protobuf_include_path ${ABS_PATH} _contains_already) + if(${_contains_already} EQUAL -1) + list(APPEND _protobuf_include_path -I ${ABS_PATH}) + endif() + endforeach() + endif() + + set(${SRCS}) + set(${HDRS}) + foreach(FIL ${ARGN}) + get_filename_component(ABS_FIL ${FIL} ABSOLUTE) + get_filename_component(FIL_WE ${FIL} NAME_WE) + + list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc") + list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h") + + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc" + "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h" + COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} + ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL} + DEPENDS ${ABS_FIL} + COMMENT "Running C++ protocol buffer compiler on ${FIL}" + VERBATIM ) + endforeach() + + set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) + set(${SRCS} ${${SRCS}} PARENT_SCOPE) + set(${HDRS} ${${HDRS}} PARENT_SCOPE) +endfunction() + +# Internal function: search for normal library as well as a debug one +# if the debug one is specified also include debug/optimized keywords +# in *_LIBRARIES variable +function(_protobuf_find_libraries name filename) + find_library(${name}_LIBRARY + NAMES ${filename} + PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Release) + mark_as_advanced(${name}_LIBRARY) + + find_library(${name}_LIBRARY_DEBUG + NAMES ${filename} + PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Debug) + mark_as_advanced(${name}_LIBRARY_DEBUG) + + if(NOT ${name}_LIBRARY_DEBUG) + # There is no debug library + set(${name}_LIBRARY_DEBUG ${${name}_LIBRARY} PARENT_SCOPE) + set(${name}_LIBRARIES ${${name}_LIBRARY} PARENT_SCOPE) + else() + # There IS a debug library + set(${name}_LIBRARIES + optimized ${${name}_LIBRARY} + debug ${${name}_LIBRARY_DEBUG} + PARENT_SCOPE + ) + endif() +endfunction() + +# Internal function: find threads library +function(_protobuf_find_threads) + set(CMAKE_THREAD_PREFER_PTHREAD TRUE) + find_package(Threads) + if(Threads_FOUND) + list(APPEND PROTOBUF_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + set(PROTOBUF_LIBRARIES "${PROTOBUF_LIBRARIES}" PARENT_SCOPE) + endif() +endfunction() + +# +# Main. +# + +# By default have PROTOBUF_GENERATE_CPP macro pass -I to protoc +# for each directory where a proto file is referenced. +if(NOT DEFINED PROTOBUF_GENERATE_CPP_APPEND_PATH) + set(PROTOBUF_GENERATE_CPP_APPEND_PATH TRUE) +endif() + + +# Google's provided vcproj files generate libraries with a "lib" +# prefix on Windows +if(MSVC) + set(PROTOBUF_ORIG_FIND_LIBRARY_PREFIXES "${CMAKE_FIND_LIBRARY_PREFIXES}") + set(CMAKE_FIND_LIBRARY_PREFIXES "lib" "") + + find_path(PROTOBUF_SRC_ROOT_FOLDER protobuf.pc.in) +endif() + +# The Protobuf library +_protobuf_find_libraries(PROTOBUF protobuf) +#DOC "The Google Protocol Buffers RELEASE Library" + +_protobuf_find_libraries(PROTOBUF_LITE protobuf-lite) + +# The Protobuf Protoc Library +_protobuf_find_libraries(PROTOBUF_PROTOC protoc) + +# Restore original find library prefixes +if(MSVC) + set(CMAKE_FIND_LIBRARY_PREFIXES "${PROTOBUF_ORIG_FIND_LIBRARY_PREFIXES}") +endif() + +if(UNIX) + _protobuf_find_threads() +endif() + +# Find the include directory +find_path(PROTOBUF_INCLUDE_DIR + google/protobuf/service.h + PATHS ${PROTOBUF_SRC_ROOT_FOLDER}/src +) +mark_as_advanced(PROTOBUF_INCLUDE_DIR) + +# Find the protoc Executable +find_host_program(PROTOBUF_PROTOC_EXECUTABLE + NAMES protoc + DOC "The Google Protocol Buffers Compiler" + PATHS + ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Release + ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Debug +) +mark_as_advanced(PROTOBUF_PROTOC_EXECUTABLE) + + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PROTOBUF DEFAULT_MSG + PROTOBUF_LIBRARY PROTOBUF_INCLUDE_DIR) + +if(PROTOBUF_FOUND) + set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIR}) +endif() diff --git a/cmake/Summary.cmake b/cmake/Summary.cmake index 557a6f04e4b..8b16f9824fc 100644 --- a/cmake/Summary.cmake +++ b/cmake/Summary.cmake @@ -118,11 +118,15 @@ function(caffe_print_configuration_summary) caffe_status(" USE_LEVELDB : ${USE_LEVELDB}") caffe_status(" USE_LMDB : ${USE_LMDB}") caffe_status(" ALLOW_LMDB_NOLOCK : ${ALLOW_LMDB_NOLOCK}") + caffe_status(" USE_HDF5 : ${USE_HDF5}") + caffe_status(" USE_GLOG : ${USE_GLOG}") caffe_status("") caffe_status("Dependencies:") caffe_status(" BLAS : " APPLE THEN "Yes (vecLib)" ELSE "Yes (${BLAS})") caffe_status(" Boost : Yes (ver. ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION})") - caffe_status(" glog : Yes") + if(USE_GLOG) + caffe_status(" glog : " GLOG_FOUND THEN "Yes" ELSE "No") + endif() caffe_status(" gflags : Yes") caffe_status(" protobuf : " PROTOBUF_FOUND THEN "Yes (ver. ${PROTOBUF_VERSION})" ELSE "No" ) if(USE_LMDB) diff --git a/cmake/Targets.cmake b/cmake/Targets.cmake index 2401f252e93..aecf88f650d 100644 --- a/cmake/Targets.cmake +++ b/cmake/Targets.cmake @@ -74,6 +74,10 @@ function(caffe_pickup_caffe_sources root) list(REMOVE_ITEM hdrs ${test_hdrs}) list(REMOVE_ITEM srcs ${test_srcs}) + if(NOT USE_GLOG) + list(APPEND srcs "${root}/src/ceres/internal/miniglog/glog/logging.cpp") + endif() + # adding headers to make the visible in some IDEs (Qt, VS, Xcode) list(APPEND srcs ${hdrs} ${PROJECT_BINARY_DIR}/caffe_config.h) list(APPEND test_srcs ${test_hdrs}) diff --git a/cmake/Templates/caffe_config.h.in b/cmake/Templates/caffe_config.h.in index 8a31b43cabf..54610f1bc34 100644 --- a/cmake/Templates/caffe_config.h.in +++ b/cmake/Templates/caffe_config.h.in @@ -31,8 +31,12 @@ /* Matlab */ #cmakedefine HAVE_MATLAB +/* glog */ +#cmakedefine USE_GLOG + /* IO libraries */ #cmakedefine USE_OPENCV #cmakedefine USE_LEVELDB #cmakedefine USE_LMDB #cmakedefine ALLOW_LMDB_NOLOCK +#cmakedefine USE_HDF5 diff --git a/docs/installation.md b/docs/installation.md index cce7ec358f5..6603a379c4e 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -24,13 +24,14 @@ Caffe has several dependencies: * 5.5, and 5.0 are compatible but considered legacy * [BLAS](http://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms) via ATLAS, MKL, or OpenBLAS. * [Boost](http://www.boost.org/) >= 1.55 -* `protobuf`, `glog`, `gflags`, `hdf5` +* `protobuf`, `gflags` Optional dependencies: * [OpenCV](http://opencv.org/) >= 2.4 including 3.0 -* IO libraries: `lmdb`, `leveldb` (note: leveldb requires `snappy`) +* IO libraries: `lmdb`, `leveldb` (note: leveldb requires `snappy`), `hdf5` * cuDNN for GPU acceleration (v3) +* `glog` Pycaffe and Matcaffe interfaces have their own natural needs. diff --git a/include/caffe/util/hdf5.hpp b/include/caffe/util/hdf5.hpp index ce568c5eb0d..3ed29d31e1c 100644 --- a/include/caffe/util/hdf5.hpp +++ b/include/caffe/util/hdf5.hpp @@ -1,3 +1,4 @@ +#ifdef USE_HDF5 #ifndef CAFFE_UTIL_HDF5_H_ #define CAFFE_UTIL_HDF5_H_ @@ -37,3 +38,4 @@ string hdf5_get_name_by_idx(hid_t loc_id, int idx); } // namespace caffe #endif // CAFFE_UTIL_HDF5_H_ +#endif // USE_HDF5 diff --git a/include/caffe/util/math_functions.hpp b/include/caffe/util/math_functions.hpp index 6f6d3feeae2..52811a9f65d 100644 --- a/include/caffe/util/math_functions.hpp +++ b/include/caffe/util/math_functions.hpp @@ -3,6 +3,7 @@ #include #include // for std::fabs and std::signbit +#include // for memset #include "glog/logging.h" diff --git a/include/ceres/internal/miniglog/glog/logging.h b/include/ceres/internal/miniglog/glog/logging.h new file mode 100644 index 00000000000..30da9a39f23 --- /dev/null +++ b/include/ceres/internal/miniglog/glog/logging.h @@ -0,0 +1,443 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2015 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: settinger@google.com (Scott Ettinger) +// mierle@gmail.com (Keir Mierle) +// +// Simplified Glog style logging with Android support. Supported macros in +// decreasing severity level per line: +// +// VLOG(2), VLOG(N) +// VLOG(1), +// LOG(INFO), VLOG(0), LG +// LOG(WARNING), +// LOG(ERROR), +// LOG(FATAL), +// +// With VLOG(n), the output is directed to one of the 5 Android log levels: +// +// 2 - Verbose +// 1 - Debug +// 0 - Info +// -1 - Warning +// -2 - Error +// -3 - Fatal +// +// Any logging of level 2 and above is directed to the Verbose level. All +// Android log output is tagged with the string "native". +// +// If the symbol ANDROID is not defined, all output goes to std::cerr. +// This allows code to be built on a different system for debug. +// +// Portions of this code are taken from the GLOG package. This code is only a +// small subset of the GLOG functionality. Notable differences from GLOG +// behavior include lack of support for displaying unprintable characters and +// lack of stack trace information upon failure of the CHECK macros. On +// non-Android systems, log output goes to std::cerr and is not written to a +// file. +// +// CHECK macros are defined to test for conditions within code. Any CHECK that +// fails will log the failure and terminate the application. +// e.g. CHECK_GE(3, 2) will pass while CHECK_GE(3, 4) will fail after logging +// "Check failed 3 >= 4". +// +// The following CHECK macros are defined: +// +// CHECK(condition) - fails if condition is false and logs condition. +// CHECK_NOTNULL(variable) - fails if the variable is NULL. +// +// The following binary check macros are also defined : +// +// Macro Operator equivalent +// -------------------- ------------------- +// CHECK_EQ(val1, val2) val1 == val2 +// CHECK_NE(val1, val2) val1 != val2 +// CHECK_GT(val1, val2) val1 > val2 +// CHECK_GE(val1, val2) val1 >= val2 +// CHECK_LT(val1, val2) val1 < val2 +// CHECK_LE(val1, val2) val1 <= val2 +// +// Debug only versions of all of the check macros are also defined. These +// macros generate no code in a release build, but avoid unused variable +// warnings / errors. +// +// To use the debug only versions, prepend a D to the normal check macros, e.g. +// DCHECK_EQ(a, b). + +#ifndef CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_ +#define CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_ + +#ifdef ANDROID +# include +#endif // ANDROID + +#include +#include +#include +#include +#include +#include +#include +#include + +// For appropriate definition of CERES_EXPORT macro. +#define CERES_EXPORT + +extern bool FLAGS_alsologtostderr; + +// Log severity level constants. +const int FATAL = -3; +const int ERROR = -2; +const int WARNING = -1; +const int INFO = 0; + +// ------------------------- Glog compatibility ------------------------------ + +namespace google { + +typedef int LogSeverity; +const int INFO = ::INFO; +const int WARNING = ::WARNING; +const int ERROR = ::ERROR; +const int FATAL = ::FATAL; + +// Sink class used for integration with mock and test functions. If sinks are +// added, all log output is also sent to each sink through the send function. +// In this implementation, WaitTillSent() is called immediately after the send. +// This implementation is not thread safe. +class CERES_EXPORT LogSink { + public: + virtual ~LogSink() {} + virtual void send(LogSeverity severity, + const char* full_filename, + const char* base_filename, + int line, + const struct tm* tm_time, + const char* message, + size_t message_len) = 0; + virtual void WaitTillSent() = 0; +}; + +// Global set of log sinks. The actual object is defined in logging.cc. +extern CERES_EXPORT std::set log_sinks_global; + +inline void InitGoogleLogging(char *argv) { + // Do nothing; this is ignored. +} + +inline void InstallFailureSignalHandler() { + // Do nothing; this is ignored. +} + +// Note: the Log sink functions are not thread safe. +inline void AddLogSink(LogSink *sink) { + // TODO(settinger): Add locks for thread safety. + log_sinks_global.insert(sink); +} +inline void RemoveLogSink(LogSink *sink) { + log_sinks_global.erase(sink); +} + +} // namespace google + +// ---------------------------- Logger Class -------------------------------- + +// Class created for each use of the logging macros. +// The logger acts as a stream and routes the final stream contents to the +// Android logcat output at the proper filter level. If ANDROID is not +// defined, output is directed to std::cerr. This class should not +// be directly instantiated in code, rather it should be invoked through the +// use of the log macros LG, LOG, or VLOG. +class CERES_EXPORT MessageLogger { + public: + MessageLogger(const char *file, int line, const char *tag, int severity) + : file_(file), line_(line), tag_(tag), severity_(severity) { + // Pre-pend the stream with the file and line number. + StripBasename(std::string(file), &filename_only_); + stream_ << filename_only_ << ":" << line << " "; + } + + // Output the contents of the stream to the proper channel on destruction. + ~MessageLogger() { + stream_ << "\n"; + +#ifdef ANDROID + static const int android_log_levels[] = { + ANDROID_LOG_FATAL, // LOG(FATAL) + ANDROID_LOG_ERROR, // LOG(ERROR) + ANDROID_LOG_WARN, // LOG(WARNING) + ANDROID_LOG_INFO, // LOG(INFO), LG, VLOG(0) + ANDROID_LOG_DEBUG, // VLOG(1) + ANDROID_LOG_VERBOSE, // VLOG(2) .. VLOG(N) + }; + + // Bound the logging level. + const int kMaxVerboseLevel = 2; + int android_level_index = std::min(std::max(FATAL, severity_), + kMaxVerboseLevel) - FATAL; + int android_log_level = android_log_levels[android_level_index]; + + // Output the log string the Android log at the appropriate level. + __android_log_write(android_log_level, tag_.c_str(), stream_.str().c_str()); + + // Indicate termination if needed. + if (severity_ == FATAL) { + __android_log_write(ANDROID_LOG_FATAL, + tag_.c_str(), + "terminating.\n"); + } +#else + // If not building on Android, log all output to std::cerr. + std::cerr << stream_.str(); +#endif // ANDROID + + LogToSinks(severity_); + WaitForSinks(); + + // Android logging at level FATAL does not terminate execution, so abort() + // is still required to stop the program. + if (severity_ == FATAL) { + abort(); + } + } + + // Return the stream associated with the logger object. + std::stringstream &stream() { return stream_; } + + private: + void LogToSinks(int severity) { + time_t rawtime; + time (&rawtime); + + struct tm* timeinfo; +#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) + // On Windows, use secure localtime_s not localtime. + struct tm windows_timeinfo; + timeinfo = &windows_timeinfo; + localtime_s(timeinfo, &rawtime); +#else + timeinfo = localtime(&rawtime); +#endif + + std::set::iterator iter; + // Send the log message to all sinks. + for (iter = google::log_sinks_global.begin(); + iter != google::log_sinks_global.end(); ++iter) { + (*iter)->send(severity, file_.c_str(), filename_only_.c_str(), line_, + timeinfo, stream_.str().c_str(), stream_.str().size()); + } + } + + void WaitForSinks() { + // TODO(settinger): Add locks for thread safety. + std::set::iterator iter; + + // Call WaitTillSent() for all sinks. + for (iter = google::log_sinks_global.begin(); + iter != google::log_sinks_global.end(); ++iter) { + (*iter)->WaitTillSent(); + } + } + + void StripBasename(const std::string &full_path, std::string *filename) { + // TODO(settinger): Add support for OSs with different path separators. + const char kSeparator = '/'; + size_t pos = full_path.rfind(kSeparator); + if (pos != std::string::npos) { + *filename = full_path.substr(pos + 1, std::string::npos); + } else { + *filename = full_path; + } + } + + std::string file_; + std::string filename_only_; + int line_; + std::string tag_; + std::stringstream stream_; + int severity_; +}; + +// ---------------------- Logging Macro definitions -------------------------- + +// This class is used to explicitly ignore values in the conditional +// logging macros. This avoids compiler warnings like "value computed +// is not used" and "statement has no effect". +class CERES_EXPORT LoggerVoidify { + public: + LoggerVoidify() { } + // This has to be an operator with a precedence lower than << but + // higher than ?: + void operator&(const std::ostream &s) { } +}; + +// Log only if condition is met. Otherwise evaluates to void. +#define LOG_IF(severity, condition) \ + !(condition) ? (void) 0 : LoggerVoidify() & \ + MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream() + +// Log only if condition is NOT met. Otherwise evaluates to void. +#define LOG_IF_FALSE(severity, condition) LOG_IF(severity, !(condition)) + +// LG is a convenient shortcut for LOG(INFO). Its use is in new +// google3 code is discouraged and the following shortcut exists for +// backward compatibility with existing code. +#ifdef MAX_LOG_LEVEL +# define LOG(n) LOG_IF(n, n <= MAX_LOG_LEVEL) +# define VLOG(n) LOG_IF(n, n <= MAX_LOG_LEVEL) +# define LG LOG_IF(INFO, INFO <= MAX_LOG_LEVEL) +# define VLOG_IF(n, condition) LOG_IF(n, (n <= MAX_LOG_LEVEL) && condition) +#else +# define LOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", n).stream() // NOLINT +# define VLOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", n).stream() // NOLINT +# define LG MessageLogger((char *)__FILE__, __LINE__, "native", INFO).stream() // NOLINT +# define VLOG_IF(n, condition) LOG_IF(n, condition) +#endif + +// Currently, VLOG is always on for levels below MAX_LOG_LEVEL. +#ifndef MAX_LOG_LEVEL +# define VLOG_IS_ON(x) (1) +#else +# define VLOG_IS_ON(x) (x <= MAX_LOG_LEVEL) +#endif + +#define SOME_KIND_OF_LOG_EVERY_N(severity, n) \ + static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \ + ++LOG_OCCURRENCES; \ + if (++LOG_OCCURRENCES_MOD_N > n) LOG_OCCURRENCES_MOD_N -= n; \ + LOG_IF(severity, LOG_OCCURRENCES_MOD_N == 1) + +#define LOG_EVERY_N(severity, n) SOME_KIND_OF_LOG_EVERY_N(severity, n) + +#ifndef NDEBUG +# define DLOG LOG +# define DLOG_IF LOG_IF +# define DLOG_EVERY_N LOG_EVERY_N +#else +# define DLOG(severity) true ? (void) 0 : LoggerVoidify() & \ + MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream() +# define DLOG_IF(severity, condition) true ? (void) 0 : LoggerVoidify() & \ + MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream() +# define DLOG_EVERY_N(severity, n) true ? (void) 0 : LoggerVoidify() & \ + MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream() +#endif + + +// Log a message and terminate. +template +void LogMessageFatal(const char *file, int line, const T &message) { + MessageLogger((char *)__FILE__, __LINE__, "native", FATAL).stream() + << message; +} + +// ---------------------------- CHECK macros --------------------------------- + +// Check for a given boolean condition. +#define CHECK(condition) LOG_IF_FALSE(FATAL, condition) \ + << "Check failed: " #condition " " + +#ifndef NDEBUG +// Debug only version of CHECK +# define DCHECK(condition) LOG_IF_FALSE(FATAL, condition) \ + << "Check failed: " #condition " " +#else +// Optimized version - generates no code. +# define DCHECK(condition) if (false) LOG_IF_FALSE(FATAL, condition) \ + << "Check failed: " #condition " " +#endif // NDEBUG + +// ------------------------- CHECK_OP macros --------------------------------- + +// Generic binary operator check macro. This should not be directly invoked, +// instead use the binary comparison macros defined below. +#define CHECK_OP(val1, val2, op) LOG_IF_FALSE(FATAL, ((val1) op (val2))) \ + << "Check failed: " #val1 " " #op " " #val2 " " + +// Check_op macro definitions +#define CHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==) +#define CHECK_NE(val1, val2) CHECK_OP(val1, val2, !=) +#define CHECK_LE(val1, val2) CHECK_OP(val1, val2, <=) +#define CHECK_LT(val1, val2) CHECK_OP(val1, val2, <) +#define CHECK_GE(val1, val2) CHECK_OP(val1, val2, >=) +#define CHECK_GT(val1, val2) CHECK_OP(val1, val2, >) + +#ifndef NDEBUG +// Debug only versions of CHECK_OP macros. +# define DCHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==) +# define DCHECK_NE(val1, val2) CHECK_OP(val1, val2, !=) +# define DCHECK_LE(val1, val2) CHECK_OP(val1, val2, <=) +# define DCHECK_LT(val1, val2) CHECK_OP(val1, val2, <) +# define DCHECK_GE(val1, val2) CHECK_OP(val1, val2, >=) +# define DCHECK_GT(val1, val2) CHECK_OP(val1, val2, >) +#else +// These versions generate no code in optimized mode. +# define DCHECK_EQ(val1, val2) if (false) CHECK_OP(val1, val2, ==) +# define DCHECK_NE(val1, val2) if (false) CHECK_OP(val1, val2, !=) +# define DCHECK_LE(val1, val2) if (false) CHECK_OP(val1, val2, <=) +# define DCHECK_LT(val1, val2) if (false) CHECK_OP(val1, val2, <) +# define DCHECK_GE(val1, val2) if (false) CHECK_OP(val1, val2, >=) +# define DCHECK_GT(val1, val2) if (false) CHECK_OP(val1, val2, >) +#endif // NDEBUG + +// ---------------------------CHECK_NOTNULL macros --------------------------- + +// Helpers for CHECK_NOTNULL(). Two are necessary to support both raw pointers +// and smart pointers. +template +T& CheckNotNullCommon(const char *file, int line, const char *names, T& t) { + if (t == NULL) { + LogMessageFatal(file, line, std::string(names)); + } + return t; +} + +template +T* CheckNotNull(const char *file, int line, const char *names, T* t) { + return CheckNotNullCommon(file, line, names, t); +} + +template +T& CheckNotNull(const char *file, int line, const char *names, T& t) { + return CheckNotNullCommon(file, line, names, t); +} + +// Check that a pointer is not null. +#define CHECK_NOTNULL(val) \ + CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) + +#ifndef NDEBUG +// Debug only version of CHECK_NOTNULL +#define DCHECK_NOTNULL(val) \ + CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) +#else +// Optimized version - generates no code. +#define DCHECK_NOTNULL(val) if (false)\ + CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) +#endif // NDEBUG + +#endif // CERCES_INTERNAL_MINIGLOG_GLOG_LOGGING_H_ diff --git a/src/caffe/CMakeLists.txt b/src/caffe/CMakeLists.txt index 40e6c11f5b0..25f08eb22be 100644 --- a/src/caffe/CMakeLists.txt +++ b/src/caffe/CMakeLists.txt @@ -28,6 +28,9 @@ caffe_default_properties(caffe) install(DIRECTORY ${Caffe_INCLUDE_DIR}/caffe DESTINATION include) install(FILES ${proto_hdrs} DESTINATION include/caffe/proto) install(TARGETS caffe proto EXPORT CaffeTargets DESTINATION lib) +if(NOT USE_GLOG) + install(DIRECTORY ${Caffe_INCLUDE_DIR}/ceres DESTINATION include) +endif() file(WRITE ${PROJECT_BINARY_DIR}/__init__.py) list(APPEND proto_python ${PROJECT_BINARY_DIR}/__init__.py) diff --git a/src/caffe/layers/hdf5_data_layer.cpp b/src/caffe/layers/hdf5_data_layer.cpp index 2f13dc641df..2f54b159a94 100644 --- a/src/caffe/layers/hdf5_data_layer.cpp +++ b/src/caffe/layers/hdf5_data_layer.cpp @@ -1,3 +1,4 @@ +#ifdef USE_HDF5 /* TODO: - load file in a separate thread ("prefetch") @@ -164,3 +165,4 @@ INSTANTIATE_CLASS(HDF5DataLayer); REGISTER_LAYER_CLASS(HDF5Data); } // namespace caffe +#endif // USE_HDF5 diff --git a/src/caffe/layers/hdf5_data_layer.cu b/src/caffe/layers/hdf5_data_layer.cu index 595d2230220..a8b467c10e0 100644 --- a/src/caffe/layers/hdf5_data_layer.cu +++ b/src/caffe/layers/hdf5_data_layer.cu @@ -1,3 +1,4 @@ +#ifdef USE_HDF5 /* TODO: - only load parts of the file, in accordance with a prototxt param "max_mem" @@ -48,3 +49,4 @@ void HDF5DataLayer::Forward_gpu(const vector*>& bottom, INSTANTIATE_LAYER_GPU_FUNCS(HDF5DataLayer); } // namespace caffe +#endif // USE_HDF5 diff --git a/src/caffe/layers/hdf5_output_layer.cpp b/src/caffe/layers/hdf5_output_layer.cpp index f8f1edcd18e..28c453a20fd 100644 --- a/src/caffe/layers/hdf5_output_layer.cpp +++ b/src/caffe/layers/hdf5_output_layer.cpp @@ -1,3 +1,4 @@ +#ifdef USE_HDF5 #include #include "hdf5.h" @@ -72,3 +73,4 @@ INSTANTIATE_CLASS(HDF5OutputLayer); REGISTER_LAYER_CLASS(HDF5Output); } // namespace caffe +#endif // USE_HDF5 diff --git a/src/caffe/layers/hdf5_output_layer.cu b/src/caffe/layers/hdf5_output_layer.cu index c1685cd34a7..891aea03862 100644 --- a/src/caffe/layers/hdf5_output_layer.cu +++ b/src/caffe/layers/hdf5_output_layer.cu @@ -1,3 +1,4 @@ +#ifdef USE_HDF5 #include #include "hdf5.h" @@ -37,3 +38,4 @@ void HDF5OutputLayer::Backward_gpu(const vector*>& top, INSTANTIATE_LAYER_GPU_FUNCS(HDF5OutputLayer); } // namespace caffe +#endif // USE_HDF5 diff --git a/src/caffe/net.cpp b/src/caffe/net.cpp index 05bee7987da..8e09a0607c3 100644 --- a/src/caffe/net.cpp +++ b/src/caffe/net.cpp @@ -5,7 +5,9 @@ #include #include +#ifdef USE_HDF5 #include "hdf5.h" +#endif // USE_HDF5 #include "caffe/common.hpp" #include "caffe/layer.hpp" @@ -859,6 +861,7 @@ void Net::CopyTrainedLayersFromBinaryProto( template void Net::CopyTrainedLayersFromHDF5(const string trained_filename) { +#ifdef USE_HDF5 hid_t file_hid = H5Fopen(trained_filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); CHECK_GE(file_hid, 0) << "Couldn't open " << trained_filename; @@ -905,6 +908,10 @@ void Net::CopyTrainedLayersFromHDF5(const string trained_filename) { } H5Gclose(data_hid); H5Fclose(file_hid); +#else + LOG(FATAL) << "CopyTrainedLayersFromHDF5 requires hdf5;" + << " compile with USE_HDF5."; +#endif // USE_HDF5 } template @@ -924,6 +931,7 @@ void Net::ToProto(NetParameter* param, bool write_diff) const { template void Net::ToHDF5(const string& filename, bool write_diff) const { +#ifdef USE_HDF5 hid_t file_hid = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); CHECK_GE(file_hid, 0) @@ -977,6 +985,9 @@ void Net::ToHDF5(const string& filename, bool write_diff) const { H5Gclose(diff_hid); } H5Fclose(file_hid); +#else + LOG(FATAL) << "ToHDF5 requires hdf5; compile with USE_HDF5."; +#endif // USE_HDF5 } template diff --git a/src/caffe/solvers/sgd_solver.cpp b/src/caffe/solvers/sgd_solver.cpp index 32bf19b17c8..9ea2afa86a1 100644 --- a/src/caffe/solvers/sgd_solver.cpp +++ b/src/caffe/solvers/sgd_solver.cpp @@ -274,6 +274,7 @@ void SGDSolver::SnapshotSolverStateToBinaryProto( template void SGDSolver::SnapshotSolverStateToHDF5( const string& model_filename) { +#ifdef USE_HDF5 string snapshot_filename = Solver::SnapshotFilename(".solverstate.h5"); LOG(INFO) << "Snapshotting solver state to HDF5 file " << snapshot_filename; @@ -295,6 +296,10 @@ void SGDSolver::SnapshotSolverStateToHDF5( } H5Gclose(history_hid); H5Fclose(file_hid); +#else + LOG(FATAL) << "SnapshotSolverStateToHDF5 requires hdf5;" + << " compile with USE_HDF5."; +#endif // USE_HDF5 } template @@ -319,6 +324,7 @@ void SGDSolver::RestoreSolverStateFromBinaryProto( template void SGDSolver::RestoreSolverStateFromHDF5(const string& state_file) { +#ifdef USE_HDF5 hid_t file_hid = H5Fopen(state_file.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); CHECK_GE(file_hid, 0) << "Couldn't open solver state file " << state_file; this->iter_ = hdf5_load_int(file_hid, "iter"); @@ -340,6 +346,10 @@ void SGDSolver::RestoreSolverStateFromHDF5(const string& state_file) { } H5Gclose(history_hid); H5Fclose(file_hid); +#else + LOG(FATAL) << "RestoreSolverStateFromHDF5 requires hdf5;" + << " compile with USE_HDF5."; +#endif // USE_HDF5 } INSTANTIATE_CLASS(SGDSolver); diff --git a/src/caffe/test/test_hdf5_output_layer.cpp b/src/caffe/test/test_hdf5_output_layer.cpp index 3833ebff78e..618d16fe373 100644 --- a/src/caffe/test/test_hdf5_output_layer.cpp +++ b/src/caffe/test/test_hdf5_output_layer.cpp @@ -1,3 +1,4 @@ +#ifdef USE_HDF5 #include #include @@ -119,3 +120,4 @@ TYPED_TEST(HDF5OutputLayerTest, TestForward) { } } // namespace caffe +#endif // USE_HDF5 diff --git a/src/caffe/test/test_hdf5data_layer.cpp b/src/caffe/test/test_hdf5data_layer.cpp index 8884ce95a23..37b65e03686 100644 --- a/src/caffe/test/test_hdf5data_layer.cpp +++ b/src/caffe/test/test_hdf5data_layer.cpp @@ -1,3 +1,4 @@ +#ifdef USE_HDF5 #include #include @@ -134,3 +135,4 @@ TYPED_TEST(HDF5DataLayerTest, TestRead) { } } // namespace caffe +#endif // USE_HDF5 diff --git a/src/caffe/util/hdf5.cpp b/src/caffe/util/hdf5.cpp index 7730e76ab87..a428d43c4d0 100644 --- a/src/caffe/util/hdf5.cpp +++ b/src/caffe/util/hdf5.cpp @@ -1,3 +1,4 @@ +#ifdef USE_HDF5 #include "caffe/util/hdf5.hpp" #include @@ -185,3 +186,4 @@ string hdf5_get_name_by_idx(hid_t loc_id, int idx) { } } // namespace caffe +#endif // USE_HDF5 diff --git a/src/ceres/internal/miniglog/glog/logging.cpp b/src/ceres/internal/miniglog/glog/logging.cpp new file mode 100644 index 00000000000..4bd93959cf6 --- /dev/null +++ b/src/ceres/internal/miniglog/glog/logging.cpp @@ -0,0 +1,41 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2015 Google Inc. All rights reserved. +// http://ceres-solver.org/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: keir@google.com (Keir Mierle) + +#include "glog/logging.h" + +bool FLAGS_alsologtostderr = false; + +namespace google { + +// This is the set of log sinks. This must be in a separate library to ensure +// that there is only one instance of this across the entire program. +std::set log_sinks_global; + +} // namespace ceres