Skip to content

Commit

Permalink
Better support for windows
Browse files Browse the repository at this point in the history
Summary:
Basically, this should make windows {static_lib, shared_lib} * {static_runtime, shared_runtime} * {cpu, gpu} work. A few highlights:

(1) Updated newest protobuf.
(2) use protoc dllexport command to ensure proper symbol export.
(3) various code updates to make sure that C2 symbols are properly shown
(4) cmake file changes to make build proper
(5) option to choose static runtime and shared runtime similar to protobuf
(6) revert to visual studio 2015 as current cuda and msvc 2017 do not play well together.
Closes facebookarchive/caffe2#1793

Reviewed By: dzhulgakov

Differential Revision: D6817719

Pulled By: Yangqing

fbshipit-source-id: d286264fccc72bf90a2fcd7da533ecca23ce557e
  • Loading branch information
Yangqing authored and facebook-github-bot committed Jan 26, 2018
1 parent 849b0a0 commit 8aa8eaa
Show file tree
Hide file tree
Showing 29 changed files with 256 additions and 138 deletions.
24 changes: 20 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ set(CAFFE2_VERSION
# ---[ Options.
# Note to developers: if you add an option below, make sure you also add it to
# cmake/Summary.cmake so that the summary prints out the option values.
include(CMakeDependentOption)
option(BUILD_BINARY "Build C++ binaries" ON)
option(BUILD_DOCS "Build documentation" OFF)
option(BUILD_PYTHON "Build Python binaries" ON)
option(BUILD_SHARED_LIBS "Build libcaffe2.so" ON)
cmake_dependent_option(
CAFFE2_USE_MSVC_STATIC_RUNTIME "Using MSVC static runtime libraries" ON
"NOT BUILD_SHARED_LIBS" OFF)
option(BUILD_OBSERVERS "Build performance observers/loggers in caffe2/share/observers directory" OFF)
option(BUILD_TEST "Build C++ test binaries (need gtest and gbenchmark)" ON)
option(USE_ATEN "Use ATen" OFF)
Expand Down Expand Up @@ -49,10 +53,13 @@ option(USE_ZMQ "Use ZMQ" OFF)
option(USE_ZSTD "Use ZSTD" OFF)
option(DEPRIORITIZE_ANACONDA "Search system include directories before Anaconda include directories" OFF)


# ---[ CMake scripts + modules
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Modules)

if (MSVC AND ${BUILD_SHARED_LIBS})
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()

# ---[ CMake build directories
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
Expand Down Expand Up @@ -101,10 +108,14 @@ else()
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if (NOT ${BUILD_SHARED_LIBS})
if (${CAFFE2_USE_MSVC_STATIC_RUNTIME})
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif(${flag_var} MATCHES "/MD")
else()
if(${flag_var} MATCHES "/MT")
string(REGEX REPLACE "/MT" "/MD" ${flag_var} "${${flag_var}}")
endif()
endif()
set(${flag_var} "${${flag_var}} /MP /bigobj")
endforeach(flag_var)
Expand Down Expand Up @@ -172,13 +183,13 @@ caffe2_print_configuration_summary()

# ---[ CMake related files
# Uninistall option.
if(NOT TARGET uninstall)
if(NOT TARGET caffe2_uninstall)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
IMMEDIATE @ONLY)

