blob: cf689d757c617808768fa7565783cca6d7bff3bd [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Manuel Bottini959c26d2019-12-02 16:22:35 +00002 * Copyright (c) 2016-2020 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 */
Michalis Spyrouf4643372019-11-29 16:17:13 +000024#ifndef ARM_COMPUTE_TYPES_H
25#define ARM_COMPUTE_TYPES_H
Anthony Barbier6ff3b192017-09-04 18:44:23 +010026
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"
Sang-Hoon Park11fedda2020-01-15 14:44:04 +000032#include "arm_compute/core/utils/misc/Macros.h"
Georgios Pinitas583137c2017-08-31 18:12:42 +010033#include "support/Half.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010034
Michel Iwaniec5dfeae62017-11-29 10:48:23 +000035#include <cmath>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010036#include <cstddef>
37#include <cstdint>
Isabella Gottardia7acb3c2019-01-08 13:48:44 +000038#include <map>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010039#include <string>
40#include <utility>
41
42namespace arm_compute
43{
Georgios Pinitas583137c2017-08-31 18:12:42 +010044/** 16-bit floating point type */
45using half = half_float::half;
46
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000047/** Permutation vector */
48using PermutationVector = Strides;
Georgios Pinitas77589b52018-08-21 14:41:35 +010049/** Bidirectional strides */
50using BiStrides = Coordinates;
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000051
Anthony Barbier6ff3b192017-09-04 18:44:23 +010052/** Image colour formats */
53enum class Format
54{
Daniil Efremov02bf80d2017-11-22 00:26:51 +070055 UNKNOWN, /**< Unknown image format */
56 U8, /**< 1 channel, 1 U8 per channel */
57 S16, /**< 1 channel, 1 S16 per channel */
58 U16, /**< 1 channel, 1 U16 per channel */
59 S32, /**< 1 channel, 1 S32 per channel */
60 U32, /**< 1 channel, 1 U32 per channel */
61 F16, /**< 1 channel, 1 F16 per channel */
62 F32, /**< 1 channel, 1 F32 per channel */
63 UV88, /**< 2 channel, 1 U8 per channel */
64 RGB888, /**< 3 channels, 1 U8 per channel */
65 RGBA8888, /**< 4 channels, 1 U8 per channel */
66 YUV444, /**< A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes */
67 YUYV422, /**< A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes */
68 NV12, /**< A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling */
69 NV21, /**< A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling */
70 IYUV, /**< A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes */
71 UYVY422 /**< A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010072};
73
74/** Available data types */
75enum class DataType
76{
Georgios Pinitas8217c8e2019-11-11 18:24:22 +000077 UNKNOWN, /**< Unknown data type */
78 U8, /**< unsigned 8-bit number */
79 S8, /**< signed 8-bit number */
80 QSYMM8, /**< quantized, symmetric fixed-point 8-bit number */
81 QASYMM8, /**< quantized, asymmetric fixed-point 8-bit number unsigned */
82 QASYMM8_SIGNED, /**< quantized, asymmetric fixed-point 8-bit number signed */
83 QSYMM8_PER_CHANNEL, /**< quantized, symmetric per channel fixed-point 8-bit number */
84 U16, /**< unsigned 16-bit number */
85 S16, /**< signed 16-bit number */
86 QSYMM16, /**< quantized, symmetric fixed-point 16-bit number */
87 QASYMM16, /**< quantized, asymmetric fixed-point 16-bit number */
88 U32, /**< unsigned 32-bit number */
89 S32, /**< signed 32-bit number */
90 U64, /**< unsigned 64-bit number */
91 S64, /**< signed 64-bit number */
92 F16, /**< 16-bit floating-point number */
93 F32, /**< 32-bit floating-point number */
94 F64, /**< 64-bit floating-point number */
95 SIZET /**< size_t */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010096};
97
Daniil Efremov02bf80d2017-11-22 00:26:51 +070098/** Available Sampling Policies */
99enum class SamplingPolicy
100{
101 CENTER, /**< Samples are taken at pixel center */
102 TOP_LEFT /**< Samples are taken at pixel top left corner */
103};
104
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100105/** Constant value of the border pixels when using BorderMode::CONSTANT */
106constexpr uint8_t CONSTANT_BORDER_VALUE = 199;
107
Alex Gildayc357c472018-03-21 13:54:09 +0000108/** Constant value used to indicate a half-scale pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100109constexpr float SCALE_PYRAMID_HALF = 0.5f;
110
Alex Gildayc357c472018-03-21 13:54:09 +0000111/** Constant value used to indicate a ORB scaled pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100112constexpr float SCALE_PYRAMID_ORB = 8.408964152537146130583778358414e-01;
113
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000114/** [DataLayout enum definition] **/
115
Georgios Pinitas4074c992018-01-30 18:13:46 +0000116/** Supported tensor data layouts */
117enum class DataLayout
118{
Alex Gildayc357c472018-03-21 13:54:09 +0000119 UNKNOWN, /**< Unknown data layout */
120 NCHW, /**< Num samples, channels, height, width */
121 NHWC /**< Num samples, height, width, channels */
Georgios Pinitas4074c992018-01-30 18:13:46 +0000122};
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000123/** [DataLayout enum definition] **/
Georgios Pinitas4074c992018-01-30 18:13:46 +0000124
Isabella Gottardid17a6772018-02-27 17:41:55 +0000125/** Supported tensor data layout dimensions */
126enum class DataLayoutDimension
127{
Alex Gildayc357c472018-03-21 13:54:09 +0000128 CHANNEL, /**< channel */
129 HEIGHT, /**< height */
130 WIDTH, /**< width */
131 BATCHES /**< batches */
Isabella Gottardid17a6772018-02-27 17:41:55 +0000132};
133
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000134/** Available ConvolutionMethod*/
135enum class ConvolutionMethod
136{
Vidhya Sudhan Loganathan8ec0bb62019-04-23 10:40:44 +0100137 GEMM, /**< Convolution using GEMM */
138 DIRECT, /**< Direct convolution */
139 WINOGRAD, /**< Convolution using Winograd */
140 FFT /**< Convolution using FFT */
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000141};
142
Manuel Bottini05069f02019-09-26 17:18:26 +0100143/** Available DepthwiseConvolutionFunction*/
144enum class DepthwiseConvolutionFunction
145{
146 OPTIMIZED, /**< Optimized Depthwise Convolution */
147 GENERIC, /**< Generic Depthwise Convolution */
148};
149
giuros0146a49a02019-04-01 13:50:22 +0100150/** Available DeconvolutionMethod*/
151enum class DeconvolutionMethod
152{
153 GEMM, /**< Deconvolution using GEMM */
154 DIRECT, /**< Direct deconvolution */
155};
156
Manuel Bottini2732cca2019-05-28 11:44:41 +0100157/** Available FuseBatchNormalizationType*/
158enum class FuseBatchNormalizationType
159{
160 CONVOLUTION, /**< For Convolution weights */
161 DEPTHWISECONVOLUTION /**< For Depthwise Convolution weights*/
162};
163
Usama Arif89890c62019-03-19 10:57:05 +0000164/** Padding mode to use for PadLayer */
165enum class PaddingMode
166{
167 CONSTANT,
168 REFLECT,
169 SYMMETRIC
170};
171
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000172/** Supported comparison operations */
173enum class ComparisonOperation
174{
175 Equal, /**< Equal comparison ( \f$ x == y \f$ ) */
176 NotEqual, /**< NotEqual comparison ( \f$ x != y \f$ ) */
177 Greater, /**< Greater comparison ( \f$ x > y \f$ ) */
178 GreaterEqual, /**< Greater equal comparison ( \f$ x >= y \f$ ) */
179 Less, /**< Less comparison ( \f$ x < y \f$ ) */
180 LessEqual /**< Less equal comparison ( \f$ x <= y \f$ ) */
181};
182
Alex Gildayc357c472018-03-21 13:54:09 +0000183/** Container for valid region of a window */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100184struct ValidRegion
185{
Alex Gildayc357c472018-03-21 13:54:09 +0000186 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100187 ValidRegion()
188 : anchor{}, shape{}
189 {
190 }
191
Alex Gildayc357c472018-03-21 13:54:09 +0000192 /** Allow instances of this class to be copy constructed */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100193 ValidRegion(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000194 /** Allow instances of this class to be move constructed */
195 ValidRegion(ValidRegion &&) = default;
196 /** Allow instances of this class to be copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100197 ValidRegion &operator=(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000198 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100199 ValidRegion &operator=(ValidRegion &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000200 /** Default destructor */
201 ~ValidRegion() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100202
Alex Gildayc357c472018-03-21 13:54:09 +0000203 /** Constructor for a valid region with default number of dimensions
204 *
205 * @param[in] an_anchor Anchor for the start of the valid region.
206 * @param[in] a_shape Shape of the valid region.
207 *
208 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000209 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
210 : anchor{ an_anchor }, shape{ a_shape }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100211 {
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000212 anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
213 }
214
Alex Gildayc357c472018-03-21 13:54:09 +0000215 /** Constructor for a valid region with specified number of dimensions
216 *
217 * @param[in] an_anchor Anchor for the start of the valid region.
218 * @param[in] a_shape Shape of the valid region.
219 * @param[in] num_dimensions Number of dimensions (must be >= number of dimensions of anchor and shape).
220 *
221 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000222 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
223 : anchor{ an_anchor }, shape{ a_shape }
224 {
225 ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
226 anchor.set_num_dimensions(num_dimensions);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100227 }
228
229 /** Return the start of the valid region for the given dimension @p d */
230 int start(unsigned int d) const
231 {
232 return anchor[d];
233 }
234
235 /** Return the end of the valid region for the given dimension @p d */
236 int end(unsigned int d) const
237 {
238 return anchor[d] + shape[d];
239 }
240
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000241 /** Accessor to set the value of anchor and shape for one of the dimensions.
242 *
243 * @param[in] dimension Dimension for which the value is set.
244 * @param[in] start Value to be set in anchor for the dimension.
245 * @param[in] size Value to be set in shape for the dimension.
246 *
247 * @return *this.
248 */
249 ValidRegion &set(size_t dimension, int start, size_t size)
250 {
251 anchor.set(dimension, start);
252 shape.set(dimension, size);
253 return *this;
254 }
255
Alex Gildayc357c472018-03-21 13:54:09 +0000256 Coordinates anchor; /**< Anchor for the start of the valid region. */
257 TensorShape shape; /**< Shape of the valid region. */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100258};
259
260/** Methods available to handle borders */
261enum class BorderMode
262{
263 UNDEFINED, /**< Borders are left undefined */
264 CONSTANT, /**< Pixels outside the image are assumed to have a constant value */
265 REPLICATE /**< Pixels outside the image are assumed to have the same value as the closest image pixel */
266};
267
268/** Container for 2D border size */
269struct BorderSize
270{
271 /** Empty border, i.e. no border */
272 constexpr BorderSize()
273 : top{ 0 }, right{ 0 }, bottom{ 0 }, left{ 0 }
274 {
275 }
276
277 /** Border with equal size around the 2D plane */
Moritz Pflanzer7655a672017-09-23 11:57:33 +0100278 explicit constexpr BorderSize(unsigned int size)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100279 : top{ size }, right{ size }, bottom{ size }, left{ size }
280 {
281 }
282
283 /** Border with same size for top/bottom and left/right */
284 constexpr BorderSize(unsigned int top_bottom, unsigned int left_right)
285 : top{ top_bottom }, right{ left_right }, bottom{ top_bottom }, left{ left_right }
286 {
287 }
288
289 /** Border with different sizes */
290 constexpr BorderSize(unsigned int top, unsigned int right, unsigned int bottom, unsigned int left)
291 : top{ top }, right{ right }, bottom{ bottom }, left{ left }
292 {
293 }
294
295 /** Check if the entire border is zero */
296 constexpr bool empty() const
297 {
298 return top == 0 && right == 0 && bottom == 0 && left == 0;
299 }
300
301 /** Check if the border is the same size on all sides */
302 constexpr bool uniform() const
303 {
304 return top == right && top == bottom && top == left;
305 }
306
Alex Gildayc357c472018-03-21 13:54:09 +0000307 /** Scale this border size.
308 *
309 * @param[in] scale Scale to multiply border size by.
310 *
311 * @return *this.
312 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100313 BorderSize &operator*=(float scale)
314 {
315 top *= scale;
316 right *= scale;
317 bottom *= scale;
318 left *= scale;
319
320 return *this;
321 }
322
Alex Gildayc357c472018-03-21 13:54:09 +0000323 /** Scale a copy of this border size.
324 *
325 * @param[in] scale Scale to multiply border size by.
326 *
327 * @return a scaled copy of this.
328 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100329 BorderSize operator*(float scale)
330 {
331 BorderSize size = *this;
332 size *= scale;
333
334 return size;
335 }
336
Alex Gildayc357c472018-03-21 13:54:09 +0000337 /** Limit this border size.
338 *
339 * @param[in] limit Border size to limit this border size to.
340 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100341 void limit(const BorderSize &limit)
342 {
343 top = std::min(top, limit.top);
344 right = std::min(right, limit.right);
345 bottom = std::min(bottom, limit.bottom);
346 left = std::min(left, limit.left);
347 }
348
Alex Gildayc357c472018-03-21 13:54:09 +0000349 unsigned int top; /**< top of the border */
350 unsigned int right; /**< right of the border */
351 unsigned int bottom; /**< bottom of the border */
352 unsigned int left; /**< left of the border */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100353};
354
Alex Gildayc357c472018-03-21 13:54:09 +0000355/** Container for 2D padding size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100356using PaddingSize = BorderSize;
357
358/** Policy to handle overflow */
359enum class ConvertPolicy
360{
361 WRAP, /**< Wrap around */
362 SATURATE /**< Saturate */
363};
364
365/** Interpolation method */
366enum class InterpolationPolicy
367{
368 NEAREST_NEIGHBOR, /**< Output values are defined to match the source pixel whose center is nearest to the sample position */
369 BILINEAR, /**< Output values are defined by bilinear interpolation between the pixels */
370 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 */
371};
372
373/** Bilinear Interpolation method used by LKTracker */
374enum class BilinearInterpolation
375{
Alex Gildayc357c472018-03-21 13:54:09 +0000376 BILINEAR_OLD_NEW, /**< Old-new method */
377 BILINEAR_SCHARR /**< Scharr method */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100378};
379
380/** Threshold mode */
381enum class ThresholdType
382{
383 BINARY, /**< Threshold with one value */
384 RANGE /**< Threshold with two values*/
385};
386
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100387/** Termination criteria */
388enum class Termination
389{
Alex Gildayc357c472018-03-21 13:54:09 +0000390 TERM_CRITERIA_EPSILON, /**< Terminate when within epsilon of a threshold */
391 TERM_CRITERIA_ITERATIONS, /**< Terminate after a maximum number of iterations */
392 TERM_CRITERIA_BOTH /**< Terminate on whichever of the other conditions occurs first */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100393};
394
395/** Magnitude calculation type. */
396enum class MagnitudeType
397{
398 L1NORM, /**< L1 normalization type */
399 L2NORM /**< L2 normalization type */
400};
401
402/** Phase calculation type.
403 *
404 * @note When PhaseType == SIGNED, each angle is mapped to the range 0 to 255 inclusive otherwise angles between 0 and 180
405 */
406enum class PhaseType
407{
408 SIGNED, /**< Angle range: [0, 360] */
409 UNSIGNED /**< Angle range: [0, 180] */
410};
411
412/** Keypoint type */
413struct KeyPoint
414{
415 int32_t x{ 0 }; /**< X coordinates */
416 int32_t y{ 0 }; /**< Y coordinates */
417 float strength{ 0.f }; /**< Strength of the point */
418 float scale{ 0.f }; /**< Scale initialized to 0 by the corner detector */
419 float orientation{ 0.f }; /**< Orientation initialized to 0 by the corner detector */
420 int32_t tracking_status{ 0 }; /**< Status initialized to 1 by the corner detector, set to 0 when the point is lost */
421 float error{ 0.f }; /**< Tracking error initialized to 0 by the corner detector */
422};
423
Alex Gildayc357c472018-03-21 13:54:09 +0000424/** Internal key point */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100425using InternalKeypoint = std::tuple<float, float, float>; /* x,y,strength */
426
427/** Rectangle type */
428struct Rectangle
429{
430 uint16_t x; /**< Top-left x coordinate */
431 uint16_t y; /**< Top-left y coordinate */
432 uint16_t width; /**< Width of the rectangle */
433 uint16_t height; /**< Height of the rectangle */
434};
435
436/** Coordinate type */
437struct Coordinates2D
438{
439 int32_t x; /**< X coordinates */
440 int32_t y; /**< Y coordinates */
441};
442
443/** Coordinate type */
444struct Coordinates3D
445{
446 uint32_t x; /**< X coordinates */
447 uint32_t y; /**< Y coordinates */
448 uint32_t z; /**< Z coordinates */
449};
450
Giuseppe Rossinid7647d42018-07-17 18:13:13 +0100451/** Padding information as a pair of unsigned int start/end */
452using PaddingInfo = std::pair<uint32_t, uint32_t>;
453
454/** List of padding information */
455using PaddingList = std::vector<PaddingInfo>;
456
giuros013175fcf2018-11-21 09:59:17 +0000457/** Information to produce a tiled version of a Tensor */
458using Multiples = std::vector<uint32_t>;
459
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100460/** Available channels */
461enum class Channel
462{
463 UNKNOWN, /** Unknown channel format */
464 C0, /**< First channel (used by formats with unknown channel types). */
465 C1, /**< Second channel (used by formats with unknown channel types). */
466 C2, /**< Third channel (used by formats with unknown channel types). */
467 C3, /**< Fourth channel (used by formats with unknown channel types). */
468 R, /**< Red channel. */
469 G, /**< Green channel. */
470 B, /**< Blue channel. */
471 A, /**< Alpha channel. */
472 Y, /**< Luma channel. */
473 U, /**< Cb/U channel. */
474 V /**< Cr/V/Value channel. */
475};
476
477/** Available matrix patterns */
478enum class MatrixPattern
479{
480 BOX, /**< Box pattern matrix. */
481 CROSS, /**< Cross pattern matrix. */
482 DISK, /**< Disk pattern matrix. */
483 OTHER /**< Any other matrix pattern. */
484};
485
486/** Available non linear functions. */
487enum class NonLinearFilterFunction : unsigned
488{
489 MEDIAN = 0, /**< Non linear median filter. */
490 MIN = 1, /**< Non linear erode. */
491 MAX = 2, /**< Non linear dilate. */
492};
493
Georgios Pinitasd9769582017-08-03 10:19:40 +0100494/** Available reduction operations */
495enum class ReductionOperation
496{
Michalis Spyrou7930db42018-11-22 17:36:28 +0000497 ARG_IDX_MAX, /**< Index of the max value */
Manuel Bottinib412fab2018-12-10 17:40:23 +0000498 ARG_IDX_MIN, /**< Index of the min value */
499 MEAN_SUM, /**< Mean of sum */
500 PROD, /**< Product */
501 SUM_SQUARE, /**< Sum of squares */
Usama Arifa4a08ad2019-05-20 12:38:33 +0100502 SUM, /**< Sum */
503 MIN, /**< Min */
Usama Arif28f0dd92019-05-20 13:44:34 +0100504 MAX, /**< Max */
Georgios Pinitasd9769582017-08-03 10:19:40 +0100505};
506
giuros01164a2722018-11-20 18:34:46 +0000507/** Available element-wise operations */
508enum class ArithmeticOperation
509{
510 ADD, /**< (x + y) */
511 SUB, /**< (x - y) */
512 DIV, /**< (x / y) */
513 MIN, /**< Min(x, y) */
514 MAX, /**< Max(x, y) */
515 SQUARED_DIFF, /**< (x - y)^2 */
Usama Arif81e671e2019-05-13 13:33:14 +0100516 POWER, /**< x ^ y */
giuros011e6e1b82019-05-14 16:12:53 +0100517 PRELU, /**< y*x if x < 0, x otherwise */
giuros01164a2722018-11-20 18:34:46 +0000518};
519
Michalis Spyroue9362622018-11-23 17:41:37 +0000520/** Available element wise unary operations */
521enum class ElementWiseUnary
522{
523 RSQRT, /**< Reverse square root */
524 EXP, /**< Exponential */
Usama Ariff6e475c2019-05-10 12:06:28 +0100525 NEG, /**< Negate */
Usama Arifc255aa72019-05-13 16:26:29 +0100526 LOG, /**< Natural Logarithm */
Manuel Bottini6ac59922019-05-15 14:06:02 +0100527 ABS, /**< Absolute value */
Michalis Spyrou0af44182019-05-17 14:04:47 +0100528 SIN, /**< Sine */
Usama Arif0a5a57a2019-05-23 14:20:33 +0100529 ROUND, /**< Round */
Michalis Spyroue9362622018-11-23 17:41:37 +0000530};
531
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100532/** The normalization type used for the normalization layer */
533enum class NormType
534{
535 IN_MAP_1D, /**< Normalization applied within the same map in 1D region */
536 IN_MAP_2D, /**< Normalization applied within the same map in 2D region */
537 CROSS_MAP /**< Normalization applied cross maps */
538};
539
540/** Normalization type for Histogram of Oriented Gradients (HOG) */
541enum class HOGNormType
542{
543 L2_NORM = 1, /**< L2-norm */
544 L2HYS_NORM = 2, /**< L2-norm followed by clipping */
545 L1_NORM = 3 /**< L1 norm */
546};
547
548/** Detection window used for the object detection. The detection window keeps the following information:
549 *
550 * -# Geometry of the rectangular window (x/y of top-left corner and width/height)
551 * -# Index of the class used for evaluating which class the detection window belongs to
552 * -# Confidence value (score) obtained with the classifier
553 */
554struct DetectionWindow
555{
556 uint16_t x{ 0 }; /**< Top-left x coordinate */
557 uint16_t y{ 0 }; /**< Top-left y coordinate */
558 uint16_t width{ 0 }; /**< Width of the detection window */
559 uint16_t height{ 0 }; /**< Height of the detection window */
560 uint16_t idx_class{ 0 }; /**< Index of the class */
561 float score{ 0.f }; /**< Confidence value for the detection window */
562};
563
564/** Dimension rounding type when down-scaling on CNNs
565 * @note Used in pooling and convolution layer
566 */
567enum class DimensionRoundingType
568{
569 FLOOR, /**< Floor rounding */
570 CEIL /**< Ceil rounding */
571};
572
573/** Available pooling types */
574enum class PoolingType
575{
576 MAX, /**< Max Pooling */
Georgios Pinitascdf51452017-08-31 14:21:36 +0100577 AVG, /**< Average Pooling */
578 L2 /**< L2 Pooling */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100579};
580
Michalis Spyrou2709d612018-09-19 09:46:47 +0100581/** Available non maxima suppression types */
582enum class NMSType
583{
584 LINEAR, /**< Linear NMS */
585 GAUSSIAN, /**< Gaussian NMS */
586 ORIGINAL /**< Original NMS */
587};
588
589/** BoxWithNonMaximaSuppressionLimit Information class */
590class BoxNMSLimitInfo final
591{
592public:
593 /** Constructor
594 *
595 * @param[in] score_thresh (Optional) Score threshold.
596 * @param[in] nms (Optional) NMS value
597 * @param[in] detections (Optional) Number of detections
598 * @param[in] soft_nms_enabled (Optional) Enable SoftNMS
599 * @param[in] soft_nms_method (Optional) Soft NMS method
600 * @param[in] soft_nms_sigma (Optional) Soft NMS sigma value
601 * @param[in] soft_nms_min_score_thres (Optional) Soft NMS minimum score threshold
Manuel Bottini5209be52019-02-13 16:34:56 +0000602 * @param[in] suppress_size (Optional) Filter out boxes based on their size. Defaults to false
603 * @param[in] min_size (Optional) Smaller boxes than min_size will be filtered out. Defaults to 1
604 * @param[in] im_width (Optional) Boxes whose centers (on the x axis) is beyond im_width will be filtered. Defaults to 1
605 * @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 +0100606 */
607 BoxNMSLimitInfo(float score_thresh = 0.05f, float nms = 0.3f,
608 int detections = 100, bool soft_nms_enabled = false,
609 NMSType soft_nms_method = NMSType::LINEAR,
Manuel Bottini5209be52019-02-13 16:34:56 +0000610 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 +0100611 : _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 +0000612 _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 +0100613 {
614 }
615 /** Get the score threshold */
616 float score_thresh() const
617 {
618 return _score_thresh;
619 }
620 /** Get the NMS */
621 float nms() const
622 {
623 return _nms;
624 }
625 /** Get the number of detections */
626 int detections_per_im() const
627 {
628 return _detections_per_im;
629 }
630 /** Check if soft NMS is enabled */
631 bool soft_nms_enabled() const
632 {
633 return _soft_nms_enabled;
634 }
635 /** Get soft NMS method */
636 NMSType soft_nms_method() const
637 {
638 return _soft_nms_method;
639 }
640 /** Get soft NMS sigma */
641 float soft_nms_sigma() const
642 {
643 return _soft_nms_sigma;
644 }
645 /** Get soft nms min score threshold */
646 float soft_nms_min_score_thres() const
647 {
648 return _soft_nms_min_score_thres;
649 }
Manuel Bottini5209be52019-02-13 16:34:56 +0000650 /** Get if NMS will suppress boxes based on their size/position */
651 bool suppress_size() const
652 {
653 return _suppress_size;
654 }
655 /** Get size suppression threshold */
656 float min_size() const
657 {
658 return _min_size;
659 }
660 /** Get image width (NMS may suppress boxes whose center sits beyond the image width) */
661 float im_width() const
662 {
663 return _im_width;
664 }
665 /** Get image height (NMS may suppress boxes whose center sits beyond the image height) */
666 float im_height() const
667 {
668 return _im_height;
669 }
Michalis Spyrou2709d612018-09-19 09:46:47 +0100670
671private:
672 float _score_thresh;
673 float _nms;
674 int _detections_per_im;
675 bool _soft_nms_enabled;
676 NMSType _soft_nms_method;
677 float _soft_nms_sigma;
678 float _soft_nms_min_score_thres;
Manuel Bottini5209be52019-02-13 16:34:56 +0000679 bool _suppress_size;
680 float _min_size;
681 float _im_width;
682 float _im_height;
Michalis Spyrou2709d612018-09-19 09:46:47 +0100683};
684
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100685/** Padding and stride information class */
686class PadStrideInfo
687{
688public:
689 /** Constructor
690 *
691 * @param[in] stride_x (Optional) Stride, in elements, across x. Defaults to 1.
692 * @param[in] stride_y (Optional) Stride, in elements, across y. Defaults to 1.
693 * @param[in] pad_x (Optional) Padding, in elements, across x. Defaults to 0.
694 * @param[in] pad_y (Optional) Padding, in elements, across y. Defaults to 0.
695 * @param[in] round (Optional) Dimensions rounding. Defaults to @ref FLOOR.
696 */
697 PadStrideInfo(unsigned int stride_x = 1, unsigned int stride_y = 1,
698 unsigned int pad_x = 0, unsigned int pad_y = 0,
699 DimensionRoundingType round = DimensionRoundingType::FLOOR)
700 : _stride(std::make_pair(stride_x, stride_y)),
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100701 _pad_left(pad_x),
702 _pad_top(pad_y),
703 _pad_right(pad_x),
704 _pad_bottom(pad_y),
705 _round_type(round)
706 {
707 }
708 /** Constructor
709 *
710 * @param[in] stride_x Stride, in elements, across x.
711 * @param[in] stride_y Stride, in elements, across y.
712 * @param[in] pad_left Padding across x on the left, in elements.
713 * @param[in] pad_top Padding across y on the top, in elements.
714 * @param[in] pad_right Padding across x on the right, in elements.
715 * @param[in] pad_bottom Padding across y on the bottom, in elements.
716 * @param[in] round Dimensions rounding.
717 */
718 PadStrideInfo(unsigned int stride_x, unsigned int stride_y,
719 unsigned int pad_left, unsigned int pad_right,
720 unsigned int pad_top, unsigned int pad_bottom,
721 DimensionRoundingType round)
722 : _stride(std::make_pair(stride_x, stride_y)),
723 _pad_left(pad_left),
724 _pad_top(pad_top),
725 _pad_right(pad_right),
726 _pad_bottom(pad_bottom),
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100727 _round_type(round)
728 {
729 }
Alex Gildayc357c472018-03-21 13:54:09 +0000730 /** Get the stride.
731 *
732 * @return a pair: stride x, stride y.
733 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100734 std::pair<unsigned int, unsigned int> stride() const
735 {
736 return _stride;
737 }
Alex Gildayc357c472018-03-21 13:54:09 +0000738 /** Check whether the padding is symmetric.
739 *
740 * @return True if the padding is symmetric.
741 */
Anthony Barbier21f67d62018-02-16 15:17:48 +0000742 bool padding_is_symmetric() const
743 {
744 return (_pad_left == _pad_right) && (_pad_top == _pad_bottom);
745 }
Alex Gildayc357c472018-03-21 13:54:09 +0000746 /** Get the padding.
747 *
748 * @note This should only be used when the padding is symmetric.
749 *
750 * @return a pair: padding left/right, padding top/bottom
751 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100752 std::pair<unsigned int, unsigned int> pad() const
753 {
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100754 //this accessor should be used only when padding is symmetric
Anthony Barbier21f67d62018-02-16 15:17:48 +0000755 ARM_COMPUTE_ERROR_ON(!padding_is_symmetric());
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100756 return std::make_pair(_pad_left, _pad_top);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100757 }
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100758
Alex Gildayc357c472018-03-21 13:54:09 +0000759 /** Get the left padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100760 unsigned int pad_left() const
761 {
762 return _pad_left;
763 }
Alex Gildayc357c472018-03-21 13:54:09 +0000764 /** Get the right padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100765 unsigned int pad_right() const
766 {
767 return _pad_right;
768 }
Alex Gildayc357c472018-03-21 13:54:09 +0000769 /** Get the top padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100770 unsigned int pad_top() const
771 {
772 return _pad_top;
773 }
Alex Gildayc357c472018-03-21 13:54:09 +0000774 /** Get the bottom padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100775 unsigned int pad_bottom() const
776 {
777 return _pad_bottom;
778 }
779
Alex Gildayc357c472018-03-21 13:54:09 +0000780 /** Get the rounding type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100781 DimensionRoundingType round() const
782 {
783 return _round_type;
784 }
785
Alex Gildayc357c472018-03-21 13:54:09 +0000786 /** Check whether this has any padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100787 bool has_padding() const
788 {
789 return (_pad_left != 0 || _pad_top != 0 || _pad_right != 0 || _pad_bottom != 0);
790 }
791
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100792private:
793 std::pair<unsigned int, unsigned int> _stride;
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100794 unsigned int _pad_left;
795 unsigned int _pad_top;
796 unsigned int _pad_right;
797 unsigned int _pad_bottom;
798
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100799 DimensionRoundingType _round_type;
800};
801
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100802/** PriorBox layer info */
803class PriorBoxLayerInfo final
804{
805public:
806 /** Default Constructor */
807 PriorBoxLayerInfo()
808 : _min_sizes(),
809 _variances(),
810 _offset(),
811 _flip(true),
812 _clip(false),
813 _max_sizes(),
814 _aspect_ratios(),
815 _img_size(),
816 _steps()
817 {
818 }
819 /** Constructor
820 *
821 * @param[in] min_sizes Min sizes vector.
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100822 * @param[in] variances Variances vector.
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100823 * @param[in] offset Offset value.
824 * @param[in] flip (Optional) Flip the aspect ratios.
825 * @param[in] clip (Optional) Clip coordinates so that they're within [0,1].
826 * @param[in] max_sizes (Optional) Max sizes vector.
827 * @param[in] aspect_ratios (Optional) Aspect ratios of the boxes.
828 * @param[in] img_size (Optional) Image size.
829 * @param[in] steps (Optional) Step values.
830 */
831 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 +0000832 const std::vector<float> &max_sizes = {}, const std::vector<float> &aspect_ratios = {},
833 const Coordinates2D &img_size = Coordinates2D{ 0, 0 }, const std::array<float, 2> &steps = { { 0.f, 0.f } })
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100834 : _min_sizes(min_sizes),
835 _variances(variances),
836 _offset(offset),
837 _flip(flip),
838 _clip(clip),
839 _max_sizes(max_sizes),
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100840 _aspect_ratios(),
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100841 _img_size(img_size),
842 _steps(steps)
843 {
844 _aspect_ratios.push_back(1.);
845 for(unsigned int i = 0; i < aspect_ratios.size(); ++i)
846 {
847 float ar = aspect_ratios[i];
848 bool already_exist = false;
849 for(auto ar_new : _aspect_ratios)
850 {
851 if(fabs(ar - ar_new) < 1e-6)
852 {
853 already_exist = true;
854 break;
855 }
856 }
857 if(!already_exist)
858 {
859 _aspect_ratios.push_back(ar);
860 if(flip)
861 {
862 _aspect_ratios.push_back(1.f / ar);
863 }
864 }
865 }
866 }
867 /** Get min sizes. */
868 std::vector<float> min_sizes() const
869 {
870 return _min_sizes;
871 }
872 /** Get min variances. */
873 std::vector<float> variances() const
874 {
875 return _variances;
876 }
877 /** Get the step coordinates */
878 std::array<float, 2> steps() const
879 {
880 return _steps;
881 }
882 /** Get the image size coordinates */
883 Coordinates2D img_size() const
884 {
885 return _img_size;
886 }
887 /** Get the offset */
888 float offset() const
889 {
890 return _offset;
891 }
892 /** Get the flip value */
893 bool flip() const
894 {
895 return _flip;
896 }
897 /** Get the clip value */
898 bool clip() const
899 {
900 return _clip;
901 }
902 /** Get max sizes. */
903 std::vector<float> max_sizes() const
904 {
905 return _max_sizes;
906 }
907 /** Get aspect ratios. */
908 std::vector<float> aspect_ratios() const
909 {
910 return _aspect_ratios;
911 }
912
913private:
914 std::vector<float> _min_sizes;
915 std::vector<float> _variances;
916 float _offset;
917 bool _flip;
918 bool _clip;
919 std::vector<float> _max_sizes;
920 std::vector<float> _aspect_ratios;
921 Coordinates2D _img_size;
922 std::array<float, 2> _steps;
923};
924
Isabella Gottardia7acb3c2019-01-08 13:48:44 +0000925// Bounding Box [xmin, ymin, xmax, ymax]
926using BBox = std::array<float, 4>;
927// LabelBBox used for map label and bounding box
928using LabelBBox = std::map<int, std::vector<BBox>>;
929
Isabella Gottardi05e56442018-11-16 11:26:52 +0000930/** Available Detection Output code types */
931enum class DetectionOutputLayerCodeType
932{
933 CORNER, /**< Use box corners */
934 CENTER_SIZE, /**< Use box centers and size */
935 CORNER_SIZE, /**< Use box centers and size */
936 TF_CENTER /**< Use box centers and size but flip x and y co-ordinates */
937};
938
939/** Detection Output layer info */
940class DetectionOutputLayerInfo final
941{
942public:
943 /** Default Constructor */
944 DetectionOutputLayerInfo()
945 : _num_classes(),
946 _share_location(),
947 _code_type(DetectionOutputLayerCodeType::CORNER),
948 _keep_top_k(),
949 _nms_threshold(),
950 _top_k(),
951 _background_label_id(),
952 _confidence_threshold(),
953 _variance_encoded_in_target(false),
954 _eta(),
955 _num_loc_classes()
956 {
957 _num_loc_classes = _share_location ? 1 : _num_classes;
958 }
959 /** Constructor
960 *
961 * @param[in] num_classes Number of classes to be predicted.
962 * @param[in] share_location If true, bounding box are shared among different classes.
963 * @param[in] code_type Type of coding method for bbox.
964 * @param[in] keep_top_k Number of total bounding boxes to be kept per image after NMS step.
965 * @param[in] nms_threshold Threshold to be used in NMS.
966 * @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.
967 * @param[in] background_label_id (Optional) Background label ID. If there is no background class, set it as -1.
968 * @param[in] confidence_threshold (Optional) Only consider detections whose confidences are larger than a threshold. Default set to -FLT_MAX.
969 * @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.
970 * @param[in] eta (Optional) Eta.
971 */
972 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,
973 float confidence_threshold = std::numeric_limits<float>::lowest(), bool variance_encoded_in_target = false, float eta = 1)
974 : _num_classes(num_classes),
975 _share_location(share_location),
976 _code_type(code_type),
977 _keep_top_k(keep_top_k),
978 _nms_threshold(nms_threshold),
979 _top_k(top_k),
980 _background_label_id(background_label_id),
981 _confidence_threshold(confidence_threshold),
982 _variance_encoded_in_target(variance_encoded_in_target),
983 _eta(eta),
984 _num_loc_classes()
985 {
986 _num_loc_classes = _share_location ? 1 : _num_classes;
987 }
988 /** Get num classes. */
989 int num_classes() const
990 {
991 return _num_classes;
992 }
993 /** Get share location. */
994 bool share_location() const
995 {
996 return _share_location;
997 }
998 /** Get detection output code type. */
999 DetectionOutputLayerCodeType code_type() const
1000 {
1001 return _code_type;
1002 }
1003 /** Get if variance encoded in target. */
1004 bool variance_encoded_in_target() const
1005 {
1006 return _variance_encoded_in_target;
1007 }
1008 /** Get the number of total bounding boxes to be kept per image. */
1009 int keep_top_k() const
1010 {
1011 return _keep_top_k;
1012 }
1013 /** Get nms threshold. */
1014 float nms_threshold() const
1015 {
1016 return _nms_threshold;
1017 }
1018 /** Get eta. */
1019 float eta() const
1020 {
1021 return _eta;
1022 }
1023 /** Get background label ID. */
1024 int background_label_id() const
1025 {
1026 return _background_label_id;
1027 }
1028 /** Get confidence threshold. */
1029 float confidence_threshold() const
1030 {
1031 return _confidence_threshold;
1032 }
1033 /** Get top K. */
1034 int top_k() const
1035 {
1036 return _top_k;
1037 }
1038 /** Get number of location classes. */
1039 int num_loc_classes() const
1040 {
1041 return _num_loc_classes;
1042 }
1043
1044private:
1045 int _num_classes;
1046 bool _share_location;
1047 DetectionOutputLayerCodeType _code_type;
1048 int _keep_top_k;
1049 float _nms_threshold;
1050 int _top_k;
1051 int _background_label_id;
1052 float _confidence_threshold;
1053 bool _variance_encoded_in_target;
1054 float _eta;
1055 int _num_loc_classes;
1056};
1057
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001058/** Detection Output layer info */
1059class DetectionPostProcessLayerInfo final
1060{
1061public:
1062 /** Default Constructor */
1063 DetectionPostProcessLayerInfo()
1064 : _max_detections(),
1065 _max_classes_per_detection(),
1066 _nms_score_threshold(),
1067 _iou_threshold(),
1068 _num_classes(),
1069 _scales_values(),
1070 _use_regular_nms(),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001071 _detection_per_class(),
1072 _dequantize_scores()
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001073 {
1074 }
1075 /** Constructor
1076 *
1077 * @param[in] max_detections Number of total detection.
1078 * @param[in] max_classes_per_detection Number of total classes to be kept after NMS step. Used in the Fast Non-Max-Suppression
1079 * @param[in] nms_score_threshold Threshold to be used in NMS
1080 * @param[in] iou_threshold Threshold to be used during the intersection over union.
1081 * @param[in] num_classes Number of classes.
1082 * @param[in] scales_values Scales values used for decode center size boxes.
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001083 * @param[in] use_regular_nms (Optional) Boolean to determinate if use regular or fast nms. Defaults to false.
1084 * @param[in] detection_per_class (Optional) Number of detection per class. Used in the Regular Non-Max-Suppression. Defaults to 100.
1085 * @param[in] dequantize_scores (Optional) If the scores need to be dequantized. Defaults to true.
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001086 */
1087 DetectionPostProcessLayerInfo(unsigned int max_detections, unsigned int max_classes_per_detection, float nms_score_threshold, float iou_threshold, unsigned int num_classes,
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001088 std::array<float, 4> scales_values, bool use_regular_nms = false, unsigned int detection_per_class = 100, bool dequantize_scores = true)
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001089 : _max_detections(max_detections),
1090 _max_classes_per_detection(max_classes_per_detection),
1091 _nms_score_threshold(nms_score_threshold),
1092 _iou_threshold(iou_threshold),
1093 _num_classes(num_classes),
1094 _scales_values(scales_values),
1095 _use_regular_nms(use_regular_nms),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001096 _detection_per_class(detection_per_class),
1097 _dequantize_scores(dequantize_scores)
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001098 {
1099 }
1100 /** Get max detections. */
1101 unsigned int max_detections() const
1102 {
1103 return _max_detections;
1104 }
1105 /** Get max_classes per detection. Used in the Fast Non-Max-Suppression.*/
1106 unsigned int max_classes_per_detection() const
1107 {
1108 return _max_classes_per_detection;
1109 }
1110 /** Get detection per class. Used in the Regular Non-Max-Suppression */
1111 unsigned int detection_per_class() const
1112 {
1113 return _detection_per_class;
1114 }
1115 /** Get nms threshold. */
1116 float nms_score_threshold() const
1117 {
1118 return _nms_score_threshold;
1119 }
1120 /** Get intersection over union threshold. */
1121 float iou_threshold() const
1122 {
1123 return _iou_threshold;
1124 }
1125 /** Get num classes. */
1126 unsigned int num_classes() const
1127 {
1128 return _num_classes;
1129 }
1130 /** Get if use regular nms. */
1131 bool use_regular_nms() const
1132 {
1133 return _use_regular_nms;
1134 }
1135 /** Get y scale value. */
1136 float scale_value_y() const
1137 {
1138 // Saved as [y,x,h,w]
1139 return _scales_values[0];
1140 }
1141 /** Get x scale value. */
1142 float scale_value_x() const
1143 {
1144 // Saved as [y,x,h,w]
1145 return _scales_values[1];
1146 }
1147 /** Get h scale value. */
1148 float scale_value_h() const
1149 {
1150 // Saved as [y,x,h,w]
1151 return _scales_values[2];
1152 }
1153 /** Get w scale value. */
1154 float scale_value_w() const
1155 {
1156 // Saved as [y,x,h,w]
1157 return _scales_values[3];
1158 }
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001159 /** Get dequantize_scores value. */
1160 bool dequantize_scores() const
1161 {
1162 return _dequantize_scores;
1163 }
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001164
1165private:
1166 unsigned int _max_detections;
1167 unsigned int _max_classes_per_detection;
1168 float _nms_score_threshold;
1169 float _iou_threshold;
1170 unsigned int _num_classes;
1171 std::array<float, 4> _scales_values;
1172 bool _use_regular_nms;
1173 unsigned int _detection_per_class;
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001174 bool _dequantize_scores;
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001175};
1176
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001177/** Pooling Layer Information struct*/
1178struct PoolingLayerInfo
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001179{
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001180 /** Default Constructor */
1181 PoolingLayerInfo()
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001182 : pool_type(PoolingType::MAX),
1183 pool_size(Size2D()),
1184 data_layout(DataLayout::UNKNOWN),
1185 pad_stride_info(PadStrideInfo()),
1186 exclude_padding(false),
1187 is_global_pooling(false),
1188 fp_mixed_precision(false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001189 {
1190 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001191 /** Constructor
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001192 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001193 * @param[in] pool_type Pooling type @ref PoolingType.
1194 * @param[in] pool_size Pooling size, in elements, across x and y.
1195 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1196 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1197 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1198 * Defaults to false;
1199 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001200 */
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001201 ARM_COMPUTE_DEPRECATED_REL_REPLACE(20.02, PoolingLayerInfo(PoolingType, unsigned int, DataLayout, PadStrideInfo, bool, bool))
1202 explicit PoolingLayerInfo(PoolingType pool_type,
1203 unsigned int pool_size,
1204 PadStrideInfo pad_stride_info = PadStrideInfo(),
1205 bool exclude_padding = false,
1206 bool fp_mixed_precision = false)
1207 : pool_type(pool_type),
1208 pool_size(Size2D(pool_size, pool_size)),
1209 data_layout(DataLayout::UNKNOWN),
1210 pad_stride_info(pad_stride_info),
1211 exclude_padding(exclude_padding),
1212 is_global_pooling(false),
1213 fp_mixed_precision(fp_mixed_precision)
1214 {
1215 }
1216 /** Constructor
1217 *
1218 * @param[in] pool_type Pooling type @ref PoolingType.
1219 * @param[in] pool_size Pooling size, in elements, across x and y.
1220 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1221 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1222 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1223 * Defaults to false;
1224 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1225 */
1226 ARM_COMPUTE_DEPRECATED_REL_REPLACE(20.02, PoolingLayerInfo(PoolingType, Size2D, DataLayout, PadStrideInfo, bool, bool))
1227 explicit PoolingLayerInfo(PoolingType pool_type,
1228 Size2D pool_size,
1229 PadStrideInfo pad_stride_info = PadStrideInfo(),
1230 bool exclude_padding = false,
1231 bool fp_mixed_precision = false)
1232 : pool_type(pool_type),
1233 pool_size(pool_size),
1234 data_layout(DataLayout::UNKNOWN),
1235 pad_stride_info(pad_stride_info),
1236 exclude_padding(exclude_padding),
1237 is_global_pooling(false),
1238 fp_mixed_precision(fp_mixed_precision)
1239 {
1240 }
1241 /** Constructor
1242 *
1243 * @note This constructor is used for global pooling
1244 *
1245 * @param[in] pool_type Pooling type @ref PoolingType.
1246 */
1247 ARM_COMPUTE_DEPRECATED_REL_REPLACE(20.02, PoolingLayerInfo(PoolingType, DataLayout))
1248 explicit PoolingLayerInfo(PoolingType pool_type)
1249 : pool_type(pool_type),
1250 pool_size(Size2D()),
1251 data_layout(DataLayout::UNKNOWN),
1252 pad_stride_info(PadStrideInfo(1, 1, 0, 0)),
1253 exclude_padding(false),
1254 is_global_pooling(true),
1255 fp_mixed_precision(false)
1256 {
1257 }
1258
1259 /** Constructor
1260 *
1261 * @param[in] pool_type Pooling type @ref PoolingType.
1262 * @param[in] pool_size Pooling size, in elements, across x and y.
1263 * @param[in] data_layout Data layout used by the layer @ref DataLayout
1264 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1265 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1266 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1267 * Defaults to false;
1268 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1269 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001270 explicit PoolingLayerInfo(PoolingType pool_type,
1271 unsigned int pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001272 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001273 PadStrideInfo pad_stride_info = PadStrideInfo(),
1274 bool exclude_padding = false,
1275 bool fp_mixed_precision = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001276 : pool_type(pool_type),
1277 pool_size(Size2D(pool_size, pool_size)),
1278 data_layout(data_layout),
1279 pad_stride_info(pad_stride_info),
1280 exclude_padding(exclude_padding),
1281 is_global_pooling(false),
1282 fp_mixed_precision(fp_mixed_precision)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001283 {
1284 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001285
1286 /** Constructor
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001287 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001288 * @param[in] pool_type Pooling type @ref PoolingType.
1289 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001290 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001291 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1292 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1293 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1294 * Defaults to false;
1295 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001296 */
1297 explicit PoolingLayerInfo(PoolingType pool_type,
1298 Size2D pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001299 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001300 PadStrideInfo pad_stride_info = PadStrideInfo(),
1301 bool exclude_padding = false,
1302 bool fp_mixed_precision = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001303 : pool_type(pool_type),
1304 pool_size(pool_size),
1305 data_layout(data_layout),
1306 pad_stride_info(pad_stride_info),
1307 exclude_padding(exclude_padding),
1308 is_global_pooling(false),
1309 fp_mixed_precision(fp_mixed_precision)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001310 {
1311 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001312
1313 /** Constructor
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001314 *
1315 * @note This constructor is used for global pooling
1316 *
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001317 * @param[in] pool_type Pooling type @ref PoolingType.
1318 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001319 */
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001320 explicit PoolingLayerInfo(PoolingType pool_type, DataLayout data_layout)
1321 : pool_type(pool_type),
1322 pool_size(Size2D()),
1323 data_layout(data_layout),
1324 pad_stride_info(PadStrideInfo(1, 1, 0, 0)),
1325 exclude_padding(false),
1326 is_global_pooling(true),
1327 fp_mixed_precision(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001328 {
1329 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001330
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001331 PoolingType pool_type;
1332 Size2D pool_size;
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001333 DataLayout data_layout;
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001334 PadStrideInfo pad_stride_info;
1335 bool exclude_padding;
1336 bool is_global_pooling;
1337 bool fp_mixed_precision;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001338};
1339
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001340/** ROI Pooling Layer Information class */
giuros0118870812018-09-13 09:31:40 +01001341class ROIPoolingLayerInfo final
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001342{
1343public:
giuros0118870812018-09-13 09:31:40 +01001344 /** Constructor
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001345 *
giuros0118870812018-09-13 09:31:40 +01001346 * @param[in] pooled_width Pooled width of the layer.
1347 * @param[in] pooled_height Pooled height of the layer.
1348 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
1349 * @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 +01001350 */
giuros0118870812018-09-13 09:31:40 +01001351 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale, unsigned int sampling_ratio = 0)
1352 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale), _sampling_ratio(sampling_ratio)
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001353 {
1354 }
Alex Gildayc357c472018-03-21 13:54:09 +00001355 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001356 unsigned int pooled_width() const
1357 {
1358 return _pooled_width;
1359 }
Alex Gildayc357c472018-03-21 13:54:09 +00001360 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001361 unsigned int pooled_height() const
1362 {
1363 return _pooled_height;
1364 }
Alex Gildayc357c472018-03-21 13:54:09 +00001365 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001366 float spatial_scale() const
1367 {
1368 return _spatial_scale;
1369 }
giuros0118870812018-09-13 09:31:40 +01001370 /** Get sampling ratio */
1371 unsigned int sampling_ratio() const
1372 {
1373 return _sampling_ratio;
1374 }
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001375
1376private:
1377 unsigned int _pooled_width;
1378 unsigned int _pooled_height;
1379 float _spatial_scale;
giuros0118870812018-09-13 09:31:40 +01001380 unsigned int _sampling_ratio;
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001381};
1382
Manuel Bottini5209be52019-02-13 16:34:56 +00001383/** Generate Proposals Information class */
1384class GenerateProposalsInfo
1385{
1386public:
1387 /** Constructor
1388 *
1389 * @param[in] im_width Width of the original image
1390 * @param[in] im_height Height of the original image
1391 * @param[in] im_scale Scale applied to the original image
1392 * @param[in] spatial_scale (Optional)Scale applied to the feature map. Defaults to 1.0
1393 * @param[in] pre_nms_topN (Optional)Number of the best scores to be selected from the transformations. Defaults to 6000.
1394 * @param[in] post_nms_topN (Optional)Number of the best scores to be selected from the NMS operation. Defaults to 300.
1395 * @param[in] nms_thres (Optional)NMS overlap threshold. Defaults to 0.7.
1396 * @param[in] min_size (Optional)Size used to validate the anchors produced. Defaults to 16.
1397 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region of interest). Defaults to 4.
1398 */
1399 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,
1400 size_t values_per_roi = 4)
1401 : _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),
1402 _min_size(min_size), _values_per_roi(values_per_roi)
1403 {
1404 }
1405
1406 /* Get the original height */
1407 float im_height() const
1408 {
1409 return _im_height;
1410 }
1411 /* Get the original width */
1412 float im_width() const
1413 {
1414 return _im_width;
1415 }
1416 /* Get the image scale */
1417 float im_scale() const
1418 {
1419 return _im_scale;
1420 }
1421 /* Get the value of how many best scores to select (before NMS) */
1422 int pre_nms_topN() const
1423 {
1424 return _pre_nms_topN;
1425 }
1426 /* Get the value of how many best scores to select (after NMS) */
1427 int post_nms_topN() const
1428 {
1429 return _post_nms_topN;
1430 }
1431 /* Get the NMS overlap threshold */
1432 float nms_thres() const
1433 {
1434 return _nms_thres;
1435 }
1436 /* Get the minimal size */
1437 float min_size() const
1438 {
1439 return _min_size;
1440 }
1441 /* Get the spatial scale to be applied to the feature maps */
1442 float spatial_scale() const
1443 {
1444 return _spatial_scale;
1445 }
1446 /* Get the values used to represent a ROI(Region of interest)*/
1447 size_t values_per_roi() const
1448 {
1449 return _values_per_roi;
1450 }
1451
1452private:
1453 float _im_height;
1454 float _im_width;
1455 float _im_scale;
1456 float _spatial_scale;
1457 int _pre_nms_topN;
1458 int _post_nms_topN;
1459 float _nms_thres;
1460 float _min_size;
1461 size_t _values_per_roi;
1462};
1463
1464/** ComputeAnchors information class */
1465class ComputeAnchorsInfo
1466{
1467public:
1468 /** Constructor
1469 *
1470 * @param[in] feat_width Feature map width
1471 * @param[in] feat_height Feature map height
1472 * @param[in] spatial_scale Feature map scale
1473 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region Of Interest). Defaults to 4
1474 */
1475 ComputeAnchorsInfo(float feat_width, float feat_height, float spatial_scale, size_t values_per_roi = 4)
1476 : _feat_height(feat_height),
1477 _feat_width(feat_width),
1478 _spatial_scale(spatial_scale),
1479 _values_per_roi(values_per_roi)
1480 {
1481 }
1482
1483 /* Get the height of the feature map */
1484 float feat_height() const
1485 {
1486 return _feat_height;
1487 }
1488
1489 /* Get the width of the feature map */
1490 float feat_width() const
1491 {
1492 return _feat_width;
1493 }
1494
1495 /* Get the scale of the feature map */
1496 float spatial_scale() const
1497 {
1498 return _spatial_scale;
1499 }
1500
1501 /* Get the values used to represent a ROI(Region Of Interest)*/
1502 size_t values_per_roi() const
1503 {
1504 return _values_per_roi;
1505 }
1506
1507private:
1508 float _feat_height;
1509 float _feat_width;
1510 float _spatial_scale;
1511 size_t _values_per_roi;
1512};
1513
giuros01c04a0e82018-10-03 12:44:35 +01001514/** Bounding Box Transform information class */
giuros01d696cb62018-11-16 10:39:59 +00001515class BoundingBoxTransformInfo final
giuros01c04a0e82018-10-03 12:44:35 +01001516{
1517public:
1518 /** Constructor
1519 *
giuros01d696cb62018-11-16 10:39:59 +00001520 * @param[in] img_width Width of the original image
1521 * @param[in] img_height Height, of the original image
1522 * @param[in] scale Scale of the original image
1523 * @param[in] apply_scale (Optional)Re-apply scaling after transforming the boxes. Defaults to false
1524 * @param[in] weights (Optional)Weights [wx, wy, ww, wh] for the deltas. Defaults to all ones
1525 * @param[in] correct_transform_coords (Optional)Correct bounding box transform coordinates. Defaults to false
1526 * @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 +01001527 */
giuros01d696cb62018-11-16 10:39:59 +00001528 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 =
1529 false,
1530 float bbox_xform_clip =
1531 4.135166556742356f)
1532 : _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 +01001533 {
1534 }
1535
1536 std::array<float, 4> weights() const
1537 {
1538 return _weights;
1539 }
1540
1541 float bbox_xform_clip() const
1542 {
1543 return _bbox_xform_clip;
1544 }
1545
1546 float img_height() const
1547 {
1548 return _img_height;
1549 }
1550
1551 float img_width() const
1552 {
1553 return _img_width;
1554 }
1555
1556 float scale() const
1557 {
1558 return _scale;
1559 }
1560
1561 bool apply_scale() const
1562 {
1563 return _apply_scale;
1564 }
1565
giuros01d696cb62018-11-16 10:39:59 +00001566 bool correct_transform_coords() const
1567 {
1568 return _correct_transform_coords;
1569 }
1570
giuros01c04a0e82018-10-03 12:44:35 +01001571private:
1572 float _img_width;
1573 float _img_height;
1574 float _scale;
1575 bool _apply_scale;
giuros01d696cb62018-11-16 10:39:59 +00001576 bool _correct_transform_coords;
giuros01c04a0e82018-10-03 12:44:35 +01001577 std::array<float, 4> _weights;
1578 float _bbox_xform_clip;
1579};
1580
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001581/** Activation Layer Information class */
1582class ActivationLayerInfo
1583{
1584public:
1585 /** Available activation functions */
1586 enum class ActivationFunction
1587 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001588 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
1589 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
1590 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
1591 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
1592 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
Manuel Bottini581c8982019-02-07 10:31:57 +00001593 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 +01001594 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
Georgios Pinitasfb0fdcd2019-08-22 17:10:04 +01001595 ELU, /**< Exponential Linear Unit ( \f$ f(x) = \begin{cases} \alpha (exp(x) - 1) & \quad \text{if } x \text{ < 0}\\ x & \quad \text{if } x \geq \text{ 0 } \end{cases} \f$ ) */
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001596 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
1597 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
1598 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
Usama Arif6a98a6e2019-05-10 17:07:27 +01001599 LINEAR, /**< Linear ( \f$ f(x)= ax + b \f$ ) */
morgolock07df3d42020-02-27 11:46:28 +00001600 IDENTITY, /**< Identity ( \f$ f(x)= x \f$ ) */
1601 HARD_SWISH /**< Hard-swish ( \f$ f(x) = (x * relu6(x+3))/6 \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001602 };
1603
Giorgio Arena11674872018-02-07 15:38:12 +00001604 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001605 /** Default Constructor
1606 *
1607 * @param[in] f The activation function to use.
1608 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001609 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1610 * @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 +01001611 */
1612 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001613 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001614 {
1615 }
Alex Gildayc357c472018-03-21 13:54:09 +00001616 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001617 ActivationFunction activation() const
1618 {
1619 return _act;
1620 }
Alex Gildayc357c472018-03-21 13:54:09 +00001621 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001622 float a() const
1623 {
1624 return _a;
1625 }
Alex Gildayc357c472018-03-21 13:54:09 +00001626 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001627 float b() const
1628 {
1629 return _b;
1630 }
Alex Gildayc357c472018-03-21 13:54:09 +00001631 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001632 bool enabled() const
1633 {
1634 return _enabled;
1635 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001636
1637private:
Usama Arif6a98a6e2019-05-10 17:07:27 +01001638 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::IDENTITY };
Giorgio Arena11674872018-02-07 15:38:12 +00001639 float _a = {};
1640 float _b = {};
1641 bool _enabled = { false };
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001642};
1643
Giorgio Arena1856ff72020-02-07 13:46:45 +00001644/** Fully connected layer info */
1645struct FullyConnectedLayerInfo
1646{
1647 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
1648 bool transpose_weights{ true }; /**< Transpose weights if true. */
1649 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
1650 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
1651 bool fp_mixed_precision{ false }; /**< Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy. */
1652 ActivationLayerInfo activation_info{}; /**< Fused activation to apply after the matrix multiplication. */
1653
1654 /** Sets the weights trained data layout
1655 *
1656 * @param[in] layout Data layout that the weights were trained with
1657 *
1658 * @return Updated object
1659 */
1660 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
1661 {
1662 weights_trained_layout = layout;
1663 return *this;
1664 }
1665 /** Sets the transpose weights flag
1666 *
1667 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
1668 *
1669 * @return Updated object
1670 */
1671 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
1672 {
1673 transpose_weights = should_transpose_weights;
1674 return *this;
1675 }
1676};
1677
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001678/** Normalization Layer Information class */
1679class NormalizationLayerInfo
1680{
1681public:
1682 /** Default Constructor
1683 *
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001684 * @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 +01001685 * @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 +00001686 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1687 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1688 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1689 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1690 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001691 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001692 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1693 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001694 {
1695 }
Alex Gildayc357c472018-03-21 13:54:09 +00001696 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001697 NormType type() const
1698 {
1699 return _type;
1700 }
Alex Gildayc357c472018-03-21 13:54:09 +00001701 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001702 uint32_t norm_size() const
1703 {
1704 return _norm_size;
1705 }
Alex Gildayc357c472018-03-21 13:54:09 +00001706 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001707 float alpha() const
1708 {
1709 return _alpha;
1710 }
Alex Gildayc357c472018-03-21 13:54:09 +00001711 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001712 float beta() const
1713 {
1714 return _beta;
1715 }
Alex Gildayc357c472018-03-21 13:54:09 +00001716 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001717 float kappa() const
1718 {
1719 return _kappa;
1720 }
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001721 /** Get the is_scaled value */
1722 bool is_scaled() const
1723 {
1724 return _is_scaled;
1725 }
Alex Gildayc357c472018-03-21 13:54:09 +00001726 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001727 bool is_cross_map() const
1728 {
1729 return _type == NormType::CROSS_MAP;
1730 }
Alex Gildayc357c472018-03-21 13:54:09 +00001731 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001732 bool is_in_map() const
1733 {
1734 return !is_cross_map();
1735 }
1736 /** Return the scaling factor of the normalization function.
1737 *
1738 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1739 * 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 +01001740 *
1741 * @return The normalization scaling factor.
1742 */
1743 float scale_coeff() const
1744 {
1745 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001746 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001747 }
1748
1749private:
1750 NormType _type;
1751 uint32_t _norm_size;
1752 float _alpha;
1753 float _beta;
1754 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001755 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001756};
1757
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001758/** 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 +01001759class WeightsInfo
1760{
1761public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001762 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001763 WeightsInfo()
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001764 : _are_reshaped(false), _kernel_width(0), _kernel_height(0), _num_kernels(0), _retain_internal_weights(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001765 {
1766 }
1767 /** Constructor
1768 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001769 * @param[in] are_reshaped True if the weights have been reshaped
1770 * @param[in] kernel_width Kernel width.
1771 * @param[in] kernel_height Kernel height.
1772 * @param[in] num_kernels Number of convolution kernels.
1773 * @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 +01001774 */
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001775 WeightsInfo(bool are_reshaped, unsigned int kernel_width, unsigned int kernel_height, unsigned int num_kernels, bool retain_internal_weights = false)
1776 : _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 +01001777 {
1778 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001779 /** Flag which specifies if the weights tensor has been reshaped.
1780 *
1781 * @return True if the weights tensors has been reshaped
1782 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001783 bool are_reshaped() const
1784 {
1785 return _are_reshaped;
1786 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001787 /** Return the number of convolution kernels
1788 *
1789 * @return The number of convolution kernels
1790 */
1791 unsigned int num_kernels() const
1792 {
1793 return _num_kernels;
1794 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001795 /** Return the width and height of the kernel
1796 *
1797 * @return The width and height of the kernel
1798 */
1799 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001800 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001801 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001802 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001803 bool retain_internal_weights() const
1804 {
1805 return _retain_internal_weights;
1806 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001807
1808private:
1809 const bool _are_reshaped;
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001810 const unsigned int _kernel_width;
1811 const unsigned int _kernel_height;
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001812 const unsigned int _num_kernels;
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001813 const bool _retain_internal_weights;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001814};
1815
Gian Marco36a0a462018-01-12 10:21:40 +00001816/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
1817 *
Gian Marco Iodice5fc07aa2019-05-15 17:08:02 +01001818 * The matrix A can only be reshaped through @ref CLGEMMReshapeLHSMatrixKernel or @ref NEGEMMInterleave4x4Kernel or @ref GCGEMMInterleave4x4Kernel
1819 * 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 +00001820 *
giuros018b6b4a92018-12-18 19:01:33 +00001821 * The matrix B can only be reshaped through @ref CLGEMMReshapeRHSMatrixKernel or @ref NEGEMMTranspose1xWKernel or @ref GCGEMMTranspose1xWKernel
1822 * 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 +00001823 *
1824 */
1825class GEMMReshapeInfo final
1826{
1827public:
1828 /** Default constructor */
1829 GEMMReshapeInfo()
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001830 : _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 +00001831 {
1832 }
1833 /** Constructor
1834 *
1835 * @param[in] m Number of matrix A rows
1836 * @param[in] n Number of matrix B columns
1837 * @param[in] k Number of matrix A columns or matrix B rows
1838 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
1839 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001840 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
1841 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001842 * @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 +01001843 * to perform 1x1 convolutions with the NHWC data layout)
1844 * @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 +00001845 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001846 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 +01001847 : _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 +01001848 _reinterpret_input_as_3d(reinterpret_input_as_3d), _broadcast_bias(broadcast_bias)
Gian Marco36a0a462018-01-12 10:21:40 +00001849 {
1850 }
1851 /** Number of matrix A rows
1852 *
1853 * @return the number of matrix A rows
1854 */
1855 int m() const
1856 {
1857 return _m;
1858 }
1859 /** Number of matrix B columns
1860 *
1861 * @return the number of matrix B columns
1862 */
1863 int n() const
1864 {
1865 return _n;
1866 }
1867 /** Number of matrix A columns or matrix B rows
1868 *
1869 * @return the number of matrix A columns or matrix B rows
1870 */
1871 int k() const
1872 {
1873 return _k;
1874 }
1875 /** Multiplication factor for the width of the 1xW transposed block
1876 *
1877 * @return the multiplication factor for the width of the 1xW transposed block
1878 */
1879 int mult_transpose1xW_width() const
1880 {
1881 return _mult_transpose1xW_width;
1882 }
1883 /** Multiplication factor for the height of the 4x4 interleaved block
1884 *
1885 * @return the multiplication factor for the height of the 4x4 interleaved block
1886 */
1887 int mult_interleave4x4_height() const
1888 {
1889 return _mult_interleave4x4_height;
1890 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001891 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
1892 *
1893 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
1894 * m = depth_output_gemm3d * output_height
1895 *
1896 * @return the depth of the output tensor to be used with the GEMM3D kernel
1897 */
1898 int depth_output_gemm3d() const
1899 {
1900 return _depth_output_gemm3d;
1901 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001902 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
1903 *
1904 * @return True if the input tensor has to be reinterpreted as 3D tensor
1905 */
1906 bool reinterpret_input_as_3d() const
1907 {
1908 return _reinterpret_input_as_3d;
1909 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001910 /** Flag which specifies whether to broadcast the shape of the bias tensor.
1911 *
1912 * @return True if the shape of the bias tensor is to be broadcasted.
1913 */
1914 bool broadcast_bias() const
1915 {
1916 return _broadcast_bias;
1917 };
Gian Marco36a0a462018-01-12 10:21:40 +00001918
1919private:
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001920 const int _m;
1921 const int _n;
1922 const int _k;
1923 const int _mult_transpose1xW_width;
1924 const int _mult_interleave4x4_height;
1925 const int _depth_output_gemm3d;
1926 const bool _reinterpret_input_as_3d;
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001927 const bool _broadcast_bias;
Gian Marco36a0a462018-01-12 10:21:40 +00001928};
1929
giuros016d109962019-01-07 17:47:19 +00001930struct DepthwiseConvolutionReshapeInfo
1931{
1932 unsigned int c0{ 1 }; /**< Number of channels processed by the depth-wise convolution */
1933 bool transpose{ false }; /**< True if the block MxC0 (where M is the area of the filter i.e. KwxKh) has to be transposed */
1934};
1935
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001936/** GEMMLowp output stage type */
1937enum class GEMMLowpOutputStageType
1938{
Manuel Bottini959c26d2019-12-02 16:22:35 +00001939 NONE, /**< No quantization */
1940 QUANTIZE_DOWN, /**< Quantize using an integer multiplication */
1941 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize using a fixed point multiplication */
1942 QUANTIZE_DOWN_FLOAT /**< Quantize using a floating point multiplication */
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001943};
1944
1945/** GEMMLowp output stage info */
1946struct GEMMLowpOutputStageInfo
1947{
Giorgio Arena1856ff72020-02-07 13:46:45 +00001948 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
1949 int32_t gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
1950 int32_t gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1951 int32_t gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
1952 int32_t gemmlowp_min_bound{ std::numeric_limits<int32_t>::lowest() }; /**< GEMMLowp min value used to saturate down the output result before converting back to QASYMM8 */
1953 int32_t gemmlowp_max_bound{ std::numeric_limits<int32_t>::max() }; /**< GEMMLowp max value used to saturate down the output result before converting back to QASYMM8 */
1954 std::vector<int32_t> gemmlowp_multipliers{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1955 std::vector<int32_t> gemmlowp_shifts{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1956 bool is_quantized_per_channel{ false }; /**< GEMMLowp quantized per-channel flag */
1957 DataType output_data_type{ DataType::UNKNOWN }; /**< Output tensor data type to use if the output is not initialized */
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001958};
1959
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00001960/** GEMM LHS (Left Hand Side) matrix information */
1961struct GEMMLHSMatrixInfo
1962{
1963 unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
1964 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1965 unsigned int v0{ 1 }; /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
1966 bool transpose{ true }; /**< True if the (m0xk0) block has to be transposed before been stored */
1967 bool interleave{ true }; /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
1968};
1969
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00001970/** GEMM RHS (Right Hand Side) matrix information */
1971struct GEMMRHSMatrixInfo
1972{
1973 unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
1974 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1975 unsigned int h0{ 1 }; /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
1976 bool transpose{ true }; /**< True if the (k0xn0) block has to be transposed before been stored */
1977 bool interleave{ true }; /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
1978};
1979
Gian Marco36a0a462018-01-12 10:21:40 +00001980/** GEMM information class. This class stores the necessary information to compute GEMM functions
1981 *
1982 * This object also contains the information about how matrix A and matrix B have been reshaped
1983 *
1984 */
Chunosov5124be52017-11-22 20:42:13 +07001985class GEMMInfo
1986{
1987public:
1988 /** Default constructor */
Georgios Pinitas37d080f2019-06-21 18:43:12 +01001989 GEMMInfo() noexcept
1990 : _is_a_reshaped(false),
1991 _is_b_reshaped(false),
1992 _reshape_b_only_on_first_run(true),
1993 _depth_output_gemm3d(0),
1994 _reinterpret_input_as_3d(false),
1995 _retain_internal_weights(false),
1996 _gemmlowp_output_stage(),
1997 _fp_mixed_precision(false),
1998 _broadcast_bias(false),
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01001999 _pretranpose_B(true),
2000 _activation_info()
Chunosov5124be52017-11-22 20:42:13 +07002001 {
2002 }
2003 /** Constructor
2004 *
2005 * @param[in] is_a_reshaped True if the matrix A has been reshaped
2006 * @param[in] is_b_reshaped True if the matrix B has been reshaped
2007 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002008 * @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 +00002009 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002010 * @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
2011 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002012 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002013 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002014 * @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 +01002015 * @param[in] broadcast_bias (Optional) Broadcast the shape of the bias tensor from a vector to a matrix.
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002016 * @param[in] activation_info (Optional) Activation to apply after the matrix multiplication
Chunosov5124be52017-11-22 20:42:13 +07002017 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002018 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,
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002019 GEMMLowpOutputStageInfo gemmlowp_output_stage = GEMMLowpOutputStageInfo(), bool fp_mixed_precision = false, bool broadcast_bias = false,
2020 const ActivationLayerInfo &activation_info = ActivationLayerInfo()) noexcept
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002021 : _is_a_reshaped(is_a_reshaped),
2022 _is_b_reshaped(is_b_reshaped),
2023 _reshape_b_only_on_first_run(reshape_b_only_on_first_run),
2024 _depth_output_gemm3d(depth_output_gemm3d),
2025 _reinterpret_input_as_3d(reinterpret_input_as_3d),
2026 _retain_internal_weights(retain_internal_weights),
2027 _gemmlowp_output_stage(gemmlowp_output_stage),
2028 _fp_mixed_precision(fp_mixed_precision),
2029 _broadcast_bias(broadcast_bias),
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002030 _pretranpose_B(reshape_b_only_on_first_run),
2031 _activation_info(activation_info)
Chunosov5124be52017-11-22 20:42:13 +07002032 {
2033 }
2034 /** Flag which specifies if the matrix A has been reshaped
2035 *
2036 * @return True if the matrix A has been reshaped
2037 */
2038 bool is_a_reshaped() const
2039 {
2040 return _is_a_reshaped;
2041 };
2042 /** Flag which specifies if the matrix B has been reshaped
2043 *
2044 * @return True if the matrix B has been reshaped
2045 */
2046 bool is_b_reshaped() const
2047 {
2048 return _is_b_reshaped;
2049 };
2050 /** Flag which specifies if the reshape of matrix B should executed only for the first
2051 *
2052 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
2053 *
2054 * @return True if the reshaped of matrix B happens only for the first run
2055 */
2056 bool reshape_b_only_on_first_run() const
2057 {
2058 return _reshape_b_only_on_first_run;
2059 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002060 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002061 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002062 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002063 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002064 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00002065 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002066 return _depth_output_gemm3d;
2067 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002068 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2069 *
2070 * @return True if the input tensor has to be reinterpreted as 3D tensor
2071 */
2072 bool reinterpret_input_as_3d() const
2073 {
2074 return _reinterpret_input_as_3d;
2075 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002076 /** Flag which specifies if the weights tensor has to be retained from previous run
2077 *
2078 * @return True if the weights tensor has to be retained
2079 */
2080 bool retain_internal_weights() const
2081 {
2082 return _retain_internal_weights;
2083 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002084 /** GEMMLowp output stage
2085 *
2086 * @return the GEMMLowp output stage info
2087 */
2088 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
2089 {
2090 return _gemmlowp_output_stage;
2091 };
Georgios Pinitasdbdea0d2019-10-16 19:21:40 +01002092 /** Sets GEMMLowp output stage
2093 *
2094 * @param[in] output_stage Output stage to set
2095 */
2096 void set_gemmlowp_output_stage(GEMMLowpOutputStageInfo &output_stage)
2097 {
2098 _gemmlowp_output_stage = output_stage;
2099 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002100 /** Flag which specifies if a wider accumulator should be used.
2101 *
2102 * @return True if a wider accumulator has to be used
2103 */
2104 bool fp_mixed_precision() const
2105 {
2106 return _fp_mixed_precision;
2107 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002108 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2109 *
2110 * @return True if the shape of the bias tensor is to be broadcasted.
2111 */
2112 bool broadcast_bias() const
2113 {
2114 return _broadcast_bias;
2115 };
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002116 /** Flag which specifies whether b should be pre-transposed if supported.
2117 *
2118 * @return True if b should be pre-transposed else false.
2119 */
2120 bool pretranpose_B() const
2121 {
2122 return _pretranpose_B;
2123 };
2124 /** Set pre-transpose b flag
2125 *
2126 * @param[in] flag Flag to set
2127 */
2128 void set_pretranpose_B(bool flag)
2129 {
2130 _pretranpose_B = flag;
2131 }
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002132 /** Activation layer to apply after the matrix multiplication
2133 *
2134 * @return ActivationLayerInfo object
2135 */
2136 ActivationLayerInfo activation_info() const
2137 {
2138 return _activation_info;
2139 }
Chunosov5124be52017-11-22 20:42:13 +07002140
2141private:
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002142 bool _is_a_reshaped;
2143 bool _is_b_reshaped;
2144 bool _reshape_b_only_on_first_run;
2145 int _depth_output_gemm3d;
2146 bool _reinterpret_input_as_3d;
2147 bool _retain_internal_weights;
2148 GEMMLowpOutputStageInfo _gemmlowp_output_stage;
2149 bool _fp_mixed_precision;
2150 bool _broadcast_bias;
2151 bool _pretranpose_B;
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002152 ActivationLayerInfo _activation_info;
Chunosov5124be52017-11-22 20:42:13 +07002153};
2154
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00002155/** Winograd information */
2156struct WinogradInfo
2157{
2158 /** Default constructor
2159 *
2160 * @param[in] output_tile_sz Width and height of the output tile
2161 * @param[in] kernel_sz Width and height of the kernel
2162 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
2163 * @param[in] conv_info Convolution info (Pads, strides)
2164 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
2165 */
2166 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
2167 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
2168 {
2169 }
2170
2171 Size2D output_tile_size{}; /**< Width and height of the output tile */
2172 Size2D kernel_size{}; /**< Width and height of the kernel*/
2173 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
2174 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
2175 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
2176};
2177
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002178/** IO formatting information class*/
2179struct IOFormatInfo
2180{
2181 /** Precision type used when printing floating point numbers */
2182 enum class PrecisionType
2183 {
2184 Default, /**< Default precision to the one that the current stream has */
2185 Custom, /**< Custom precision specified by the user using the precision parameter */
2186 Full /**< The maximum precision of the floating point representation */
2187 };
2188
2189 /** Specifies the area to be printed, used by Tensor objects */
2190 enum class PrintRegion
2191 {
2192 ValidRegion, /**< Prints the valid region of the Tensor object */
2193 NoPadding, /**< Prints the Tensor object without the padding */
2194 Full /**< Print the tensor object including padding */
2195 };
2196
Alex Gildayc357c472018-03-21 13:54:09 +00002197 /** Construct a set of IO formatting information.
2198 *
2199 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
2200 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
2201 * @param[in] precision Precision value for float point numbers. Default: 10.
2202 * @param[in] align_columns Whether to align columns when printed. Default: true.
2203 * @param[in] element_delim Delimeter between elements. Default: " ".
2204 * @param[in] row_delim Delimenter between rows. Default: "\n".
2205 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002206 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
2207 PrecisionType precision_type = PrecisionType::Default,
2208 unsigned int precision = 10,
2209 bool align_columns = true,
2210 std::string element_delim = " ",
2211 std::string row_delim = "\n")
2212 : print_region(print_region),
2213 precision_type(precision_type),
2214 precision(precision),
2215 element_delim(element_delim),
2216 row_delim(row_delim),
2217 align_columns(align_columns)
2218 {
2219 }
2220
Alex Gildayc357c472018-03-21 13:54:09 +00002221 /** Area to be printed by Tensor objects */
2222 PrintRegion print_region;
2223 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002224 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00002225 /** Floating point precision */
2226 unsigned int precision;
2227 /** Element delimeter */
2228 std::string element_delim;
2229 /** Row delimeter */
2230 std::string row_delim;
2231 /** Align columns */
2232 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002233};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00002234} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +00002235#endif /* ARM_COMPUTE_TYPES_H */