blob: d49315d5913c79418602d7dd90098df87fd3f355 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Manuel Bottinicc5171b2019-01-09 17:04:39 +00002 * Copyright (c) 2016-2019 ARM Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#ifndef __ARM_COMPUTE_TYPES_H__
25#define __ARM_COMPUTE_TYPES_H__
26
27#include "arm_compute/core/Coordinates.h"
Georgios Pinitas4c5469b2019-05-21 13:32:43 +010028#include "arm_compute/core/QuantizationInfo.h"
Isabella Gottardi6e464c32018-01-26 12:32:45 +000029#include "arm_compute/core/Size2D.h"
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000030#include "arm_compute/core/Strides.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010031#include "arm_compute/core/TensorShape.h"
Georgios Pinitas583137c2017-08-31 18:12:42 +010032#include "support/Half.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010033
Michel Iwaniec5dfeae62017-11-29 10:48:23 +000034#include <cmath>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010035#include <cstddef>
36#include <cstdint>
37#include <string>
38#include <utility>
39
40namespace arm_compute
41{
Georgios Pinitas583137c2017-08-31 18:12:42 +010042/** 16-bit floating point type */
43using half = half_float::half;
44
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000045/** Permutation vector */
46using PermutationVector = Strides;
Georgios Pinitas77589b52018-08-21 14:41:35 +010047/** Bidirectional strides */
48using BiStrides = Coordinates;
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000049
Anthony Barbier6ff3b192017-09-04 18:44:23 +010050/** Image colour formats */
51enum class Format
52{
Daniil Efremov02bf80d2017-11-22 00:26:51 +070053 UNKNOWN, /**< Unknown image format */
54 U8, /**< 1 channel, 1 U8 per channel */
55 S16, /**< 1 channel, 1 S16 per channel */
56 U16, /**< 1 channel, 1 U16 per channel */
57 S32, /**< 1 channel, 1 S32 per channel */
58 U32, /**< 1 channel, 1 U32 per channel */
59 F16, /**< 1 channel, 1 F16 per channel */
60 F32, /**< 1 channel, 1 F32 per channel */
61 UV88, /**< 2 channel, 1 U8 per channel */
62 RGB888, /**< 3 channels, 1 U8 per channel */
63 RGBA8888, /**< 4 channels, 1 U8 per channel */
64 YUV444, /**< A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes */
65 YUYV422, /**< A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes */
66 NV12, /**< A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling */
67 NV21, /**< A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling */
68 IYUV, /**< A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes */
69 UYVY422 /**< A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010070};
71
72/** Available data types */
73enum class DataType
74{
Georgios Pinitas4c5469b2019-05-21 13:32:43 +010075 UNKNOWN, /**< Unknown data type */
76 U8, /**< unsigned 8-bit number */
77 S8, /**< signed 8-bit number */
78 QSYMM8, /**< quantized, symmetric fixed-point 8-bit number */
79 QASYMM8, /**< quantized, asymmetric fixed-point 8-bit number */
80 QSYMM8_PER_CHANNEL, /**< quantized, symmetric per channel fixed-point 8-bit number */
81 U16, /**< unsigned 16-bit number */
82 S16, /**< signed 16-bit number */
83 U32, /**< unsigned 32-bit number */
84 S32, /**< signed 32-bit number */
85 U64, /**< unsigned 64-bit number */
86 S64, /**< signed 64-bit number */
87 F16, /**< 16-bit floating-point number */
88 F32, /**< 32-bit floating-point number */
89 F64, /**< 64-bit floating-point number */
90 SIZET /**< size_t */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010091};
92
Daniil Efremov02bf80d2017-11-22 00:26:51 +070093/** Available Sampling Policies */
94enum class SamplingPolicy
95{
96 CENTER, /**< Samples are taken at pixel center */
97 TOP_LEFT /**< Samples are taken at pixel top left corner */
98};
99
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100100/** Constant value of the border pixels when using BorderMode::CONSTANT */
101constexpr uint8_t CONSTANT_BORDER_VALUE = 199;
102
Alex Gildayc357c472018-03-21 13:54:09 +0000103/** Constant value used to indicate a half-scale pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100104constexpr float SCALE_PYRAMID_HALF = 0.5f;
105
Alex Gildayc357c472018-03-21 13:54:09 +0000106/** Constant value used to indicate a ORB scaled pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100107constexpr float SCALE_PYRAMID_ORB = 8.408964152537146130583778358414e-01;
108
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000109/** [DataLayout enum definition] **/
110
Georgios Pinitas4074c992018-01-30 18:13:46 +0000111/** Supported tensor data layouts */
112enum class DataLayout
113{
Alex Gildayc357c472018-03-21 13:54:09 +0000114 UNKNOWN, /**< Unknown data layout */
115 NCHW, /**< Num samples, channels, height, width */
116 NHWC /**< Num samples, height, width, channels */
Georgios Pinitas4074c992018-01-30 18:13:46 +0000117};
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000118/** [DataLayout enum definition] **/
Georgios Pinitas4074c992018-01-30 18:13:46 +0000119
Isabella Gottardid17a6772018-02-27 17:41:55 +0000120/** Supported tensor data layout dimensions */
121enum class DataLayoutDimension
122{
Alex Gildayc357c472018-03-21 13:54:09 +0000123 CHANNEL, /**< channel */
124 HEIGHT, /**< height */
125 WIDTH, /**< width */
126 BATCHES /**< batches */
Isabella Gottardid17a6772018-02-27 17:41:55 +0000127};
128
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000129/** Available ConvolutionMethod*/
130enum class ConvolutionMethod
131{
Vidhya Sudhan Loganathan8ec0bb62019-04-23 10:40:44 +0100132 GEMM, /**< Convolution using GEMM */
133 DIRECT, /**< Direct convolution */
134 WINOGRAD, /**< Convolution using Winograd */
135 FFT /**< Convolution using FFT */
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000136};
137
giuros0146a49a02019-04-01 13:50:22 +0100138/** Available DeconvolutionMethod*/
139enum class DeconvolutionMethod
140{
141 GEMM, /**< Deconvolution using GEMM */
142 DIRECT, /**< Direct deconvolution */
143};
144
Usama Arif89890c62019-03-19 10:57:05 +0000145/** Padding mode to use for PadLayer */
146enum class PaddingMode
147{
148 CONSTANT,
149 REFLECT,
150 SYMMETRIC
151};
152
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000153/** Supported comparison operations */
154enum class ComparisonOperation
155{
156 Equal, /**< Equal comparison ( \f$ x == y \f$ ) */
157 NotEqual, /**< NotEqual comparison ( \f$ x != y \f$ ) */
158 Greater, /**< Greater comparison ( \f$ x > y \f$ ) */
159 GreaterEqual, /**< Greater equal comparison ( \f$ x >= y \f$ ) */
160 Less, /**< Less comparison ( \f$ x < y \f$ ) */
161 LessEqual /**< Less equal comparison ( \f$ x <= y \f$ ) */
162};
163
Alex Gildayc357c472018-03-21 13:54:09 +0000164/** Container for valid region of a window */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100165struct ValidRegion
166{
Alex Gildayc357c472018-03-21 13:54:09 +0000167 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100168 ValidRegion()
169 : anchor{}, shape{}
170 {
171 }
172
Alex Gildayc357c472018-03-21 13:54:09 +0000173 /** Allow instances of this class to be copy constructed */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100174 ValidRegion(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000175 /** Allow instances of this class to be move constructed */
176 ValidRegion(ValidRegion &&) = default;
177 /** Allow instances of this class to be copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100178 ValidRegion &operator=(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000179 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100180 ValidRegion &operator=(ValidRegion &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000181 /** Default destructor */
182 ~ValidRegion() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100183
Alex Gildayc357c472018-03-21 13:54:09 +0000184 /** Constructor for a valid region with default number of dimensions
185 *
186 * @param[in] an_anchor Anchor for the start of the valid region.
187 * @param[in] a_shape Shape of the valid region.
188 *
189 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000190 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
191 : anchor{ an_anchor }, shape{ a_shape }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100192 {
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000193 anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
194 }
195
Alex Gildayc357c472018-03-21 13:54:09 +0000196 /** Constructor for a valid region with specified number of dimensions
197 *
198 * @param[in] an_anchor Anchor for the start of the valid region.
199 * @param[in] a_shape Shape of the valid region.
200 * @param[in] num_dimensions Number of dimensions (must be >= number of dimensions of anchor and shape).
201 *
202 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000203 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
204 : anchor{ an_anchor }, shape{ a_shape }
205 {
206 ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
207 anchor.set_num_dimensions(num_dimensions);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100208 }
209
210 /** Return the start of the valid region for the given dimension @p d */
211 int start(unsigned int d) const
212 {
213 return anchor[d];
214 }
215
216 /** Return the end of the valid region for the given dimension @p d */
217 int end(unsigned int d) const
218 {
219 return anchor[d] + shape[d];
220 }
221
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000222 /** Accessor to set the value of anchor and shape for one of the dimensions.
223 *
224 * @param[in] dimension Dimension for which the value is set.
225 * @param[in] start Value to be set in anchor for the dimension.
226 * @param[in] size Value to be set in shape for the dimension.
227 *
228 * @return *this.
229 */
230 ValidRegion &set(size_t dimension, int start, size_t size)
231 {
232 anchor.set(dimension, start);
233 shape.set(dimension, size);
234 return *this;
235 }
236
Alex Gildayc357c472018-03-21 13:54:09 +0000237 Coordinates anchor; /**< Anchor for the start of the valid region. */
238 TensorShape shape; /**< Shape of the valid region. */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100239};
240
241/** Methods available to handle borders */
242enum class BorderMode
243{
244 UNDEFINED, /**< Borders are left undefined */
245 CONSTANT, /**< Pixels outside the image are assumed to have a constant value */
246 REPLICATE /**< Pixels outside the image are assumed to have the same value as the closest image pixel */
247};
248
249/** Container for 2D border size */
250struct BorderSize
251{
252 /** Empty border, i.e. no border */
253 constexpr BorderSize()
254 : top{ 0 }, right{ 0 }, bottom{ 0 }, left{ 0 }
255 {
256 }
257
258 /** Border with equal size around the 2D plane */
Moritz Pflanzer7655a672017-09-23 11:57:33 +0100259 explicit constexpr BorderSize(unsigned int size)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100260 : top{ size }, right{ size }, bottom{ size }, left{ size }
261 {
262 }
263
264 /** Border with same size for top/bottom and left/right */
265 constexpr BorderSize(unsigned int top_bottom, unsigned int left_right)
266 : top{ top_bottom }, right{ left_right }, bottom{ top_bottom }, left{ left_right }
267 {
268 }
269
270 /** Border with different sizes */
271 constexpr BorderSize(unsigned int top, unsigned int right, unsigned int bottom, unsigned int left)
272 : top{ top }, right{ right }, bottom{ bottom }, left{ left }
273 {
274 }
275
276 /** Check if the entire border is zero */
277 constexpr bool empty() const
278 {
279 return top == 0 && right == 0 && bottom == 0 && left == 0;
280 }
281
282 /** Check if the border is the same size on all sides */
283 constexpr bool uniform() const
284 {
285 return top == right && top == bottom && top == left;
286 }
287
Alex Gildayc357c472018-03-21 13:54:09 +0000288 /** Scale this border size.
289 *
290 * @param[in] scale Scale to multiply border size by.
291 *
292 * @return *this.
293 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100294 BorderSize &operator*=(float scale)
295 {
296 top *= scale;
297 right *= scale;
298 bottom *= scale;
299 left *= scale;
300
301 return *this;
302 }
303
Alex Gildayc357c472018-03-21 13:54:09 +0000304 /** Scale a copy of this border size.
305 *
306 * @param[in] scale Scale to multiply border size by.
307 *
308 * @return a scaled copy of this.
309 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100310 BorderSize operator*(float scale)
311 {
312 BorderSize size = *this;
313 size *= scale;
314
315 return size;
316 }
317
Alex Gildayc357c472018-03-21 13:54:09 +0000318 /** Limit this border size.
319 *
320 * @param[in] limit Border size to limit this border size to.
321 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100322 void limit(const BorderSize &limit)
323 {
324 top = std::min(top, limit.top);
325 right = std::min(right, limit.right);
326 bottom = std::min(bottom, limit.bottom);
327 left = std::min(left, limit.left);
328 }
329
Alex Gildayc357c472018-03-21 13:54:09 +0000330 unsigned int top; /**< top of the border */
331 unsigned int right; /**< right of the border */
332 unsigned int bottom; /**< bottom of the border */
333 unsigned int left; /**< left of the border */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100334};
335
Alex Gildayc357c472018-03-21 13:54:09 +0000336/** Container for 2D padding size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100337using PaddingSize = BorderSize;
338
339/** Policy to handle overflow */
340enum class ConvertPolicy
341{
342 WRAP, /**< Wrap around */
343 SATURATE /**< Saturate */
344};
345
346/** Interpolation method */
347enum class InterpolationPolicy
348{
349 NEAREST_NEIGHBOR, /**< Output values are defined to match the source pixel whose center is nearest to the sample position */
350 BILINEAR, /**< Output values are defined by bilinear interpolation between the pixels */
351 AREA, /**< Output values are determined by averaging the source pixels whose areas fall under the area of the destination pixel, projected onto the source image */
352};
353
354/** Bilinear Interpolation method used by LKTracker */
355enum class BilinearInterpolation
356{
Alex Gildayc357c472018-03-21 13:54:09 +0000357 BILINEAR_OLD_NEW, /**< Old-new method */
358 BILINEAR_SCHARR /**< Scharr method */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100359};
360
361/** Threshold mode */
362enum class ThresholdType
363{
364 BINARY, /**< Threshold with one value */
365 RANGE /**< Threshold with two values*/
366};
367
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100368/** Termination criteria */
369enum class Termination
370{
Alex Gildayc357c472018-03-21 13:54:09 +0000371 TERM_CRITERIA_EPSILON, /**< Terminate when within epsilon of a threshold */
372 TERM_CRITERIA_ITERATIONS, /**< Terminate after a maximum number of iterations */
373 TERM_CRITERIA_BOTH /**< Terminate on whichever of the other conditions occurs first */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100374};
375
376/** Magnitude calculation type. */
377enum class MagnitudeType
378{
379 L1NORM, /**< L1 normalization type */
380 L2NORM /**< L2 normalization type */
381};
382
383/** Phase calculation type.
384 *
385 * @note When PhaseType == SIGNED, each angle is mapped to the range 0 to 255 inclusive otherwise angles between 0 and 180
386 */
387enum class PhaseType
388{
389 SIGNED, /**< Angle range: [0, 360] */
390 UNSIGNED /**< Angle range: [0, 180] */
391};
392
393/** Keypoint type */
394struct KeyPoint
395{
396 int32_t x{ 0 }; /**< X coordinates */
397 int32_t y{ 0 }; /**< Y coordinates */
398 float strength{ 0.f }; /**< Strength of the point */
399 float scale{ 0.f }; /**< Scale initialized to 0 by the corner detector */
400 float orientation{ 0.f }; /**< Orientation initialized to 0 by the corner detector */
401 int32_t tracking_status{ 0 }; /**< Status initialized to 1 by the corner detector, set to 0 when the point is lost */
402 float error{ 0.f }; /**< Tracking error initialized to 0 by the corner detector */
403};
404
Alex Gildayc357c472018-03-21 13:54:09 +0000405/** Internal key point */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100406using InternalKeypoint = std::tuple<float, float, float>; /* x,y,strength */
407
408/** Rectangle type */
409struct Rectangle
410{
411 uint16_t x; /**< Top-left x coordinate */
412 uint16_t y; /**< Top-left y coordinate */
413 uint16_t width; /**< Width of the rectangle */
414 uint16_t height; /**< Height of the rectangle */
415};
416
417/** Coordinate type */
418struct Coordinates2D
419{
420 int32_t x; /**< X coordinates */
421 int32_t y; /**< Y coordinates */
422};
423
424/** Coordinate type */
425struct Coordinates3D
426{
427 uint32_t x; /**< X coordinates */
428 uint32_t y; /**< Y coordinates */
429 uint32_t z; /**< Z coordinates */
430};
431
Giuseppe Rossinid7647d42018-07-17 18:13:13 +0100432/** Padding information as a pair of unsigned int start/end */
433using PaddingInfo = std::pair<uint32_t, uint32_t>;
434
435/** List of padding information */
436using PaddingList = std::vector<PaddingInfo>;
437
giuros013175fcf2018-11-21 09:59:17 +0000438/** Information to produce a tiled version of a Tensor */
439using Multiples = std::vector<uint32_t>;
440
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100441/** Available channels */
442enum class Channel
443{
444 UNKNOWN, /** Unknown channel format */
445 C0, /**< First channel (used by formats with unknown channel types). */
446 C1, /**< Second channel (used by formats with unknown channel types). */
447 C2, /**< Third channel (used by formats with unknown channel types). */
448 C3, /**< Fourth channel (used by formats with unknown channel types). */
449 R, /**< Red channel. */
450 G, /**< Green channel. */
451 B, /**< Blue channel. */
452 A, /**< Alpha channel. */
453 Y, /**< Luma channel. */
454 U, /**< Cb/U channel. */
455 V /**< Cr/V/Value channel. */
456};
457
458/** Available matrix patterns */
459enum class MatrixPattern
460{
461 BOX, /**< Box pattern matrix. */
462 CROSS, /**< Cross pattern matrix. */
463 DISK, /**< Disk pattern matrix. */
464 OTHER /**< Any other matrix pattern. */
465};
466
467/** Available non linear functions. */
468enum class NonLinearFilterFunction : unsigned
469{
470 MEDIAN = 0, /**< Non linear median filter. */
471 MIN = 1, /**< Non linear erode. */
472 MAX = 2, /**< Non linear dilate. */
473};
474
Georgios Pinitasd9769582017-08-03 10:19:40 +0100475/** Available reduction operations */
476enum class ReductionOperation
477{
Michalis Spyrou7930db42018-11-22 17:36:28 +0000478 ARG_IDX_MAX, /**< Index of the max value */
Manuel Bottinib412fab2018-12-10 17:40:23 +0000479 ARG_IDX_MIN, /**< Index of the min value */
480 MEAN_SUM, /**< Mean of sum */
481 PROD, /**< Product */
482 SUM_SQUARE, /**< Sum of squares */
Usama Arifa4a08ad2019-05-20 12:38:33 +0100483 SUM, /**< Sum */
484 MIN, /**< Min */
Usama Arif28f0dd92019-05-20 13:44:34 +0100485 MAX, /**< Max */
Georgios Pinitasd9769582017-08-03 10:19:40 +0100486};
487
giuros01164a2722018-11-20 18:34:46 +0000488/** Available element-wise operations */
489enum class ArithmeticOperation
490{
491 ADD, /**< (x + y) */
492 SUB, /**< (x - y) */
493 DIV, /**< (x / y) */
494 MIN, /**< Min(x, y) */
495 MAX, /**< Max(x, y) */
496 SQUARED_DIFF, /**< (x - y)^2 */
Usama Arif81e671e2019-05-13 13:33:14 +0100497 POWER, /**< x ^ y */
giuros011e6e1b82019-05-14 16:12:53 +0100498 PRELU, /**< y*x if x < 0, x otherwise */
giuros01164a2722018-11-20 18:34:46 +0000499};
500
Michalis Spyroue9362622018-11-23 17:41:37 +0000501/** Available element wise unary operations */
502enum class ElementWiseUnary
503{
504 RSQRT, /**< Reverse square root */
505 EXP, /**< Exponential */
Usama Ariff6e475c2019-05-10 12:06:28 +0100506 NEG, /**< Negate */
Usama Arifc255aa72019-05-13 16:26:29 +0100507 LOG, /**< Natural Logarithm */
Manuel Bottini6ac59922019-05-15 14:06:02 +0100508 ABS, /**< Absolute value */
Michalis Spyrou0af44182019-05-17 14:04:47 +0100509 SIN, /**< Sine */
Usama Arif0a5a57a2019-05-23 14:20:33 +0100510 ROUND, /**< Round */
Michalis Spyroue9362622018-11-23 17:41:37 +0000511};
512
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100513/** The normalization type used for the normalization layer */
514enum class NormType
515{
516 IN_MAP_1D, /**< Normalization applied within the same map in 1D region */
517 IN_MAP_2D, /**< Normalization applied within the same map in 2D region */
518 CROSS_MAP /**< Normalization applied cross maps */
519};
520
521/** Normalization type for Histogram of Oriented Gradients (HOG) */
522enum class HOGNormType
523{
524 L2_NORM = 1, /**< L2-norm */
525 L2HYS_NORM = 2, /**< L2-norm followed by clipping */
526 L1_NORM = 3 /**< L1 norm */
527};
528
529/** Detection window used for the object detection. The detection window keeps the following information:
530 *
531 * -# Geometry of the rectangular window (x/y of top-left corner and width/height)
532 * -# Index of the class used for evaluating which class the detection window belongs to
533 * -# Confidence value (score) obtained with the classifier
534 */
535struct DetectionWindow
536{
537 uint16_t x{ 0 }; /**< Top-left x coordinate */
538 uint16_t y{ 0 }; /**< Top-left y coordinate */
539 uint16_t width{ 0 }; /**< Width of the detection window */
540 uint16_t height{ 0 }; /**< Height of the detection window */
541 uint16_t idx_class{ 0 }; /**< Index of the class */
542 float score{ 0.f }; /**< Confidence value for the detection window */
543};
544
545/** Dimension rounding type when down-scaling on CNNs
546 * @note Used in pooling and convolution layer
547 */
548enum class DimensionRoundingType
549{
550 FLOOR, /**< Floor rounding */
551 CEIL /**< Ceil rounding */
552};
553
554/** Available pooling types */
555enum class PoolingType
556{
557 MAX, /**< Max Pooling */
Georgios Pinitascdf51452017-08-31 14:21:36 +0100558 AVG, /**< Average Pooling */
559 L2 /**< L2 Pooling */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100560};
561
Michalis Spyrou2709d612018-09-19 09:46:47 +0100562/** Available non maxima suppression types */
563enum class NMSType
564{
565 LINEAR, /**< Linear NMS */
566 GAUSSIAN, /**< Gaussian NMS */
567 ORIGINAL /**< Original NMS */
568};
569
570/** BoxWithNonMaximaSuppressionLimit Information class */
571class BoxNMSLimitInfo final
572{
573public:
574 /** Constructor
575 *
576 * @param[in] score_thresh (Optional) Score threshold.
577 * @param[in] nms (Optional) NMS value
578 * @param[in] detections (Optional) Number of detections
579 * @param[in] soft_nms_enabled (Optional) Enable SoftNMS
580 * @param[in] soft_nms_method (Optional) Soft NMS method
581 * @param[in] soft_nms_sigma (Optional) Soft NMS sigma value
582 * @param[in] soft_nms_min_score_thres (Optional) Soft NMS minimum score threshold
Manuel Bottini5209be52019-02-13 16:34:56 +0000583 * @param[in] suppress_size (Optional) Filter out boxes based on their size. Defaults to false
584 * @param[in] min_size (Optional) Smaller boxes than min_size will be filtered out. Defaults to 1
585 * @param[in] im_width (Optional) Boxes whose centers (on the x axis) is beyond im_width will be filtered. Defaults to 1
586 * @param[in] im_height (Optional) Boxes whose centers (on the y axis) is beyond im_height will be filtered. Defaults to 1
Michalis Spyrou2709d612018-09-19 09:46:47 +0100587 */
588 BoxNMSLimitInfo(float score_thresh = 0.05f, float nms = 0.3f,
589 int detections = 100, bool soft_nms_enabled = false,
590 NMSType soft_nms_method = NMSType::LINEAR,
Manuel Bottini5209be52019-02-13 16:34:56 +0000591 float soft_nms_sigma = 0.5f, float soft_nms_min_score_thres = 0.001f, bool suppress_size = false, float min_size = 1.0f, float im_width = 1.0f, float im_height = 1.0f)
Michalis Spyrou2709d612018-09-19 09:46:47 +0100592 : _score_thresh(score_thresh), _nms(nms), _detections_per_im(detections), _soft_nms_enabled(soft_nms_enabled), _soft_nms_method(soft_nms_method), _soft_nms_sigma(soft_nms_sigma),
Manuel Bottini5209be52019-02-13 16:34:56 +0000593 _soft_nms_min_score_thres(soft_nms_min_score_thres), _suppress_size(suppress_size), _min_size(min_size), _im_width(im_width), _im_height(im_height)
Michalis Spyrou2709d612018-09-19 09:46:47 +0100594 {
595 }
596 /** Get the score threshold */
597 float score_thresh() const
598 {
599 return _score_thresh;
600 }
601 /** Get the NMS */
602 float nms() const
603 {
604 return _nms;
605 }
606 /** Get the number of detections */
607 int detections_per_im() const
608 {
609 return _detections_per_im;
610 }
611 /** Check if soft NMS is enabled */
612 bool soft_nms_enabled() const
613 {
614 return _soft_nms_enabled;
615 }
616 /** Get soft NMS method */
617 NMSType soft_nms_method() const
618 {
619 return _soft_nms_method;
620 }
621 /** Get soft NMS sigma */
622 float soft_nms_sigma() const
623 {
624 return _soft_nms_sigma;
625 }
626 /** Get soft nms min score threshold */
627 float soft_nms_min_score_thres() const
628 {
629 return _soft_nms_min_score_thres;
630 }
Manuel Bottini5209be52019-02-13 16:34:56 +0000631 /** Get if NMS will suppress boxes based on their size/position */
632 bool suppress_size() const
633 {
634 return _suppress_size;
635 }
636 /** Get size suppression threshold */
637 float min_size() const
638 {
639 return _min_size;
640 }
641 /** Get image width (NMS may suppress boxes whose center sits beyond the image width) */
642 float im_width() const
643 {
644 return _im_width;
645 }
646 /** Get image height (NMS may suppress boxes whose center sits beyond the image height) */
647 float im_height() const
648 {
649 return _im_height;
650 }
Michalis Spyrou2709d612018-09-19 09:46:47 +0100651
652private:
653 float _score_thresh;
654 float _nms;
655 int _detections_per_im;
656 bool _soft_nms_enabled;
657 NMSType _soft_nms_method;
658 float _soft_nms_sigma;
659 float _soft_nms_min_score_thres;
Manuel Bottini5209be52019-02-13 16:34:56 +0000660 bool _suppress_size;
661 float _min_size;
662 float _im_width;
663 float _im_height;
Michalis Spyrou2709d612018-09-19 09:46:47 +0100664};
665
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100666/** Padding and stride information class */
667class PadStrideInfo
668{
669public:
670 /** Constructor
671 *
672 * @param[in] stride_x (Optional) Stride, in elements, across x. Defaults to 1.
673 * @param[in] stride_y (Optional) Stride, in elements, across y. Defaults to 1.
674 * @param[in] pad_x (Optional) Padding, in elements, across x. Defaults to 0.
675 * @param[in] pad_y (Optional) Padding, in elements, across y. Defaults to 0.
676 * @param[in] round (Optional) Dimensions rounding. Defaults to @ref FLOOR.
677 */
678 PadStrideInfo(unsigned int stride_x = 1, unsigned int stride_y = 1,
679 unsigned int pad_x = 0, unsigned int pad_y = 0,
680 DimensionRoundingType round = DimensionRoundingType::FLOOR)
681 : _stride(std::make_pair(stride_x, stride_y)),
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100682 _pad_left(pad_x),
683 _pad_top(pad_y),
684 _pad_right(pad_x),
685 _pad_bottom(pad_y),
686 _round_type(round)
687 {
688 }
689 /** Constructor
690 *
691 * @param[in] stride_x Stride, in elements, across x.
692 * @param[in] stride_y Stride, in elements, across y.
693 * @param[in] pad_left Padding across x on the left, in elements.
694 * @param[in] pad_top Padding across y on the top, in elements.
695 * @param[in] pad_right Padding across x on the right, in elements.
696 * @param[in] pad_bottom Padding across y on the bottom, in elements.
697 * @param[in] round Dimensions rounding.
698 */
699 PadStrideInfo(unsigned int stride_x, unsigned int stride_y,
700 unsigned int pad_left, unsigned int pad_right,
701 unsigned int pad_top, unsigned int pad_bottom,
702 DimensionRoundingType round)
703 : _stride(std::make_pair(stride_x, stride_y)),
704 _pad_left(pad_left),
705 _pad_top(pad_top),
706 _pad_right(pad_right),
707 _pad_bottom(pad_bottom),
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100708 _round_type(round)
709 {
710 }
Alex Gildayc357c472018-03-21 13:54:09 +0000711 /** Get the stride.
712 *
713 * @return a pair: stride x, stride y.
714 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100715 std::pair<unsigned int, unsigned int> stride() const
716 {
717 return _stride;
718 }
Alex Gildayc357c472018-03-21 13:54:09 +0000719 /** Check whether the padding is symmetric.
720 *
721 * @return True if the padding is symmetric.
722 */
Anthony Barbier21f67d62018-02-16 15:17:48 +0000723 bool padding_is_symmetric() const
724 {
725 return (_pad_left == _pad_right) && (_pad_top == _pad_bottom);
726 }
Alex Gildayc357c472018-03-21 13:54:09 +0000727 /** Get the padding.
728 *
729 * @note This should only be used when the padding is symmetric.
730 *
731 * @return a pair: padding left/right, padding top/bottom
732 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100733 std::pair<unsigned int, unsigned int> pad() const
734 {
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100735 //this accessor should be used only when padding is symmetric
Anthony Barbier21f67d62018-02-16 15:17:48 +0000736 ARM_COMPUTE_ERROR_ON(!padding_is_symmetric());
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100737 return std::make_pair(_pad_left, _pad_top);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100738 }
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100739
Alex Gildayc357c472018-03-21 13:54:09 +0000740 /** Get the left padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100741 unsigned int pad_left() const
742 {
743 return _pad_left;
744 }
Alex Gildayc357c472018-03-21 13:54:09 +0000745 /** Get the right padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100746 unsigned int pad_right() const
747 {
748 return _pad_right;
749 }
Alex Gildayc357c472018-03-21 13:54:09 +0000750 /** Get the top padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100751 unsigned int pad_top() const
752 {
753 return _pad_top;
754 }
Alex Gildayc357c472018-03-21 13:54:09 +0000755 /** Get the bottom padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100756 unsigned int pad_bottom() const
757 {
758 return _pad_bottom;
759 }
760
Alex Gildayc357c472018-03-21 13:54:09 +0000761 /** Get the rounding type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100762 DimensionRoundingType round() const
763 {
764 return _round_type;
765 }
766
Alex Gildayc357c472018-03-21 13:54:09 +0000767 /** Check whether this has any padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100768 bool has_padding() const
769 {
770 return (_pad_left != 0 || _pad_top != 0 || _pad_right != 0 || _pad_bottom != 0);
771 }
772
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100773private:
774 std::pair<unsigned int, unsigned int> _stride;
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100775 unsigned int _pad_left;
776 unsigned int _pad_top;
777 unsigned int _pad_right;
778 unsigned int _pad_bottom;
779
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100780 DimensionRoundingType _round_type;
781};
782
Georgios Pinitas7d66a8e2018-07-17 12:28:42 +0100783/** Fully connected layer info */
784struct FullyConnectedLayerInfo
785{
786 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
787 bool transpose_weights{ true }; /**< Transpose weights if true. */
788 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
789 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
Georgios Pinitasc55cef12018-08-01 15:24:18 +0100790
791 /** Sets the weights trained data layout
792 *
793 * @param[in] layout Data layout that the weights were trained with
794 *
795 * @return Updated object
796 */
797 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
798 {
799 weights_trained_layout = layout;
800 return *this;
801 }
Georgios Pinitas195b0ba2018-08-02 17:18:51 +0100802 /** Sets the transpose weights flag
803 *
804 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
805 *
806 * @return Updated object
807 */
808 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
809 {
810 transpose_weights = should_transpose_weights;
811 return *this;
812 }
Georgios Pinitas7d66a8e2018-07-17 12:28:42 +0100813};
814
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100815/** PriorBox layer info */
816class PriorBoxLayerInfo final
817{
818public:
819 /** Default Constructor */
820 PriorBoxLayerInfo()
821 : _min_sizes(),
822 _variances(),
823 _offset(),
824 _flip(true),
825 _clip(false),
826 _max_sizes(),
827 _aspect_ratios(),
828 _img_size(),
829 _steps()
830 {
831 }
832 /** Constructor
833 *
834 * @param[in] min_sizes Min sizes vector.
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100835 * @param[in] variances Variances vector.
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100836 * @param[in] offset Offset value.
837 * @param[in] flip (Optional) Flip the aspect ratios.
838 * @param[in] clip (Optional) Clip coordinates so that they're within [0,1].
839 * @param[in] max_sizes (Optional) Max sizes vector.
840 * @param[in] aspect_ratios (Optional) Aspect ratios of the boxes.
841 * @param[in] img_size (Optional) Image size.
842 * @param[in] steps (Optional) Step values.
843 */
844 PriorBoxLayerInfo(const std::vector<float> &min_sizes, const std::vector<float> &variances, float offset, bool flip = true, bool clip = false,
Pablo Tello32521432018-11-15 14:43:10 +0000845 const std::vector<float> &max_sizes = {}, const std::vector<float> &aspect_ratios = {},
846 const Coordinates2D &img_size = Coordinates2D{ 0, 0 }, const std::array<float, 2> &steps = { { 0.f, 0.f } })
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100847 : _min_sizes(min_sizes),
848 _variances(variances),
849 _offset(offset),
850 _flip(flip),
851 _clip(clip),
852 _max_sizes(max_sizes),
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100853 _aspect_ratios(),
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100854 _img_size(img_size),
855 _steps(steps)
856 {
857 _aspect_ratios.push_back(1.);
858 for(unsigned int i = 0; i < aspect_ratios.size(); ++i)
859 {
860 float ar = aspect_ratios[i];
861 bool already_exist = false;
862 for(auto ar_new : _aspect_ratios)
863 {
864 if(fabs(ar - ar_new) < 1e-6)
865 {
866 already_exist = true;
867 break;
868 }
869 }
870 if(!already_exist)
871 {
872 _aspect_ratios.push_back(ar);
873 if(flip)
874 {
875 _aspect_ratios.push_back(1.f / ar);
876 }
877 }
878 }
879 }
880 /** Get min sizes. */
881 std::vector<float> min_sizes() const
882 {
883 return _min_sizes;
884 }
885 /** Get min variances. */
886 std::vector<float> variances() const
887 {
888 return _variances;
889 }
890 /** Get the step coordinates */
891 std::array<float, 2> steps() const
892 {
893 return _steps;
894 }
895 /** Get the image size coordinates */
896 Coordinates2D img_size() const
897 {
898 return _img_size;
899 }
900 /** Get the offset */
901 float offset() const
902 {
903 return _offset;
904 }
905 /** Get the flip value */
906 bool flip() const
907 {
908 return _flip;
909 }
910 /** Get the clip value */
911 bool clip() const
912 {
913 return _clip;
914 }
915 /** Get max sizes. */
916 std::vector<float> max_sizes() const
917 {
918 return _max_sizes;
919 }
920 /** Get aspect ratios. */
921 std::vector<float> aspect_ratios() const
922 {
923 return _aspect_ratios;
924 }
925
926private:
927 std::vector<float> _min_sizes;
928 std::vector<float> _variances;
929 float _offset;
930 bool _flip;
931 bool _clip;
932 std::vector<float> _max_sizes;
933 std::vector<float> _aspect_ratios;
934 Coordinates2D _img_size;
935 std::array<float, 2> _steps;
936};
937
Isabella Gottardi05e56442018-11-16 11:26:52 +0000938/** Available Detection Output code types */
939enum class DetectionOutputLayerCodeType
940{
941 CORNER, /**< Use box corners */
942 CENTER_SIZE, /**< Use box centers and size */
943 CORNER_SIZE, /**< Use box centers and size */
944 TF_CENTER /**< Use box centers and size but flip x and y co-ordinates */
945};
946
947/** Detection Output layer info */
948class DetectionOutputLayerInfo final
949{
950public:
951 /** Default Constructor */
952 DetectionOutputLayerInfo()
953 : _num_classes(),
954 _share_location(),
955 _code_type(DetectionOutputLayerCodeType::CORNER),
956 _keep_top_k(),
957 _nms_threshold(),
958 _top_k(),
959 _background_label_id(),
960 _confidence_threshold(),
961 _variance_encoded_in_target(false),
962 _eta(),
963 _num_loc_classes()
964 {
965 _num_loc_classes = _share_location ? 1 : _num_classes;
966 }
967 /** Constructor
968 *
969 * @param[in] num_classes Number of classes to be predicted.
970 * @param[in] share_location If true, bounding box are shared among different classes.
971 * @param[in] code_type Type of coding method for bbox.
972 * @param[in] keep_top_k Number of total bounding boxes to be kept per image after NMS step.
973 * @param[in] nms_threshold Threshold to be used in NMS.
974 * @param[in] top_k (Optional) Number of boxes per image with top confidence scores that are fed into the NMS algorithm. Default set to -1.
975 * @param[in] background_label_id (Optional) Background label ID. If there is no background class, set it as -1.
976 * @param[in] confidence_threshold (Optional) Only consider detections whose confidences are larger than a threshold. Default set to -FLT_MAX.
977 * @param[in] variance_encoded_in_target (Optional) If true, variance is encoded in target. Otherwise we need to adjust the predicted offset accordingly.Default set to false.
978 * @param[in] eta (Optional) Eta.
979 */
980 DetectionOutputLayerInfo(int num_classes, bool share_location, DetectionOutputLayerCodeType code_type, int keep_top_k, float nms_threshold, int top_k = -1, int background_label_id = -1,
981 float confidence_threshold = std::numeric_limits<float>::lowest(), bool variance_encoded_in_target = false, float eta = 1)
982 : _num_classes(num_classes),
983 _share_location(share_location),
984 _code_type(code_type),
985 _keep_top_k(keep_top_k),
986 _nms_threshold(nms_threshold),
987 _top_k(top_k),
988 _background_label_id(background_label_id),
989 _confidence_threshold(confidence_threshold),
990 _variance_encoded_in_target(variance_encoded_in_target),
991 _eta(eta),
992 _num_loc_classes()
993 {
994 _num_loc_classes = _share_location ? 1 : _num_classes;
995 }
996 /** Get num classes. */
997 int num_classes() const
998 {
999 return _num_classes;
1000 }
1001 /** Get share location. */
1002 bool share_location() const
1003 {
1004 return _share_location;
1005 }
1006 /** Get detection output code type. */
1007 DetectionOutputLayerCodeType code_type() const
1008 {
1009 return _code_type;
1010 }
1011 /** Get if variance encoded in target. */
1012 bool variance_encoded_in_target() const
1013 {
1014 return _variance_encoded_in_target;
1015 }
1016 /** Get the number of total bounding boxes to be kept per image. */
1017 int keep_top_k() const
1018 {
1019 return _keep_top_k;
1020 }
1021 /** Get nms threshold. */
1022 float nms_threshold() const
1023 {
1024 return _nms_threshold;
1025 }
1026 /** Get eta. */
1027 float eta() const
1028 {
1029 return _eta;
1030 }
1031 /** Get background label ID. */
1032 int background_label_id() const
1033 {
1034 return _background_label_id;
1035 }
1036 /** Get confidence threshold. */
1037 float confidence_threshold() const
1038 {
1039 return _confidence_threshold;
1040 }
1041 /** Get top K. */
1042 int top_k() const
1043 {
1044 return _top_k;
1045 }
1046 /** Get number of location classes. */
1047 int num_loc_classes() const
1048 {
1049 return _num_loc_classes;
1050 }
1051
1052private:
1053 int _num_classes;
1054 bool _share_location;
1055 DetectionOutputLayerCodeType _code_type;
1056 int _keep_top_k;
1057 float _nms_threshold;
1058 int _top_k;
1059 int _background_label_id;
1060 float _confidence_threshold;
1061 bool _variance_encoded_in_target;
1062 float _eta;
1063 int _num_loc_classes;
1064};
1065
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001066/** Pooling Layer Information class */
1067class PoolingLayerInfo
1068{
1069public:
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001070 /** Default Constructor */
1071 PoolingLayerInfo()
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001072 : _pool_type(PoolingType::MAX), _pool_size(Size2D()), _pad_stride_info(PadStrideInfo()), _exclude_padding(false), _is_global_pooling(false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001073 {
1074 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001075 /** Default Constructor
1076 *
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001077 * @param[in] pool_type Pooling type @ref PoolingType.
1078 * @param[in] pool_size Pooling size, in elements, across x and y.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001079 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
Georgios Pinitasadaae7e2017-10-30 15:56:32 +00001080 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1081 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1082 * Defaults to false;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001083 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001084 explicit PoolingLayerInfo(PoolingType pool_type,
1085 unsigned int pool_size,
1086 PadStrideInfo pad_stride_info = PadStrideInfo(),
1087 bool exclude_padding = false)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001088 : _pool_type(pool_type), _pool_size(Size2D(pool_size, pool_size)), _pad_stride_info(pad_stride_info), _exclude_padding(exclude_padding), _is_global_pooling(false)
1089 {
1090 }
1091 /** Default Constructor
1092 *
1093 * @param[in] pool_type Pooling type @ref PoolingType.
1094 * @param[in] pool_size Pooling size, in elements, across x and y.
1095 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1096 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1097 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1098 * Defaults to false;
1099 */
1100 explicit PoolingLayerInfo(PoolingType pool_type,
1101 Size2D pool_size,
1102 PadStrideInfo pad_stride_info = PadStrideInfo(),
1103 bool exclude_padding = false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001104 : _pool_type(pool_type), _pool_size(pool_size), _pad_stride_info(pad_stride_info), _exclude_padding(exclude_padding), _is_global_pooling(false)
1105 {
1106 }
1107 /** Default Constructor
1108 *
1109 * @note This constructor is used for global pooling
1110 *
1111 * @param[in] pool_type Pooling type @ref PoolingType.
1112 */
1113 explicit PoolingLayerInfo(PoolingType pool_type)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001114 : _pool_type(pool_type), _pool_size(Size2D()), _pad_stride_info(PadStrideInfo(1, 1, 0, 0)), _exclude_padding(false), _is_global_pooling(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001115 {
1116 }
Alex Gildayc357c472018-03-21 13:54:09 +00001117 /** Get the pooling type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001118 PoolingType pool_type() const
1119 {
1120 return _pool_type;
1121 }
Alex Gildayc357c472018-03-21 13:54:09 +00001122 /** Get the pooling size */
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001123 const Size2D &pool_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001124 {
1125 return _pool_size;
1126 }
Alex Gildayc357c472018-03-21 13:54:09 +00001127 /** Get the padding and stride */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001128 PadStrideInfo pad_stride_info() const
1129 {
1130 return _pad_stride_info;
1131 }
Alex Gildayc357c472018-03-21 13:54:09 +00001132 /** Check if padding is excluded in calculations */
Georgios Pinitasadaae7e2017-10-30 15:56:32 +00001133 bool exclude_padding() const
1134 {
1135 return _exclude_padding;
1136 }
Alex Gildayc357c472018-03-21 13:54:09 +00001137 /** Check if is global pooling */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001138 bool is_global_pooling() const
1139 {
1140 return _is_global_pooling;
1141 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001142
1143private:
1144 PoolingType _pool_type;
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001145 Size2D _pool_size;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001146 PadStrideInfo _pad_stride_info;
Georgios Pinitasadaae7e2017-10-30 15:56:32 +00001147 bool _exclude_padding;
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001148 bool _is_global_pooling;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001149};
1150
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001151/** ROI Pooling Layer Information class */
giuros0118870812018-09-13 09:31:40 +01001152class ROIPoolingLayerInfo final
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001153{
1154public:
giuros0118870812018-09-13 09:31:40 +01001155 /** Constructor
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001156 *
giuros0118870812018-09-13 09:31:40 +01001157 * @param[in] pooled_width Pooled width of the layer.
1158 * @param[in] pooled_height Pooled height of the layer.
1159 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
1160 * @param[in] sampling_ratio Number of samples to include in each pooling region (if set to zero, a ceil(roi_dims/pooling_dims))
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001161 */
giuros0118870812018-09-13 09:31:40 +01001162 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale, unsigned int sampling_ratio = 0)
1163 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale), _sampling_ratio(sampling_ratio)
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001164 {
1165 }
Alex Gildayc357c472018-03-21 13:54:09 +00001166 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001167 unsigned int pooled_width() const
1168 {
1169 return _pooled_width;
1170 }
Alex Gildayc357c472018-03-21 13:54:09 +00001171 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001172 unsigned int pooled_height() const
1173 {
1174 return _pooled_height;
1175 }
Alex Gildayc357c472018-03-21 13:54:09 +00001176 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001177 float spatial_scale() const
1178 {
1179 return _spatial_scale;
1180 }
giuros0118870812018-09-13 09:31:40 +01001181 /** Get sampling ratio */
1182 unsigned int sampling_ratio() const
1183 {
1184 return _sampling_ratio;
1185 }
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001186
1187private:
1188 unsigned int _pooled_width;
1189 unsigned int _pooled_height;
1190 float _spatial_scale;
giuros0118870812018-09-13 09:31:40 +01001191 unsigned int _sampling_ratio;
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001192};
1193
Manuel Bottini5209be52019-02-13 16:34:56 +00001194/** Generate Proposals Information class */
1195class GenerateProposalsInfo
1196{
1197public:
1198 /** Constructor
1199 *
1200 * @param[in] im_width Width of the original image
1201 * @param[in] im_height Height of the original image
1202 * @param[in] im_scale Scale applied to the original image
1203 * @param[in] spatial_scale (Optional)Scale applied to the feature map. Defaults to 1.0
1204 * @param[in] pre_nms_topN (Optional)Number of the best scores to be selected from the transformations. Defaults to 6000.
1205 * @param[in] post_nms_topN (Optional)Number of the best scores to be selected from the NMS operation. Defaults to 300.
1206 * @param[in] nms_thres (Optional)NMS overlap threshold. Defaults to 0.7.
1207 * @param[in] min_size (Optional)Size used to validate the anchors produced. Defaults to 16.
1208 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region of interest). Defaults to 4.
1209 */
1210 GenerateProposalsInfo(float im_width, float im_height, float im_scale, float spatial_scale = 1.0, int pre_nms_topN = 6000, int post_nms_topN = 300, float nms_thres = 0.7, float min_size = 16.0,
1211 size_t values_per_roi = 4)
1212 : _im_height(im_height), _im_width(im_width), _im_scale(im_scale), _spatial_scale(spatial_scale), _pre_nms_topN(pre_nms_topN), _post_nms_topN(post_nms_topN), _nms_thres(nms_thres),
1213 _min_size(min_size), _values_per_roi(values_per_roi)
1214 {
1215 }
1216
1217 /* Get the original height */
1218 float im_height() const
1219 {
1220 return _im_height;
1221 }
1222 /* Get the original width */
1223 float im_width() const
1224 {
1225 return _im_width;
1226 }
1227 /* Get the image scale */
1228 float im_scale() const
1229 {
1230 return _im_scale;
1231 }
1232 /* Get the value of how many best scores to select (before NMS) */
1233 int pre_nms_topN() const
1234 {
1235 return _pre_nms_topN;
1236 }
1237 /* Get the value of how many best scores to select (after NMS) */
1238 int post_nms_topN() const
1239 {
1240 return _post_nms_topN;
1241 }
1242 /* Get the NMS overlap threshold */
1243 float nms_thres() const
1244 {
1245 return _nms_thres;
1246 }
1247 /* Get the minimal size */
1248 float min_size() const
1249 {
1250 return _min_size;
1251 }
1252 /* Get the spatial scale to be applied to the feature maps */
1253 float spatial_scale() const
1254 {
1255 return _spatial_scale;
1256 }
1257 /* Get the values used to represent a ROI(Region of interest)*/
1258 size_t values_per_roi() const
1259 {
1260 return _values_per_roi;
1261 }
1262
1263private:
1264 float _im_height;
1265 float _im_width;
1266 float _im_scale;
1267 float _spatial_scale;
1268 int _pre_nms_topN;
1269 int _post_nms_topN;
1270 float _nms_thres;
1271 float _min_size;
1272 size_t _values_per_roi;
1273};
1274
1275/** ComputeAnchors information class */
1276class ComputeAnchorsInfo
1277{
1278public:
1279 /** Constructor
1280 *
1281 * @param[in] feat_width Feature map width
1282 * @param[in] feat_height Feature map height
1283 * @param[in] spatial_scale Feature map scale
1284 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region Of Interest). Defaults to 4
1285 */
1286 ComputeAnchorsInfo(float feat_width, float feat_height, float spatial_scale, size_t values_per_roi = 4)
1287 : _feat_height(feat_height),
1288 _feat_width(feat_width),
1289 _spatial_scale(spatial_scale),
1290 _values_per_roi(values_per_roi)
1291 {
1292 }
1293
1294 /* Get the height of the feature map */
1295 float feat_height() const
1296 {
1297 return _feat_height;
1298 }
1299
1300 /* Get the width of the feature map */
1301 float feat_width() const
1302 {
1303 return _feat_width;
1304 }
1305
1306 /* Get the scale of the feature map */
1307 float spatial_scale() const
1308 {
1309 return _spatial_scale;
1310 }
1311
1312 /* Get the values used to represent a ROI(Region Of Interest)*/
1313 size_t values_per_roi() const
1314 {
1315 return _values_per_roi;
1316 }
1317
1318private:
1319 float _feat_height;
1320 float _feat_width;
1321 float _spatial_scale;
1322 size_t _values_per_roi;
1323};
1324
giuros01c04a0e82018-10-03 12:44:35 +01001325/** Bounding Box Transform information class */
giuros01d696cb62018-11-16 10:39:59 +00001326class BoundingBoxTransformInfo final
giuros01c04a0e82018-10-03 12:44:35 +01001327{
1328public:
1329 /** Constructor
1330 *
giuros01d696cb62018-11-16 10:39:59 +00001331 * @param[in] img_width Width of the original image
1332 * @param[in] img_height Height, of the original image
1333 * @param[in] scale Scale of the original image
1334 * @param[in] apply_scale (Optional)Re-apply scaling after transforming the boxes. Defaults to false
1335 * @param[in] weights (Optional)Weights [wx, wy, ww, wh] for the deltas. Defaults to all ones
1336 * @param[in] correct_transform_coords (Optional)Correct bounding box transform coordinates. Defaults to false
1337 * @param[in] bbox_xform_clip (Optional)Minimum bounding box width and height after bounding box transformation in log-space. Defaults to log(1000/16)
giuros01c04a0e82018-10-03 12:44:35 +01001338 */
giuros01d696cb62018-11-16 10:39:59 +00001339 BoundingBoxTransformInfo(float img_width, float img_height, float scale, bool apply_scale = false, const std::array<float, 4> weights = { { 1.f, 1.f, 1.f, 1.f } }, bool correct_transform_coords =
1340 false,
1341 float bbox_xform_clip =
1342 4.135166556742356f)
1343 : _img_width(img_width), _img_height(img_height), _scale(scale), _apply_scale(apply_scale), _correct_transform_coords(correct_transform_coords), _weights(weights), _bbox_xform_clip(bbox_xform_clip)
giuros01c04a0e82018-10-03 12:44:35 +01001344 {
1345 }
1346
1347 std::array<float, 4> weights() const
1348 {
1349 return _weights;
1350 }
1351
1352 float bbox_xform_clip() const
1353 {
1354 return _bbox_xform_clip;
1355 }
1356
1357 float img_height() const
1358 {
1359 return _img_height;
1360 }
1361
1362 float img_width() const
1363 {
1364 return _img_width;
1365 }
1366
1367 float scale() const
1368 {
1369 return _scale;
1370 }
1371
1372 bool apply_scale() const
1373 {
1374 return _apply_scale;
1375 }
1376
giuros01d696cb62018-11-16 10:39:59 +00001377 bool correct_transform_coords() const
1378 {
1379 return _correct_transform_coords;
1380 }
1381
giuros01c04a0e82018-10-03 12:44:35 +01001382private:
1383 float _img_width;
1384 float _img_height;
1385 float _scale;
1386 bool _apply_scale;
giuros01d696cb62018-11-16 10:39:59 +00001387 bool _correct_transform_coords;
giuros01c04a0e82018-10-03 12:44:35 +01001388 std::array<float, 4> _weights;
1389 float _bbox_xform_clip;
1390};
1391
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001392/** Activation Layer Information class */
1393class ActivationLayerInfo
1394{
1395public:
1396 /** Available activation functions */
1397 enum class ActivationFunction
1398 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001399 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
1400 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
1401 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
1402 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
1403 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
Manuel Bottini581c8982019-02-07 10:31:57 +00001404 LEAKY_RELU, /**< Leaky Rectifier ( \f$ f(x) = \begin{cases} \alpha x & \quad \text{if } x \text{ < 0}\\ x & \quad \text{if } x \geq \text{ 0 } \end{cases} \f$ ) */
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001405 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
1406 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
1407 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
1408 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
Usama Arif6a98a6e2019-05-10 17:07:27 +01001409 LINEAR, /**< Linear ( \f$ f(x)= ax + b \f$ ) */
1410 IDENTITY /**< Identity ( \f$ f(x)= x \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001411 };
1412
Giorgio Arena11674872018-02-07 15:38:12 +00001413 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001414 /** Default Constructor
1415 *
1416 * @param[in] f The activation function to use.
1417 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001418 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1419 * @param[in] b (Optional) The beta parameter used by some activation functions (@ref ActivationFunction::LINEAR, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::TANH).
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001420 */
1421 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001422 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001423 {
1424 }
Alex Gildayc357c472018-03-21 13:54:09 +00001425 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001426 ActivationFunction activation() const
1427 {
1428 return _act;
1429 }
Alex Gildayc357c472018-03-21 13:54:09 +00001430 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001431 float a() const
1432 {
1433 return _a;
1434 }
Alex Gildayc357c472018-03-21 13:54:09 +00001435 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001436 float b() const
1437 {
1438 return _b;
1439 }
Alex Gildayc357c472018-03-21 13:54:09 +00001440 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001441 bool enabled() const
1442 {
1443 return _enabled;
1444 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001445
1446private:
Usama Arif6a98a6e2019-05-10 17:07:27 +01001447 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::IDENTITY };
Giorgio Arena11674872018-02-07 15:38:12 +00001448 float _a = {};
1449 float _b = {};
1450 bool _enabled = { false };
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001451};
1452
1453/** Normalization Layer Information class */
1454class NormalizationLayerInfo
1455{
1456public:
1457 /** Default Constructor
1458 *
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001459 * @param[in] type The normalization type. Can be @ref NormType::IN_MAP_1D, @ref NormType::IN_MAP_2D or @ref NormType::CROSS_MAP
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001460 * @param[in] norm_size The normalization size is the number of elements to normalize across. Defaults to 5.
Georgios Pinitas41caa622017-11-16 14:37:08 +00001461 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1462 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1463 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1464 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1465 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001466 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001467 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1468 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001469 {
1470 }
Alex Gildayc357c472018-03-21 13:54:09 +00001471 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001472 NormType type() const
1473 {
1474 return _type;
1475 }
Alex Gildayc357c472018-03-21 13:54:09 +00001476 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001477 uint32_t norm_size() const
1478 {
1479 return _norm_size;
1480 }
Alex Gildayc357c472018-03-21 13:54:09 +00001481 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001482 float alpha() const
1483 {
1484 return _alpha;
1485 }
Alex Gildayc357c472018-03-21 13:54:09 +00001486 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001487 float beta() const
1488 {
1489 return _beta;
1490 }
Alex Gildayc357c472018-03-21 13:54:09 +00001491 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001492 float kappa() const
1493 {
1494 return _kappa;
1495 }
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001496 /** Get the is_scaled value */
1497 bool is_scaled() const
1498 {
1499 return _is_scaled;
1500 }
Alex Gildayc357c472018-03-21 13:54:09 +00001501 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001502 bool is_cross_map() const
1503 {
1504 return _type == NormType::CROSS_MAP;
1505 }
Alex Gildayc357c472018-03-21 13:54:09 +00001506 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001507 bool is_in_map() const
1508 {
1509 return !is_cross_map();
1510 }
1511 /** Return the scaling factor of the normalization function.
1512 *
1513 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1514 * where alpha is returned plainly, else alpha is scaled by the total number of elements used for the normalization.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001515 *
1516 * @return The normalization scaling factor.
1517 */
1518 float scale_coeff() const
1519 {
1520 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001521 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001522 }
1523
1524private:
1525 NormType _type;
1526 uint32_t _norm_size;
1527 float _alpha;
1528 float _beta;
1529 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001530 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001531};
1532
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001533/** Convolution Layer Weights Information class. This class stores the necessary information to compute convolution layer when the weights are already reshaped */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001534class WeightsInfo
1535{
1536public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001537 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001538 WeightsInfo()
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001539 : _are_reshaped(false), _kernel_width(0), _kernel_height(0), _num_kernels(0), _retain_internal_weights(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001540 {
1541 }
1542 /** Constructor
1543 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001544 * @param[in] are_reshaped True if the weights have been reshaped
1545 * @param[in] kernel_width Kernel width.
1546 * @param[in] kernel_height Kernel height.
1547 * @param[in] num_kernels Number of convolution kernels.
1548 * @param[in] retain_internal_weights (Optional) True if internal reshaped weights must be retained. Used for reconfiguration purposes. Default is false.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001549 */
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001550 WeightsInfo(bool are_reshaped, unsigned int kernel_width, unsigned int kernel_height, unsigned int num_kernels, bool retain_internal_weights = false)
1551 : _are_reshaped(are_reshaped), _kernel_width(kernel_width), _kernel_height(kernel_height), _num_kernels(num_kernels), _retain_internal_weights(retain_internal_weights)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001552 {
1553 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001554 /** Flag which specifies if the weights tensor has been reshaped.
1555 *
1556 * @return True if the weights tensors has been reshaped
1557 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001558 bool are_reshaped() const
1559 {
1560 return _are_reshaped;
1561 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001562 /** Return the number of convolution kernels
1563 *
1564 * @return The number of convolution kernels
1565 */
1566 unsigned int num_kernels() const
1567 {
1568 return _num_kernels;
1569 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001570 /** Return the width and height of the kernel
1571 *
1572 * @return The width and height of the kernel
1573 */
1574 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001575 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001576 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001577 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001578 bool retain_internal_weights() const
1579 {
1580 return _retain_internal_weights;
1581 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001582
1583private:
1584 const bool _are_reshaped;
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001585 const unsigned int _kernel_width;
1586 const unsigned int _kernel_height;
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001587 const unsigned int _num_kernels;
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001588 const bool _retain_internal_weights;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001589};
1590
Gian Marco36a0a462018-01-12 10:21:40 +00001591/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
1592 *
Gian Marco Iodice5fc07aa2019-05-15 17:08:02 +01001593 * The matrix A can only be reshaped through @ref CLGEMMReshapeLHSMatrixKernel or @ref NEGEMMInterleave4x4Kernel or @ref GCGEMMInterleave4x4Kernel
1594 * Note: Optionally just for @ref CLGEMMReshapeLHSMatrixKernel is it possible to set mult_interleave4x4_height, the multiplication factor for the height of the 4x4 interleaved block
Gian Marco36a0a462018-01-12 10:21:40 +00001595 *
giuros018b6b4a92018-12-18 19:01:33 +00001596 * The matrix B can only be reshaped through @ref CLGEMMReshapeRHSMatrixKernel or @ref NEGEMMTranspose1xWKernel or @ref GCGEMMTranspose1xWKernel
1597 * Note: Optionally just for @ref CLGEMMReshapeRHSMatrixKernel is it possible to set mult_transpose1xW_width, the multiplication factor for the width of the 1xW transposed block
Gian Marco36a0a462018-01-12 10:21:40 +00001598 *
1599 */
1600class GEMMReshapeInfo final
1601{
1602public:
1603 /** Default constructor */
1604 GEMMReshapeInfo()
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001605 : _m(1), _n(1), _k(1), _mult_transpose1xW_width(1), _mult_interleave4x4_height(1), _depth_output_gemm3d(0), _reinterpret_input_as_3d(false), _broadcast_bias(false)
Gian Marco36a0a462018-01-12 10:21:40 +00001606 {
1607 }
1608 /** Constructor
1609 *
1610 * @param[in] m Number of matrix A rows
1611 * @param[in] n Number of matrix B columns
1612 * @param[in] k Number of matrix A columns or matrix B rows
1613 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
1614 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001615 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
1616 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001617 * @param[in] reinterpret_input_as_3d (Optional) Reinterpret the input as 3D tensor. (i.e. this flag should be set to true when GEMM is used
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001618 * to perform 1x1 convolutions with the NHWC data layout)
1619 * @param[in] broadcast_bias (Optional) Broadcast the shape of the bias tensor from a vector to a matrix.
Gian Marco36a0a462018-01-12 10:21:40 +00001620 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001621 GEMMReshapeInfo(int m, int n, int k, int mult_transpose1xW_width = 1, int mult_interleave4x4_height = 1, int depth_output_gemm3d = 0, bool reinterpret_input_as_3d = false, bool broadcast_bias = false)
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001622 : _m(m), _n(n), _k(k), _mult_transpose1xW_width(mult_transpose1xW_width), _mult_interleave4x4_height(mult_interleave4x4_height), _depth_output_gemm3d(depth_output_gemm3d),
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001623 _reinterpret_input_as_3d(reinterpret_input_as_3d), _broadcast_bias(broadcast_bias)
Gian Marco36a0a462018-01-12 10:21:40 +00001624 {
1625 }
1626 /** Number of matrix A rows
1627 *
1628 * @return the number of matrix A rows
1629 */
1630 int m() const
1631 {
1632 return _m;
1633 }
1634 /** Number of matrix B columns
1635 *
1636 * @return the number of matrix B columns
1637 */
1638 int n() const
1639 {
1640 return _n;
1641 }
1642 /** Number of matrix A columns or matrix B rows
1643 *
1644 * @return the number of matrix A columns or matrix B rows
1645 */
1646 int k() const
1647 {
1648 return _k;
1649 }
1650 /** Multiplication factor for the width of the 1xW transposed block
1651 *
1652 * @return the multiplication factor for the width of the 1xW transposed block
1653 */
1654 int mult_transpose1xW_width() const
1655 {
1656 return _mult_transpose1xW_width;
1657 }
1658 /** Multiplication factor for the height of the 4x4 interleaved block
1659 *
1660 * @return the multiplication factor for the height of the 4x4 interleaved block
1661 */
1662 int mult_interleave4x4_height() const
1663 {
1664 return _mult_interleave4x4_height;
1665 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001666 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
1667 *
1668 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
1669 * m = depth_output_gemm3d * output_height
1670 *
1671 * @return the depth of the output tensor to be used with the GEMM3D kernel
1672 */
1673 int depth_output_gemm3d() const
1674 {
1675 return _depth_output_gemm3d;
1676 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001677 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
1678 *
1679 * @return True if the input tensor has to be reinterpreted as 3D tensor
1680 */
1681 bool reinterpret_input_as_3d() const
1682 {
1683 return _reinterpret_input_as_3d;
1684 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001685 /** Flag which specifies whether to broadcast the shape of the bias tensor.
1686 *
1687 * @return True if the shape of the bias tensor is to be broadcasted.
1688 */
1689 bool broadcast_bias() const
1690 {
1691 return _broadcast_bias;
1692 };
Gian Marco36a0a462018-01-12 10:21:40 +00001693
1694private:
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001695 const int _m;
1696 const int _n;
1697 const int _k;
1698 const int _mult_transpose1xW_width;
1699 const int _mult_interleave4x4_height;
1700 const int _depth_output_gemm3d;
1701 const bool _reinterpret_input_as_3d;
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001702 const bool _broadcast_bias;
Gian Marco36a0a462018-01-12 10:21:40 +00001703};
1704
giuros016d109962019-01-07 17:47:19 +00001705struct DepthwiseConvolutionReshapeInfo
1706{
1707 unsigned int c0{ 1 }; /**< Number of channels processed by the depth-wise convolution */
1708 bool transpose{ false }; /**< True if the block MxC0 (where M is the area of the filter i.e. KwxKh) has to be transposed */
1709};
1710
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001711/** GEMMLowp output stage type */
1712enum class GEMMLowpOutputStageType
1713{
1714 NONE, /**< No quantization to uint8 */
1715 QUANTIZE_DOWN, /**< Quantize to uint8 using an integer multiplication */
1716 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize to uint8 using a fixed point multiplication */
1717 QUANTIZE_DOWN_FLOAT /**< Quantize to uint8 using a floating point multiplication */
1718};
1719
1720/** GEMMLowp output stage info */
1721struct GEMMLowpOutputStageInfo
1722{
1723 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
1724 int gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
1725 int gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1726 int gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
1727 int gemmlowp_min_bound{ 0 }; /**< GEMMLowp min value used to saturate down the output result before converting back to QASYMM8 */
1728 int gemmlowp_max_bound{ 0 }; /**< GEMMLowp max value used to saturate down the output result before converting back to QASYMM8 */
1729};
1730
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00001731/** GEMM LHS (Left Hand Side) matrix information */
1732struct GEMMLHSMatrixInfo
1733{
1734 unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
1735 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1736 unsigned int v0{ 1 }; /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
1737 bool transpose{ true }; /**< True if the (m0xk0) block has to be transposed before been stored */
1738 bool interleave{ true }; /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
1739};
1740
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00001741/** GEMM RHS (Right Hand Side) matrix information */
1742struct GEMMRHSMatrixInfo
1743{
1744 unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
1745 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1746 unsigned int h0{ 1 }; /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
1747 bool transpose{ true }; /**< True if the (k0xn0) block has to be transposed before been stored */
1748 bool interleave{ true }; /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
1749};
1750
Gian Marco36a0a462018-01-12 10:21:40 +00001751/** GEMM information class. This class stores the necessary information to compute GEMM functions
1752 *
1753 * This object also contains the information about how matrix A and matrix B have been reshaped
1754 *
1755 */
Chunosov5124be52017-11-22 20:42:13 +07001756class GEMMInfo
1757{
1758public:
1759 /** Default constructor */
1760 GEMMInfo()
Anthony Barbier08a45172018-11-30 17:20:26 +00001761 : _is_a_reshaped(false), _is_b_reshaped(false), _reshape_b_only_on_first_run(true), _depth_output_gemm3d(0), _reinterpret_input_as_3d(false), _retain_internal_weights(false), _gemmlowp_output_stage(),
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001762 _fp_mixed_precision(false), _broadcast_bias(false)
Chunosov5124be52017-11-22 20:42:13 +07001763 {
1764 }
1765 /** Constructor
1766 *
1767 * @param[in] is_a_reshaped True if the matrix A has been reshaped
1768 * @param[in] is_b_reshaped True if the matrix B has been reshaped
1769 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001770 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001771 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001772 * @param[in] reinterpret_input_as_3d (Optional) Reinterpret the input as 3D tensor. (i.e. this flag should be set to true when GEMM is used
1773 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01001774 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001775 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001776 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001777 * @param[in] broadcast_bias (Optional) Broadcast the shape of the bias tensor from a vector to a matrix.
Chunosov5124be52017-11-22 20:42:13 +07001778 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001779 GEMMInfo(bool is_a_reshaped, bool is_b_reshaped, bool reshape_b_only_on_first_run, int depth_output_gemm3d = 0, bool reinterpret_input_as_3d = false, bool retain_internal_weights = false,
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001780 GEMMLowpOutputStageInfo gemmlowp_output_stage = GEMMLowpOutputStageInfo(), bool fp_mixed_precision = false, bool broadcast_bias = false)
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001781 : _is_a_reshaped(is_a_reshaped), _is_b_reshaped(is_b_reshaped), _reshape_b_only_on_first_run(reshape_b_only_on_first_run), _depth_output_gemm3d(depth_output_gemm3d),
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001782 _reinterpret_input_as_3d(reinterpret_input_as_3d), _retain_internal_weights(retain_internal_weights), _gemmlowp_output_stage(gemmlowp_output_stage), _fp_mixed_precision(fp_mixed_precision),
1783 _broadcast_bias(broadcast_bias)
Chunosov5124be52017-11-22 20:42:13 +07001784 {
1785 }
1786 /** Flag which specifies if the matrix A has been reshaped
1787 *
1788 * @return True if the matrix A has been reshaped
1789 */
1790 bool is_a_reshaped() const
1791 {
1792 return _is_a_reshaped;
1793 };
1794 /** Flag which specifies if the matrix B has been reshaped
1795 *
1796 * @return True if the matrix B has been reshaped
1797 */
1798 bool is_b_reshaped() const
1799 {
1800 return _is_b_reshaped;
1801 };
1802 /** Flag which specifies if the reshape of matrix B should executed only for the first
1803 *
1804 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
1805 *
1806 * @return True if the reshaped of matrix B happens only for the first run
1807 */
1808 bool reshape_b_only_on_first_run() const
1809 {
1810 return _reshape_b_only_on_first_run;
1811 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001812 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00001813 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001814 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00001815 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001816 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00001817 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001818 return _depth_output_gemm3d;
1819 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001820 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
1821 *
1822 * @return True if the input tensor has to be reinterpreted as 3D tensor
1823 */
1824 bool reinterpret_input_as_3d() const
1825 {
1826 return _reinterpret_input_as_3d;
1827 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01001828 /** Flag which specifies if the weights tensor has to be retained from previous run
1829 *
1830 * @return True if the weights tensor has to be retained
1831 */
1832 bool retain_internal_weights() const
1833 {
1834 return _retain_internal_weights;
1835 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001836 /** GEMMLowp output stage
1837 *
1838 * @return the GEMMLowp output stage info
1839 */
1840 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
1841 {
1842 return _gemmlowp_output_stage;
1843 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001844 /** Flag which specifies if a wider accumulator should be used.
1845 *
1846 * @return True if a wider accumulator has to be used
1847 */
1848 bool fp_mixed_precision() const
1849 {
1850 return _fp_mixed_precision;
1851 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001852 /** Flag which specifies whether to broadcast the shape of the bias tensor.
1853 *
1854 * @return True if the shape of the bias tensor is to be broadcasted.
1855 */
1856 bool broadcast_bias() const
1857 {
1858 return _broadcast_bias;
1859 };
Chunosov5124be52017-11-22 20:42:13 +07001860
1861private:
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001862 const bool _is_a_reshaped;
1863 const bool _is_b_reshaped;
1864 const bool _reshape_b_only_on_first_run;
1865 const int _depth_output_gemm3d;
1866 const bool _reinterpret_input_as_3d;
1867 const bool _retain_internal_weights;
1868 const GEMMLowpOutputStageInfo _gemmlowp_output_stage;
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001869 const bool _fp_mixed_precision;
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001870 const bool _broadcast_bias;
Chunosov5124be52017-11-22 20:42:13 +07001871};
1872
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00001873/** Winograd information */
1874struct WinogradInfo
1875{
1876 /** Default constructor
1877 *
1878 * @param[in] output_tile_sz Width and height of the output tile
1879 * @param[in] kernel_sz Width and height of the kernel
1880 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
1881 * @param[in] conv_info Convolution info (Pads, strides)
1882 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
1883 */
1884 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
1885 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
1886 {
1887 }
1888
1889 Size2D output_tile_size{}; /**< Width and height of the output tile */
1890 Size2D kernel_size{}; /**< Width and height of the kernel*/
1891 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
1892 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
1893 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
1894};
1895
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001896/** IO formatting information class*/
1897struct IOFormatInfo
1898{
1899 /** Precision type used when printing floating point numbers */
1900 enum class PrecisionType
1901 {
1902 Default, /**< Default precision to the one that the current stream has */
1903 Custom, /**< Custom precision specified by the user using the precision parameter */
1904 Full /**< The maximum precision of the floating point representation */
1905 };
1906
1907 /** Specifies the area to be printed, used by Tensor objects */
1908 enum class PrintRegion
1909 {
1910 ValidRegion, /**< Prints the valid region of the Tensor object */
1911 NoPadding, /**< Prints the Tensor object without the padding */
1912 Full /**< Print the tensor object including padding */
1913 };
1914
Alex Gildayc357c472018-03-21 13:54:09 +00001915 /** Construct a set of IO formatting information.
1916 *
1917 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
1918 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
1919 * @param[in] precision Precision value for float point numbers. Default: 10.
1920 * @param[in] align_columns Whether to align columns when printed. Default: true.
1921 * @param[in] element_delim Delimeter between elements. Default: " ".
1922 * @param[in] row_delim Delimenter between rows. Default: "\n".
1923 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001924 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
1925 PrecisionType precision_type = PrecisionType::Default,
1926 unsigned int precision = 10,
1927 bool align_columns = true,
1928 std::string element_delim = " ",
1929 std::string row_delim = "\n")
1930 : print_region(print_region),
1931 precision_type(precision_type),
1932 precision(precision),
1933 element_delim(element_delim),
1934 row_delim(row_delim),
1935 align_columns(align_columns)
1936 {
1937 }
1938
Alex Gildayc357c472018-03-21 13:54:09 +00001939 /** Area to be printed by Tensor objects */
1940 PrintRegion print_region;
1941 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001942 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00001943 /** Floating point precision */
1944 unsigned int precision;
1945 /** Element delimeter */
1946 std::string element_delim;
1947 /** Row delimeter */
1948 std::string row_delim;
1949 /** Align columns */
1950 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001951};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00001952} // namespace arm_compute
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001953#endif /* __ARM_COMPUTE_TYPES_H__ */