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