Skip to content

Commit

Permalink
build changes to make cpu unified build working. (pytorch#10504)
Browse files Browse the repository at this point in the history
Summary:
Properly annotated all apis for cpu front. Checked with cmake using

cmake -DUSE_ATEN=ON -DUSE_CUDA=OFF -DBUILD_ATEN=ON

and resulting libcaffe2.so has about 11k symbols.
Pull Request resolved: pytorch#10504

Reviewed By: ezyang

Differential Revision: D9316491

Pulled By: Yangqing

fbshipit-source-id: 215659abf350af7032e9a4b0f28a856babab2454
  • Loading branch information
Yangqing authored and facebook-github-bot committed Aug 16, 2018
1 parent 87cac4c commit 0a809fc
Show file tree
Hide file tree
Showing 45 changed files with 253 additions and 205 deletions.
13 changes: 4 additions & 9 deletions aten/src/ATen/ATenGeneral.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
#pragma once

#ifdef _WIN32
# if defined(ATen_cpu_EXPORTS) || defined(caffe2_EXPORTS)
# define AT_API __declspec(dllexport)
# else
# define AT_API __declspec(dllimport)
# endif
#else
# define AT_API
#endif
#include "ATen/core/Macros.h"

// TODO: Merge the *_API macros.
#define AT_API AT_CORE_API
19 changes: 11 additions & 8 deletions aten/src/ATen/core/Macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@

#ifdef _WIN32
#if !defined(AT_CORE_STATIC_WINDOWS)
#if defined(ATen_cpu_EXPORTS) || defined(caffe2_EXPORTS)
// TODO: unfiy the controlling macros.
#if defined(CAFFE2_BUILD_MAIN_LIBS) || defined(ATen_cpu_EXPORTS) || defined(caffe2_EXPORTS)
#define AT_CORE_API __declspec(dllexport)
#else
#else // defined(CAFFE2_BUILD_MAIN_LIBS) || defined(ATen_cpu_EXPORTS) || defined(caffe2_EXPORTS)
#define AT_CORE_API __declspec(dllimport)
#endif
#else
#endif // defined(CAFFE2_BUILD_MAIN_LIBS) || defined(ATen_cpu_EXPORTS) || defined(caffe2_EXPORTS)
#else // !defined(AT_CORE_STATIC_WINDOWS)
#define AT_CORE_API
#endif
#else
#define AT_CORE_API
#endif
#endif // !defined(AT_CORE_STATIC_WINDOWS)
#else // _WIN32
#if defined(__GNUC__)
#define AT_CORE_API __attribute__((__visibility__("default")))
#endif // defined(__GNUC__)
#endif // _WIN32

// Disable the copy and assignment operator for a class. Note that this will
// disable the usage of the class in std containers.
Expand Down
27 changes: 15 additions & 12 deletions aten/src/ATen/core/typeid.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class TypeMeta;
* use TypeIdentifier with custom types. This is for example used to store the
* dtype of tensors.
*/
class TypeIdentifier final : public at::IdWrapper<TypeIdentifier, uint16_t> {
class AT_CORE_API TypeIdentifier final : public at::IdWrapper<TypeIdentifier, uint16_t> {
public:
static TypeIdentifier createTypeId();

Expand Down Expand Up @@ -82,14 +82,14 @@ inline std::ostream& operator<<(

namespace caffe2 {

std::unordered_map<TypeIdentifier, std::string>& gTypeNames();
std::unordered_set<std::string>& gRegisteredTypeNames();
AT_CORE_API std::unordered_map<TypeIdentifier, std::string>& gTypeNames();
AT_CORE_API std::unordered_set<std::string>& gRegisteredTypeNames();

// A utility function to return an exception std::string by prepending its
// exception type before its what() content.
std::string GetExceptionString(const std::exception& e);
// exception type before its what() content
AT_CORE_API std::string GetExceptionString(const std::exception& e);

std::mutex& gTypeRegistrationMutex();
AT_CORE_API std::mutex& gTypeRegistrationMutex();

template <typename T>
struct TypeNameRegisterer {
Expand Down Expand Up @@ -136,7 +136,7 @@ struct TypeNameRegisterer {
* stores some additional data such as the item size and the name of the type
* for run-time inspection.
*/
class TypeMeta {
class AT_CORE_API TypeMeta {
public:
using PlacementNew = void(void*, size_t);
using TypedCopy = void(const void*, void*, size_t);
Expand Down Expand Up @@ -399,7 +399,10 @@ inline bool operator!=(const TypeMeta& lhs, const TypeMeta& rhs) noexcept {
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0537r0.html
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51930
// and as a result, we define these two macros slightly differently.

// TODO(jiayq): AT_CORE_API below is not correct, because we may use the
// definition in third party dependent libraries. The proper way is to use
// CAFFE2_EXPORT (which explicitly requires dllexport). Marking this as a
// todo item when the unified build is finished.
#ifdef _MSC_VER
#define CAFFE_KNOWN_TYPE(T) \
template <> \
Expand All @@ -425,10 +428,10 @@ inline bool operator!=(const TypeMeta& lhs, const TypeMeta& rhs) noexcept {
* for your own types to allocate dynamic ids for them.
*/
#ifdef _MSC_VER
#define CAFFE_DECLARE_KNOWN_TYPE(PreallocatedId, T) \
template <> \
inline AT_CORE_API TypeIdentifier TypeMeta::Id<T>() { \
return TypeIdentifier(PreallocatedId); \
#define CAFFE_DECLARE_KNOWN_TYPE(PreallocatedId, T) \
template <> \
inline AT_CORE_API TypeIdentifier TypeMeta::Id<T>() { \
return TypeIdentifier(PreallocatedId); \
}
#else // _MSC_VER
#define CAFFE_DECLARE_KNOWN_TYPE(PreallocatedId, T) \
Expand Down
31 changes: 20 additions & 11 deletions aten/src/TH/THGeneral.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,27 @@
# define TH_EXTERNC extern
#endif

// Note(jiayq): copied from ATen/core/Macros.h. Because internal build of TH
// and ATen are not unified yet, we need to duplicate code for now. Long term
// we should merge macros.
#ifdef _WIN32
# if defined(ATen_cpu_EXPORTS) || defined(caffe2_EXPORTS)
# define TH_API TH_EXTERNC __declspec(dllexport)
# define TH_CPP_API __declspec(dllexport)
# else
# define TH_API TH_EXTERNC __declspec(dllimport)
# define TH_CPP_API __declspec(dllimport)
# endif
#else
# define TH_API TH_EXTERNC
# define TH_CPP_API
#endif
#if !defined(AT_CORE_STATIC_WINDOWS)
// TODO: unfiy the controlling macros.
#if defined(CAFFE2_BUILD_MAIN_LIBS) || defined(ATen_cpu_EXPORTS) || defined(caffe2_EXPORTS)
#define TH_CPP_API __declspec(dllexport)
#else // defined(CAFFE2_BUILD_MAIN_LIBS) || defined(ATen_cpu_EXPORTS) || defined(caffe2_EXPORTS)
#define TH_CPP_API __declspec(dllimport)
#endif // defined(CAFFE2_BUILD_MAIN_LIBS) || defined(ATen_cpu_EXPORTS) || defined(caffe2_EXPORTS)
#else // !defined(AT_CORE_STATIC_WINDOWS)
#define TH_CPP_API
#endif // !defined(AT_CORE_STATIC_WINDOWS)
#else // _WIN32
#if defined(__GNUC__)
#define TH_CPP_API __attribute__((__visibility__("default")))
#endif // defined(__GNUC__)
#endif // _WIN32

#define TH_API TH_EXTERNC TH_CPP_API

#ifdef _WIN32
# define TH_NO_RETURN __declspec(noreturn)
Expand Down
7 changes: 7 additions & 0 deletions caffe2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,13 @@ else()
target_compile_options(caffe2 INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-std=c++11>")
endif()

# Note(jiayq): This is not complete yet, but in the end we will need to deal with
# explicit hidden visibility.
# This line is here so that when testing build, we can enable it to properly test
# annotation of public symbols. When finally doing proper build with all symbols
# annotated, we will enable this line and have it wrapped with gcc/clang checks.
# target_compile_options(caffe2 PRIVATE "-fvisibility=hidden")

target_compile_options(caffe2 PRIVATE "-DCAFFE2_BUILD_MAIN_LIB")
if (MSVC AND NOT BUILD_SHARED_LIBS)
# Note [Supporting both static and dynamic libraries on Window]
Expand Down
4 changes: 2 additions & 2 deletions caffe2/contrib/gloo/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace caffe2 {
namespace gloo {

void signalFailure(Blob* status_blob, std::exception& exception);
CAFFE2_API void signalFailure(Blob* status_blob, std::exception& exception);

struct createDeviceAttr {
// "tcp" or "ibverbs"
Expand All @@ -22,7 +22,7 @@ struct createDeviceAttr {
std::string interface;
};

std::shared_ptr<::gloo::transport::Device> createDevice(
CAFFE2_API std::shared_ptr<::gloo::transport::Device> createDevice(
const createDeviceAttr attr);

// Captures the parameters passed to Gloo.
Expand Down
3 changes: 2 additions & 1 deletion caffe2/contrib/gloo/store_handler.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#pragma once

#include "caffe2/core/common.h"
#include "caffe2/distributed/store_handler.h"

#include <gloo/rendezvous/store.h>

namespace caffe2 {
namespace gloo {

class StoreHandlerWrapper : public ::gloo::rendezvous::Store {
class CAFFE2_API StoreHandlerWrapper : public ::gloo::rendezvous::Store {
public:
explicit StoreHandlerWrapper(StoreHandler& handler) : handler_(handler) {}

Expand Down
12 changes: 6 additions & 6 deletions caffe2/core/allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ constexpr size_t gCaffe2Alignment = 32;
using MemoryDeleter = void (*)(void*);

// A helper function that is basically doing nothing.
void NoDelete(void*);
CAFFE2_API void NoDelete(void*);

// A virtual allocator class to do memory allocation and deallocation.
struct CPUAllocator {
struct CAFFE2_API CPUAllocator {
CPUAllocator() {}
virtual ~CPUAllocator() noexcept {}
virtual std::pair<void*, MemoryDeleter> New(size_t nbytes) = 0;
Expand All @@ -29,7 +29,7 @@ struct CPUAllocator {

// A virtual struct that is used to report Caffe2's memory allocation and
// deallocation status
class MemoryAllocationReporter {
class CAFFE2_API MemoryAllocationReporter {
public:
MemoryAllocationReporter() : allocated_(0) {}
void New(void* ptr, size_t nbytes);
Expand All @@ -41,7 +41,7 @@ class MemoryAllocationReporter {
size_t allocated_;
};

struct DefaultCPUAllocator final : CPUAllocator {
struct CAFFE2_API DefaultCPUAllocator final : CPUAllocator {
DefaultCPUAllocator() {}
~DefaultCPUAllocator() override {}
std::pair<void*, MemoryDeleter> New(size_t nbytes) override {
Expand Down Expand Up @@ -78,10 +78,10 @@ struct DefaultCPUAllocator final : CPUAllocator {
};

// Get the CPU Alloctor.
CPUAllocator* GetCPUAllocator();
CAFFE2_API CPUAllocator* GetCPUAllocator();
// Sets the CPU allocator to the given allocator: the caller gives away the
// ownership of the pointer.
void SetCPUAllocator(CPUAllocator* alloc);
CAFFE2_API void SetCPUAllocator(CPUAllocator* alloc);

} // namespace caffe2

Expand Down
2 changes: 1 addition & 1 deletion caffe2/core/blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace caffe2 {
* properly when the blob is deallocated or re-allocated with a new type. A blob
* could contain anything, although the most common case is to contain a Tensor.
*/
class Blob {
class CAFFE2_API Blob {
public:
typedef void (*DestroyCall)(void*);

Expand Down
36 changes: 2 additions & 34 deletions caffe2/core/blob_serialization.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,13 @@ constexpr auto kTensorBlobType = "Tensor";
// String used to separate chunk id from the blob name when storing in DB
constexpr auto kChunkIdSeparator = "#%";

// The Blob serialization registry and serializer creator functions.
CAFFE_DECLARE_TYPED_REGISTRY(
BlobSerializerRegistry,
TypeIdentifier,
BlobSerializerBase,
std::unique_ptr);
#define REGISTER_BLOB_SERIALIZER(id, ...) \
CAFFE_REGISTER_TYPED_CLASS(BlobSerializerRegistry, id, __VA_ARGS__)
// Creates an operator with the given operator definition.
inline unique_ptr<BlobSerializerBase> CreateSerializer(TypeIdentifier id) {
return BlobSerializerRegistry()->Create(id);
}

/**
* @brief TensorSerializer is the serializer for Tensors.
*
* TensorSerializer takes in a blob that contains a Tensor, and serializes it
* into a TensorProto protocol buffer.
*/
class TensorSerializer : public BlobSerializerBase {
class CAFFE2_API TensorSerializer : public BlobSerializerBase {
public:
TensorSerializer() {}
~TensorSerializer() override {}
Expand Down Expand Up @@ -73,25 +60,6 @@ class TensorSerializer : public BlobSerializerBase {
unique_ptr<BaseContext> context_;
};

/**
* @brief BlobDeserializerBase is an abstract class that deserializes a blob
* from a BlobProto or a TensorProto.
*/
class BlobDeserializerBase {
public:
virtual ~BlobDeserializerBase() {}

// Deserializes from a BlobProto object.
virtual void Deserialize(const BlobProto& proto, Blob* blob) = 0;
};

CAFFE_DECLARE_REGISTRY(BlobDeserializerRegistry, BlobDeserializerBase);
#define REGISTER_BLOB_DESERIALIZER(name, ...) \
CAFFE_REGISTER_CLASS(BlobDeserializerRegistry, name, __VA_ARGS__)
// Creates an operator with the given operator definition.
inline unique_ptr<BlobDeserializerBase> CreateDeserializer(const string& type) {
return BlobDeserializerRegistry()->Create(type);
}

/**
* @brief TensorDeserializer is the deserializer for Tensors.
Expand All @@ -101,7 +69,7 @@ inline unique_ptr<BlobDeserializerBase> CreateDeserializer(const string& type) {
* tensor, change the TensorProto's corresponding fields before calling
* Deserialize.
*/
class TensorDeserializer : public BlobDeserializerBase {
class CAFFE2_API TensorDeserializer : public BlobDeserializerBase {
public:
void Deserialize(const BlobProto& proto, Blob* blob) override;
void Deserialize(const TensorProto& proto, Tensor* tensor);
Expand Down
39 changes: 39 additions & 0 deletions caffe2/core/blob_serializer_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
#include <string>
#include <functional>

#include "caffe2/core/common.h"
#include "caffe2/core/registry.h"
#include "caffe2/proto/caffe2.pb.h"

namespace caffe2 {

class Blob;
Expand Down Expand Up @@ -52,4 +56,39 @@ class BlobSerializerBase {
}
};

// The Blob serialization registry and serializer creator functions.
CAFFE_DECLARE_TYPED_REGISTRY(
BlobSerializerRegistry,
TypeIdentifier,
BlobSerializerBase,
std::unique_ptr);
#define REGISTER_BLOB_SERIALIZER(id, ...) \
CAFFE_REGISTER_TYPED_CLASS(BlobSerializerRegistry, id, __VA_ARGS__)
// Creates an operator with the given operator definition.
inline unique_ptr<BlobSerializerBase> CreateSerializer(TypeIdentifier id) {
return BlobSerializerRegistry()->Create(id);
}


/**
* @brief BlobDeserializerBase is an abstract class that deserializes a blob
* from a BlobProto or a TensorProto.
*/
class CAFFE2_API BlobDeserializerBase {
public:
virtual ~BlobDeserializerBase() {}

// Deserializes from a BlobProto object.
virtual void Deserialize(const BlobProto& proto, Blob* blob) = 0;
};

CAFFE_DECLARE_REGISTRY(BlobDeserializerRegistry, BlobDeserializerBase);
#define REGISTER_BLOB_DESERIALIZER(name, ...) \
CAFFE_REGISTER_CLASS(BlobDeserializerRegistry, name, __VA_ARGS__)
// Creates an operator with the given operator definition.
inline unique_ptr<BlobDeserializerBase> CreateDeserializer(const string& type) {
return BlobDeserializerRegistry()->Create(type);
}


} // namespace caffe2
Loading

0 comments on commit 0a809fc

Please sign in to comment.