IVGCVSW-4129 Fix thread starvation due to low capture periods
[platform/upstream/armnn.git] / include / armnn / Types.hpp
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6
7 #include <array>
8 #include <functional>
9 #include <memory>
10 #include <stdint.h>
11 #include "BackendId.hpp"
12 #include "Exceptions.hpp"
13
14 namespace armnn
15 {
16
17 constexpr unsigned int MaxNumOfTensorDimensions = 5U;
18
19 // The lowest performance data capture interval we support is 10 miliseconds.
20 constexpr unsigned int LOWEST_CAPTURE_PERIOD = 10000u;
21
22 /// @enum Status enumeration
23 /// @var Status::Successful
24 /// @var Status::Failure
25 enum class Status
26 {
27     Success = 0,
28     Failure = 1
29 };
30
31 enum class DataType
32 {
33     Float16 = 0,
34     Float32 = 1,
35     QuantisedAsymm8 = 2,
36     Signed32 = 3,
37     Boolean = 4,
38     QuantisedSymm16 = 5,
39     QuantizedSymm8PerAxis = 6
40 };
41
42 enum class DataLayout
43 {
44     NCHW = 1,
45     NHWC = 2
46 };
47
48 enum class ActivationFunction
49 {
50     Sigmoid     = 0,
51     TanH        = 1,
52     Linear      = 2,
53     ReLu        = 3,
54     BoundedReLu = 4, ///< min(a, max(b, input))
55     SoftReLu    = 5,
56     LeakyReLu   = 6,
57     Abs         = 7,
58     Sqrt        = 8,
59     Square      = 9
60 };
61
62 enum class ArgMinMaxFunction
63 {
64     Min = 0,
65     Max = 1
66 };
67
68 enum class ComparisonOperation
69 {
70     Equal          = 0,
71     Greater        = 1,
72     GreaterOrEqual = 2,
73     Less           = 3,
74     LessOrEqual    = 4,
75     NotEqual       = 5
76 };
77
78 enum class PoolingAlgorithm
79 {
80     Max     = 0,
81     Average = 1,
82     L2      = 2
83 };
84
85 enum class ResizeMethod
86 {
87     Bilinear        = 0,
88     NearestNeighbor = 1
89 };
90
91 ///
92 /// The padding method modifies the output of pooling layers.
93 /// In both supported methods, the values are ignored (they are
94 /// not even zeroes, which would make a difference for max pooling
95 /// a tensor with negative values). The difference between
96 /// IgnoreValue and Exclude is that the former counts the padding
97 /// fields in the divisor of Average and L2 pooling, while
98 /// Exclude does not.
99 ///
100 enum class PaddingMethod
101 {
102     /// The padding fields count, but are ignored
103     IgnoreValue = 0,
104     /// The padding fields don't count and are ignored
105     Exclude     = 1
106 };
107
108 enum class NormalizationAlgorithmChannel
109 {
110     Across = 0,
111     Within = 1
112 };
113
114 enum class NormalizationAlgorithmMethod
115 {
116     /// Krichevsky 2012: Local Brightness Normalization
117     LocalBrightness = 0,
118     /// Jarret 2009: Local Contrast Normalization
119     LocalContrast = 1
120 };
121
122 enum class OutputShapeRounding
123 {
124     Floor       = 0,
125     Ceiling     = 1
126 };
127
128 /// Each backend should implement an IBackend.
129 class IBackend
130 {
131 protected:
132     IBackend() {}
133     virtual ~IBackend() {}
134
135 public:
136     virtual const BackendId& GetId() const = 0;
137 };
138
139 using IBackendSharedPtr = std::shared_ptr<IBackend>;
140 using IBackendUniquePtr = std::unique_ptr<IBackend, void(*)(IBackend* backend)>;
141
142 /// Device specific knowledge to be passed to the optimizer.
143 class IDeviceSpec
144 {
145 protected:
146     IDeviceSpec() {}
147     virtual ~IDeviceSpec() {}
148 public:
149     virtual const BackendIdSet& GetSupportedBackends() const = 0;
150 };
151
152 /// Type of identifiers for bindable layers (inputs, outputs).
153 using LayerBindingId = int;
154
155 class PermutationVector
156 {
157 public:
158     using ValueType = unsigned int;
159     using SizeType = unsigned int;
160     using ArrayType = std::array<ValueType, MaxNumOfTensorDimensions>;
161     using ConstIterator = typename ArrayType::const_iterator;
162
163     /// @param dimMappings - Indicates how to translate tensor elements from a given source into the target destination,
164     /// when source and target potentially have different memory layouts.
165     ///
166     /// E.g. For a 4-d tensor laid out in a memory with the format (Batch Element, Height, Width, Channels),
167     /// which is to be passed as an input to ArmNN, each source dimension is mapped to the corresponding
168     /// ArmNN dimension. The Batch dimension remains the same (0 -> 0). The source Height dimension is mapped
169     /// to the location of the ArmNN Height dimension (1 -> 2). Similar arguments are made for the Width and
170     /// Channels (2 -> 3 and 3 -> 1). This will lead to @ref m_DimMappings pointing to the following array:
171     /// [ 0, 2, 3, 1 ].
172     ///
173     /// Note that the mapping should be reversed if considering the case of ArmNN 4-d outputs (Batch Element,
174     /// Channels, Height, Width) being written to a destination with the format mentioned above. We now have
175     /// 0 -> 0, 2 -> 1, 3 -> 2, 1 -> 3, which, when reordered, lead to the following @ref m_DimMappings contents:
176     /// [ 0, 3, 1, 2 ].
177     ///
178     PermutationVector(const ValueType *dimMappings, SizeType numDimMappings);
179
180     PermutationVector(std::initializer_list<ValueType> dimMappings);
181
182     ValueType operator[](SizeType i) const { return m_DimMappings.at(i); }
183
184     SizeType GetSize() const { return m_NumDimMappings; }
185
186     ConstIterator begin() const { return m_DimMappings.begin(); }
187     ConstIterator end() const { return m_DimMappings.end(); }
188
189     bool IsEqual(const PermutationVector& other) const
190     {
191         if (m_NumDimMappings != other.m_NumDimMappings) return false;
192         for (unsigned int i = 0; i < m_NumDimMappings; ++i)
193         {
194             if (m_DimMappings[i] != other.m_DimMappings[i]) return false;
195         }
196         return true;
197     }
198
199     bool IsInverse(const PermutationVector& other) const
200     {
201         bool isInverse = (GetSize() == other.GetSize());
202         for (SizeType i = 0; isInverse && (i < GetSize()); ++i)
203         {
204             isInverse = (m_DimMappings[other.m_DimMappings[i]] == i);
205         }
206         return isInverse;
207     }
208
209 private:
210     ArrayType m_DimMappings;
211     /// Number of valid entries in @ref m_DimMappings
212     SizeType m_NumDimMappings;
213 };
214
215 namespace profiling { class ProfilingGuid; }
216
217 /// Define LayerGuid type.
218 using LayerGuid = profiling::ProfilingGuid;
219
220 class ITensorHandle;
221
222 /// Define the type of callback for the Debug layer to call
223 /// @param guid - guid of layer connected to the input of the Debug layer
224 /// @param slotIndex - index of the output slot connected to the input of the Debug layer
225 /// @param tensorHandle - TensorHandle for the input tensor to the Debug layer
226 using DebugCallbackFunction = std::function<void(LayerGuid guid, unsigned int slotIndex, ITensorHandle* tensorHandle)>;
227
228
229 namespace profiling
230 {
231
232 class ProfilingGuid
233 {
234 public:
235     ProfilingGuid(uint64_t guid) : m_Guid(guid) {}
236
237     operator uint64_t() const { return m_Guid; }
238
239     bool operator==(const ProfilingGuid& other) const
240     {
241         return m_Guid == other.m_Guid;
242     }
243
244     bool operator!=(const ProfilingGuid& other) const
245     {
246         return m_Guid != other.m_Guid;
247     }
248
249     bool operator<(const ProfilingGuid& other) const
250     {
251         return m_Guid < other.m_Guid;
252     }
253
254     bool operator<=(const ProfilingGuid& other) const
255     {
256         return m_Guid <= other.m_Guid;
257     }
258
259     bool operator>(const ProfilingGuid& other) const
260     {
261         return m_Guid > other.m_Guid;
262     }
263
264     bool operator>=(const ProfilingGuid& other) const
265     {
266         return m_Guid >= other.m_Guid;
267     }
268
269 protected:
270     uint64_t m_Guid;
271 };
272
273 /// Strongly typed guids to distinguish between those generated at runtime, and those that are statically defined.
274 struct ProfilingDynamicGuid : public ProfilingGuid
275 {
276     using ProfilingGuid::ProfilingGuid;
277 };
278
279 struct ProfilingStaticGuid : public ProfilingGuid
280 {
281     using ProfilingGuid::ProfilingGuid;
282 };
283
284 } // namespace profiling
285
286 } // namespace armnn
287
288
289 namespace std
290 {
291 // make ProfilingGuid hashable
292 template<>
293 struct hash<armnn::profiling::ProfilingGuid>
294 {
295     std::size_t operator()(armnn::profiling::ProfilingGuid const& guid) const noexcept
296     {
297         return hash<uint64_t>()(uint64_t(guid));
298     }
299 };
300
301 // make ProfilingDynamicGuid hashable
302 template<>
303 struct hash<armnn::profiling::ProfilingDynamicGuid>
304 {
305     std::size_t operator()(armnn::profiling::ProfilingDynamicGuid const& guid) const noexcept
306     {
307         return hash<uint64_t>()(uint64_t(guid));
308     }
309 };
310
311 // make ProfilingStaticGuid hashable
312 template<>
313 struct hash<armnn::profiling::ProfilingStaticGuid>
314 {
315     std::size_t operator()(armnn::profiling::ProfilingStaticGuid const& guid) const noexcept
316     {
317         return hash<uint64_t>()(uint64_t(guid));
318     }
319 };
320 } // namespace std