add_custom_target(uninstall
add_custom_target(caffe2_uninstall
COMMAND ${CMAKE_COMMAND} -P
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
Expand All @@ -200,6 +211,11 @@ if (USE_GFLAGS)
endif()
if (NOT CAFFE2_USE_CUSTOM_PROTOBUF)
list(APPEND CAFFE2_INTERFACE_LIBS ${PROTOBUF_LIBRARIES})
else()
# TODO(jiayq): this is not ideal, as during installation one will not
# have the libprotobuf target ready. It is here only so that we can
# make in-house cmake builds run (link) properly.
list(APPEND CAFFE2_INTERFACE_LIBS libprotobuf)
endif()

if ((NOT USE_GLOG) OR (NOT USE_GFLAGS) OR CAFFE2_USE_CUSTOM_PROTOBUF)
Expand Down
4 changes: 4 additions & 0 deletions caffe/proto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ file(GLOB Caffe_PROTOBUF_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.proto")
caffe2_protobuf_generate_cpp_py(Caffe_PROTO_SRCS Caffe_PROTO_HEADERS Caffe_PROTO_PY ${Caffe_PROTOBUF_FILES})

add_library(Caffe_PROTO OBJECT ${Caffe_PROTO_HEADERS} ${Caffe_PROTO_SRCS})
if (MSVC)
target_compile_definitions(
Caffe_PROTO PRIVATE "-DCAFFE2_API=__declspec(dllexport)")
endif()
install(FILES ${Caffe_PROTO_HEADERS} DESTINATION include/caffe/proto)
2 changes: 1 addition & 1 deletion caffe2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ add_library(caffe2 ${Caffe2_CPU_SRCS} $<TARGET_OBJECTS:Caffe_PROTO> $<TARGET_OBJ
target_link_libraries(caffe2 PRIVATE ${Caffe2_DEPENDENCY_LIBS})
target_include_directories(caffe2 INTERFACE $<INSTALL_INTERFACE:include>)
target_compile_options(caffe2 INTERFACE "-std=c++11")
target_compile_options(caffe2 PRIVATE "-DCAFFE2_BUILD_MAIN_LIB")
install(TARGETS caffe2 EXPORT Caffe2Targets DESTINATION lib)
caffe_add_linker_flag(caffe2 Caffe2_CPU_LINK)
list(APPEND Caffe2_MAIN_LIBS_ORDER caffe2 Caffe2_PROTO)
Expand Down Expand Up @@ -130,7 +131,6 @@ if(USE_CUDA)
set(CUDA_LIBRARIES ${__tmp})
target_include_directories(
caffe2_gpu INTERFACE $<INSTALL_INTERFACE:include>)
target_compile_options(caffe2 INTERFACE "-std=c++11")
list(APPEND Caffe2_MAIN_LIBS_ORDER caffe2_gpu)
add_dependencies(caffe2_gpu Caffe2_PROTO)
if (BUILD_SHARED_LIBS)
Expand Down
2 changes: 0 additions & 2 deletions caffe2/core/allocator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ void SetCPUAllocator(CPUAllocator* alloc) {
g_cpu_allocator.reset(alloc);
}

MemoryAllocationReporter CPUContext::reporter_;

void MemoryAllocationReporter::New(void* ptr, size_t nbytes) {
std::lock_guard<std::mutex> guard(mutex_);
size_table_[ptr] = nbytes;
Expand Down
38 changes: 33 additions & 5 deletions caffe2/core/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,42 @@ private: \
#endif
#endif

#if defined(__GNUC__)
#if __GNUC_PREREQ(4, 9)
#define CAFFE2_EXPORT [[gnu::visibility("default")]]
// Defines CAFFE2_EXPORT and CAFFE2_IMPORT. On Windows, this corresponds to
// different declarations (dllexport and dllimport). On Linux/Mac, it just
// resolves to the same "default visibility" setting.
#if defined(_MSC_VER)
#if defined(CAFFE2_BUILD_SHARED_LIBS)
#define CAFFE2_EXPORT __declspec(dllexport)
#define CAFFE2_IMPORT __declspec(dllimport)
#else
#define CAFFE2_EXPORT
#define CAFFE2_IMPORT
#endif
#else
#define CAFFE2_EXPORT __attribute__((__visibility__("default")))
#if defined(__GNUC__)
#if __GNUC_PREREQ(4, 9)
#define CAFFE2_EXPORT [[gnu::visibility("default")]]
#else
#define CAFFE2_EXPORT __attribute__((__visibility__("default")))
#endif
#else
#define CAFFE2_EXPORT
#endif
#define CAFFE2_IMPORT CAFFE2_EXPORT
#endif

// CAFFE2_API is a macro that, depends on whether you are building the
// main caffe2 library or not, resolves to either CAFFE2_EXPORT or
// CAFFE2_IMPORT.
//
// This is used in e.g. Caffe2's protobuf files: when building the main library,
// it is defined as CAFFE2_EXPORT to fix a Windows global-variable-in-dll
// issue, and for anyone dependent on Caffe2 it will be defined as CAFFE2_IMPORT.

#ifdef CAFFE2_BUILD_MAIN_LIB
#define CAFFE2_API CAFFE2_EXPORT
#else
#define CAFFE2_EXPORT
#define CAFFE2_API CAFFE2_IMPORT
#endif

// make_unique is a C++14 feature. If we don't have 14, we will emulate
Expand Down
5 changes: 5 additions & 0 deletions caffe2/core/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@

namespace caffe2 {

MemoryAllocationReporter& CPUContext::reporter() {
static MemoryAllocationReporter static_reporter;
return static_reporter;
}

uint32_t RandomNumberSeed() {
// Originally copied from folly::randomNumberSeed (at 418ad4)
// modified to use chrono instead of sys/time.h
Expand Down
6 changes: 3 additions & 3 deletions caffe2/core/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class CPUContext final {
static std::pair<void*, MemoryDeleter> New(size_t nbytes) {
auto data_and_deleter = GetCPUAllocator()->New(nbytes);
if (FLAGS_caffe2_report_cpu_memory_usage) {
reporter_.New(data_and_deleter.first, nbytes);
reporter().New(data_and_deleter.first, nbytes);
data_and_deleter.second = ReportAndDelete;
}
return data_and_deleter;
Expand Down Expand Up @@ -171,11 +171,11 @@ class CPUContext final {
// TODO(jiayq): instead of hard-coding a generator, make it more flexible.
int random_seed_{1701};
std::unique_ptr<rand_gen_type> random_generator_;
static MemoryAllocationReporter reporter_;
static MemoryAllocationReporter& reporter();

private:
static void ReportAndDelete(void* ptr) {
reporter_.Delete(ptr);
reporter().Delete(ptr);
GetCPUAllocator()->GetDeleter()(ptr);
}
};
Expand Down
2 changes: 1 addition & 1 deletion caffe2/core/context_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class CUDAContext final {

~CUDAContext() {
if (curand_generator_) {
CURAND_ENFORCE(curandDestroyGenerator(curand_generator_));
CURAND_CHECK(curandDestroyGenerator(curand_generator_));
}
FinishDeviceComputation();
}
Expand Down
2 changes: 1 addition & 1 deletion caffe2/core/context_gpu_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
#include <thread>
#include <array>

#include "caffe2/proto/caffe2.pb.h"
#include "caffe2/core/context_gpu.h"
#include "caffe2/proto/caffe2.pb.h"
#include <gtest/gtest.h>

CAFFE2_DECLARE_bool(caffe2_cuda_full_device_control);
Expand Down
3 changes: 2 additions & 1 deletion caffe2/core/context_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@

#include <random>

#include "caffe2/proto/caffe2.pb.h"
#include "caffe2/core/common.h"
#include "caffe2/core/context.h"
#include "caffe2/proto/caffe2.pb.h"
#include <gtest/gtest.h>

namespace caffe2 {
Expand Down
41 changes: 32 additions & 9 deletions caffe2/core/event.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,38 @@

namespace caffe2 {

EventCreateFunction Event::event_creator_[MaxDeviceTypes];
EventRecordFunction Event::event_recorder_[MaxDeviceTypes];
EventWaitFunction Event::event_waiter_[MaxDeviceTypes][MaxDeviceTypes];
EventFinishFunction Event::event_finisher_[MaxDeviceTypes];

EventQueryFunction Event::event_querier_[MaxDeviceTypes];
EventErrorMessageFunction Event::event_err_msg_getter_[MaxDeviceTypes];
EventSetFinishedFunction Event::event_finished_setter_[MaxDeviceTypes];
EventResetFunction Event::event_resetter_[MaxDeviceTypes];
EventCreateFunction* Event::event_creator() {
static EventCreateFunction event_creator_[MaxDeviceTypes];
return event_creator_;
}
EventRecordFunction* Event::event_recorder() {
static EventRecordFunction event_recorder_[MaxDeviceTypes];
return event_recorder_;
}
Event::EWFMatrix Event::event_waiter() {
static EventWaitFunction event_waiter_[MaxDeviceTypes][MaxDeviceTypes];
return event_waiter_;
}
EventFinishFunction* Event::event_finisher() {
static EventFinishFunction event_finisher_[MaxDeviceTypes];
return event_finisher_;
}
EventQueryFunction* Event::event_querier() {
static EventQueryFunction event_querier_[MaxDeviceTypes];
return event_querier_;
}
EventErrorMessageFunction* Event::event_err_msg_getter() {
static EventErrorMessageFunction event_err_msg_getter_[MaxDeviceTypes];
return event_err_msg_getter_;
}
EventSetFinishedFunction* Event::event_finished_setter() {
static EventSetFinishedFunction event_finished_setter_[MaxDeviceTypes];
return event_finished_setter_;
}
EventResetFunction* Event::event_resetter() {
static EventResetFunction event_resetter_[MaxDeviceTypes];
return event_resetter_;
}

namespace {
const std::string kNoError = "No error";
Expand Down
Loading

0 comments on commit 8aa8eaa

Please sign in to comment.