1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
/*******************************************************************************
* Copyright 2016-2018 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
#ifndef NSTL_HPP
#define NSTL_HPP
#include <stdint.h>
#include <limits.h>
#include <float.h>
#include <vector>
#include <map>
#include "z_magic.hpp"
namespace mkldnn {
namespace impl {
void *malloc(size_t size, int alignment);
void free(void *p);
struct c_compatible {
enum { default_alignment = 64 };
static void *operator new(size_t sz) {
return malloc(sz, default_alignment);
}
static void *operator new(size_t sz, void *p) { UNUSED(sz); return p; }
static void *operator new[](size_t sz) {
return malloc(sz, default_alignment);
}
static void operator delete(void *p) { free(p); }
static void operator delete[](void *p) { free(p); }
};
namespace nstl {
template<typename T>
inline const T abs(const T& a) {
return a >= 0 ? a : -a;
}
template<typename T>
inline const T& max(const T& a, const T& b) {
return a > b ? a : b;
}
template<typename T>
inline const T& min(const T& a, const T& b) {
return a < b ? a : b;
}
template<typename T> void swap(T& t1, T& t2) {
T tmp(t1);
t1 = t2;
t2 = tmp;
}
// Rationale: MKL-DNN needs numeric limits implementation that does not
// generate dependencies on C++ run-time libraries.
template<typename T> struct numeric_limits;
template<> struct numeric_limits<float> {
static constexpr float lowest() { return -FLT_MAX; }
static constexpr float max() { return FLT_MAX; }
};
template<> struct numeric_limits<int32_t> {
static constexpr int lowest() { return INT32_MIN; }
static constexpr int max() { return INT32_MAX; }
};
template<> struct numeric_limits<int16_t> {
static constexpr int16_t lowest() { return INT16_MIN; }
static constexpr int16_t max() { return INT16_MAX; }
};
template<> struct numeric_limits<int8_t> {
static constexpr int8_t lowest() { return INT8_MIN; }
static constexpr int8_t max() { return INT8_MAX; }
};
template<> struct numeric_limits<uint8_t> {
static constexpr uint8_t lowest() { return 0; }
static constexpr uint8_t max() { return UINT8_MAX; }
};
template<typename T> struct is_integral
{ static constexpr bool value = false; };
template<> struct is_integral<int32_t> { static constexpr bool value = true; };
template<> struct is_integral<int16_t> { static constexpr bool value = true; };
template<> struct is_integral<int8_t> { static constexpr bool value = true; };
template<> struct is_integral<uint8_t> { static constexpr bool value = true; };
template <typename T, typename U> struct is_same
{ static constexpr bool value = false; };
template <typename T> struct is_same<T, T>
{ static constexpr bool value = true; };
// Rationale: MKL-DNN needs container implementations that do not generate
// dependencies on C++ run-time libraries.
//
// Implementation philosophy: caller is responsible to check if the operation
// is valid. The only functions that have to return status are those that
// depend on memory allocation or similar operations.
//
// This means that e.g. an operator [] does not have to check for boundaries.
// The caller should have checked the boundaries. If it did not we crash and
// burn: this is a bug in MKL-DNN and throwing an exception would not have been
// recoverable.
//
// On the other hand, insert() or resize() or a similar operation needs to
// return a status because the outcome depends on factors external to the
// caller. The situation is probably also not recoverable also, but MKL-DNN
// needs to be nice and report "out of memory" to the users.
enum nstl_status_t {
success = 0,
out_of_memory
};
template <typename T> class vector: public c_compatible {
private:
std::vector<T> _impl;
public:
typedef typename std::vector<T>::iterator iterator;
typedef typename std::vector<T>::const_iterator const_iterator;
typedef typename std::vector<T>::size_type size_type;
vector() {}
vector(size_type n): _impl(n) {}
vector(size_type n, const T &value): _impl(n, value) {}
template <typename input_iterator>
vector(input_iterator first, input_iterator last): _impl(first, last) {}
~vector() {}
size_type size() const { return _impl.size(); }
T& operator[] (size_type i) { return _impl[i]; }
const T& operator[] (size_type i) const { return _impl[i]; }
iterator begin() { return _impl.begin(); }
const_iterator begin() const { return _impl.begin(); }
iterator end() { return _impl.end(); }
const_iterator end() const { return _impl.end(); }
template <typename input_iterator>
nstl_status_t insert(iterator pos, input_iterator begin, input_iterator end)
{
_impl.insert(pos, begin, end);
return success;
}
void clear() { _impl.clear(); }
void push_back(const T& t) { _impl.push_back(t); }
void resize(size_type count) { _impl.resize(count); }
void reserve(size_type count) { _impl.reserve(count); }
};
template <typename Key, typename T> class map: public c_compatible {
private:
std::map<Key, T> _impl;
public:
typedef typename std::map<Key, T>::iterator iterator;
typedef typename std::map<Key, T>::const_iterator const_iterator;
typedef typename std::map<Key, T>::size_type size_type;
map() {}
~map() {}
size_type size() const { return _impl.size(); }
T& operator[](const Key &k) { return _impl[k]; }
const T& operator[](const Key &k) const { return _impl[k]; }
iterator begin() { return _impl.begin(); }
const_iterator begin() const { return _impl.begin(); }
iterator end() { return _impl.end(); }
const_iterator end() const { return _impl.end(); }
template <typename input_iterator>
void clear() { _impl.clear(); }
};
}
}
}
#endif
// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
|