1 #ifndef _ABSTRACT_TYPES_HPP_
2 #define _ABSTRACT_TYPES_HPP_
3 
4 #include <string>
5 #include <map>
6 #include <vector>
7 #include <mkldnn.h>
8 #include <mkldnn.hpp>
9 
10 namespace ideep {
11 
12 #if defined (__GNUC__)
13 #define IDEEP_DEPRECATED __attribute__((deprecated))
14 #elif defined(_MSC_VER)
15 #define IDEEP_DEPRECATED __declspec(deprecated)
16 #else
17 #define IDEEP_DEPRECATED
18 #endif
19 
20 #ifdef _WIN32
21 #define IDEEP_EXPORT __declspec(dllexport)
22 #elif defined(__GNUC__)
23 #define IDEEP_EXPORT __attribute__((__visibility__("default")))
24 #else
25 #define IDEEP_EXPORT
26 #endif
27 
28 #ifdef _WIN32
29 #define IDEEP_EXPORT __declspec(dllexport)
30 #elif defined(__GNUC__)
31 #define IDEEP_EXPORT __attribute__((__visibility__("default")))
32 #else
33 #define IDEEP_EXPORT
34 #endif
35 
36 #define IDEEP_ENFORCE(condition, message) \
37   do {  \
38     error::wrap_c_api((condition) \
39         ? mkldnn_success : mkldnn_invalid_arguments, (message));  \
40   } while(false) \
41 
42 #define IDEEP_STD_ALL_EQ(v, i) \
43   std::all_of(v.begin(), v.end(), []( \
44         std::remove_reference<decltype(v)>::type::value_type k){return k == i;})
45 
46 #define IDEEP_STD_ANY_LE(v, i) \
47   std::any_of(v.begin(), v.end(), []( \
48         std::remove_reference<decltype(v)>::type::value_type k){return k <= i;})
49 
50 #define IDEEP_STD_EACH_SUB(v, i) \
51   for (auto it = v.begin(); it != v.end(); it++) {*it -= i;}
52 
53 #define IDEEP_CROSS_EQUAL(v1, v2, i1, i2) \
54   (((v1 == i1) && (v2 == i2)) || ((v1 == i2) && (v2 == i1)))
55 
56 // For 2D convolution with grouped weights, the ndims must be 5 (goihw)
57 #define IDEEP_IS_GROUPED_4DIMS(d) (((d).size() == 5) ? 1 : 0)
58 
59 #define IDEEP_MOD_PTR(ptr, bytes) (((uintptr_t)(ptr)) & ((bytes) - 1))
60 #define IDEEP_IS_ALIGNED_PTR(ptr, bytes) ((IDEEP_MOD_PTR(ptr, bytes)) == 0)
61 
62 struct error: public std::exception {
63     mkldnn_status_t status;
64     const char *message;
65 
errorideep::error66     error(mkldnn_status_t astatus, const char* amessage)
67         : status(astatus), message(amessage) {}
68 
wrap_c_apiideep::error69     static void wrap_c_api(mkldnn_status_t status, const char * message) {
70       if (status != mkldnn_success) {
71         throw error(status, message);
72       }
73     }
74 };
75 
76 /// Same class for resource management, except public default constructor
77 /// Movable support for better performance
78 template <typename T, typename traits = mkldnn::handle_traits<T>>
79 class c_wrapper :
80   public std::shared_ptr<typename std::remove_pointer<T>::type> {
81   using super = std::shared_ptr<typename std::remove_pointer<T>::type>;
82 public:
83   /// Constructs a C handle wrapper.
84   /// @param t The C handle to wrap.
85   /// @param weak A flag to specify whether to construct a weak wrapper.
c_wrapper(T t=nullptr,bool weak=false)86   c_wrapper(T t = nullptr, bool weak = false): super(t, [weak]() {
87     auto dummy = [](T) {
88       return decltype(traits::destructor(0))(0);
89     };
90     return weak? dummy : traits::destructor;
91   }()) {}
92 
93   using super::super;
94 
95   /// Resets the value of a C handle.
96   /// @param t The new value of the C handle.
97   /// @param weak A flag to specify whether the wrapper should be weak.
reset(T t,bool weak=false)98   void reset(T t, bool weak = false) {
99     auto dummy_destructor = [](T) {
100       return decltype(traits::destructor(0))(0);
101     };
102     super::reset(t, weak ? dummy_destructor : traits::destructor);
103   }
104 };
105 
106 using batch_normalization_flag = mkldnn::batch_normalization_flag;
107 using query = mkldnn::query;
108 using scale_t = std::vector<float>;
109 using round_mode = mkldnn::round_mode;
110 
111 #define IDEEP_OP_SCALE_MASK(scale_size) (((scale_size) > 1) ? 2 : 0)
112 #define IDEEP_TENSOR_SCALE_MASK(scale_size, grouped) \
113   (((scale_size) > 1) ? ((grouped) ? 3 : 1) : 0)
114 
115 const scale_t IDEEP_DEF_SCALE {1.0f};
116 
117 constexpr int IDEEP_U8_MAX = 0xFF;
118 constexpr int IDEEP_S8_MAX = 0x7F;
119 constexpr int IDEEP_S32_MAX = 0x7FFFFFFF;
120 const std::map<mkldnn::memory::data_type, int> dt_max_map
121 {
122   {mkldnn::memory::data_type::s32, IDEEP_S32_MAX},
123   {mkldnn::memory::data_type::s8, IDEEP_S8_MAX},
124   {mkldnn::memory::data_type::u8, IDEEP_U8_MAX}
125 };
126 
127 /// hide other formats
128 enum format {
129   format_undef = mkldnn_format_undef,
130   any = mkldnn_any,
131   blocked = mkldnn_blocked,
132   x = mkldnn_x,
133   nc = mkldnn_nc,
134   io = mkldnn_io,
135   oi = mkldnn_oi,
136   nchw = mkldnn_nchw,
137   nhwc = mkldnn_nhwc,
138   chwn = mkldnn_chwn,
139   ncdhw = mkldnn_ncdhw,
140   ndhwc = mkldnn_ndhwc,
141   oihw = mkldnn_oihw,
142   ihwo = mkldnn_ihwo,
143   hwio = mkldnn_hwio,
144   oidhw = mkldnn_oidhw,
145   goihw = mkldnn_goihw,
146   hwigo = mkldnn_hwigo,
147   ntc = mkldnn_ntc,
148   tnc = mkldnn_tnc,
149   iohw = mkldnn_format_last + 1,
150   format_last = iohw + 1
151 };
152 
153 /// cpu execution engine only.
154 struct engine: public mkldnn::engine {
155   explicit engine(const mkldnn_engine_t& aengine) = delete;
156   engine(engine const &) = delete;
157   void operator =(engine const &) = delete;
158 
159   /// Singleton CPU engine for all primitives
160   static IDEEP_EXPORT engine &cpu_engine();
161 
162   /// Put this global engine in only one library
163   #define INIT_GLOBAL_ENGINE \
164   ideep::engine &ideep::engine::cpu_engine() { \
165     static engine cpu_engine; \
166     return cpu_engine; \
167   }
168 
default_formatideep::engine169   inline static format default_format(int ndims) {
170     switch(ndims) {
171     case 1:
172       return format::x;
173     case 2:
174       return format::nc;
175     case 3:
176       return format::blocked;
177     case 4:
178       return format::nchw;
179     case 5:
180       return format::ncdhw;
181     default:
182       return format::format_undef;
183     }
184   }
185 
186 private:
187   /// Constructs an engine.
188   ///
189   /// @param akind The kind of engine to construct.
190   /// @param dformat The default data type of the engine.
191 
engineideep::engine192   engine(kind akind = kind::cpu)
193     :mkldnn::engine(akind, 0) {
194   }
195 };
196 
197 /// A default stream
198 struct stream: public mkldnn::stream {
199   using mkldnn::stream::stream;
default_streamideep::stream200   static stream default_stream() {
201     return stream(mkldnn::stream::kind::eager);
202   }
203 };
204 
205 using key_t = std::string;
206 
207 using kind = mkldnn::primitive::kind;
208 using prop_kind = mkldnn::prop_kind;
209 using algorithm = mkldnn::algorithm;
210 using padding_kind = mkldnn::padding_kind;
211 }
212 
213 #endif
214