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