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