blob: c0e0683fe6af81120ea0450daf1f4c5d178d1801 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * 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 Pinitase8291ac2020-02-26 09:58:13 +000033#include "support/Bfloat16.h"
Georgios Pinitas583137c2017-08-31 18:12:42 +010034#include "support/Half.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010035
Michel Iwaniec5dfeae62017-11-29 10:48:23 +000036#include <cmath>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010037#include <cstddef>
38#include <cstdint>
Isabella Gottardia7acb3c2019-01-08 13:48:44 +000039#include <map>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010040#include <string>
41#include <utility>
42
43namespace arm_compute
44{
Georgios Pinitas583137c2017-08-31 18:12:42 +010045/** 16-bit floating point type */
46using half = half_float::half;
47
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000048/** Permutation vector */
49using PermutationVector = Strides;
Georgios Pinitas77589b52018-08-21 14:41:35 +010050/** Bidirectional strides */
51using BiStrides = Coordinates;
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000052
Anthony Barbier6ff3b192017-09-04 18:44:23 +010053/** Image colour formats */
54enum class Format
55{
Daniil Efremov02bf80d2017-11-22 00:26:51 +070056 UNKNOWN, /**< Unknown image format */
57 U8, /**< 1 channel, 1 U8 per channel */
58 S16, /**< 1 channel, 1 S16 per channel */
59 U16, /**< 1 channel, 1 U16 per channel */
60 S32, /**< 1 channel, 1 S32 per channel */
61 U32, /**< 1 channel, 1 U32 per channel */
Georgios Pinitase8291ac2020-02-26 09:58:13 +000062 BFLOAT16, /**< 16-bit brain floating-point number */
Daniil Efremov02bf80d2017-11-22 00:26:51 +070063 F16, /**< 1 channel, 1 F16 per channel */
64 F32, /**< 1 channel, 1 F32 per channel */
65 UV88, /**< 2 channel, 1 U8 per channel */
66 RGB888, /**< 3 channels, 1 U8 per channel */
67 RGBA8888, /**< 4 channels, 1 U8 per channel */
68 YUV444, /**< A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes */
69 YUYV422, /**< A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes */
70 NV12, /**< A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling */
71 NV21, /**< A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling */
72 IYUV, /**< A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes */
73 UYVY422 /**< A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010074};
75
76/** Available data types */
77enum class DataType
78{
Georgios Pinitas8217c8e2019-11-11 18:24:22 +000079 UNKNOWN, /**< Unknown data type */
80 U8, /**< unsigned 8-bit number */
81 S8, /**< signed 8-bit number */
82 QSYMM8, /**< quantized, symmetric fixed-point 8-bit number */
83 QASYMM8, /**< quantized, asymmetric fixed-point 8-bit number unsigned */
84 QASYMM8_SIGNED, /**< quantized, asymmetric fixed-point 8-bit number signed */
85 QSYMM8_PER_CHANNEL, /**< quantized, symmetric per channel fixed-point 8-bit number */
86 U16, /**< unsigned 16-bit number */
87 S16, /**< signed 16-bit number */
88 QSYMM16, /**< quantized, symmetric fixed-point 16-bit number */
89 QASYMM16, /**< quantized, asymmetric fixed-point 16-bit number */
90 U32, /**< unsigned 32-bit number */
91 S32, /**< signed 32-bit number */
92 U64, /**< unsigned 64-bit number */
93 S64, /**< signed 64-bit number */
Georgios Pinitase8291ac2020-02-26 09:58:13 +000094 BFLOAT16, /**< 16-bit brain floating-point number */
Georgios Pinitas8217c8e2019-11-11 18:24:22 +000095 F16, /**< 16-bit floating-point number */
96 F32, /**< 32-bit floating-point number */
97 F64, /**< 64-bit floating-point number */
98 SIZET /**< size_t */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010099};
100
Daniil Efremov02bf80d2017-11-22 00:26:51 +0700101/** Available Sampling Policies */
102enum class SamplingPolicy
103{
104 CENTER, /**< Samples are taken at pixel center */
105 TOP_LEFT /**< Samples are taken at pixel top left corner */
106};
107
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100108/** Constant value of the border pixels when using BorderMode::CONSTANT */
109constexpr uint8_t CONSTANT_BORDER_VALUE = 199;
110
Alex Gildayc357c472018-03-21 13:54:09 +0000111/** Constant value used to indicate a half-scale pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100112constexpr float SCALE_PYRAMID_HALF = 0.5f;
113
Alex Gildayc357c472018-03-21 13:54:09 +0000114/** Constant value used to indicate a ORB scaled pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100115constexpr float SCALE_PYRAMID_ORB = 8.408964152537146130583778358414e-01;
116
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000117/** [DataLayout enum definition] **/
118
Georgios Pinitas4074c992018-01-30 18:13:46 +0000119/** Supported tensor data layouts */
120enum class DataLayout
121{
Alex Gildayc357c472018-03-21 13:54:09 +0000122 UNKNOWN, /**< Unknown data layout */
123 NCHW, /**< Num samples, channels, height, width */
124 NHWC /**< Num samples, height, width, channels */
Georgios Pinitas4074c992018-01-30 18:13:46 +0000125};
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000126/** [DataLayout enum definition] **/
Georgios Pinitas4074c992018-01-30 18:13:46 +0000127
Isabella Gottardid17a6772018-02-27 17:41:55 +0000128/** Supported tensor data layout dimensions */
129enum class DataLayoutDimension
130{
Alex Gildayc357c472018-03-21 13:54:09 +0000131 CHANNEL, /**< channel */
132 HEIGHT, /**< height */
133 WIDTH, /**< width */
134 BATCHES /**< batches */
Isabella Gottardid17a6772018-02-27 17:41:55 +0000135};
136
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000137/** Available ConvolutionMethod*/
138enum class ConvolutionMethod
139{
Vidhya Sudhan Loganathan8ec0bb62019-04-23 10:40:44 +0100140 GEMM, /**< Convolution using GEMM */
141 DIRECT, /**< Direct convolution */
142 WINOGRAD, /**< Convolution using Winograd */
143 FFT /**< Convolution using FFT */
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000144};
145
Manuel Bottini05069f02019-09-26 17:18:26 +0100146/** Available DepthwiseConvolutionFunction*/
147enum class DepthwiseConvolutionFunction
148{
149 OPTIMIZED, /**< Optimized Depthwise Convolution */
150 GENERIC, /**< Generic Depthwise Convolution */
151};
152
giuros0146a49a02019-04-01 13:50:22 +0100153/** Available DeconvolutionMethod*/
154enum class DeconvolutionMethod
155{
156 GEMM, /**< Deconvolution using GEMM */
157 DIRECT, /**< Direct deconvolution */
158};
159
Manuel Bottini2732cca2019-05-28 11:44:41 +0100160/** Available FuseBatchNormalizationType*/
161enum class FuseBatchNormalizationType
162{
163 CONVOLUTION, /**< For Convolution weights */
164 DEPTHWISECONVOLUTION /**< For Depthwise Convolution weights*/
165};
166
Usama Arif89890c62019-03-19 10:57:05 +0000167/** Padding mode to use for PadLayer */
168enum class PaddingMode
169{
170 CONSTANT,
171 REFLECT,
172 SYMMETRIC
173};
174
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000175/** Supported comparison operations */
176enum class ComparisonOperation
177{
178 Equal, /**< Equal comparison ( \f$ x == y \f$ ) */
179 NotEqual, /**< NotEqual comparison ( \f$ x != y \f$ ) */
180 Greater, /**< Greater comparison ( \f$ x > y \f$ ) */
181 GreaterEqual, /**< Greater equal comparison ( \f$ x >= y \f$ ) */
182 Less, /**< Less comparison ( \f$ x < y \f$ ) */
183 LessEqual /**< Less equal comparison ( \f$ x <= y \f$ ) */
184};
185
Alex Gildayc357c472018-03-21 13:54:09 +0000186/** Container for valid region of a window */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100187struct ValidRegion
188{
Alex Gildayc357c472018-03-21 13:54:09 +0000189 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100190 ValidRegion()
191 : anchor{}, shape{}
192 {
193 }
194
Alex Gildayc357c472018-03-21 13:54:09 +0000195 /** Allow instances of this class to be copy constructed */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100196 ValidRegion(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000197 /** Allow instances of this class to be move constructed */
198 ValidRegion(ValidRegion &&) = default;
199 /** Allow instances of this class to be copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100200 ValidRegion &operator=(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000201 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100202 ValidRegion &operator=(ValidRegion &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000203 /** Default destructor */
204 ~ValidRegion() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100205
Alex Gildayc357c472018-03-21 13:54:09 +0000206 /** Constructor for a valid region with default number of dimensions
207 *
208 * @param[in] an_anchor Anchor for the start of the valid region.
209 * @param[in] a_shape Shape of the valid region.
210 *
211 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000212 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
213 : anchor{ an_anchor }, shape{ a_shape }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100214 {
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000215 anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
216 }
217
Alex Gildayc357c472018-03-21 13:54:09 +0000218 /** Constructor for a valid region with specified number of dimensions
219 *
220 * @param[in] an_anchor Anchor for the start of the valid region.
221 * @param[in] a_shape Shape of the valid region.
222 * @param[in] num_dimensions Number of dimensions (must be >= number of dimensions of anchor and shape).
223 *
224 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000225 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
226 : anchor{ an_anchor }, shape{ a_shape }
227 {
228 ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
229 anchor.set_num_dimensions(num_dimensions);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100230 }
231
232 /** Return the start of the valid region for the given dimension @p d */
233 int start(unsigned int d) const
234 {
235 return anchor[d];
236 }
237
238 /** Return the end of the valid region for the given dimension @p d */
239 int end(unsigned int d) const
240 {
241 return anchor[d] + shape[d];
242 }
243
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000244 /** Accessor to set the value of anchor and shape for one of the dimensions.
245 *
246 * @param[in] dimension Dimension for which the value is set.
247 * @param[in] start Value to be set in anchor for the dimension.
248 * @param[in] size Value to be set in shape for the dimension.
249 *
250 * @return *this.
251 */
252 ValidRegion &set(size_t dimension, int start, size_t size)
253 {
254 anchor.set(dimension, start);
255 shape.set(dimension, size);
256 return *this;
257 }
258
Alex Gildayc357c472018-03-21 13:54:09 +0000259 Coordinates anchor; /**< Anchor for the start of the valid region. */
260 TensorShape shape; /**< Shape of the valid region. */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100261};
262
263/** Methods available to handle borders */
264enum class BorderMode
265{
266 UNDEFINED, /**< Borders are left undefined */
267 CONSTANT, /**< Pixels outside the image are assumed to have a constant value */
268 REPLICATE /**< Pixels outside the image are assumed to have the same value as the closest image pixel */
269};
270
271/** Container for 2D border size */
272struct BorderSize
273{
274 /** Empty border, i.e. no border */
275 constexpr BorderSize()
276 : top{ 0 }, right{ 0 }, bottom{ 0 }, left{ 0 }
277 {
278 }
279
280 /** Border with equal size around the 2D plane */
Moritz Pflanzer7655a672017-09-23 11:57:33 +0100281 explicit constexpr BorderSize(unsigned int size)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100282 : top{ size }, right{ size }, bottom{ size }, left{ size }
283 {
284 }
285
286 /** Border with same size for top/bottom and left/right */
287 constexpr BorderSize(unsigned int top_bottom, unsigned int left_right)
288 : top{ top_bottom }, right{ left_right }, bottom{ top_bottom }, left{ left_right }
289 {
290 }
291
292 /** Border with different sizes */
293 constexpr BorderSize(unsigned int top, unsigned int right, unsigned int bottom, unsigned int left)
294 : top{ top }, right{ right }, bottom{ bottom }, left{ left }
295 {
296 }
297
298 /** Check if the entire border is zero */
299 constexpr bool empty() const
300 {
301 return top == 0 && right == 0 && bottom == 0 && left == 0;
302 }
303
304 /** Check if the border is the same size on all sides */
305 constexpr bool uniform() const
306 {
307 return top == right && top == bottom && top == left;
308 }
309
Alex Gildayc357c472018-03-21 13:54:09 +0000310 /** Scale this border size.
311 *
312 * @param[in] scale Scale to multiply border size by.
313 *
314 * @return *this.
315 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100316 BorderSize &operator*=(float scale)
317 {
318 top *= scale;
319 right *= scale;
320 bottom *= scale;
321 left *= scale;
322
323 return *this;
324 }
325
Alex Gildayc357c472018-03-21 13:54:09 +0000326 /** Scale a copy of this border size.
327 *
328 * @param[in] scale Scale to multiply border size by.
329 *
330 * @return a scaled copy of this.
331 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100332 BorderSize operator*(float scale)
333 {
334 BorderSize size = *this;
335 size *= scale;
336
337 return size;
338 }
339
Alex Gildayc357c472018-03-21 13:54:09 +0000340 /** Limit this border size.
341 *
342 * @param[in] limit Border size to limit this border size to.
343 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100344 void limit(const BorderSize &limit)
345 {
346 top = std::min(top, limit.top);
347 right = std::min(right, limit.right);
348 bottom = std::min(bottom, limit.bottom);
349 left = std::min(left, limit.left);
350 }
351
Alex Gildayc357c472018-03-21 13:54:09 +0000352 unsigned int top; /**< top of the border */
353 unsigned int right; /**< right of the border */
354 unsigned int bottom; /**< bottom of the border */
355 unsigned int left; /**< left of the border */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100356};
357
Alex Gildayc357c472018-03-21 13:54:09 +0000358/** Container for 2D padding size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100359using PaddingSize = BorderSize;
360
361/** Policy to handle overflow */
362enum class ConvertPolicy
363{
364 WRAP, /**< Wrap around */
365 SATURATE /**< Saturate */
366};
367
368/** Interpolation method */
369enum class InterpolationPolicy
370{
371 NEAREST_NEIGHBOR, /**< Output values are defined to match the source pixel whose center is nearest to the sample position */
372 BILINEAR, /**< Output values are defined by bilinear interpolation between the pixels */
373 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 */
374};
375
376/** Bilinear Interpolation method used by LKTracker */
377enum class BilinearInterpolation
378{
Alex Gildayc357c472018-03-21 13:54:09 +0000379 BILINEAR_OLD_NEW, /**< Old-new method */
380 BILINEAR_SCHARR /**< Scharr method */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100381};
382
383/** Threshold mode */
384enum class ThresholdType
385{
386 BINARY, /**< Threshold with one value */
387 RANGE /**< Threshold with two values*/
388};
389
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100390/** Termination criteria */
391enum class Termination
392{
Alex Gildayc357c472018-03-21 13:54:09 +0000393 TERM_CRITERIA_EPSILON, /**< Terminate when within epsilon of a threshold */
394 TERM_CRITERIA_ITERATIONS, /**< Terminate after a maximum number of iterations */
395 TERM_CRITERIA_BOTH /**< Terminate on whichever of the other conditions occurs first */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100396};
397
398/** Magnitude calculation type. */
399enum class MagnitudeType
400{
401 L1NORM, /**< L1 normalization type */
402 L2NORM /**< L2 normalization type */
403};
404
405/** Phase calculation type.
406 *
407 * @note When PhaseType == SIGNED, each angle is mapped to the range 0 to 255 inclusive otherwise angles between 0 and 180
408 */
409enum class PhaseType
410{
411 SIGNED, /**< Angle range: [0, 360] */
412 UNSIGNED /**< Angle range: [0, 180] */
413};
414
415/** Keypoint type */
416struct KeyPoint
417{
418 int32_t x{ 0 }; /**< X coordinates */
419 int32_t y{ 0 }; /**< Y coordinates */
420 float strength{ 0.f }; /**< Strength of the point */
421 float scale{ 0.f }; /**< Scale initialized to 0 by the corner detector */
422 float orientation{ 0.f }; /**< Orientation initialized to 0 by the corner detector */
423 int32_t tracking_status{ 0 }; /**< Status initialized to 1 by the corner detector, set to 0 when the point is lost */
424 float error{ 0.f }; /**< Tracking error initialized to 0 by the corner detector */
425};
426
Alex Gildayc357c472018-03-21 13:54:09 +0000427/** Internal key point */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100428using InternalKeypoint = std::tuple<float, float, float>; /* x,y,strength */
429
430/** Rectangle type */
431struct Rectangle
432{
433 uint16_t x; /**< Top-left x coordinate */
434 uint16_t y; /**< Top-left y coordinate */
435 uint16_t width; /**< Width of the rectangle */
436 uint16_t height; /**< Height of the rectangle */
437};
438
439/** Coordinate type */
440struct Coordinates2D
441{
442 int32_t x; /**< X coordinates */
443 int32_t y; /**< Y coordinates */
444};
445
446/** Coordinate type */
447struct Coordinates3D
448{
449 uint32_t x; /**< X coordinates */
450 uint32_t y; /**< Y coordinates */
451 uint32_t z; /**< Z coordinates */
452};
453
Giuseppe Rossinid7647d42018-07-17 18:13:13 +0100454/** Padding information as a pair of unsigned int start/end */
455using PaddingInfo = std::pair<uint32_t, uint32_t>;
456
457/** List of padding information */
458using PaddingList = std::vector<PaddingInfo>;
459
giuros013175fcf2018-11-21 09:59:17 +0000460/** Information to produce a tiled version of a Tensor */
461using Multiples = std::vector<uint32_t>;
462
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100463/** Available channels */
464enum class Channel
465{
466 UNKNOWN, /** Unknown channel format */
467 C0, /**< First channel (used by formats with unknown channel types). */
468 C1, /**< Second channel (used by formats with unknown channel types). */
469 C2, /**< Third channel (used by formats with unknown channel types). */
470 C3, /**< Fourth channel (used by formats with unknown channel types). */
471 R, /**< Red channel. */
472 G, /**< Green channel. */
473 B, /**< Blue channel. */
474 A, /**< Alpha channel. */
475 Y, /**< Luma channel. */
476 U, /**< Cb/U channel. */
477 V /**< Cr/V/Value channel. */
478};
479
480/** Available matrix patterns */
481enum class MatrixPattern
482{
483 BOX, /**< Box pattern matrix. */
484 CROSS, /**< Cross pattern matrix. */
485 DISK, /**< Disk pattern matrix. */
486 OTHER /**< Any other matrix pattern. */
487};
488
489/** Available non linear functions. */
490enum class NonLinearFilterFunction : unsigned
491{
492 MEDIAN = 0, /**< Non linear median filter. */
493 MIN = 1, /**< Non linear erode. */
494 MAX = 2, /**< Non linear dilate. */
495};
496
Georgios Pinitasd9769582017-08-03 10:19:40 +0100497/** Available reduction operations */
498enum class ReductionOperation
499{
Michalis Spyrou7930db42018-11-22 17:36:28 +0000500 ARG_IDX_MAX, /**< Index of the max value */
Manuel Bottinib412fab2018-12-10 17:40:23 +0000501 ARG_IDX_MIN, /**< Index of the min value */
502 MEAN_SUM, /**< Mean of sum */
503 PROD, /**< Product */
504 SUM_SQUARE, /**< Sum of squares */
Usama Arifa4a08ad2019-05-20 12:38:33 +0100505 SUM, /**< Sum */
506 MIN, /**< Min */
Usama Arif28f0dd92019-05-20 13:44:34 +0100507 MAX, /**< Max */
Georgios Pinitasd9769582017-08-03 10:19:40 +0100508};
509
giuros01164a2722018-11-20 18:34:46 +0000510/** Available element-wise operations */
511enum class ArithmeticOperation
512{
513 ADD, /**< (x + y) */
514 SUB, /**< (x - y) */
515 DIV, /**< (x / y) */
516 MIN, /**< Min(x, y) */
517 MAX, /**< Max(x, y) */
518 SQUARED_DIFF, /**< (x - y)^2 */
Usama Arif81e671e2019-05-13 13:33:14 +0100519 POWER, /**< x ^ y */
giuros011e6e1b82019-05-14 16:12:53 +0100520 PRELU, /**< y*x if x < 0, x otherwise */
giuros01164a2722018-11-20 18:34:46 +0000521};
522
Michalis Spyroue9362622018-11-23 17:41:37 +0000523/** Available element wise unary operations */
524enum class ElementWiseUnary
525{
526 RSQRT, /**< Reverse square root */
527 EXP, /**< Exponential */
Usama Ariff6e475c2019-05-10 12:06:28 +0100528 NEG, /**< Negate */
Usama Arifc255aa72019-05-13 16:26:29 +0100529 LOG, /**< Natural Logarithm */
Manuel Bottini6ac59922019-05-15 14:06:02 +0100530 ABS, /**< Absolute value */
Michalis Spyrou0af44182019-05-17 14:04:47 +0100531 SIN, /**< Sine */
Usama Arif0a5a57a2019-05-23 14:20:33 +0100532 ROUND, /**< Round */
Michalis Spyroue9362622018-11-23 17:41:37 +0000533};
534
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100535/** The normalization type used for the normalization layer */
536enum class NormType
537{
538 IN_MAP_1D, /**< Normalization applied within the same map in 1D region */
539 IN_MAP_2D, /**< Normalization applied within the same map in 2D region */
540 CROSS_MAP /**< Normalization applied cross maps */
541};
542
543/** Normalization type for Histogram of Oriented Gradients (HOG) */
544enum class HOGNormType
545{
546 L2_NORM = 1, /**< L2-norm */
547 L2HYS_NORM = 2, /**< L2-norm followed by clipping */
548 L1_NORM = 3 /**< L1 norm */
549};
550
551/** Detection window used for the object detection. The detection window keeps the following information:
552 *
553 * -# Geometry of the rectangular window (x/y of top-left corner and width/height)
554 * -# Index of the class used for evaluating which class the detection window belongs to
555 * -# Confidence value (score) obtained with the classifier
556 */
557struct DetectionWindow
558{
559 uint16_t x{ 0 }; /**< Top-left x coordinate */
560 uint16_t y{ 0 }; /**< Top-left y coordinate */
561 uint16_t width{ 0 }; /**< Width of the detection window */
562 uint16_t height{ 0 }; /**< Height of the detection window */
563 uint16_t idx_class{ 0 }; /**< Index of the class */
564 float score{ 0.f }; /**< Confidence value for the detection window */
565};
566
567/** Dimension rounding type when down-scaling on CNNs
568 * @note Used in pooling and convolution layer
569 */
570enum class DimensionRoundingType
571{
572 FLOOR, /**< Floor rounding */
573 CEIL /**< Ceil rounding */
574};
575
576/** Available pooling types */
577enum class PoolingType
578{
579 MAX, /**< Max Pooling */
Georgios Pinitascdf51452017-08-31 14:21:36 +0100580 AVG, /**< Average Pooling */
581 L2 /**< L2 Pooling */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100582};
583
Michalis Spyrou2709d612018-09-19 09:46:47 +0100584/** Available non maxima suppression types */
585enum class NMSType
586{
587 LINEAR, /**< Linear NMS */
588 GAUSSIAN, /**< Gaussian NMS */
589 ORIGINAL /**< Original NMS */
590};
591
592/** BoxWithNonMaximaSuppressionLimit Information class */
593class BoxNMSLimitInfo final
594{
595public:
596 /** Constructor
597 *
598 * @param[in] score_thresh (Optional) Score threshold.
599 * @param[in] nms (Optional) NMS value
600 * @param[in] detections (Optional) Number of detections
601 * @param[in] soft_nms_enabled (Optional) Enable SoftNMS
602 * @param[in] soft_nms_method (Optional) Soft NMS method
603 * @param[in] soft_nms_sigma (Optional) Soft NMS sigma value
604 * @param[in] soft_nms_min_score_thres (Optional) Soft NMS minimum score threshold
Manuel Bottini5209be52019-02-13 16:34:56 +0000605 * @param[in] suppress_size (Optional) Filter out boxes based on their size. Defaults to false
606 * @param[in] min_size (Optional) Smaller boxes than min_size will be filtered out. Defaults to 1
607 * @param[in] im_width (Optional) Boxes whose centers (on the x axis) is beyond im_width will be filtered. Defaults to 1
608 * @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 +0100609 */
610 BoxNMSLimitInfo(float score_thresh = 0.05f, float nms = 0.3f,
611 int detections = 100, bool soft_nms_enabled = false,
612 NMSType soft_nms_method = NMSType::LINEAR,
Manuel Bottini5209be52019-02-13 16:34:56 +0000613 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 +0100614 : _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 +0000615 _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 +0100616 {
617 }
618 /** Get the score threshold */
619 float score_thresh() const
620 {
621 return _score_thresh;
622 }
623 /** Get the NMS */
624 float nms() const
625 {
626 return _nms;
627 }
628 /** Get the number of detections */
629 int detections_per_im() const
630 {
631 return _detections_per_im;
632 }
633 /** Check if soft NMS is enabled */
634 bool soft_nms_enabled() const
635 {
636 return _soft_nms_enabled;
637 }
638 /** Get soft NMS method */
639 NMSType soft_nms_method() const
640 {
641 return _soft_nms_method;
642 }
643 /** Get soft NMS sigma */
644 float soft_nms_sigma() const
645 {
646 return _soft_nms_sigma;
647 }
648 /** Get soft nms min score threshold */
649 float soft_nms_min_score_thres() const
650 {
651 return _soft_nms_min_score_thres;
652 }
Manuel Bottini5209be52019-02-13 16:34:56 +0000653 /** Get if NMS will suppress boxes based on their size/position */
654 bool suppress_size() const
655 {
656 return _suppress_size;
657 }
658 /** Get size suppression threshold */
659 float min_size() const
660 {
661 return _min_size;
662 }
663 /** Get image width (NMS may suppress boxes whose center sits beyond the image width) */
664 float im_width() const
665 {
666 return _im_width;
667 }
668 /** Get image height (NMS may suppress boxes whose center sits beyond the image height) */
669 float im_height() const
670 {
671 return _im_height;
672 }
Michalis Spyrou2709d612018-09-19 09:46:47 +0100673
674private:
675 float _score_thresh;
676 float _nms;
677 int _detections_per_im;
678 bool _soft_nms_enabled;
679 NMSType _soft_nms_method;
680 float _soft_nms_sigma;
681 float _soft_nms_min_score_thres;
Manuel Bottini5209be52019-02-13 16:34:56 +0000682 bool _suppress_size;
683 float _min_size;
684 float _im_width;
685 float _im_height;
Michalis Spyrou2709d612018-09-19 09:46:47 +0100686};
687
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100688/** Padding and stride information class */
689class PadStrideInfo
690{
691public:
692 /** Constructor
693 *
694 * @param[in] stride_x (Optional) Stride, in elements, across x. Defaults to 1.
695 * @param[in] stride_y (Optional) Stride, in elements, across y. Defaults to 1.
696 * @param[in] pad_x (Optional) Padding, in elements, across x. Defaults to 0.
697 * @param[in] pad_y (Optional) Padding, in elements, across y. Defaults to 0.
698 * @param[in] round (Optional) Dimensions rounding. Defaults to @ref FLOOR.
699 */
700 PadStrideInfo(unsigned int stride_x = 1, unsigned int stride_y = 1,
701 unsigned int pad_x = 0, unsigned int pad_y = 0,
702 DimensionRoundingType round = DimensionRoundingType::FLOOR)
703 : _stride(std::make_pair(stride_x, stride_y)),
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100704 _pad_left(pad_x),
705 _pad_top(pad_y),
706 _pad_right(pad_x),
707 _pad_bottom(pad_y),
708 _round_type(round)
709 {
710 }
711 /** Constructor
712 *
713 * @param[in] stride_x Stride, in elements, across x.
714 * @param[in] stride_y Stride, in elements, across y.
715 * @param[in] pad_left Padding across x on the left, in elements.
716 * @param[in] pad_top Padding across y on the top, in elements.
717 * @param[in] pad_right Padding across x on the right, in elements.
718 * @param[in] pad_bottom Padding across y on the bottom, in elements.
719 * @param[in] round Dimensions rounding.
720 */
721 PadStrideInfo(unsigned int stride_x, unsigned int stride_y,
722 unsigned int pad_left, unsigned int pad_right,
723 unsigned int pad_top, unsigned int pad_bottom,
724 DimensionRoundingType round)
725 : _stride(std::make_pair(stride_x, stride_y)),
726 _pad_left(pad_left),
727 _pad_top(pad_top),
728 _pad_right(pad_right),
729 _pad_bottom(pad_bottom),
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100730 _round_type(round)
731 {
732 }
Alex Gildayc357c472018-03-21 13:54:09 +0000733 /** Get the stride.
734 *
735 * @return a pair: stride x, stride y.
736 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100737 std::pair<unsigned int, unsigned int> stride() const
738 {
739 return _stride;
740 }
Alex Gildayc357c472018-03-21 13:54:09 +0000741 /** Check whether the padding is symmetric.
742 *
743 * @return True if the padding is symmetric.
744 */
Anthony Barbier21f67d62018-02-16 15:17:48 +0000745 bool padding_is_symmetric() const
746 {
747 return (_pad_left == _pad_right) && (_pad_top == _pad_bottom);
748 }
Alex Gildayc357c472018-03-21 13:54:09 +0000749 /** Get the padding.
750 *
751 * @note This should only be used when the padding is symmetric.
752 *
753 * @return a pair: padding left/right, padding top/bottom
754 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100755 std::pair<unsigned int, unsigned int> pad() const
756 {
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100757 //this accessor should be used only when padding is symmetric
Anthony Barbier21f67d62018-02-16 15:17:48 +0000758 ARM_COMPUTE_ERROR_ON(!padding_is_symmetric());
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100759 return std::make_pair(_pad_left, _pad_top);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100760 }
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100761
Alex Gildayc357c472018-03-21 13:54:09 +0000762 /** Get the left padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100763 unsigned int pad_left() const
764 {
765 return _pad_left;
766 }
Alex Gildayc357c472018-03-21 13:54:09 +0000767 /** Get the right padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100768 unsigned int pad_right() const
769 {
770 return _pad_right;
771 }
Alex Gildayc357c472018-03-21 13:54:09 +0000772 /** Get the top padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100773 unsigned int pad_top() const
774 {
775 return _pad_top;
776 }
Alex Gildayc357c472018-03-21 13:54:09 +0000777 /** Get the bottom padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100778 unsigned int pad_bottom() const
779 {
780 return _pad_bottom;
781 }
782
Alex Gildayc357c472018-03-21 13:54:09 +0000783 /** Get the rounding type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100784 DimensionRoundingType round() const
785 {
786 return _round_type;
787 }
788
Alex Gildayc357c472018-03-21 13:54:09 +0000789 /** Check whether this has any padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100790 bool has_padding() const
791 {
792 return (_pad_left != 0 || _pad_top != 0 || _pad_right != 0 || _pad_bottom != 0);
793 }
794
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100795private:
796 std::pair<unsigned int, unsigned int> _stride;
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100797 unsigned int _pad_left;
798 unsigned int _pad_top;
799 unsigned int _pad_right;
800 unsigned int _pad_bottom;
801
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100802 DimensionRoundingType _round_type;
803};
804
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100805/** PriorBox layer info */
806class PriorBoxLayerInfo final
807{
808public:
809 /** Default Constructor */
810 PriorBoxLayerInfo()
811 : _min_sizes(),
812 _variances(),
813 _offset(),
814 _flip(true),
815 _clip(false),
816 _max_sizes(),
817 _aspect_ratios(),
818 _img_size(),
819 _steps()
820 {
821 }
822 /** Constructor
823 *
824 * @param[in] min_sizes Min sizes vector.
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100825 * @param[in] variances Variances vector.
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100826 * @param[in] offset Offset value.
827 * @param[in] flip (Optional) Flip the aspect ratios.
828 * @param[in] clip (Optional) Clip coordinates so that they're within [0,1].
829 * @param[in] max_sizes (Optional) Max sizes vector.
830 * @param[in] aspect_ratios (Optional) Aspect ratios of the boxes.
831 * @param[in] img_size (Optional) Image size.
832 * @param[in] steps (Optional) Step values.
833 */
834 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 +0000835 const std::vector<float> &max_sizes = {}, const std::vector<float> &aspect_ratios = {},
836 const Coordinates2D &img_size = Coordinates2D{ 0, 0 }, const std::array<float, 2> &steps = { { 0.f, 0.f } })
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100837 : _min_sizes(min_sizes),
838 _variances(variances),
839 _offset(offset),
840 _flip(flip),
841 _clip(clip),
842 _max_sizes(max_sizes),
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100843 _aspect_ratios(),
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100844 _img_size(img_size),
845 _steps(steps)
846 {
847 _aspect_ratios.push_back(1.);
848 for(unsigned int i = 0; i < aspect_ratios.size(); ++i)
849 {
850 float ar = aspect_ratios[i];
851 bool already_exist = false;
852 for(auto ar_new : _aspect_ratios)
853 {
854 if(fabs(ar - ar_new) < 1e-6)
855 {
856 already_exist = true;
857 break;
858 }
859 }
860 if(!already_exist)
861 {
862 _aspect_ratios.push_back(ar);
863 if(flip)
864 {
865 _aspect_ratios.push_back(1.f / ar);
866 }
867 }
868 }
869 }
870 /** Get min sizes. */
871 std::vector<float> min_sizes() const
872 {
873 return _min_sizes;
874 }
875 /** Get min variances. */
876 std::vector<float> variances() const
877 {
878 return _variances;
879 }
880 /** Get the step coordinates */
881 std::array<float, 2> steps() const
882 {
883 return _steps;
884 }
885 /** Get the image size coordinates */
886 Coordinates2D img_size() const
887 {
888 return _img_size;
889 }
890 /** Get the offset */
891 float offset() const
892 {
893 return _offset;
894 }
895 /** Get the flip value */
896 bool flip() const
897 {
898 return _flip;
899 }
900 /** Get the clip value */
901 bool clip() const
902 {
903 return _clip;
904 }
905 /** Get max sizes. */
906 std::vector<float> max_sizes() const
907 {
908 return _max_sizes;
909 }
910 /** Get aspect ratios. */
911 std::vector<float> aspect_ratios() const
912 {
913 return _aspect_ratios;
914 }
915
916private:
917 std::vector<float> _min_sizes;
918 std::vector<float> _variances;
919 float _offset;
920 bool _flip;
921 bool _clip;
922 std::vector<float> _max_sizes;
923 std::vector<float> _aspect_ratios;
924 Coordinates2D _img_size;
925 std::array<float, 2> _steps;
926};
927
Isabella Gottardia7acb3c2019-01-08 13:48:44 +0000928// Bounding Box [xmin, ymin, xmax, ymax]
929using BBox = std::array<float, 4>;
930// LabelBBox used for map label and bounding box
931using LabelBBox = std::map<int, std::vector<BBox>>;
932
Isabella Gottardi05e56442018-11-16 11:26:52 +0000933/** Available Detection Output code types */
934enum class DetectionOutputLayerCodeType
935{
936 CORNER, /**< Use box corners */
937 CENTER_SIZE, /**< Use box centers and size */
938 CORNER_SIZE, /**< Use box centers and size */
939 TF_CENTER /**< Use box centers and size but flip x and y co-ordinates */
940};
941
942/** Detection Output layer info */
943class DetectionOutputLayerInfo final
944{
945public:
946 /** Default Constructor */
947 DetectionOutputLayerInfo()
948 : _num_classes(),
949 _share_location(),
950 _code_type(DetectionOutputLayerCodeType::CORNER),
951 _keep_top_k(),
952 _nms_threshold(),
953 _top_k(),
954 _background_label_id(),
955 _confidence_threshold(),
956 _variance_encoded_in_target(false),
957 _eta(),
958 _num_loc_classes()
959 {
960 _num_loc_classes = _share_location ? 1 : _num_classes;
961 }
962 /** Constructor
963 *
964 * @param[in] num_classes Number of classes to be predicted.
965 * @param[in] share_location If true, bounding box are shared among different classes.
966 * @param[in] code_type Type of coding method for bbox.
967 * @param[in] keep_top_k Number of total bounding boxes to be kept per image after NMS step.
968 * @param[in] nms_threshold Threshold to be used in NMS.
969 * @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.
970 * @param[in] background_label_id (Optional) Background label ID. If there is no background class, set it as -1.
971 * @param[in] confidence_threshold (Optional) Only consider detections whose confidences are larger than a threshold. Default set to -FLT_MAX.
972 * @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.
973 * @param[in] eta (Optional) Eta.
974 */
975 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,
976 float confidence_threshold = std::numeric_limits<float>::lowest(), bool variance_encoded_in_target = false, float eta = 1)
977 : _num_classes(num_classes),
978 _share_location(share_location),
979 _code_type(code_type),
980 _keep_top_k(keep_top_k),
981 _nms_threshold(nms_threshold),
982 _top_k(top_k),
983 _background_label_id(background_label_id),
984 _confidence_threshold(confidence_threshold),
985 _variance_encoded_in_target(variance_encoded_in_target),
986 _eta(eta),
987 _num_loc_classes()
988 {
989 _num_loc_classes = _share_location ? 1 : _num_classes;
990 }
991 /** Get num classes. */
992 int num_classes() const
993 {
994 return _num_classes;
995 }
996 /** Get share location. */
997 bool share_location() const
998 {
999 return _share_location;
1000 }
1001 /** Get detection output code type. */
1002 DetectionOutputLayerCodeType code_type() const
1003 {
1004 return _code_type;
1005 }
1006 /** Get if variance encoded in target. */
1007 bool variance_encoded_in_target() const
1008 {
1009 return _variance_encoded_in_target;
1010 }
1011 /** Get the number of total bounding boxes to be kept per image. */
1012 int keep_top_k() const
1013 {
1014 return _keep_top_k;
1015 }
1016 /** Get nms threshold. */
1017 float nms_threshold() const
1018 {
1019 return _nms_threshold;
1020 }
1021 /** Get eta. */
1022 float eta() const
1023 {
1024 return _eta;
1025 }
1026 /** Get background label ID. */
1027 int background_label_id() const
1028 {
1029 return _background_label_id;
1030 }
1031 /** Get confidence threshold. */
1032 float confidence_threshold() const
1033 {
1034 return _confidence_threshold;
1035 }
1036 /** Get top K. */
1037 int top_k() const
1038 {
1039 return _top_k;
1040 }
1041 /** Get number of location classes. */
1042 int num_loc_classes() const
1043 {
1044 return _num_loc_classes;
1045 }
1046
1047private:
1048 int _num_classes;
1049 bool _share_location;
1050 DetectionOutputLayerCodeType _code_type;
1051 int _keep_top_k;
1052 float _nms_threshold;
1053 int _top_k;
1054 int _background_label_id;
1055 float _confidence_threshold;
1056 bool _variance_encoded_in_target;
1057 float _eta;
1058 int _num_loc_classes;
1059};
1060
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001061/** Detection Output layer info */
1062class DetectionPostProcessLayerInfo final
1063{
1064public:
1065 /** Default Constructor */
1066 DetectionPostProcessLayerInfo()
1067 : _max_detections(),
1068 _max_classes_per_detection(),
1069 _nms_score_threshold(),
1070 _iou_threshold(),
1071 _num_classes(),
1072 _scales_values(),
1073 _use_regular_nms(),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001074 _detection_per_class(),
1075 _dequantize_scores()
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001076 {
1077 }
1078 /** Constructor
1079 *
1080 * @param[in] max_detections Number of total detection.
1081 * @param[in] max_classes_per_detection Number of total classes to be kept after NMS step. Used in the Fast Non-Max-Suppression
1082 * @param[in] nms_score_threshold Threshold to be used in NMS
1083 * @param[in] iou_threshold Threshold to be used during the intersection over union.
1084 * @param[in] num_classes Number of classes.
1085 * @param[in] scales_values Scales values used for decode center size boxes.
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001086 * @param[in] use_regular_nms (Optional) Boolean to determinate if use regular or fast nms. Defaults to false.
1087 * @param[in] detection_per_class (Optional) Number of detection per class. Used in the Regular Non-Max-Suppression. Defaults to 100.
1088 * @param[in] dequantize_scores (Optional) If the scores need to be dequantized. Defaults to true.
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001089 */
1090 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 +01001091 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 +00001092 : _max_detections(max_detections),
1093 _max_classes_per_detection(max_classes_per_detection),
1094 _nms_score_threshold(nms_score_threshold),
1095 _iou_threshold(iou_threshold),
1096 _num_classes(num_classes),
1097 _scales_values(scales_values),
1098 _use_regular_nms(use_regular_nms),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001099 _detection_per_class(detection_per_class),
1100 _dequantize_scores(dequantize_scores)
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001101 {
1102 }
1103 /** Get max detections. */
1104 unsigned int max_detections() const
1105 {
1106 return _max_detections;
1107 }
1108 /** Get max_classes per detection. Used in the Fast Non-Max-Suppression.*/
1109 unsigned int max_classes_per_detection() const
1110 {
1111 return _max_classes_per_detection;
1112 }
1113 /** Get detection per class. Used in the Regular Non-Max-Suppression */
1114 unsigned int detection_per_class() const
1115 {
1116 return _detection_per_class;
1117 }
1118 /** Get nms threshold. */
1119 float nms_score_threshold() const
1120 {
1121 return _nms_score_threshold;
1122 }
1123 /** Get intersection over union threshold. */
1124 float iou_threshold() const
1125 {
1126 return _iou_threshold;
1127 }
1128 /** Get num classes. */
1129 unsigned int num_classes() const
1130 {
1131 return _num_classes;
1132 }
1133 /** Get if use regular nms. */
1134 bool use_regular_nms() const
1135 {
1136 return _use_regular_nms;
1137 }
1138 /** Get y scale value. */
1139 float scale_value_y() const
1140 {
1141 // Saved as [y,x,h,w]
1142 return _scales_values[0];
1143 }
1144 /** Get x scale value. */
1145 float scale_value_x() const
1146 {
1147 // Saved as [y,x,h,w]
1148 return _scales_values[1];
1149 }
1150 /** Get h scale value. */
1151 float scale_value_h() const
1152 {
1153 // Saved as [y,x,h,w]
1154 return _scales_values[2];
1155 }
1156 /** Get w scale value. */
1157 float scale_value_w() const
1158 {
1159 // Saved as [y,x,h,w]
1160 return _scales_values[3];
1161 }
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001162 /** Get dequantize_scores value. */
1163 bool dequantize_scores() const
1164 {
1165 return _dequantize_scores;
1166 }
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001167
1168private:
1169 unsigned int _max_detections;
1170 unsigned int _max_classes_per_detection;
1171 float _nms_score_threshold;
1172 float _iou_threshold;
1173 unsigned int _num_classes;
1174 std::array<float, 4> _scales_values;
1175 bool _use_regular_nms;
1176 unsigned int _detection_per_class;
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001177 bool _dequantize_scores;
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001178};
1179
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001180/** Pooling Layer Information struct*/
1181struct PoolingLayerInfo
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001182{
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001183 /** Default Constructor */
1184 PoolingLayerInfo()
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001185 : pool_type(PoolingType::MAX),
1186 pool_size(Size2D()),
1187 data_layout(DataLayout::UNKNOWN),
1188 pad_stride_info(PadStrideInfo()),
1189 exclude_padding(false),
1190 is_global_pooling(false),
1191 fp_mixed_precision(false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001192 {
1193 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001194 /** Constructor
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001195 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001196 * @param[in] pool_type Pooling type @ref PoolingType.
1197 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001198 * @param[in] data_layout Data layout used by the layer @ref DataLayout
1199 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1200 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1201 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1202 * Defaults to false;
1203 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1204 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001205 explicit PoolingLayerInfo(PoolingType pool_type,
1206 unsigned int pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001207 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001208 PadStrideInfo pad_stride_info = PadStrideInfo(),
1209 bool exclude_padding = false,
1210 bool fp_mixed_precision = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001211 : pool_type(pool_type),
1212 pool_size(Size2D(pool_size, pool_size)),
1213 data_layout(data_layout),
1214 pad_stride_info(pad_stride_info),
1215 exclude_padding(exclude_padding),
1216 is_global_pooling(false),
1217 fp_mixed_precision(fp_mixed_precision)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001218 {
1219 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001220
1221 /** Constructor
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001222 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001223 * @param[in] pool_type Pooling type @ref PoolingType.
1224 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001225 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001226 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1227 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1228 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1229 * Defaults to false;
1230 * @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 +00001231 */
1232 explicit PoolingLayerInfo(PoolingType pool_type,
1233 Size2D pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001234 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001235 PadStrideInfo pad_stride_info = PadStrideInfo(),
1236 bool exclude_padding = false,
1237 bool fp_mixed_precision = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001238 : pool_type(pool_type),
1239 pool_size(pool_size),
1240 data_layout(data_layout),
1241 pad_stride_info(pad_stride_info),
1242 exclude_padding(exclude_padding),
1243 is_global_pooling(false),
1244 fp_mixed_precision(fp_mixed_precision)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001245 {
1246 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001247
1248 /** Constructor
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001249 *
1250 * @note This constructor is used for global pooling
1251 *
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001252 * @param[in] pool_type Pooling type @ref PoolingType.
1253 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001254 */
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001255 explicit PoolingLayerInfo(PoolingType pool_type, DataLayout data_layout)
1256 : pool_type(pool_type),
1257 pool_size(Size2D()),
1258 data_layout(data_layout),
1259 pad_stride_info(PadStrideInfo(1, 1, 0, 0)),
1260 exclude_padding(false),
1261 is_global_pooling(true),
1262 fp_mixed_precision(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001263 {
1264 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001265
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001266 PoolingType pool_type;
1267 Size2D pool_size;
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001268 DataLayout data_layout;
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001269 PadStrideInfo pad_stride_info;
1270 bool exclude_padding;
1271 bool is_global_pooling;
1272 bool fp_mixed_precision;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001273};
1274
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001275/** ROI Pooling Layer Information class */
giuros0118870812018-09-13 09:31:40 +01001276class ROIPoolingLayerInfo final
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001277{
1278public:
giuros0118870812018-09-13 09:31:40 +01001279 /** Constructor
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001280 *
giuros0118870812018-09-13 09:31:40 +01001281 * @param[in] pooled_width Pooled width of the layer.
1282 * @param[in] pooled_height Pooled height of the layer.
1283 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
1284 * @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 +01001285 */
giuros0118870812018-09-13 09:31:40 +01001286 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale, unsigned int sampling_ratio = 0)
1287 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale), _sampling_ratio(sampling_ratio)
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001288 {
1289 }
Alex Gildayc357c472018-03-21 13:54:09 +00001290 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001291 unsigned int pooled_width() const
1292 {
1293 return _pooled_width;
1294 }
Alex Gildayc357c472018-03-21 13:54:09 +00001295 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001296 unsigned int pooled_height() const
1297 {
1298 return _pooled_height;
1299 }
Alex Gildayc357c472018-03-21 13:54:09 +00001300 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001301 float spatial_scale() const
1302 {
1303 return _spatial_scale;
1304 }
giuros0118870812018-09-13 09:31:40 +01001305 /** Get sampling ratio */
1306 unsigned int sampling_ratio() const
1307 {
1308 return _sampling_ratio;
1309 }
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001310
1311private:
1312 unsigned int _pooled_width;
1313 unsigned int _pooled_height;
1314 float _spatial_scale;
giuros0118870812018-09-13 09:31:40 +01001315 unsigned int _sampling_ratio;
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001316};
1317
Manuel Bottini5209be52019-02-13 16:34:56 +00001318/** Generate Proposals Information class */
1319class GenerateProposalsInfo
1320{
1321public:
1322 /** Constructor
1323 *
1324 * @param[in] im_width Width of the original image
1325 * @param[in] im_height Height of the original image
1326 * @param[in] im_scale Scale applied to the original image
1327 * @param[in] spatial_scale (Optional)Scale applied to the feature map. Defaults to 1.0
1328 * @param[in] pre_nms_topN (Optional)Number of the best scores to be selected from the transformations. Defaults to 6000.
1329 * @param[in] post_nms_topN (Optional)Number of the best scores to be selected from the NMS operation. Defaults to 300.
1330 * @param[in] nms_thres (Optional)NMS overlap threshold. Defaults to 0.7.
1331 * @param[in] min_size (Optional)Size used to validate the anchors produced. Defaults to 16.
1332 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region of interest). Defaults to 4.
1333 */
1334 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,
1335 size_t values_per_roi = 4)
1336 : _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),
1337 _min_size(min_size), _values_per_roi(values_per_roi)
1338 {
1339 }
1340
1341 /* Get the original height */
1342 float im_height() const
1343 {
1344 return _im_height;
1345 }
1346 /* Get the original width */
1347 float im_width() const
1348 {
1349 return _im_width;
1350 }
1351 /* Get the image scale */
1352 float im_scale() const
1353 {
1354 return _im_scale;
1355 }
1356 /* Get the value of how many best scores to select (before NMS) */
1357 int pre_nms_topN() const
1358 {
1359 return _pre_nms_topN;
1360 }
1361 /* Get the value of how many best scores to select (after NMS) */
1362 int post_nms_topN() const
1363 {
1364 return _post_nms_topN;
1365 }
1366 /* Get the NMS overlap threshold */
1367 float nms_thres() const
1368 {
1369 return _nms_thres;
1370 }
1371 /* Get the minimal size */
1372 float min_size() const
1373 {
1374 return _min_size;
1375 }
1376 /* Get the spatial scale to be applied to the feature maps */
1377 float spatial_scale() const
1378 {
1379 return _spatial_scale;
1380 }
1381 /* Get the values used to represent a ROI(Region of interest)*/
1382 size_t values_per_roi() const
1383 {
1384 return _values_per_roi;
1385 }
1386
1387private:
1388 float _im_height;
1389 float _im_width;
1390 float _im_scale;
1391 float _spatial_scale;
1392 int _pre_nms_topN;
1393 int _post_nms_topN;
1394 float _nms_thres;
1395 float _min_size;
1396 size_t _values_per_roi;
1397};
1398
1399/** ComputeAnchors information class */
1400class ComputeAnchorsInfo
1401{
1402public:
1403 /** Constructor
1404 *
1405 * @param[in] feat_width Feature map width
1406 * @param[in] feat_height Feature map height
1407 * @param[in] spatial_scale Feature map scale
1408 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region Of Interest). Defaults to 4
1409 */
1410 ComputeAnchorsInfo(float feat_width, float feat_height, float spatial_scale, size_t values_per_roi = 4)
1411 : _feat_height(feat_height),
1412 _feat_width(feat_width),
1413 _spatial_scale(spatial_scale),
1414 _values_per_roi(values_per_roi)
1415 {
1416 }
1417
1418 /* Get the height of the feature map */
1419 float feat_height() const
1420 {
1421 return _feat_height;
1422 }
1423
1424 /* Get the width of the feature map */
1425 float feat_width() const
1426 {
1427 return _feat_width;
1428 }
1429
1430 /* Get the scale of the feature map */
1431 float spatial_scale() const
1432 {
1433 return _spatial_scale;
1434 }
1435
1436 /* Get the values used to represent a ROI(Region Of Interest)*/
1437 size_t values_per_roi() const
1438 {
1439 return _values_per_roi;
1440 }
1441
1442private:
1443 float _feat_height;
1444 float _feat_width;
1445 float _spatial_scale;
1446 size_t _values_per_roi;
1447};
1448
giuros01c04a0e82018-10-03 12:44:35 +01001449/** Bounding Box Transform information class */
giuros01d696cb62018-11-16 10:39:59 +00001450class BoundingBoxTransformInfo final
giuros01c04a0e82018-10-03 12:44:35 +01001451{
1452public:
1453 /** Constructor
1454 *
giuros01d696cb62018-11-16 10:39:59 +00001455 * @param[in] img_width Width of the original image
1456 * @param[in] img_height Height, of the original image
1457 * @param[in] scale Scale of the original image
1458 * @param[in] apply_scale (Optional)Re-apply scaling after transforming the boxes. Defaults to false
1459 * @param[in] weights (Optional)Weights [wx, wy, ww, wh] for the deltas. Defaults to all ones
1460 * @param[in] correct_transform_coords (Optional)Correct bounding box transform coordinates. Defaults to false
1461 * @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 +01001462 */
giuros01d696cb62018-11-16 10:39:59 +00001463 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 =
1464 false,
1465 float bbox_xform_clip =
1466 4.135166556742356f)
1467 : _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 +01001468 {
1469 }
1470
1471 std::array<float, 4> weights() const
1472 {
1473 return _weights;
1474 }
1475
1476 float bbox_xform_clip() const
1477 {
1478 return _bbox_xform_clip;
1479 }
1480
1481 float img_height() const
1482 {
1483 return _img_height;
1484 }
1485
1486 float img_width() const
1487 {
1488 return _img_width;
1489 }
1490
1491 float scale() const
1492 {
1493 return _scale;
1494 }
1495
1496 bool apply_scale() const
1497 {
1498 return _apply_scale;
1499 }
1500
giuros01d696cb62018-11-16 10:39:59 +00001501 bool correct_transform_coords() const
1502 {
1503 return _correct_transform_coords;
1504 }
1505
giuros01c04a0e82018-10-03 12:44:35 +01001506private:
1507 float _img_width;
1508 float _img_height;
1509 float _scale;
1510 bool _apply_scale;
giuros01d696cb62018-11-16 10:39:59 +00001511 bool _correct_transform_coords;
giuros01c04a0e82018-10-03 12:44:35 +01001512 std::array<float, 4> _weights;
1513 float _bbox_xform_clip;
1514};
1515
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001516/** Activation Layer Information class */
1517class ActivationLayerInfo
1518{
1519public:
1520 /** Available activation functions */
1521 enum class ActivationFunction
1522 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001523 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
1524 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
1525 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
1526 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
1527 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
Manuel Bottini581c8982019-02-07 10:31:57 +00001528 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 +01001529 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
Georgios Pinitasfb0fdcd2019-08-22 17:10:04 +01001530 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 +01001531 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
1532 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
1533 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
Usama Arif6a98a6e2019-05-10 17:07:27 +01001534 LINEAR, /**< Linear ( \f$ f(x)= ax + b \f$ ) */
morgolock07df3d42020-02-27 11:46:28 +00001535 IDENTITY, /**< Identity ( \f$ f(x)= x \f$ ) */
1536 HARD_SWISH /**< Hard-swish ( \f$ f(x) = (x * relu6(x+3))/6 \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001537 };
1538
Giorgio Arena11674872018-02-07 15:38:12 +00001539 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001540 /** Default Constructor
1541 *
1542 * @param[in] f The activation function to use.
1543 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001544 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1545 * @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 +01001546 */
1547 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001548 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001549 {
1550 }
Alex Gildayc357c472018-03-21 13:54:09 +00001551 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001552 ActivationFunction activation() const
1553 {
1554 return _act;
1555 }
Alex Gildayc357c472018-03-21 13:54:09 +00001556 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001557 float a() const
1558 {
1559 return _a;
1560 }
Alex Gildayc357c472018-03-21 13:54:09 +00001561 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001562 float b() const
1563 {
1564 return _b;
1565 }
Alex Gildayc357c472018-03-21 13:54:09 +00001566 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001567 bool enabled() const
1568 {
1569 return _enabled;
1570 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001571
1572private:
Usama Arif6a98a6e2019-05-10 17:07:27 +01001573 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::IDENTITY };
Giorgio Arena11674872018-02-07 15:38:12 +00001574 float _a = {};
1575 float _b = {};
1576 bool _enabled = { false };
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001577};
1578
Giorgio Arena1856ff72020-02-07 13:46:45 +00001579/** Fully connected layer info */
1580struct FullyConnectedLayerInfo
1581{
1582 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
1583 bool transpose_weights{ true }; /**< Transpose weights if true. */
1584 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
1585 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
1586 bool fp_mixed_precision{ false }; /**< Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy. */
1587 ActivationLayerInfo activation_info{}; /**< Fused activation to apply after the matrix multiplication. */
1588
1589 /** Sets the weights trained data layout
1590 *
1591 * @param[in] layout Data layout that the weights were trained with
1592 *
1593 * @return Updated object
1594 */
1595 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
1596 {
1597 weights_trained_layout = layout;
1598 return *this;
1599 }
1600 /** Sets the transpose weights flag
1601 *
1602 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
1603 *
1604 * @return Updated object
1605 */
1606 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
1607 {
1608 transpose_weights = should_transpose_weights;
1609 return *this;
1610 }
1611};
1612
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001613/** Normalization Layer Information class */
1614class NormalizationLayerInfo
1615{
1616public:
1617 /** Default Constructor
1618 *
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001619 * @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 +01001620 * @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 +00001621 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1622 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1623 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1624 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1625 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001626 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001627 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1628 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001629 {
1630 }
Alex Gildayc357c472018-03-21 13:54:09 +00001631 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001632 NormType type() const
1633 {
1634 return _type;
1635 }
Alex Gildayc357c472018-03-21 13:54:09 +00001636 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001637 uint32_t norm_size() const
1638 {
1639 return _norm_size;
1640 }
Alex Gildayc357c472018-03-21 13:54:09 +00001641 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001642 float alpha() const
1643 {
1644 return _alpha;
1645 }
Alex Gildayc357c472018-03-21 13:54:09 +00001646 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001647 float beta() const
1648 {
1649 return _beta;
1650 }
Alex Gildayc357c472018-03-21 13:54:09 +00001651 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001652 float kappa() const
1653 {
1654 return _kappa;
1655 }
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001656 /** Get the is_scaled value */
1657 bool is_scaled() const
1658 {
1659 return _is_scaled;
1660 }
Alex Gildayc357c472018-03-21 13:54:09 +00001661 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001662 bool is_cross_map() const
1663 {
1664 return _type == NormType::CROSS_MAP;
1665 }
Alex Gildayc357c472018-03-21 13:54:09 +00001666 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001667 bool is_in_map() const
1668 {
1669 return !is_cross_map();
1670 }
1671 /** Return the scaling factor of the normalization function.
1672 *
1673 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1674 * 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 +01001675 *
1676 * @return The normalization scaling factor.
1677 */
1678 float scale_coeff() const
1679 {
1680 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001681 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001682 }
1683
1684private:
1685 NormType _type;
1686 uint32_t _norm_size;
1687 float _alpha;
1688 float _beta;
1689 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001690 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001691};
1692
thecha012bfadd92020-08-12 17:25:51 +01001693class StridedSliceLayerInfo
1694{
1695public:
1696 /** Default Constructor
1697 *
1698 * @param[in] begin_mask (Optional) If the ith bit of begin_mask is set, starts[i] is ignored and the fullest possible range in that dimension is used instead.
1699 * @param[in] end_mask (Optional) If the ith bit of end_mask is set, ends[i] is ignored and the fullest possible range in that dimension is used instead.
1700 * @param[in] shrink_axis_mask (Optional) If the ith bit of shrink_axis_mask is set, it implies that the ith specification shrinks the dimensionality by 1.
1701 */
1702 StridedSliceLayerInfo(int32_t begin_mask = 0, int32_t end_mask = 0, int32_t shrink_axis_mask = 0)
1703 : _begin_mask(begin_mask), _end_mask(end_mask), _shrink_axis_mask(shrink_axis_mask)
1704 {
1705 }
1706
1707 /* Get the begin mask value */
1708 int32_t begin_mask() const
1709 {
1710 return _begin_mask;
1711 }
1712
1713 /* Get the end mask value */
1714 int32_t end_mask() const
1715 {
1716 return _end_mask;
1717 }
1718
1719 /* Get the shrink axis mask value */
1720 int32_t shrink_axis_mask() const
1721 {
1722 return _shrink_axis_mask;
1723 }
1724
1725private:
1726 int32_t _begin_mask;
1727 int32_t _end_mask;
1728 int32_t _shrink_axis_mask;
1729};
1730
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001731/** 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 +01001732class WeightsInfo
1733{
1734public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001735 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001736 WeightsInfo()
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001737 : _are_reshaped(false), _kernel_width(0), _kernel_height(0), _num_kernels(0), _retain_internal_weights(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001738 {
1739 }
1740 /** Constructor
1741 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001742 * @param[in] are_reshaped True if the weights have been reshaped
1743 * @param[in] kernel_width Kernel width.
1744 * @param[in] kernel_height Kernel height.
1745 * @param[in] num_kernels Number of convolution kernels.
1746 * @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 +01001747 */
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001748 WeightsInfo(bool are_reshaped, unsigned int kernel_width, unsigned int kernel_height, unsigned int num_kernels, bool retain_internal_weights = false)
1749 : _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 +01001750 {
1751 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001752 /** Flag which specifies if the weights tensor has been reshaped.
1753 *
1754 * @return True if the weights tensors has been reshaped
1755 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001756 bool are_reshaped() const
1757 {
1758 return _are_reshaped;
1759 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001760 /** Return the number of convolution kernels
1761 *
1762 * @return The number of convolution kernels
1763 */
1764 unsigned int num_kernels() const
1765 {
1766 return _num_kernels;
1767 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001768 /** Return the width and height of the kernel
1769 *
1770 * @return The width and height of the kernel
1771 */
1772 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001773 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001774 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001775 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001776 bool retain_internal_weights() const
1777 {
1778 return _retain_internal_weights;
1779 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001780
1781private:
SiCong Liebd8fb42020-08-18 11:03:14 +01001782 bool _are_reshaped;
1783 unsigned int _kernel_width;
1784 unsigned int _kernel_height;
1785 unsigned int _num_kernels;
1786 bool _retain_internal_weights;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001787};
1788
Gian Marco36a0a462018-01-12 10:21:40 +00001789/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
1790 *
Gian Marco Iodice5fc07aa2019-05-15 17:08:02 +01001791 * The matrix A can only be reshaped through @ref CLGEMMReshapeLHSMatrixKernel or @ref NEGEMMInterleave4x4Kernel or @ref GCGEMMInterleave4x4Kernel
1792 * 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 +00001793 *
giuros018b6b4a92018-12-18 19:01:33 +00001794 * The matrix B can only be reshaped through @ref CLGEMMReshapeRHSMatrixKernel or @ref NEGEMMTranspose1xWKernel or @ref GCGEMMTranspose1xWKernel
1795 * 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 +00001796 *
1797 */
1798class GEMMReshapeInfo final
1799{
1800public:
1801 /** Default constructor */
1802 GEMMReshapeInfo()
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001803 : _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 +00001804 {
1805 }
1806 /** Constructor
1807 *
1808 * @param[in] m Number of matrix A rows
1809 * @param[in] n Number of matrix B columns
1810 * @param[in] k Number of matrix A columns or matrix B rows
1811 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
1812 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001813 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
1814 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001815 * @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 +01001816 * to perform 1x1 convolutions with the NHWC data layout)
1817 * @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 +00001818 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001819 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 +01001820 : _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 +01001821 _reinterpret_input_as_3d(reinterpret_input_as_3d), _broadcast_bias(broadcast_bias)
Gian Marco36a0a462018-01-12 10:21:40 +00001822 {
1823 }
1824 /** Number of matrix A rows
1825 *
1826 * @return the number of matrix A rows
1827 */
1828 int m() const
1829 {
1830 return _m;
1831 }
1832 /** Number of matrix B columns
1833 *
1834 * @return the number of matrix B columns
1835 */
1836 int n() const
1837 {
1838 return _n;
1839 }
1840 /** Number of matrix A columns or matrix B rows
1841 *
1842 * @return the number of matrix A columns or matrix B rows
1843 */
1844 int k() const
1845 {
1846 return _k;
1847 }
1848 /** Multiplication factor for the width of the 1xW transposed block
1849 *
1850 * @return the multiplication factor for the width of the 1xW transposed block
1851 */
1852 int mult_transpose1xW_width() const
1853 {
1854 return _mult_transpose1xW_width;
1855 }
1856 /** Multiplication factor for the height of the 4x4 interleaved block
1857 *
1858 * @return the multiplication factor for the height of the 4x4 interleaved block
1859 */
1860 int mult_interleave4x4_height() const
1861 {
1862 return _mult_interleave4x4_height;
1863 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001864 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
1865 *
1866 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
1867 * m = depth_output_gemm3d * output_height
1868 *
1869 * @return the depth of the output tensor to be used with the GEMM3D kernel
1870 */
1871 int depth_output_gemm3d() const
1872 {
1873 return _depth_output_gemm3d;
1874 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001875 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
1876 *
1877 * @return True if the input tensor has to be reinterpreted as 3D tensor
1878 */
1879 bool reinterpret_input_as_3d() const
1880 {
1881 return _reinterpret_input_as_3d;
1882 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001883 /** Flag which specifies whether to broadcast the shape of the bias tensor.
1884 *
1885 * @return True if the shape of the bias tensor is to be broadcasted.
1886 */
1887 bool broadcast_bias() const
1888 {
1889 return _broadcast_bias;
1890 };
Gian Marco36a0a462018-01-12 10:21:40 +00001891
1892private:
SiCong Liebd8fb42020-08-18 11:03:14 +01001893 int _m;
1894 int _n;
1895 int _k;
1896 int _mult_transpose1xW_width;
1897 int _mult_interleave4x4_height;
1898 int _depth_output_gemm3d;
1899 bool _reinterpret_input_as_3d;
1900 bool _broadcast_bias;
Gian Marco36a0a462018-01-12 10:21:40 +00001901};
1902
giuros016d109962019-01-07 17:47:19 +00001903struct DepthwiseConvolutionReshapeInfo
1904{
1905 unsigned int c0{ 1 }; /**< Number of channels processed by the depth-wise convolution */
1906 bool transpose{ false }; /**< True if the block MxC0 (where M is the area of the filter i.e. KwxKh) has to be transposed */
1907};
1908
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001909/** GEMMLowp output stage type */
1910enum class GEMMLowpOutputStageType
1911{
Manuel Bottini959c26d2019-12-02 16:22:35 +00001912 NONE, /**< No quantization */
1913 QUANTIZE_DOWN, /**< Quantize using an integer multiplication */
1914 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize using a fixed point multiplication */
1915 QUANTIZE_DOWN_FLOAT /**< Quantize using a floating point multiplication */
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001916};
1917
1918/** GEMMLowp output stage info */
1919struct GEMMLowpOutputStageInfo
1920{
Giorgio Arena1856ff72020-02-07 13:46:45 +00001921 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
1922 int32_t gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
1923 int32_t gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1924 int32_t gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
1925 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 */
1926 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 */
1927 std::vector<int32_t> gemmlowp_multipliers{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1928 std::vector<int32_t> gemmlowp_shifts{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
Sheri Zhang1b14c752020-03-09 14:29:52 +00001929 float gemmlowp_real_multiplier{ 0 }; /**< GEMMLowp output stage real multiplier used for quantizing to QASYMM8 */
Giorgio Arena1856ff72020-02-07 13:46:45 +00001930 bool is_quantized_per_channel{ false }; /**< GEMMLowp quantized per-channel flag */
1931 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 +01001932};
1933
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00001934/** GEMM LHS (Left Hand Side) matrix information */
1935struct GEMMLHSMatrixInfo
1936{
morgolockaba2f912020-05-05 16:28:19 +01001937 GEMMLHSMatrixInfo() = default;
1938 GEMMLHSMatrixInfo(unsigned int m, unsigned int k, unsigned int v, bool trans, bool inter)
1939 : m0(m), k0(k), v0(v), transpose(trans), interleave(inter)
1940 {
1941 }
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00001942 unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
1943 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1944 unsigned int v0{ 1 }; /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
1945 bool transpose{ true }; /**< True if the (m0xk0) block has to be transposed before been stored */
1946 bool interleave{ true }; /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
1947};
1948
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00001949/** GEMM RHS (Right Hand Side) matrix information */
1950struct GEMMRHSMatrixInfo
1951{
morgolockaba2f912020-05-05 16:28:19 +01001952 GEMMRHSMatrixInfo() = default;
Gian Marco Iodicee3a849a2020-06-10 17:59:30 +01001953 GEMMRHSMatrixInfo(unsigned int n, unsigned int k, unsigned int h, bool trans, bool inter, bool export_to_cl_img)
1954 : n0(n), k0(k), h0(h), transpose(trans), interleave(inter), export_to_cl_image(export_to_cl_img)
morgolockaba2f912020-05-05 16:28:19 +01001955 {
1956 }
Gian Marco Iodicedd717c32020-05-28 10:22:03 +01001957 unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
1958 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1959 unsigned int h0{ 1 }; /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
1960 bool transpose{ true }; /**< True if the (k0xn0) block has to be transposed before been stored */
1961 bool interleave{ true }; /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
1962 bool export_to_cl_image{ false }; /**< True if the reshaped rhs has to be exported to cl_image. n0 must be equal to 4 */
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00001963};
1964
Gian Marco36a0a462018-01-12 10:21:40 +00001965/** GEMM information class. This class stores the necessary information to compute GEMM functions
1966 *
1967 * This object also contains the information about how matrix A and matrix B have been reshaped
1968 *
1969 */
Chunosov5124be52017-11-22 20:42:13 +07001970class GEMMInfo
1971{
1972public:
1973 /** Default constructor */
Georgios Pinitas37d080f2019-06-21 18:43:12 +01001974 GEMMInfo() noexcept
1975 : _is_a_reshaped(false),
1976 _is_b_reshaped(false),
1977 _reshape_b_only_on_first_run(true),
1978 _depth_output_gemm3d(0),
1979 _reinterpret_input_as_3d(false),
1980 _retain_internal_weights(false),
1981 _gemmlowp_output_stage(),
1982 _fp_mixed_precision(false),
1983 _broadcast_bias(false),
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01001984 _pretranpose_B(true),
1985 _activation_info()
Chunosov5124be52017-11-22 20:42:13 +07001986 {
1987 }
1988 /** Constructor
1989 *
1990 * @param[in] is_a_reshaped True if the matrix A has been reshaped
1991 * @param[in] is_b_reshaped True if the matrix B has been reshaped
1992 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001993 * @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 +00001994 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001995 * @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
1996 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01001997 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001998 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001999 * @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 +01002000 * @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 +01002001 * @param[in] activation_info (Optional) Activation to apply after the matrix multiplication
Chunosov5124be52017-11-22 20:42:13 +07002002 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002003 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 +01002004 GEMMLowpOutputStageInfo gemmlowp_output_stage = GEMMLowpOutputStageInfo(), bool fp_mixed_precision = false, bool broadcast_bias = false,
2005 const ActivationLayerInfo &activation_info = ActivationLayerInfo()) noexcept
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002006 : _is_a_reshaped(is_a_reshaped),
2007 _is_b_reshaped(is_b_reshaped),
2008 _reshape_b_only_on_first_run(reshape_b_only_on_first_run),
2009 _depth_output_gemm3d(depth_output_gemm3d),
2010 _reinterpret_input_as_3d(reinterpret_input_as_3d),
2011 _retain_internal_weights(retain_internal_weights),
2012 _gemmlowp_output_stage(gemmlowp_output_stage),
2013 _fp_mixed_precision(fp_mixed_precision),
2014 _broadcast_bias(broadcast_bias),
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002015 _pretranpose_B(reshape_b_only_on_first_run),
2016 _activation_info(activation_info)
Chunosov5124be52017-11-22 20:42:13 +07002017 {
2018 }
2019 /** Flag which specifies if the matrix A has been reshaped
2020 *
2021 * @return True if the matrix A has been reshaped
2022 */
2023 bool is_a_reshaped() const
2024 {
2025 return _is_a_reshaped;
2026 };
2027 /** Flag which specifies if the matrix B has been reshaped
2028 *
2029 * @return True if the matrix B has been reshaped
2030 */
2031 bool is_b_reshaped() const
2032 {
2033 return _is_b_reshaped;
2034 };
2035 /** Flag which specifies if the reshape of matrix B should executed only for the first
2036 *
2037 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
2038 *
2039 * @return True if the reshaped of matrix B happens only for the first run
2040 */
2041 bool reshape_b_only_on_first_run() const
2042 {
2043 return _reshape_b_only_on_first_run;
2044 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002045 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002046 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002047 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002048 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002049 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00002050 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002051 return _depth_output_gemm3d;
2052 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002053 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2054 *
2055 * @return True if the input tensor has to be reinterpreted as 3D tensor
2056 */
2057 bool reinterpret_input_as_3d() const
2058 {
2059 return _reinterpret_input_as_3d;
2060 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002061 /** Flag which specifies if the weights tensor has to be retained from previous run
2062 *
2063 * @return True if the weights tensor has to be retained
2064 */
2065 bool retain_internal_weights() const
2066 {
2067 return _retain_internal_weights;
2068 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002069 /** GEMMLowp output stage
2070 *
2071 * @return the GEMMLowp output stage info
2072 */
2073 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
2074 {
2075 return _gemmlowp_output_stage;
2076 };
Georgios Pinitasdbdea0d2019-10-16 19:21:40 +01002077 /** Sets GEMMLowp output stage
2078 *
2079 * @param[in] output_stage Output stage to set
2080 */
2081 void set_gemmlowp_output_stage(GEMMLowpOutputStageInfo &output_stage)
2082 {
2083 _gemmlowp_output_stage = output_stage;
2084 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002085 /** Flag which specifies if a wider accumulator should be used.
2086 *
2087 * @return True if a wider accumulator has to be used
2088 */
2089 bool fp_mixed_precision() const
2090 {
2091 return _fp_mixed_precision;
2092 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002093 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2094 *
2095 * @return True if the shape of the bias tensor is to be broadcasted.
2096 */
2097 bool broadcast_bias() const
2098 {
2099 return _broadcast_bias;
2100 };
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002101 /** Flag which specifies whether b should be pre-transposed if supported.
2102 *
2103 * @return True if b should be pre-transposed else false.
2104 */
2105 bool pretranpose_B() const
2106 {
2107 return _pretranpose_B;
2108 };
2109 /** Set pre-transpose b flag
2110 *
2111 * @param[in] flag Flag to set
2112 */
2113 void set_pretranpose_B(bool flag)
2114 {
2115 _pretranpose_B = flag;
2116 }
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002117 /** Activation layer to apply after the matrix multiplication
2118 *
2119 * @return ActivationLayerInfo object
2120 */
2121 ActivationLayerInfo activation_info() const
2122 {
2123 return _activation_info;
2124 }
SiCongLi2e5fd632020-03-02 15:39:15 +00002125 /** Set activation layer info
2126 *
2127 * @param[in] activation_info ActivationLayerInfo object to set
2128 */
2129 void set_activation_info(const ActivationLayerInfo &activation_info)
2130 {
2131 _activation_info = activation_info;
2132 }
Chunosov5124be52017-11-22 20:42:13 +07002133
2134private:
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002135 bool _is_a_reshaped;
2136 bool _is_b_reshaped;
2137 bool _reshape_b_only_on_first_run;
2138 int _depth_output_gemm3d;
2139 bool _reinterpret_input_as_3d;
2140 bool _retain_internal_weights;
2141 GEMMLowpOutputStageInfo _gemmlowp_output_stage;
2142 bool _fp_mixed_precision;
2143 bool _broadcast_bias;
2144 bool _pretranpose_B;
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002145 ActivationLayerInfo _activation_info;
Chunosov5124be52017-11-22 20:42:13 +07002146};
2147
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00002148/** Winograd information */
2149struct WinogradInfo
2150{
2151 /** Default constructor
2152 *
2153 * @param[in] output_tile_sz Width and height of the output tile
2154 * @param[in] kernel_sz Width and height of the kernel
2155 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
2156 * @param[in] conv_info Convolution info (Pads, strides)
2157 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
2158 */
2159 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
2160 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
2161 {
2162 }
2163
2164 Size2D output_tile_size{}; /**< Width and height of the output tile */
2165 Size2D kernel_size{}; /**< Width and height of the kernel*/
2166 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
2167 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
2168 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
2169};
2170
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002171/** IO formatting information class*/
2172struct IOFormatInfo
2173{
2174 /** Precision type used when printing floating point numbers */
2175 enum class PrecisionType
2176 {
2177 Default, /**< Default precision to the one that the current stream has */
2178 Custom, /**< Custom precision specified by the user using the precision parameter */
2179 Full /**< The maximum precision of the floating point representation */
2180 };
2181
2182 /** Specifies the area to be printed, used by Tensor objects */
2183 enum class PrintRegion
2184 {
2185 ValidRegion, /**< Prints the valid region of the Tensor object */
2186 NoPadding, /**< Prints the Tensor object without the padding */
2187 Full /**< Print the tensor object including padding */
2188 };
2189
Alex Gildayc357c472018-03-21 13:54:09 +00002190 /** Construct a set of IO formatting information.
2191 *
2192 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
2193 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
2194 * @param[in] precision Precision value for float point numbers. Default: 10.
2195 * @param[in] align_columns Whether to align columns when printed. Default: true.
2196 * @param[in] element_delim Delimeter between elements. Default: " ".
2197 * @param[in] row_delim Delimenter between rows. Default: "\n".
2198 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002199 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
2200 PrecisionType precision_type = PrecisionType::Default,
2201 unsigned int precision = 10,
2202 bool align_columns = true,
2203 std::string element_delim = " ",
2204 std::string row_delim = "\n")
2205 : print_region(print_region),
2206 precision_type(precision_type),
2207 precision(precision),
2208 element_delim(element_delim),
2209 row_delim(row_delim),
2210 align_columns(align_columns)
2211 {
2212 }
2213
Alex Gildayc357c472018-03-21 13:54:09 +00002214 /** Area to be printed by Tensor objects */
2215 PrintRegion print_region;
2216 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002217 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00002218 /** Floating point precision */
2219 unsigned int precision;
2220 /** Element delimeter */
2221 std::string element_delim;
2222 /** Row delimeter */
2223 std::string row_delim;
2224 /** Align columns */
2225 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002226};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00002227} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +00002228#endif /* ARM_COMPUTE_TYPES_H */