Caffe2 - C++ API
A deep learning, cross platform ML framework
common.h
1 #ifndef CAFFE2_CORE_COMMON_H_
2 #define CAFFE2_CORE_COMMON_H_
3 
4 #include <algorithm>
5 #include <map>
6 #include <memory>
7 #include <numeric>
8 #include <set>
9 #include <sstream>
10 #include <string>
11 #include <type_traits>
12 #include <vector>
13 
14 #ifdef __APPLE__
15 #include <TargetConditionals.h>
16 #endif
17 
18 #if defined(_MSC_VER)
19 #include <io.h>
20 #else
21 #include <unistd.h>
22 #endif
23 
24 // Macros used during the build of this caffe2 instance. This header file
25 // is automatically generated by the cmake script during build.
26 #include "caffe2/core/macros.h"
27 
28 // Caffe2 version. The plan is to increment the minor version every other week
29 // as a track point for bugs, until we find a proper versioning cycle.
30 
31 #define CAFFE2_VERSION_MAJOR 0
32 #define CAFFE2_VERSION_MINOR 6
33 #define CAFFE2_VERSION_PATCH 0
34 #define CAFFE2_VERSION \
35  (CAFFE2_VERSION_MAJOR * 10000 + CAFFE2_VERSION_MINOR * 100 + \
36  CAFFE2_VERSION_PATCH)
37 
38 namespace caffe2 {
39 
40 // Data type for caffe2 Index/Size. We use size_t to be safe here as well as for
41 // large matrices that are common in sparse math.
42 typedef int64_t TIndex;
43 
44 // Note(Yangqing): NVCC does not play well with unordered_map on some platforms,
45 // forcing us to use std::map instead of unordered_map. This may affect speed
46 // in some cases, but in most of the computation code we do not access map very
47 // often, so it should be fine for us. I am putting a CaffeMap alias so we can
48 // change it more easily if things work out for unordered_map down the road.
49 template <typename Key, typename Value>
50 using CaffeMap = std::map<Key, Value>;
51 // using CaffeMap = std::unordered_map;
52 
53 // Using statements for common classes that we refer to in caffe2 very often.
54 // Note that we only place it inside caffe2 so the global namespace is not
55 // polluted.
56 /* using override */
57 using std::set;
58 using std::string;
59 using std::unique_ptr;
60 using std::vector;
61 
62 // Just in order to mark things as not implemented. Do not use in final code.
63 #define CAFFE_NOT_IMPLEMENTED CAFFE_THROW("Not Implemented.")
64 
65 // suppress an unused variable.
66 #define UNUSED_VARIABLE __attribute__((unused))
67 
68 // Disable the copy and assignment operator for a class. Note that this will
69 // disable the usage of the class in std containers.
70 #ifndef DISABLE_COPY_AND_ASSIGN
71 #define DISABLE_COPY_AND_ASSIGN(classname) \
72 private: \
73  classname(const classname&) = delete; \
74  classname& operator=(const classname&) = delete
75 #endif
76 
77 // Define enabled when building for iOS or Android devices
78 #if !defined(CAFFE2_MOBILE)
79 #if defined(__ANDROID__)
80 #define CAFFE2_ANDROID 1
81 #define CAFFE2_MOBILE 1
82 #elif (defined(__APPLE__) && \
83  (TARGET_IPHONE_SIMULATOR || TARGET_OS_SIMULATOR || TARGET_OS_IPHONE))
84 #define CAFFE2_IOS 1
85 #define CAFFE2_MOBILE 1
86 #elif (defined(__APPLE__) && TARGET_OS_MAC)
87 #define CAFFE2_IOS 1
88 #define CAFFE2_MOBILE 0
89 #else
90 #define CAFFE2_MOBILE 0
91 #endif // ANDROID / IOS / MACOS
92 #endif // CAFFE2_MOBILE
93 
94 // Define alignment macro that is cross platform
95 #if defined(_MSC_VER)
96 #define CAFFE2_ALIGNED(x) __declspec(align(x))
97 #else
98 #define CAFFE2_ALIGNED(x) __attribute__((aligned(x)))
99 #endif
100 
105 #ifndef __GNUC_PREREQ
106 #if defined __GNUC__ && defined __GNUC_MINOR__
107 #define __GNUC_PREREQ(maj, min) \
108  ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
109 #else
110 #define __GNUC_PREREQ(maj, min) 0
111 #endif
112 #endif
113 
114 #if defined(__GNUC__)
115 #if __GNUC_PREREQ(4, 9)
116 #define CAFFE2_EXPORT [[gnu::visibility("default")]]
117 #else
118 #define CAFFE2_EXPORT __attribute__((__visibility__("default")))
119 #endif
120 #else
121 #define CAFFE2_EXPORT
122 #endif
123 
124 // make_unique is a C++14 feature. If we don't have 14, we will emulate
125 // its behavior. This is copied from folly/Memory.h
126 #if __cplusplus >= 201402L || \
127  (defined __cpp_lib_make_unique && __cpp_lib_make_unique >= 201304L) || \
128  (defined(_MSC_VER) && _MSC_VER >= 1900)
129 /* using override */ using std::make_unique;
130 #else
131 
132 template<typename T, typename... Args>
133 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
134 make_unique(Args&&... args) {
135  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
136 }
137 
138 // Allows 'make_unique<T[]>(10)'. (N3690 s20.9.1.4 p3-4)
139 template<typename T>
140 typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
141 make_unique(const size_t n) {
142  return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
143 }
144 
145 // Disallows 'make_unique<T[10]>()'. (N3690 s20.9.1.4 p5)
146 template<typename T, typename... Args>
147 typename std::enable_if<
148  std::extent<T>::value != 0, std::unique_ptr<T>>::type
149 make_unique(Args&&...) = delete;
150 
151 #endif
152 
153 // to_string implementation for Android related stuff.
154 #ifndef __ANDROID__
155 using std::to_string;
156 #else
157 template <typename T>
158 std::string to_string(T value)
159 {
160  std::ostringstream os;
161  os << value;
162  return os.str();
163 }
164 #endif
165 
166 // dynamic cast reroute: if RTTI is disabled, go to reinterpret_cast
167 template <typename Dst, typename Src>
168 inline Dst dynamic_cast_if_rtti(Src ptr) {
169 #ifdef __GXX_RTTI
170  return dynamic_cast<Dst>(ptr);
171 #else
172  return reinterpret_cast<Dst>(ptr);
173 #endif
174 }
175 
176 // SkipIndices are used in operator_fallback_gpu.h and operator_fallback_mkl.h
177 // as utilty functions that marks input / output indices to skip when we use a
178 // CPU operator as the fallback of GPU/MKL operator option.
179 template <int... values>
180 class SkipIndices {
181  private:
182  template <int V>
183  static inline bool ContainsInternal(const int i) {
184  return (i == V);
185  }
186  template <int First, int Second, int... Rest>
187  static inline bool ContainsInternal(const int i) {
188  return (i == First) && ContainsInternal<Second, Rest...>(i);
189  }
190 
191  public:
192  static inline bool Contains(const int i) {
193  return ContainsInternal<values...>(i);
194  }
195 };
196 
197 template <>
198 class SkipIndices<> {
199  public:
200  static inline bool Contains(const int i) {
201  return false;
202  }
203 };
204 
205 } // namespace caffe2
206 
207 #endif // CAFFE2_CORE_COMMON_H_
Simple registry implementation in Caffe2 that uses static variables to register object creators durin...