From 5024ff1a7ff6e6d36cee8f5017921de0e3a1b2da Mon Sep 17 00:00:00 2001 From: sunnycase Date: Sat, 28 Aug 2021 23:24:38 +0800 Subject: [PATCH] Support more OSes (#10) * Support macos * Link BLAS lib * Add windows * Fix windows io * Fix test python layer * Fix tests for win --- .github/workflows/python-build.yml | 2 +- .gitignore | 1 + .vscode/launch.json | 7 - CMakeLists.txt | 17 +-- cmake/Dependencies.cmake | 48 ++----- cmake/Misc.cmake | 4 - cmake/Modules/FindAtlas.cmake | 52 ------- cmake/Modules/FindLAPACK.cmake | 190 ------------------------- cmake/Modules/FindMKL.cmake | 110 -------------- cmake/Modules/FindNumPy.cmake | 58 -------- cmake/Modules/FindvecLib.cmake | 36 ----- cmake/Summary.cmake | 2 +- cmake/Targets.cmake | 10 +- python/CMakeLists.txt | 17 ++- python/caffe/_caffe.cpp | 4 +- python/caffe/test/test_python_layer.py | 4 + python/caffe/test/test_solver.py | 5 +- python/requirements.txt | 12 -- src/caffe/CMakeLists.txt | 10 ++ src/caffe/test/CMakeLists.txt | 2 +- src/caffe/util/db_lmdb.cpp | 5 + src/caffe/util/io.cpp | 9 ++ src/caffe/util/signal_handler.cpp | 26 +++- 23 files changed, 92 insertions(+), 539 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 cmake/Modules/FindAtlas.cmake delete mode 100644 cmake/Modules/FindLAPACK.cmake delete mode 100644 cmake/Modules/FindMKL.cmake delete mode 100644 cmake/Modules/FindNumPy.cmake delete mode 100644 cmake/Modules/FindvecLib.cmake diff --git a/.github/workflows/python-build.yml b/.github/workflows/python-build.yml index fee278c2523..4f91e2e76d9 100644 --- a/.github/workflows/python-build.yml +++ b/.github/workflows/python-build.yml @@ -15,7 +15,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-18.04] + os: [ubuntu-18.04,windows-2019,macos-10.15] steps: - uses: actions/checkout@v2 diff --git a/.gitignore b/.gitignore index 0bfc7e1fa06..5c8a250e31c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ # Compiled Dynamic libraries *.so *.dylib +*.pyd # Compiled Static libraries *.lai diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index ce8a4f2aab3..00000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [] -} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e969c2e5e78..47adedd6332 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,15 +52,6 @@ if(NOT CONAN_EXPORTED) conan_add_remote(NAME sunnycase URL https://conan.sunnycase.moe INDEX 0) endif() -set(CMAKE_SKIP_RPATH OFF) -if (APPLE) - set(CMAKE_MACOSX_RPATH TRUE) - set(CMAKE_INSTALL_RPATH "@loader_path/../lib") - set(CMAKE_INSTALL_NAME_DIR "@rpath") -else () - set(CMAKE_INSTALL_RPATH "$ORIGIN/..lib") -endif() - conan_cmake_run(CONANFILE conanfile.py BASIC_SETUP TARGETS OPTIONS ${CONAN_OPTS} @@ -76,6 +67,10 @@ if(UNIX OR APPLE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall") endif() +if(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8 /W3 /D_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS /D_CRT_SECURE_NO_WARNINGS /DNOMINMAX /DHAVE_CXX11_ATOMIC /DOS_WINDOWS") +endif() + caffe_set_caffe_link() if(USE_libstdcpp) @@ -84,7 +79,9 @@ if(USE_libstdcpp) endif() # ---[ Warnings -caffe_warnings_disable(CMAKE_CXX_FLAGS -Wno-sign-compare -Wno-uninitialized) +if(MSVC) + caffe_warnings_disable(CMAKE_CXX_FLAGS -Wno-sign-compare -Wno-uninitialized) +endif() # ---[ Config generation configure_file(cmake/Templates/caffe_config.h.in "${PROJECT_BINARY_DIR}/caffe_config.h") diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake index 205b57d60d7..56af435d2fb 100644 --- a/cmake/Dependencies.cmake +++ b/cmake/Dependencies.cmake @@ -112,54 +112,28 @@ if(NOT APPLE) set_property(CACHE BLAS PROPERTY STRINGS "Atlas;Open;MKL") if(BLAS STREQUAL "Open" OR BLAS STREQUAL "open") - find_package(OpenBLAS REQUIRED) - list(APPEND Caffe_LINKER_LIBS PUBLIC OpenBLAS::OpenBLAS) + set(BLA_VENDOR OpenBLAS) elseif(BLAS STREQUAL "MKL" OR BLAS STREQUAL "mkl") - find_package(MKL REQUIRED) - list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${MKL_INCLUDE_DIR}) - list(APPEND Caffe_LINKER_LIBS PUBLIC ${MKL_LIBRARIES}) + set(BLA_VENDOR Intel10_64lp) list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_MKL) endif() elseif(APPLE) - find_package(vecLib REQUIRED) - list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${vecLib_INCLUDE_DIR}) - list(APPEND Caffe_LINKER_LIBS PUBLIC ${vecLib_LINKER_LIBS}) - - if(VECLIB_FOUND) - if(NOT vecLib_INCLUDE_DIR MATCHES "^/System/Library/Frameworks/vecLib.framework.*") - list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_ACCELERATE) - endif() + set(BLA_VENDOR Apple) +endif() + +if(APPLE) + if(NOT BLAS_LIBRARIES MATCHES "^/System/Library/Frameworks/vecLib.framework.*") + list(APPEND Caffe_DEFINITIONS PUBLIC -DUSE_ACCELERATE) endif() endif() +find_package(BLAS REQUIRED) +list(APPEND Caffe_LINKER_LIBS PRIVATE BLAS::BLAS) + # ---[ Python find_package(Python3 COMPONENTS Interpreter Development NumPy REQUIRED) if(BUILD_python) - #if(NOT "${python_version}" VERSION_LESS "3") - # # use python3 - # find_package(PythonInterp) - # find_package(PythonLibs) - # find_package(NumPy) - # # Find the matching boost python implementation - # set(version ${PYTHONLIBS_VERSION_STRING}) - - # STRING( REGEX REPLACE "[^0-9]" "" boost_py_version ${version} ) - # find_package(Boost 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( REGEX REPLACE "[^0-9]" "" boost_py_version ${version} ) - # find_package(Boost 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() - # endif() - # endwhile() set(HAVE_PYTHON TRUE) if(BUILD_python_layer) list(APPEND Caffe_DEFINITIONS PRIVATE -DWITH_PYTHON_LAYER) diff --git a/cmake/Misc.cmake b/cmake/Misc.cmake index fcb246472f0..950d3eb6c49 100644 --- a/cmake/Misc.cmake +++ b/cmake/Misc.cmake @@ -28,10 +28,6 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${PROJECT_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) - list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR} __is_systtem_dir) if(${__is_systtem_dir} STREQUAL -1) diff --git a/cmake/Modules/FindAtlas.cmake b/cmake/Modules/FindAtlas.cmake deleted file mode 100644 index 7ffa6393bbc..00000000000 --- a/cmake/Modules/FindAtlas.cmake +++ /dev/null @@ -1,52 +0,0 @@ -# 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 lapack alapack_r alapack lapack_atlas atllapack 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} lapack: ${Atlas_LAPACK_LIBRARY}") -endif(ATLAS_FOUND) - diff --git a/cmake/Modules/FindLAPACK.cmake b/cmake/Modules/FindLAPACK.cmake deleted file mode 100644 index 9641c45d196..00000000000 --- a/cmake/Modules/FindLAPACK.cmake +++ /dev/null @@ -1,190 +0,0 @@ -# - 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/FindMKL.cmake b/cmake/Modules/FindMKL.cmake deleted file mode 100644 index ef0c3bf1c64..00000000000 --- a/cmake/Modules/FindMKL.cmake +++ /dev/null @@ -1,110 +0,0 @@ -# Find the MKL libraries -# -# Options: -# -# MKL_USE_SINGLE_DYNAMIC_LIBRARY : use single dynamic library interface -# MKL_USE_STATIC_LIBS : use static libraries -# MKL_MULTI_THREADED : use multi-threading -# -# This module defines the following variables: -# -# MKL_FOUND : True mkl is found -# MKL_INCLUDE_DIR : include directory -# MKL_LIBRARIES : the libraries to link against. - - -# ---[ Options -caffe_option(MKL_USE_SINGLE_DYNAMIC_LIBRARY "Use single dynamic library interface" ON) -caffe_option(MKL_USE_STATIC_LIBS "Use static libraries" OFF IF NOT MKL_USE_SINGLE_DYNAMIC_LIBRARY) -caffe_option(MKL_MULTI_THREADED "Use multi-threading" ON IF NOT MKL_USE_SINGLE_DYNAMIC_LIBRARY) - -# ---[ Root folders -set(INTEL_ROOT "/opt/intel" CACHE PATH "Folder contains intel libs") -find_path(MKL_ROOT include/mkl.h PATHS $ENV{MKLROOT} ${INTEL_ROOT}/mkl - DOC "Folder contains MKL") - -# ---[ Find include dir -find_path(MKL_INCLUDE_DIR mkl.h PATHS ${MKL_ROOT} PATH_SUFFIXES include) -set(__looked_for MKL_INCLUDE_DIR) - -# ---[ Find libraries -if(CMAKE_SIZEOF_VOID_P EQUAL 4) - set(__path_suffixes lib lib/ia32) -else() - set(__path_suffixes lib lib/intel64) -endif() - -set(__mkl_libs "") -if(MKL_USE_SINGLE_DYNAMIC_LIBRARY) - list(APPEND __mkl_libs rt) -else() - if(CMAKE_SIZEOF_VOID_P EQUAL 4) - if(WIN32) - list(APPEND __mkl_libs intel_c) - else() - list(APPEND __mkl_libs intel gf) - endif() - else() - list(APPEND __mkl_libs intel_lp64 gf_lp64) - endif() - - if(MKL_MULTI_THREADED) - list(APPEND __mkl_libs intel_thread) - else() - list(APPEND __mkl_libs sequential) - endif() - - list(APPEND __mkl_libs core cdft_core) -endif() - - -foreach (__lib ${__mkl_libs}) - set(__mkl_lib "mkl_${__lib}") - string(TOUPPER ${__mkl_lib} __mkl_lib_upper) - - if(MKL_USE_STATIC_LIBS) - set(__mkl_lib "lib${__mkl_lib}.a") - endif() - - find_library(${__mkl_lib_upper}_LIBRARY - NAMES ${__mkl_lib} - PATHS ${MKL_ROOT} "${MKL_INCLUDE_DIR}/.." - PATH_SUFFIXES ${__path_suffixes} - DOC "The path to Intel(R) MKL ${__mkl_lib} library") - mark_as_advanced(${__mkl_lib_upper}_LIBRARY) - - list(APPEND __looked_for ${__mkl_lib_upper}_LIBRARY) - list(APPEND MKL_LIBRARIES ${${__mkl_lib_upper}_LIBRARY}) -endforeach() - - -if(NOT MKL_USE_SINGLE_DYNAMIC_LIBRARY) - if (MKL_USE_STATIC_LIBS) - set(__iomp5_libs iomp5 libiomp5mt.lib) - else() - set(__iomp5_libs iomp5 libiomp5md.lib) - endif() - - if(WIN32) - find_path(INTEL_INCLUDE_DIR omp.h PATHS ${INTEL_ROOT} PATH_SUFFIXES include) - list(APPEND __looked_for INTEL_INCLUDE_DIR) - endif() - - find_library(MKL_RTL_LIBRARY ${__iomp5_libs} - PATHS ${INTEL_RTL_ROOT} ${INTEL_ROOT}/compiler ${MKL_ROOT}/.. ${MKL_ROOT}/../compiler - PATH_SUFFIXES ${__path_suffixes} - DOC "Path to Path to OpenMP runtime library") - - list(APPEND __looked_for MKL_RTL_LIBRARY) - list(APPEND MKL_LIBRARIES ${MKL_RTL_LIBRARY}) -endif() - - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(MKL DEFAULT_MSG ${__looked_for}) - -if(MKL_FOUND) - message(STATUS "Found MKL (include: ${MKL_INCLUDE_DIR}, lib: ${MKL_LIBRARIES}") -endif() - -caffe_clear_vars(__looked_for __mkl_libs __path_suffixes __lib_suffix __iomp5_libs) diff --git a/cmake/Modules/FindNumPy.cmake b/cmake/Modules/FindNumPy.cmake deleted file mode 100644 index a671494caba..00000000000 --- a/cmake/Modules/FindNumPy.cmake +++ /dev/null @@ -1,58 +0,0 @@ -# - 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/FindvecLib.cmake b/cmake/Modules/FindvecLib.cmake deleted file mode 100644 index 4d44e613a00..00000000000 --- a/cmake/Modules/FindvecLib.cmake +++ /dev/null @@ -1,36 +0,0 @@ -# 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") - -exec_program(xcode-select ARGS -print-path OUTPUT_VARIABLE CMAKE_XCODE_DEVELOPER_DIR) -find_path(vecLib_INCLUDE_DIR vecLib.h - DOC "vecLib include directory" - PATHS /System/Library/Frameworks/Accelerate.framework/Versions/Current/${__veclib_include_suffix} - /System/Library/${__veclib_include_suffix} - ${CMAKE_XCODE_DEVELOPER_DIR}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Accelerate.framework/Versions/Current/Frameworks/vecLib.framework/Headers/ - NO_DEFAULT_PATH) - -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/Summary.cmake b/cmake/Summary.cmake index 022b88b986a..53897ccd79d 100644 --- a/cmake/Summary.cmake +++ b/cmake/Summary.cmake @@ -123,7 +123,7 @@ function(caffe_print_configuration_summary) caffe_status(" USE_HDF5 : ${USE_HDF5}") caffe_status("") caffe_status("Dependencies:") - caffe_status(" BLAS : " APPLE THEN "Yes (vecLib)" ELSE "Yes (${BLAS})") + caffe_status(" BLAS : Yes (${BLAS_LIBRARIES})") caffe_status(" Boost : Yes (ver. ${Boost_VERSION})") caffe_status(" glog : Yes") caffe_status(" gflags : Yes") diff --git a/cmake/Targets.cmake b/cmake/Targets.cmake index 090f86c5500..4fa3c4d265a 100644 --- a/cmake/Targets.cmake +++ b/cmake/Targets.cmake @@ -2,15 +2,7 @@ # 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 macro(caffe_set_caffe_link) - 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() + set(Caffe_LINK PRIVATE caffe) endmacro() ################################################################################################ # Convenient command to setup source group for IDEs that support this feature (VS, XCode) diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 5a8a2fdcdff..d1a53079e00 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -8,12 +8,9 @@ file(GLOB_RECURSE python_srcs ${PROJECT_SOURCE_DIR}/python/*.cpp) add_library(pycaffe MODULE ${python_srcs}) caffe_default_properties(pycaffe) set_target_properties(pycaffe PROPERTIES PREFIX "" OUTPUT_NAME "_caffe") -target_link_libraries(pycaffe PUBLIC ${Caffe_LINK} Python3::Module Python3::NumPy) - -if (APPLE) - set_target_properties(pycaffe PROPERTIES INSTALL_RPATH "@loader_path/..;@loader_path") -else() - set_target_properties(pycaffe PROPERTIES INSTALL_RPATH "$ORIGIN/..;$ORIGIN") +target_link_libraries(pycaffe PRIVATE caffe Python3::Module Python3::NumPy) +if(MSVC) + set_target_properties(pycaffe PROPERTIES SUFFIX ".pyd") endif() if(UNIX OR APPLE) @@ -24,6 +21,14 @@ if(UNIX OR APPLE) COMMAND touch ${PROJECT_SOURCE_DIR}/python/caffe/proto/__init__.py COMMAND cp ${proto_gen_folder}/*.py ${PROJECT_SOURCE_DIR}/python/caffe/proto/ COMMENT "Creating symlink ${__linkname} -> ${PROJECT_BINARY_DIR}/lib/_caffe${Caffe_POSTFIX}.so") +elseif(WIN32) + set(__linkname "${PROJECT_SOURCE_DIR}/python/caffe/_caffe.pyd") + add_custom_command(TARGET pycaffe POST_BUILD + COMMAND ${CMAKE_COMMAND} -E create_symlink $ "${__linkname}" + COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_SOURCE_DIR}/python/caffe/proto + COMMAND ${CMAKE_COMMAND} -E touch ${PROJECT_SOURCE_DIR}/python/caffe/proto/__init__.py + COMMAND (robocopy "\"${proto_gen_folder}\" \"${PROJECT_SOURCE_DIR}/python/caffe/proto\" *.py") ^& IF %ERRORLEVEL% LEQ 4 set ERRORLEVEL=0 + COMMENT "Creating symlink ${__linkname} -> ${PROJECT_BINARY_DIR}/lib/_caffe.pyd") endif() # ---[ Install diff --git a/python/caffe/_caffe.cpp b/python/caffe/_caffe.cpp index d21bf0619c6..067968b0b50 100644 --- a/python/caffe/_caffe.cpp +++ b/python/caffe/_caffe.cpp @@ -60,9 +60,9 @@ void InitLogLevel(int level) { FLAGS_minloglevel = level; InitLog(); } -void InitLogLevelPipe(int level, bool stderr) { +void InitLogLevelPipe(int level, bool stderr_) { FLAGS_minloglevel = level; - FLAGS_logtostderr = stderr; + FLAGS_logtostderr = stderr_; InitLog(); } void Log(const string& s) { diff --git a/python/caffe/test/test_python_layer.py b/python/caffe/test/test_python_layer.py index 899514e90f1..79d5b6bc7ba 100644 --- a/python/caffe/test/test_python_layer.py +++ b/python/caffe/test/test_python_layer.py @@ -151,6 +151,10 @@ def test_parameter(self): self.assertEqual(layer.blobs[0].data[0], -1) net.copy_from(caffemodel_file) self.assertEqual(layer.blobs[0].data[0], 1) + if os.name == 'nt': + # On Windows, attempting to remove a file that is in use + # causes an exception to be raised." + os.close(h) os.remove(caffemodel_file) # Test weight sharing diff --git a/python/caffe/test/test_solver.py b/python/caffe/test/test_solver.py index 50c9d5412d7..1867a47a01e 100644 --- a/python/caffe/test/test_solver.py +++ b/python/caffe/test/test_solver.py @@ -13,7 +13,10 @@ def setUp(self): self.num_output = 13 net_f = simple_net_file(self.num_output) f = tempfile.NamedTemporaryFile(mode='w+', delete=False) - f.write("""net: '""" + net_f + """' + net_f_mod = net_f + if os.name == 'nt': + net_f_mod = net_f_mod.replace("\\", "/") + f.write("""net: '""" + net_f_mod + """' test_iter: 10 test_interval: 10 base_lr: 0.01 momentum: 0.9 weight_decay: 0.0005 lr_policy: 'inv' gamma: 0.0001 power: 0.75 display: 100 max_iter: 100 snapshot_after_train: false diff --git a/python/requirements.txt b/python/requirements.txt index e7d89e67f48..ff581f48e7b 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -1,17 +1,5 @@ -Cython>=0.19.2 numpy>=1.7.1 scipy>=0.13.2 scikit-image>=0.9.3 -matplotlib>=1.3.1 -ipython>=3.0.0 -h5py>=2.2.0 -leveldb>=0.191 -networkx>=1.8.1 -nose>=1.3.0 -pandas>=0.12.0 -python-dateutil>=1.4,<2 protobuf>=2.5.0 -python-gflags>=2.0 -pyyaml>=3.10 -Pillow>=2.3.0 six>=1.1.0 \ No newline at end of file diff --git a/src/caffe/CMakeLists.txt b/src/caffe/CMakeLists.txt index dcec2263014..ce090ae0bfa 100644 --- a/src/caffe/CMakeLists.txt +++ b/src/caffe/CMakeLists.txt @@ -29,6 +29,16 @@ target_compile_definitions(caffe ${Caffe_DEFINITIONS}) if(Caffe_COMPILE_OPTIONS) target_compile_options(caffe ${Caffe_COMPILE_OPTIONS}) endif() + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" + OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") + target_link_options(caffe PUBLIC -Wl,-force_load $) +elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + target_link_options(caffe PUBLIC -Wl,--whole-archive $ -Wl,--no-whole-archive) +elseif(MSVC) + target_link_options(caffe PUBLIC /WHOLEARCHIVE:$) +endif() + set_target_properties(caffe PROPERTIES VERSION ${CAFFE_TARGET_VERSION} SOVERSION ${CAFFE_TARGET_SOVERSION} diff --git a/src/caffe/test/CMakeLists.txt b/src/caffe/test/CMakeLists.txt index d8afc30b76b..c3b08790873 100644 --- a/src/caffe/test/CMakeLists.txt +++ b/src/caffe/test/CMakeLists.txt @@ -27,7 +27,7 @@ endif() # ---[ Adding test target add_executable(${the_target} EXCLUDE_FROM_ALL ${test_srcs}) -target_link_libraries(${the_target} gtest ${Caffe_LINK}) +target_link_libraries(${the_target} PRIVATE gtest caffe) caffe_default_properties(${the_target}) caffe_set_runtime_directory(${the_target} "${PROJECT_BINARY_DIR}/test") diff --git a/src/caffe/util/db_lmdb.cpp b/src/caffe/util/db_lmdb.cpp index 491a9bd03a6..c9da49e1e4b 100644 --- a/src/caffe/util/db_lmdb.cpp +++ b/src/caffe/util/db_lmdb.cpp @@ -1,6 +1,11 @@ #ifdef USE_LMDB #include "caffe/util/db_lmdb.hpp" +#if defined(_MSC_VER) +#include +#define mkdir(X, Y) _mkdir(X) +#endif + #include #include diff --git a/src/caffe/util/io.cpp b/src/caffe/util/io.cpp index 5295d9dddb9..73983095e00 100644 --- a/src/caffe/util/io.cpp +++ b/src/caffe/util/io.cpp @@ -1,4 +1,9 @@ #include + +#if defined(_MSC_VER) +#include +#endif + #include #include #include @@ -50,7 +55,11 @@ void WriteProtoToTextFile(const Message& proto, const char* filename) { } bool ReadProtoFromBinaryFile(const char* filename, Message* proto) { +#if defined (_MSC_VER) // for MSC compiler binary flag needs to be specified + int fd = open(filename, O_RDONLY | O_BINARY); +#else int fd = open(filename, O_RDONLY); +#endif CHECK_NE(fd, -1) << "File not found: " << filename; ZeroCopyInputStream* raw_input = new FileInputStream(fd); CodedInputStream* coded_input = new CodedInputStream(raw_input); diff --git a/src/caffe/util/signal_handler.cpp b/src/caffe/util/signal_handler.cpp index 9658fb390ea..777d4162207 100644 --- a/src/caffe/util/signal_handler.cpp +++ b/src/caffe/util/signal_handler.cpp @@ -13,9 +13,15 @@ namespace { void handle_signal(int signal) { switch (signal) { +#ifdef _MSC_VER + case SIGBREAK: // there is no SIGHUP in windows, take SIGBREAK instead. + got_sighup = true; + break; +#else case SIGHUP: got_sighup = true; break; +#endif case SIGINT: got_sigint = true; break; @@ -27,7 +33,14 @@ namespace { LOG(FATAL) << "Tried to hookup signal handlers more than once."; } already_hooked_up = true; - +#ifdef _MSC_VER + if (signal(SIGBREAK, handle_signal) == SIG_ERR) { + LOG(FATAL) << "Cannot install SIGBREAK handler."; + } + if (signal(SIGINT, handle_signal) == SIG_ERR) { + LOG(FATAL) << "Cannot install SIGINT handler."; + } +#else struct sigaction sa; // Setup the handler sa.sa_handler = &handle_signal; @@ -42,11 +55,20 @@ namespace { if (sigaction(SIGINT, &sa, NULL) == -1) { LOG(FATAL) << "Cannot install SIGINT handler."; } +#endif } // Set the signal handlers to the default. void UnhookHandler() { if (already_hooked_up) { +#ifdef _MSC_VER + if (signal(SIGBREAK, SIG_DFL) == SIG_ERR) { + LOG(FATAL) << "Cannot uninstall SIGBREAK handler."; + } + if (signal(SIGINT, SIG_DFL) == SIG_ERR) { + LOG(FATAL) << "Cannot uninstall SIGINT handler."; + } +#else struct sigaction sa; // Setup the sighup handler sa.sa_handler = SIG_DFL; @@ -61,7 +83,7 @@ namespace { if (sigaction(SIGINT, &sa, NULL) == -1) { LOG(FATAL) << "Cannot uninstall SIGINT handler."; } - +#endif already_hooked_up = false; } }