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 namespace caffe2 {
29 
30 // Data type for caffe2 Index/Size. We use size_t to be safe here as well as for
31 // large matrices that are common in sparse math.
32 typedef int64_t TIndex;
33 
34 // Note(Yangqing): NVCC does not play well with unordered_map on some platforms,
35 // forcing us to use std::map instead of unordered_map. This may affect speed
36 // in some cases, but in most of the computation code we do not access map very
37 // often, so it should be fine for us. I am putting a CaffeMap alias so we can
38 // change it more easily if things work out for unordered_map down the road.
39 template <typename Key, typename Value>
40 using CaffeMap = std::map<Key, Value>;
41 // using CaffeMap = std::unordered_map;
42 
43 // Using statements for common classes that we refer to in caffe2 very often.
44 // Note that we only place it inside caffe2 so the global namespace is not
45 // polluted.
46 /* using override */
47 using std::set;
48 using std::string;
49 using std::unique_ptr;
50 using std::vector;
51 
52 // Just in order to mark things as not implemented. Do not use in final code.
53 #define CAFFE_NOT_IMPLEMENTED CAFFE_THROW("Not Implemented.")
54 
55 // suppress an unused variable.
56 #ifdef _MSC_VER
57 #define CAFFE2_UNUSED
58 #define CAFFE2_USED
59 #else
60 #define CAFFE2_UNUSED __attribute__((__unused__))
61 #define CAFFE2_USED __attribute__((__used__))
62 #endif //_MSC_VER
63 
64 // Disable the copy and assignment operator for a class. Note that this will
65 // disable the usage of the class in std containers.
66 #ifndef DISABLE_COPY_AND_ASSIGN
67 #define DISABLE_COPY_AND_ASSIGN(classname) \
68 private: \
69  classname(const classname&) = delete; \
70  classname& operator=(const classname&) = delete
71 #endif
72 
73 // Define enabled when building for iOS or Android devices
74 #if !defined(CAFFE2_MOBILE)
75 #if defined(__ANDROID__)
76 #define CAFFE2_ANDROID 1
77 #define CAFFE2_MOBILE 1
78 #elif (defined(__APPLE__) && \
79  (TARGET_IPHONE_SIMULATOR || TARGET_OS_SIMULATOR || TARGET_OS_IPHONE))
80 #define CAFFE2_IOS 1
81 #define CAFFE2_MOBILE 1
82 #elif (defined(__APPLE__) && TARGET_OS_MAC)
83 #define CAFFE2_IOS 1
84 #define CAFFE2_MOBILE 0
85 #else
86 #define CAFFE2_MOBILE 0
87 #endif // ANDROID / IOS / MACOS
88 #endif // CAFFE2_MOBILE
89 
90 // Define alignment macro that is cross platform
91 #if defined(_MSC_VER)
92 #define CAFFE2_ALIGNED(x) __declspec(align(x))
93 #else
94 #define CAFFE2_ALIGNED(x) __attribute__((aligned(x)))
95 #endif
96 
101 #ifndef __GNUC_PREREQ
102 #if defined __GNUC__ && defined __GNUC_MINOR__
103 #define __GNUC_PREREQ(maj, min) \
104  ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
105 #else
106 #define __GNUC_PREREQ(maj, min) 0
107 #endif
108 #endif
109 
110 // Defines CAFFE2_EXPORT and CAFFE2_IMPORT. On Windows, this corresponds to
111 // different declarations (dllexport and dllimport). On Linux/Mac, it just
112 // resolves to the same "default visibility" setting.
113 #if defined(_MSC_VER)
114 #if defined(CAFFE2_BUILD_SHARED_LIBS)
115 #define CAFFE2_EXPORT __declspec(dllexport)
116 #define CAFFE2_IMPORT __declspec(dllimport)
117 #else
118 #define CAFFE2_EXPORT
119 #define CAFFE2_IMPORT
120 #endif
121 #else
122 #if defined(__GNUC__)
123 #if __GNUC_PREREQ(4, 9)
124 #define CAFFE2_EXPORT [[gnu::visibility("default")]]
125 #else
126 #define CAFFE2_EXPORT __attribute__((__visibility__("default")))
127 #endif
128 #else
129 #define CAFFE2_EXPORT
130 #endif
131 #define CAFFE2_IMPORT CAFFE2_EXPORT
132 #endif
133 
134 // CAFFE2_API is a macro that, depends on whether you are building the
135 // main caffe2 library or not, resolves to either CAFFE2_EXPORT or
136 // CAFFE2_IMPORT.
137 //
138 // This is used in e.g. Caffe2's protobuf files: when building the main library,
139 // it is defined as CAFFE2_EXPORT to fix a Windows global-variable-in-dll
140 // issue, and for anyone dependent on Caffe2 it will be defined as
141 // CAFFE2_IMPORT.
142 
143 #ifdef CAFFE2_BUILD_MAIN_LIB
144 #define CAFFE2_API CAFFE2_EXPORT
145 #else
146 #define CAFFE2_API CAFFE2_IMPORT
147 #endif
148 
149 // make_unique is a C++14 feature. If we don't have 14, we will emulate
150 // its behavior. This is copied from folly/Memory.h
151 #if __cplusplus >= 201402L || \
152  (defined __cpp_lib_make_unique && __cpp_lib_make_unique >= 201304L) || \
153  (defined(_MSC_VER) && _MSC_VER >= 1900)
154 /* using override */
155 using std::make_unique;
156 #else
157 
158 template<typename T, typename... Args>
159 typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
160 make_unique(Args&&... args) {
161  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
162 }
163 
164 // Allows 'make_unique<T[]>(10)'. (N3690 s20.9.1.4 p3-4)
165 template<typename T>
166 typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
167 make_unique(const size_t n) {
168  return std::unique_ptr<T>(new typename std::remove_extent<T>::type[n]());
169 }
170 
171 // Disallows 'make_unique<T[10]>()'. (N3690 s20.9.1.4 p5)
172 template<typename T, typename... Args>
173 typename std::enable_if<
174  std::extent<T>::value != 0, std::unique_ptr<T>>::type
175 make_unique(Args&&...) = delete;
176 
177 #endif
178 
179 // to_string, stoi and stod implementation for Android related stuff.
180 // Note(jiayq): Do not use the CAFFE2_TESTONLY_FORCE_STD_STRING_TEST macro
181 // outside testing code that lives under common_test.cc
182 #if defined(__ANDROID__) || defined(CAFFE2_TESTONLY_FORCE_STD_STRING_TEST)
183 #define CAFFE2_TESTONLY_WE_ARE_USING_CUSTOM_STRING_FUNCTIONS 1
184 template <typename T>
185 std::string to_string(T value)
186 {
187  std::ostringstream os;
188  os << value;
189  return os.str();
190 }
191 
192 inline int stoi(const string& str) {
193  std::stringstream ss;
194  int n = 0;
195  ss << str;
196  ss >> n;
197  return n;
198 }
199 
200 inline double stod(const string& str, std::size_t* pos = 0) {
201  std::stringstream ss;
202  ss << str;
203  double val = 0;
204  ss >> val;
205  if (pos) {
206  if (ss.tellg() == std::streampos(-1)) {
207  *pos = str.size();
208  } else {
209  *pos = ss.tellg();
210  }
211  }
212  return val;
213 }
214 #else
215 #define CAFFE2_TESTONLY_WE_ARE_USING_CUSTOM_STRING_FUNCTIONS 0
216 using std::to_string;
217 using std::stoi;
218 using std::stod;
219 #endif // defined(__ANDROID__) || defined(CAFFE2_FORCE_STD_STRING_FALLBACK_TEST)
220 
221 // dynamic cast reroute: if RTTI is disabled, go to reinterpret_cast
222 template <typename Dst, typename Src>
223 inline Dst dynamic_cast_if_rtti(Src ptr) {
224 #ifdef __GXX_RTTI
225  return dynamic_cast<Dst>(ptr);
226 #else
227  return reinterpret_cast<Dst>(ptr);
228 #endif
229 }
230 
231 // SkipIndices are used in operator_fallback_gpu.h and operator_fallback_mkl.h
232 // as utilty functions that marks input / output indices to skip when we use a
233 // CPU operator as the fallback of GPU/MKL operator option.
234 template <int... values>
235 class SkipIndices {
236  private:
237  template <int V>
238  static inline bool ContainsInternal(const int i) {
239  return (i == V);
240  }
241  template <int First, int Second, int... Rest>
242  static inline bool ContainsInternal(const int i) {
243  return (i == First) && ContainsInternal<Second, Rest...>(i);
244  }
245 
246  public:
247  static inline bool Contains(const int i) {
248  return ContainsInternal<values...>(i);
249  }
250 };
251 
252 template <>
253 class SkipIndices<> {
254  public:
255  static inline bool Contains(const int /*i*/) {
256  return false;
257  }
258 };
259 
260 // HasCudaRuntime() tells the program whether the binary has Cuda runtime
261 // linked. This function should not be used in static initialization functions
262 // as the underlying boolean variable is going to be switched on when one
263 // loads libcaffe2_gpu.so.
264 bool HasCudaRuntime();
265 namespace internal {
266 // Sets the Cuda Runtime flag that is used by HasCudaRuntime(). You should
267 // never use this function - it is only used by the Caffe2 gpu code to notify
268 // Caffe2 core that cuda runtime has been loaded.
269 void SetCudaRuntimeFlag();
270 }
271 // Returns which setting Caffe2 was configured and built with (exported from
272 // CMake)
273 const std::map<string, string>& GetBuildOptions();
274 
275 } // namespace caffe2
276 
277 #endif // CAFFE2_CORE_COMMON_H_
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...