blob: 0dd1afc240a3bd713e6aba7e49714f14ab5069b1 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Manuel Bottiniceaa0bf2021-02-16 15:15:19 +00002 * Copyright (c) 2016-2021 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"
Adnan AlSinane4563a02021-09-01 15:32:03 +010030#include "arm_compute/core/Size3D.h"
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000031#include "arm_compute/core/Strides.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010032#include "arm_compute/core/TensorShape.h"
Sang-Hoon Park11fedda2020-01-15 14:44:04 +000033#include "arm_compute/core/utils/misc/Macros.h"
Georgios Pinitase8291ac2020-02-26 09:58:13 +000034#include "support/Bfloat16.h"
Georgios Pinitas583137c2017-08-31 18:12:42 +010035#include "support/Half.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010036
Michel Iwaniec5dfeae62017-11-29 10:48:23 +000037#include <cmath>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010038#include <cstddef>
39#include <cstdint>
Isabella Gottardia7acb3c2019-01-08 13:48:44 +000040#include <map>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010041#include <string>
42#include <utility>
43
44namespace arm_compute
45{
Georgios Pinitas583137c2017-08-31 18:12:42 +010046/** 16-bit floating point type */
47using half = half_float::half;
48
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000049/** Permutation vector */
50using PermutationVector = Strides;
Georgios Pinitas77589b52018-08-21 14:41:35 +010051/** Bidirectional strides */
52using BiStrides = Coordinates;
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000053
Anthony Barbier6ff3b192017-09-04 18:44:23 +010054/** Image colour formats */
55enum class Format
56{
Daniil Efremov02bf80d2017-11-22 00:26:51 +070057 UNKNOWN, /**< Unknown image format */
58 U8, /**< 1 channel, 1 U8 per channel */
59 S16, /**< 1 channel, 1 S16 per channel */
60 U16, /**< 1 channel, 1 U16 per channel */
61 S32, /**< 1 channel, 1 S32 per channel */
62 U32, /**< 1 channel, 1 U32 per channel */
Georgios Pinitase8291ac2020-02-26 09:58:13 +000063 BFLOAT16, /**< 16-bit brain floating-point number */
Daniil Efremov02bf80d2017-11-22 00:26:51 +070064 F16, /**< 1 channel, 1 F16 per channel */
65 F32, /**< 1 channel, 1 F32 per channel */
66 UV88, /**< 2 channel, 1 U8 per channel */
67 RGB888, /**< 3 channels, 1 U8 per channel */
68 RGBA8888, /**< 4 channels, 1 U8 per channel */
69 YUV444, /**< A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes */
70 YUYV422, /**< A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes */
71 NV12, /**< A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling */
72 NV21, /**< A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling */
73 IYUV, /**< A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes */
74 UYVY422 /**< A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010075};
76
77/** Available data types */
78enum class DataType
79{
Georgios Pinitas8217c8e2019-11-11 18:24:22 +000080 UNKNOWN, /**< Unknown data type */
81 U8, /**< unsigned 8-bit number */
82 S8, /**< signed 8-bit number */
83 QSYMM8, /**< quantized, symmetric fixed-point 8-bit number */
84 QASYMM8, /**< quantized, asymmetric fixed-point 8-bit number unsigned */
85 QASYMM8_SIGNED, /**< quantized, asymmetric fixed-point 8-bit number signed */
86 QSYMM8_PER_CHANNEL, /**< quantized, symmetric per channel fixed-point 8-bit number */
87 U16, /**< unsigned 16-bit number */
88 S16, /**< signed 16-bit number */
89 QSYMM16, /**< quantized, symmetric fixed-point 16-bit number */
90 QASYMM16, /**< quantized, asymmetric fixed-point 16-bit number */
91 U32, /**< unsigned 32-bit number */
92 S32, /**< signed 32-bit number */
93 U64, /**< unsigned 64-bit number */
94 S64, /**< signed 64-bit number */
Georgios Pinitase8291ac2020-02-26 09:58:13 +000095 BFLOAT16, /**< 16-bit brain floating-point number */
Georgios Pinitas8217c8e2019-11-11 18:24:22 +000096 F16, /**< 16-bit floating-point number */
97 F32, /**< 32-bit floating-point number */
98 F64, /**< 64-bit floating-point number */
99 SIZET /**< size_t */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100100};
101
Daniil Efremov02bf80d2017-11-22 00:26:51 +0700102/** Available Sampling Policies */
103enum class SamplingPolicy
104{
105 CENTER, /**< Samples are taken at pixel center */
106 TOP_LEFT /**< Samples are taken at pixel top left corner */
107};
108
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000109/** [DataLayout enum definition] **/
110
Georgios Pinitas4074c992018-01-30 18:13:46 +0000111/** Supported tensor data layouts */
112enum class DataLayout
113{
Alex Gildayc357c472018-03-21 13:54:09 +0000114 UNKNOWN, /**< Unknown data layout */
115 NCHW, /**< Num samples, channels, height, width */
Adnan AlSinane4563a02021-09-01 15:32:03 +0100116 NHWC, /**< Num samples, height, width, channels */
117 NDHWC /**< Num samples, depth, height, width, channels */
Georgios Pinitas4074c992018-01-30 18:13:46 +0000118};
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000119/** [DataLayout enum definition] **/
Georgios Pinitas4074c992018-01-30 18:13:46 +0000120
Isabella Gottardid17a6772018-02-27 17:41:55 +0000121/** Supported tensor data layout dimensions */
122enum class DataLayoutDimension
123{
Alex Gildayc357c472018-03-21 13:54:09 +0000124 CHANNEL, /**< channel */
125 HEIGHT, /**< height */
126 WIDTH, /**< width */
127 BATCHES /**< batches */
Isabella Gottardid17a6772018-02-27 17:41:55 +0000128};
129
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000130/** Available ConvolutionMethod*/
131enum class ConvolutionMethod
132{
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000133 GEMM, /**< Convolution using GEMM */
134 GEMM_CONV2D, /**< Direct 2D GEMM convolution */
135 DIRECT, /**< Direct convolution */
136 WINOGRAD, /**< Convolution using Winograd */
137 FFT /**< Convolution using FFT */
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000138};
139
Manuel Bottini05069f02019-09-26 17:18:26 +0100140/** Available DepthwiseConvolutionFunction*/
141enum class DepthwiseConvolutionFunction
142{
143 OPTIMIZED, /**< Optimized Depthwise Convolution */
144 GENERIC, /**< Generic Depthwise Convolution */
145};
146
giuros0146a49a02019-04-01 13:50:22 +0100147/** Available DeconvolutionMethod*/
148enum class DeconvolutionMethod
149{
150 GEMM, /**< Deconvolution using GEMM */
151 DIRECT, /**< Direct deconvolution */
152};
153
Manuel Bottini2732cca2019-05-28 11:44:41 +0100154/** Available FuseBatchNormalizationType*/
155enum class FuseBatchNormalizationType
156{
157 CONVOLUTION, /**< For Convolution weights */
158 DEPTHWISECONVOLUTION /**< For Depthwise Convolution weights*/
159};
160
Usama Arif89890c62019-03-19 10:57:05 +0000161/** Padding mode to use for PadLayer */
162enum class PaddingMode
163{
164 CONSTANT,
165 REFLECT,
166 SYMMETRIC
167};
168
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000169/** Supported comparison operations */
170enum class ComparisonOperation
171{
172 Equal, /**< Equal comparison ( \f$ x == y \f$ ) */
173 NotEqual, /**< NotEqual comparison ( \f$ x != y \f$ ) */
174 Greater, /**< Greater comparison ( \f$ x > y \f$ ) */
175 GreaterEqual, /**< Greater equal comparison ( \f$ x >= y \f$ ) */
176 Less, /**< Less comparison ( \f$ x < y \f$ ) */
177 LessEqual /**< Less equal comparison ( \f$ x <= y \f$ ) */
178};
179
Alex Gildayc357c472018-03-21 13:54:09 +0000180/** Container for valid region of a window */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100181struct ValidRegion
182{
Alex Gildayc357c472018-03-21 13:54:09 +0000183 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100184 ValidRegion()
185 : anchor{}, shape{}
186 {
187 }
188
Alex Gildayc357c472018-03-21 13:54:09 +0000189 /** Allow instances of this class to be copy constructed */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100190 ValidRegion(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000191 /** Allow instances of this class to be move constructed */
192 ValidRegion(ValidRegion &&) = default;
193 /** Allow instances of this class to be copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100194 ValidRegion &operator=(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000195 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100196 ValidRegion &operator=(ValidRegion &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000197 /** Default destructor */
198 ~ValidRegion() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100199
Alex Gildayc357c472018-03-21 13:54:09 +0000200 /** Constructor for a valid region with default number of dimensions
201 *
202 * @param[in] an_anchor Anchor for the start of the valid region.
203 * @param[in] a_shape Shape of the valid region.
204 *
205 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000206 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
207 : anchor{ an_anchor }, shape{ a_shape }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100208 {
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000209 anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
210 }
211
Alex Gildayc357c472018-03-21 13:54:09 +0000212 /** Constructor for a valid region with specified number of dimensions
213 *
214 * @param[in] an_anchor Anchor for the start of the valid region.
215 * @param[in] a_shape Shape of the valid region.
216 * @param[in] num_dimensions Number of dimensions (must be >= number of dimensions of anchor and shape).
217 *
218 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000219 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
220 : anchor{ an_anchor }, shape{ a_shape }
221 {
222 ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
223 anchor.set_num_dimensions(num_dimensions);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100224 }
225
226 /** Return the start of the valid region for the given dimension @p d */
227 int start(unsigned int d) const
228 {
229 return anchor[d];
230 }
231
232 /** Return the end of the valid region for the given dimension @p d */
233 int end(unsigned int d) const
234 {
235 return anchor[d] + shape[d];
236 }
237
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000238 /** Accessor to set the value of anchor and shape for one of the dimensions.
239 *
240 * @param[in] dimension Dimension for which the value is set.
241 * @param[in] start Value to be set in anchor for the dimension.
242 * @param[in] size Value to be set in shape for the dimension.
243 *
244 * @return *this.
245 */
246 ValidRegion &set(size_t dimension, int start, size_t size)
247 {
248 anchor.set(dimension, start);
249 shape.set(dimension, size);
250 return *this;
251 }
252
Alex Gildayc357c472018-03-21 13:54:09 +0000253 Coordinates anchor; /**< Anchor for the start of the valid region. */
254 TensorShape shape; /**< Shape of the valid region. */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100255};
256
257/** Methods available to handle borders */
258enum class BorderMode
259{
260 UNDEFINED, /**< Borders are left undefined */
261 CONSTANT, /**< Pixels outside the image are assumed to have a constant value */
262 REPLICATE /**< Pixels outside the image are assumed to have the same value as the closest image pixel */
263};
264
265/** Container for 2D border size */
266struct BorderSize
267{
268 /** Empty border, i.e. no border */
Pablo Marquez Tello383de022021-03-18 11:31:13 +0000269 constexpr BorderSize() noexcept
270 : top{ 0 },
271 right{ 0 },
272 bottom{ 0 },
273 left{ 0 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100274 {
275 }
276
277 /** Border with equal size around the 2D plane */
Pablo Marquez Tello383de022021-03-18 11:31:13 +0000278 explicit constexpr BorderSize(unsigned int size) noexcept
279 : top{ size },
280 right{ size },
281 bottom{ size },
282 left{ size }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100283 {
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
Giorgio Arena1e2af2a2020-10-15 17:39:41 +0100340 /** Check equality with another BorderSize struct
341 *
342 * @param[in] rhs other struct to check against
343 *
344 * @return true if they are equal
345 */
346 bool operator==(const BorderSize &rhs)
347 {
348 return (top == rhs.top) && (right == rhs.right) && (bottom == rhs.bottom) && (left == rhs.left);
349 }
350
351 /** Check non-equality with another BorderSize struct
352 *
353 * @param[in] rhs other struct to check against
354 *
355 * @return true if they are different
356 */
357 bool operator!=(const BorderSize &rhs)
358 {
359 return !(*this == rhs);
360 }
361
Alex Gildayc357c472018-03-21 13:54:09 +0000362 /** Limit this border size.
363 *
364 * @param[in] limit Border size to limit this border size to.
365 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100366 void limit(const BorderSize &limit)
367 {
368 top = std::min(top, limit.top);
369 right = std::min(right, limit.right);
370 bottom = std::min(bottom, limit.bottom);
371 left = std::min(left, limit.left);
372 }
373
Alex Gildayc357c472018-03-21 13:54:09 +0000374 unsigned int top; /**< top of the border */
375 unsigned int right; /**< right of the border */
376 unsigned int bottom; /**< bottom of the border */
377 unsigned int left; /**< left of the border */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100378};
379
Alex Gildayc357c472018-03-21 13:54:09 +0000380/** Container for 2D padding size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100381using PaddingSize = BorderSize;
382
383/** Policy to handle overflow */
384enum class ConvertPolicy
385{
386 WRAP, /**< Wrap around */
387 SATURATE /**< Saturate */
388};
389
390/** Interpolation method */
391enum class InterpolationPolicy
392{
393 NEAREST_NEIGHBOR, /**< Output values are defined to match the source pixel whose center is nearest to the sample position */
394 BILINEAR, /**< Output values are defined by bilinear interpolation between the pixels */
395 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 */
396};
397
398/** Bilinear Interpolation method used by LKTracker */
399enum class BilinearInterpolation
400{
Alex Gildayc357c472018-03-21 13:54:09 +0000401 BILINEAR_OLD_NEW, /**< Old-new method */
402 BILINEAR_SCHARR /**< Scharr method */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100403};
404
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100405/** Rectangle type */
406struct Rectangle
407{
408 uint16_t x; /**< Top-left x coordinate */
409 uint16_t y; /**< Top-left y coordinate */
410 uint16_t width; /**< Width of the rectangle */
411 uint16_t height; /**< Height of the rectangle */
412};
413
414/** Coordinate type */
415struct Coordinates2D
416{
417 int32_t x; /**< X coordinates */
418 int32_t y; /**< Y coordinates */
419};
420
421/** Coordinate type */
422struct Coordinates3D
423{
424 uint32_t x; /**< X coordinates */
425 uint32_t y; /**< Y coordinates */
426 uint32_t z; /**< Z coordinates */
427};
428
Giuseppe Rossinid7647d42018-07-17 18:13:13 +0100429/** Padding information as a pair of unsigned int start/end */
430using PaddingInfo = std::pair<uint32_t, uint32_t>;
431
432/** List of padding information */
433using PaddingList = std::vector<PaddingInfo>;
434
giuros013175fcf2018-11-21 09:59:17 +0000435/** Information to produce a tiled version of a Tensor */
436using Multiples = std::vector<uint32_t>;
437
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100438/** Available channels */
439enum class Channel
440{
441 UNKNOWN, /** Unknown channel format */
442 C0, /**< First channel (used by formats with unknown channel types). */
443 C1, /**< Second channel (used by formats with unknown channel types). */
444 C2, /**< Third channel (used by formats with unknown channel types). */
445 C3, /**< Fourth channel (used by formats with unknown channel types). */
446 R, /**< Red channel. */
447 G, /**< Green channel. */
448 B, /**< Blue channel. */
449 A, /**< Alpha channel. */
450 Y, /**< Luma channel. */
451 U, /**< Cb/U channel. */
452 V /**< Cr/V/Value channel. */
453};
454
Georgios Pinitasd9769582017-08-03 10:19:40 +0100455/** Available reduction operations */
456enum class ReductionOperation
457{
Michalis Spyrou7930db42018-11-22 17:36:28 +0000458 ARG_IDX_MAX, /**< Index of the max value */
Manuel Bottinib412fab2018-12-10 17:40:23 +0000459 ARG_IDX_MIN, /**< Index of the min value */
460 MEAN_SUM, /**< Mean of sum */
461 PROD, /**< Product */
462 SUM_SQUARE, /**< Sum of squares */
Usama Arifa4a08ad2019-05-20 12:38:33 +0100463 SUM, /**< Sum */
464 MIN, /**< Min */
Usama Arif28f0dd92019-05-20 13:44:34 +0100465 MAX, /**< Max */
Georgios Pinitasd9769582017-08-03 10:19:40 +0100466};
467
giuros01164a2722018-11-20 18:34:46 +0000468/** Available element-wise operations */
469enum class ArithmeticOperation
470{
471 ADD, /**< (x + y) */
472 SUB, /**< (x - y) */
473 DIV, /**< (x / y) */
474 MIN, /**< Min(x, y) */
475 MAX, /**< Max(x, y) */
476 SQUARED_DIFF, /**< (x - y)^2 */
Usama Arif81e671e2019-05-13 13:33:14 +0100477 POWER, /**< x ^ y */
giuros011e6e1b82019-05-14 16:12:53 +0100478 PRELU, /**< y*x if x < 0, x otherwise */
giuros01164a2722018-11-20 18:34:46 +0000479};
480
Michalis Spyroue9362622018-11-23 17:41:37 +0000481/** Available element wise unary operations */
482enum class ElementWiseUnary
483{
Sang-Hoon Park75eea332020-11-13 13:44:13 +0000484 RSQRT, /**< Reverse square root */
485 EXP, /**< Exponential */
486 NEG, /**< Negate */
487 LOG, /**< Natural Logarithm */
488 ABS, /**< Absolute value */
489 SIN, /**< Sine */
490 ROUND, /**< Round */
491 LOGICAL_NOT, /**< Logical Not */
Michalis Spyroue9362622018-11-23 17:41:37 +0000492};
493
Manuel Bottini63bb7ca2020-12-02 13:22:14 +0000494/** Available bitwise operations */
495enum class BitwiseOperation
496{
497 AND, /**< Bitwise AND operation */
498 NOT, /**< Bitwise NOT operation */
499 OR, /**< Bitwise OR operation */
500 XOR, /**< Bitwise XOR operation */
501};
502
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100503/** The normalization type used for the normalization layer */
504enum class NormType
505{
506 IN_MAP_1D, /**< Normalization applied within the same map in 1D region */
507 IN_MAP_2D, /**< Normalization applied within the same map in 2D region */
508 CROSS_MAP /**< Normalization applied cross maps */
509};
510
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100511/** Detection window used for the object detection. The detection window keeps the following information:
512 *
513 * -# Geometry of the rectangular window (x/y of top-left corner and width/height)
514 * -# Index of the class used for evaluating which class the detection window belongs to
515 * -# Confidence value (score) obtained with the classifier
516 */
517struct DetectionWindow
518{
519 uint16_t x{ 0 }; /**< Top-left x coordinate */
520 uint16_t y{ 0 }; /**< Top-left y coordinate */
521 uint16_t width{ 0 }; /**< Width of the detection window */
522 uint16_t height{ 0 }; /**< Height of the detection window */
523 uint16_t idx_class{ 0 }; /**< Index of the class */
524 float score{ 0.f }; /**< Confidence value for the detection window */
525};
526
527/** Dimension rounding type when down-scaling on CNNs
528 * @note Used in pooling and convolution layer
529 */
530enum class DimensionRoundingType
531{
532 FLOOR, /**< Floor rounding */
533 CEIL /**< Ceil rounding */
534};
535
536/** Available pooling types */
537enum class PoolingType
538{
539 MAX, /**< Max Pooling */
Georgios Pinitascdf51452017-08-31 14:21:36 +0100540 AVG, /**< Average Pooling */
541 L2 /**< L2 Pooling */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100542};
543
Michalis Spyrou2709d612018-09-19 09:46:47 +0100544/** Available non maxima suppression types */
545enum class NMSType
546{
547 LINEAR, /**< Linear NMS */
548 GAUSSIAN, /**< Gaussian NMS */
549 ORIGINAL /**< Original NMS */
550};
551
552/** BoxWithNonMaximaSuppressionLimit Information class */
553class BoxNMSLimitInfo final
554{
555public:
556 /** Constructor
557 *
558 * @param[in] score_thresh (Optional) Score threshold.
559 * @param[in] nms (Optional) NMS value
560 * @param[in] detections (Optional) Number of detections
561 * @param[in] soft_nms_enabled (Optional) Enable SoftNMS
562 * @param[in] soft_nms_method (Optional) Soft NMS method
563 * @param[in] soft_nms_sigma (Optional) Soft NMS sigma value
564 * @param[in] soft_nms_min_score_thres (Optional) Soft NMS minimum score threshold
Manuel Bottini5209be52019-02-13 16:34:56 +0000565 * @param[in] suppress_size (Optional) Filter out boxes based on their size. Defaults to false
566 * @param[in] min_size (Optional) Smaller boxes than min_size will be filtered out. Defaults to 1
567 * @param[in] im_width (Optional) Boxes whose centers (on the x axis) is beyond im_width will be filtered. Defaults to 1
568 * @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 +0100569 */
570 BoxNMSLimitInfo(float score_thresh = 0.05f, float nms = 0.3f,
571 int detections = 100, bool soft_nms_enabled = false,
572 NMSType soft_nms_method = NMSType::LINEAR,
Manuel Bottini5209be52019-02-13 16:34:56 +0000573 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 +0100574 : _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 +0000575 _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 +0100576 {
577 }
578 /** Get the score threshold */
579 float score_thresh() const
580 {
581 return _score_thresh;
582 }
583 /** Get the NMS */
584 float nms() const
585 {
586 return _nms;
587 }
588 /** Get the number of detections */
589 int detections_per_im() const
590 {
591 return _detections_per_im;
592 }
593 /** Check if soft NMS is enabled */
594 bool soft_nms_enabled() const
595 {
596 return _soft_nms_enabled;
597 }
598 /** Get soft NMS method */
599 NMSType soft_nms_method() const
600 {
601 return _soft_nms_method;
602 }
603 /** Get soft NMS sigma */
604 float soft_nms_sigma() const
605 {
606 return _soft_nms_sigma;
607 }
608 /** Get soft nms min score threshold */
609 float soft_nms_min_score_thres() const
610 {
611 return _soft_nms_min_score_thres;
612 }
Manuel Bottini5209be52019-02-13 16:34:56 +0000613 /** Get if NMS will suppress boxes based on their size/position */
614 bool suppress_size() const
615 {
616 return _suppress_size;
617 }
618 /** Get size suppression threshold */
619 float min_size() const
620 {
621 return _min_size;
622 }
623 /** Get image width (NMS may suppress boxes whose center sits beyond the image width) */
624 float im_width() const
625 {
626 return _im_width;
627 }
628 /** Get image height (NMS may suppress boxes whose center sits beyond the image height) */
629 float im_height() const
630 {
631 return _im_height;
632 }
Michalis Spyrou2709d612018-09-19 09:46:47 +0100633
634private:
635 float _score_thresh;
636 float _nms;
637 int _detections_per_im;
638 bool _soft_nms_enabled;
639 NMSType _soft_nms_method;
640 float _soft_nms_sigma;
641 float _soft_nms_min_score_thres;
Manuel Bottini5209be52019-02-13 16:34:56 +0000642 bool _suppress_size;
643 float _min_size;
644 float _im_width;
645 float _im_height;
Michalis Spyrou2709d612018-09-19 09:46:47 +0100646};
647
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100648/** Padding and stride information class */
649class PadStrideInfo
650{
651public:
652 /** Constructor
653 *
654 * @param[in] stride_x (Optional) Stride, in elements, across x. Defaults to 1.
655 * @param[in] stride_y (Optional) Stride, in elements, across y. Defaults to 1.
656 * @param[in] pad_x (Optional) Padding, in elements, across x. Defaults to 0.
657 * @param[in] pad_y (Optional) Padding, in elements, across y. Defaults to 0.
658 * @param[in] round (Optional) Dimensions rounding. Defaults to @ref FLOOR.
659 */
660 PadStrideInfo(unsigned int stride_x = 1, unsigned int stride_y = 1,
661 unsigned int pad_x = 0, unsigned int pad_y = 0,
662 DimensionRoundingType round = DimensionRoundingType::FLOOR)
663 : _stride(std::make_pair(stride_x, stride_y)),
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100664 _pad_left(pad_x),
665 _pad_top(pad_y),
666 _pad_right(pad_x),
667 _pad_bottom(pad_y),
668 _round_type(round)
669 {
670 }
671 /** Constructor
672 *
673 * @param[in] stride_x Stride, in elements, across x.
674 * @param[in] stride_y Stride, in elements, across y.
675 * @param[in] pad_left Padding across x on the left, in elements.
676 * @param[in] pad_top Padding across y on the top, in elements.
677 * @param[in] pad_right Padding across x on the right, in elements.
678 * @param[in] pad_bottom Padding across y on the bottom, in elements.
679 * @param[in] round Dimensions rounding.
680 */
681 PadStrideInfo(unsigned int stride_x, unsigned int stride_y,
682 unsigned int pad_left, unsigned int pad_right,
683 unsigned int pad_top, unsigned int pad_bottom,
684 DimensionRoundingType round)
685 : _stride(std::make_pair(stride_x, stride_y)),
686 _pad_left(pad_left),
687 _pad_top(pad_top),
688 _pad_right(pad_right),
689 _pad_bottom(pad_bottom),
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100690 _round_type(round)
691 {
692 }
Alex Gildayc357c472018-03-21 13:54:09 +0000693 /** Get the stride.
694 *
695 * @return a pair: stride x, stride y.
696 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100697 std::pair<unsigned int, unsigned int> stride() const
698 {
699 return _stride;
700 }
Alex Gildayc357c472018-03-21 13:54:09 +0000701 /** Check whether the padding is symmetric.
702 *
703 * @return True if the padding is symmetric.
704 */
Anthony Barbier21f67d62018-02-16 15:17:48 +0000705 bool padding_is_symmetric() const
706 {
707 return (_pad_left == _pad_right) && (_pad_top == _pad_bottom);
708 }
Alex Gildayc357c472018-03-21 13:54:09 +0000709 /** Get the padding.
710 *
711 * @note This should only be used when the padding is symmetric.
712 *
713 * @return a pair: padding left/right, padding top/bottom
714 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100715 std::pair<unsigned int, unsigned int> pad() const
716 {
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100717 //this accessor should be used only when padding is symmetric
Anthony Barbier21f67d62018-02-16 15:17:48 +0000718 ARM_COMPUTE_ERROR_ON(!padding_is_symmetric());
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100719 return std::make_pair(_pad_left, _pad_top);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100720 }
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100721
Alex Gildayc357c472018-03-21 13:54:09 +0000722 /** Get the left padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100723 unsigned int pad_left() const
724 {
725 return _pad_left;
726 }
Alex Gildayc357c472018-03-21 13:54:09 +0000727 /** Get the right padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100728 unsigned int pad_right() const
729 {
730 return _pad_right;
731 }
Alex Gildayc357c472018-03-21 13:54:09 +0000732 /** Get the top padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100733 unsigned int pad_top() const
734 {
735 return _pad_top;
736 }
Alex Gildayc357c472018-03-21 13:54:09 +0000737 /** Get the bottom padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100738 unsigned int pad_bottom() const
739 {
740 return _pad_bottom;
741 }
742
Alex Gildayc357c472018-03-21 13:54:09 +0000743 /** Get the rounding type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100744 DimensionRoundingType round() const
745 {
746 return _round_type;
747 }
748
Alex Gildayc357c472018-03-21 13:54:09 +0000749 /** Check whether this has any padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100750 bool has_padding() const
751 {
752 return (_pad_left != 0 || _pad_top != 0 || _pad_right != 0 || _pad_bottom != 0);
753 }
754
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100755private:
756 std::pair<unsigned int, unsigned int> _stride;
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100757 unsigned int _pad_left;
758 unsigned int _pad_top;
759 unsigned int _pad_right;
760 unsigned int _pad_bottom;
761
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100762 DimensionRoundingType _round_type;
763};
764
Adnan AlSinane4563a02021-09-01 15:32:03 +0100765/** Padding information for 3D operations like Conv3d */
766struct Padding3D
767{
768 size_t left = { 0 }; /**< Padding across the width dimenstion on the left, in elements. */
769 size_t right = { 0 }; /**< Padding across the width dimenstion on the right, in elements. */
770 size_t top = { 0 }; /**< Padding across the height dimenstion on the top, in elements. */
771 size_t bottom = { 0 }; /**< Padding across the height dimenstion on the bottom, in elements. */
772 size_t front = { 0 }; /**< Padding across the depth dimenstion on the front, in elements. */
773 size_t back = { 0 }; /**< Padding across the depth dimenstion on the back, in elements. */
774};
775
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100776/** PriorBox layer info */
777class PriorBoxLayerInfo final
778{
779public:
780 /** Default Constructor */
781 PriorBoxLayerInfo()
782 : _min_sizes(),
783 _variances(),
784 _offset(),
785 _flip(true),
786 _clip(false),
787 _max_sizes(),
788 _aspect_ratios(),
789 _img_size(),
790 _steps()
791 {
792 }
793 /** Constructor
794 *
795 * @param[in] min_sizes Min sizes vector.
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100796 * @param[in] variances Variances vector.
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100797 * @param[in] offset Offset value.
798 * @param[in] flip (Optional) Flip the aspect ratios.
799 * @param[in] clip (Optional) Clip coordinates so that they're within [0,1].
800 * @param[in] max_sizes (Optional) Max sizes vector.
801 * @param[in] aspect_ratios (Optional) Aspect ratios of the boxes.
802 * @param[in] img_size (Optional) Image size.
803 * @param[in] steps (Optional) Step values.
804 */
805 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 +0000806 const std::vector<float> &max_sizes = {}, const std::vector<float> &aspect_ratios = {},
807 const Coordinates2D &img_size = Coordinates2D{ 0, 0 }, const std::array<float, 2> &steps = { { 0.f, 0.f } })
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100808 : _min_sizes(min_sizes),
809 _variances(variances),
810 _offset(offset),
811 _flip(flip),
812 _clip(clip),
813 _max_sizes(max_sizes),
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100814 _aspect_ratios(),
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100815 _img_size(img_size),
816 _steps(steps)
817 {
818 _aspect_ratios.push_back(1.);
819 for(unsigned int i = 0; i < aspect_ratios.size(); ++i)
820 {
821 float ar = aspect_ratios[i];
822 bool already_exist = false;
823 for(auto ar_new : _aspect_ratios)
824 {
825 if(fabs(ar - ar_new) < 1e-6)
826 {
827 already_exist = true;
828 break;
829 }
830 }
831 if(!already_exist)
832 {
833 _aspect_ratios.push_back(ar);
834 if(flip)
835 {
836 _aspect_ratios.push_back(1.f / ar);
837 }
838 }
839 }
840 }
841 /** Get min sizes. */
842 std::vector<float> min_sizes() const
843 {
844 return _min_sizes;
845 }
846 /** Get min variances. */
847 std::vector<float> variances() const
848 {
849 return _variances;
850 }
851 /** Get the step coordinates */
852 std::array<float, 2> steps() const
853 {
854 return _steps;
855 }
856 /** Get the image size coordinates */
857 Coordinates2D img_size() const
858 {
859 return _img_size;
860 }
861 /** Get the offset */
862 float offset() const
863 {
864 return _offset;
865 }
866 /** Get the flip value */
867 bool flip() const
868 {
869 return _flip;
870 }
871 /** Get the clip value */
872 bool clip() const
873 {
874 return _clip;
875 }
876 /** Get max sizes. */
877 std::vector<float> max_sizes() const
878 {
879 return _max_sizes;
880 }
881 /** Get aspect ratios. */
882 std::vector<float> aspect_ratios() const
883 {
884 return _aspect_ratios;
885 }
886
887private:
888 std::vector<float> _min_sizes;
889 std::vector<float> _variances;
890 float _offset;
891 bool _flip;
892 bool _clip;
893 std::vector<float> _max_sizes;
894 std::vector<float> _aspect_ratios;
895 Coordinates2D _img_size;
896 std::array<float, 2> _steps;
897};
898
Isabella Gottardia7acb3c2019-01-08 13:48:44 +0000899// Bounding Box [xmin, ymin, xmax, ymax]
900using BBox = std::array<float, 4>;
901// LabelBBox used for map label and bounding box
902using LabelBBox = std::map<int, std::vector<BBox>>;
903
Isabella Gottardi05e56442018-11-16 11:26:52 +0000904/** Available Detection Output code types */
905enum class DetectionOutputLayerCodeType
906{
907 CORNER, /**< Use box corners */
908 CENTER_SIZE, /**< Use box centers and size */
909 CORNER_SIZE, /**< Use box centers and size */
910 TF_CENTER /**< Use box centers and size but flip x and y co-ordinates */
911};
912
913/** Detection Output layer info */
914class DetectionOutputLayerInfo final
915{
916public:
917 /** Default Constructor */
918 DetectionOutputLayerInfo()
919 : _num_classes(),
920 _share_location(),
921 _code_type(DetectionOutputLayerCodeType::CORNER),
922 _keep_top_k(),
923 _nms_threshold(),
924 _top_k(),
925 _background_label_id(),
926 _confidence_threshold(),
927 _variance_encoded_in_target(false),
928 _eta(),
929 _num_loc_classes()
930 {
931 _num_loc_classes = _share_location ? 1 : _num_classes;
932 }
933 /** Constructor
934 *
935 * @param[in] num_classes Number of classes to be predicted.
936 * @param[in] share_location If true, bounding box are shared among different classes.
937 * @param[in] code_type Type of coding method for bbox.
938 * @param[in] keep_top_k Number of total bounding boxes to be kept per image after NMS step.
939 * @param[in] nms_threshold Threshold to be used in NMS.
940 * @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.
941 * @param[in] background_label_id (Optional) Background label ID. If there is no background class, set it as -1.
942 * @param[in] confidence_threshold (Optional) Only consider detections whose confidences are larger than a threshold. Default set to -FLT_MAX.
943 * @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.
944 * @param[in] eta (Optional) Eta.
945 */
946 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,
947 float confidence_threshold = std::numeric_limits<float>::lowest(), bool variance_encoded_in_target = false, float eta = 1)
948 : _num_classes(num_classes),
949 _share_location(share_location),
950 _code_type(code_type),
951 _keep_top_k(keep_top_k),
952 _nms_threshold(nms_threshold),
953 _top_k(top_k),
954 _background_label_id(background_label_id),
955 _confidence_threshold(confidence_threshold),
956 _variance_encoded_in_target(variance_encoded_in_target),
957 _eta(eta),
958 _num_loc_classes()
959 {
960 _num_loc_classes = _share_location ? 1 : _num_classes;
961 }
962 /** Get num classes. */
963 int num_classes() const
964 {
965 return _num_classes;
966 }
967 /** Get share location. */
968 bool share_location() const
969 {
970 return _share_location;
971 }
972 /** Get detection output code type. */
973 DetectionOutputLayerCodeType code_type() const
974 {
975 return _code_type;
976 }
977 /** Get if variance encoded in target. */
978 bool variance_encoded_in_target() const
979 {
980 return _variance_encoded_in_target;
981 }
982 /** Get the number of total bounding boxes to be kept per image. */
983 int keep_top_k() const
984 {
985 return _keep_top_k;
986 }
987 /** Get nms threshold. */
988 float nms_threshold() const
989 {
990 return _nms_threshold;
991 }
992 /** Get eta. */
993 float eta() const
994 {
995 return _eta;
996 }
997 /** Get background label ID. */
998 int background_label_id() const
999 {
1000 return _background_label_id;
1001 }
1002 /** Get confidence threshold. */
1003 float confidence_threshold() const
1004 {
1005 return _confidence_threshold;
1006 }
1007 /** Get top K. */
1008 int top_k() const
1009 {
1010 return _top_k;
1011 }
1012 /** Get number of location classes. */
1013 int num_loc_classes() const
1014 {
1015 return _num_loc_classes;
1016 }
1017
1018private:
1019 int _num_classes;
1020 bool _share_location;
1021 DetectionOutputLayerCodeType _code_type;
1022 int _keep_top_k;
1023 float _nms_threshold;
1024 int _top_k;
1025 int _background_label_id;
1026 float _confidence_threshold;
1027 bool _variance_encoded_in_target;
1028 float _eta;
1029 int _num_loc_classes;
1030};
1031
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001032/** Detection Output layer info */
1033class DetectionPostProcessLayerInfo final
1034{
1035public:
1036 /** Default Constructor */
1037 DetectionPostProcessLayerInfo()
1038 : _max_detections(),
1039 _max_classes_per_detection(),
1040 _nms_score_threshold(),
1041 _iou_threshold(),
1042 _num_classes(),
1043 _scales_values(),
1044 _use_regular_nms(),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001045 _detection_per_class(),
1046 _dequantize_scores()
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001047 {
1048 }
1049 /** Constructor
1050 *
1051 * @param[in] max_detections Number of total detection.
1052 * @param[in] max_classes_per_detection Number of total classes to be kept after NMS step. Used in the Fast Non-Max-Suppression
1053 * @param[in] nms_score_threshold Threshold to be used in NMS
1054 * @param[in] iou_threshold Threshold to be used during the intersection over union.
1055 * @param[in] num_classes Number of classes.
1056 * @param[in] scales_values Scales values used for decode center size boxes.
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001057 * @param[in] use_regular_nms (Optional) Boolean to determinate if use regular or fast nms. Defaults to false.
1058 * @param[in] detection_per_class (Optional) Number of detection per class. Used in the Regular Non-Max-Suppression. Defaults to 100.
1059 * @param[in] dequantize_scores (Optional) If the scores need to be dequantized. Defaults to true.
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001060 */
1061 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 +01001062 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 +00001063 : _max_detections(max_detections),
1064 _max_classes_per_detection(max_classes_per_detection),
1065 _nms_score_threshold(nms_score_threshold),
1066 _iou_threshold(iou_threshold),
1067 _num_classes(num_classes),
1068 _scales_values(scales_values),
1069 _use_regular_nms(use_regular_nms),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001070 _detection_per_class(detection_per_class),
1071 _dequantize_scores(dequantize_scores)
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001072 {
1073 }
1074 /** Get max detections. */
1075 unsigned int max_detections() const
1076 {
1077 return _max_detections;
1078 }
1079 /** Get max_classes per detection. Used in the Fast Non-Max-Suppression.*/
1080 unsigned int max_classes_per_detection() const
1081 {
1082 return _max_classes_per_detection;
1083 }
1084 /** Get detection per class. Used in the Regular Non-Max-Suppression */
1085 unsigned int detection_per_class() const
1086 {
1087 return _detection_per_class;
1088 }
1089 /** Get nms threshold. */
1090 float nms_score_threshold() const
1091 {
1092 return _nms_score_threshold;
1093 }
1094 /** Get intersection over union threshold. */
1095 float iou_threshold() const
1096 {
1097 return _iou_threshold;
1098 }
1099 /** Get num classes. */
1100 unsigned int num_classes() const
1101 {
1102 return _num_classes;
1103 }
1104 /** Get if use regular nms. */
1105 bool use_regular_nms() const
1106 {
1107 return _use_regular_nms;
1108 }
1109 /** Get y scale value. */
1110 float scale_value_y() const
1111 {
1112 // Saved as [y,x,h,w]
1113 return _scales_values[0];
1114 }
1115 /** Get x scale value. */
1116 float scale_value_x() const
1117 {
1118 // Saved as [y,x,h,w]
1119 return _scales_values[1];
1120 }
1121 /** Get h scale value. */
1122 float scale_value_h() const
1123 {
1124 // Saved as [y,x,h,w]
1125 return _scales_values[2];
1126 }
1127 /** Get w scale value. */
1128 float scale_value_w() const
1129 {
1130 // Saved as [y,x,h,w]
1131 return _scales_values[3];
1132 }
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001133 /** Get dequantize_scores value. */
1134 bool dequantize_scores() const
1135 {
1136 return _dequantize_scores;
1137 }
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001138
1139private:
1140 unsigned int _max_detections;
1141 unsigned int _max_classes_per_detection;
1142 float _nms_score_threshold;
1143 float _iou_threshold;
1144 unsigned int _num_classes;
1145 std::array<float, 4> _scales_values;
1146 bool _use_regular_nms;
1147 unsigned int _detection_per_class;
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001148 bool _dequantize_scores;
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001149};
1150
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001151/** Pooling Layer Information struct*/
1152struct PoolingLayerInfo
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001153{
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001154 /** Default Constructor */
1155 PoolingLayerInfo()
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001156 : pool_type(PoolingType::MAX),
1157 pool_size(Size2D()),
1158 data_layout(DataLayout::UNKNOWN),
1159 pad_stride_info(PadStrideInfo()),
1160 exclude_padding(false),
1161 is_global_pooling(false),
1162 fp_mixed_precision(false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001163 {
1164 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001165 /** Constructor
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001166 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001167 * @param[in] pool_type Pooling type @ref PoolingType.
1168 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001169 * @param[in] data_layout Data layout used by the layer @ref DataLayout
1170 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1171 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1172 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1173 * Defaults to false;
1174 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1175 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001176 explicit PoolingLayerInfo(PoolingType pool_type,
1177 unsigned int pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001178 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001179 PadStrideInfo pad_stride_info = PadStrideInfo(),
1180 bool exclude_padding = false,
1181 bool fp_mixed_precision = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001182 : pool_type(pool_type),
1183 pool_size(Size2D(pool_size, pool_size)),
1184 data_layout(data_layout),
1185 pad_stride_info(pad_stride_info),
1186 exclude_padding(exclude_padding),
1187 is_global_pooling(false),
1188 fp_mixed_precision(fp_mixed_precision)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001189 {
1190 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001191
1192 /** Constructor
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001193 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001194 * @param[in] pool_type Pooling type @ref PoolingType.
1195 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001196 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001197 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1198 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1199 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1200 * Defaults to false;
1201 * @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 +00001202 */
1203 explicit PoolingLayerInfo(PoolingType pool_type,
1204 Size2D pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001205 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001206 PadStrideInfo pad_stride_info = PadStrideInfo(),
1207 bool exclude_padding = false,
1208 bool fp_mixed_precision = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001209 : pool_type(pool_type),
1210 pool_size(pool_size),
1211 data_layout(data_layout),
1212 pad_stride_info(pad_stride_info),
1213 exclude_padding(exclude_padding),
1214 is_global_pooling(false),
1215 fp_mixed_precision(fp_mixed_precision)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001216 {
1217 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001218
1219 /** Constructor
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001220 *
1221 * @note This constructor is used for global pooling
1222 *
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001223 * @param[in] pool_type Pooling type @ref PoolingType.
1224 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001225 */
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001226 explicit PoolingLayerInfo(PoolingType pool_type, DataLayout data_layout)
1227 : pool_type(pool_type),
1228 pool_size(Size2D()),
1229 data_layout(data_layout),
1230 pad_stride_info(PadStrideInfo(1, 1, 0, 0)),
1231 exclude_padding(false),
1232 is_global_pooling(true),
1233 fp_mixed_precision(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001234 {
1235 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001236
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001237 PoolingType pool_type;
1238 Size2D pool_size;
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001239 DataLayout data_layout;
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001240 PadStrideInfo pad_stride_info;
1241 bool exclude_padding;
1242 bool is_global_pooling;
1243 bool fp_mixed_precision;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001244};
1245
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001246/** ROI Pooling Layer Information class */
giuros0118870812018-09-13 09:31:40 +01001247class ROIPoolingLayerInfo final
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001248{
1249public:
giuros0118870812018-09-13 09:31:40 +01001250 /** Constructor
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001251 *
giuros0118870812018-09-13 09:31:40 +01001252 * @param[in] pooled_width Pooled width of the layer.
1253 * @param[in] pooled_height Pooled height of the layer.
1254 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
1255 * @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 +01001256 */
giuros0118870812018-09-13 09:31:40 +01001257 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale, unsigned int sampling_ratio = 0)
1258 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale), _sampling_ratio(sampling_ratio)
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001259 {
1260 }
Alex Gildayc357c472018-03-21 13:54:09 +00001261 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001262 unsigned int pooled_width() const
1263 {
1264 return _pooled_width;
1265 }
Alex Gildayc357c472018-03-21 13:54:09 +00001266 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001267 unsigned int pooled_height() const
1268 {
1269 return _pooled_height;
1270 }
Alex Gildayc357c472018-03-21 13:54:09 +00001271 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001272 float spatial_scale() const
1273 {
1274 return _spatial_scale;
1275 }
giuros0118870812018-09-13 09:31:40 +01001276 /** Get sampling ratio */
1277 unsigned int sampling_ratio() const
1278 {
1279 return _sampling_ratio;
1280 }
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001281
1282private:
1283 unsigned int _pooled_width;
1284 unsigned int _pooled_height;
1285 float _spatial_scale;
giuros0118870812018-09-13 09:31:40 +01001286 unsigned int _sampling_ratio;
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001287};
1288
Manuel Bottini5209be52019-02-13 16:34:56 +00001289/** Generate Proposals Information class */
1290class GenerateProposalsInfo
1291{
1292public:
1293 /** Constructor
1294 *
1295 * @param[in] im_width Width of the original image
1296 * @param[in] im_height Height of the original image
1297 * @param[in] im_scale Scale applied to the original image
1298 * @param[in] spatial_scale (Optional)Scale applied to the feature map. Defaults to 1.0
1299 * @param[in] pre_nms_topN (Optional)Number of the best scores to be selected from the transformations. Defaults to 6000.
1300 * @param[in] post_nms_topN (Optional)Number of the best scores to be selected from the NMS operation. Defaults to 300.
1301 * @param[in] nms_thres (Optional)NMS overlap threshold. Defaults to 0.7.
1302 * @param[in] min_size (Optional)Size used to validate the anchors produced. Defaults to 16.
1303 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region of interest). Defaults to 4.
1304 */
1305 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,
1306 size_t values_per_roi = 4)
1307 : _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),
1308 _min_size(min_size), _values_per_roi(values_per_roi)
1309 {
1310 }
1311
1312 /* Get the original height */
1313 float im_height() const
1314 {
1315 return _im_height;
1316 }
1317 /* Get the original width */
1318 float im_width() const
1319 {
1320 return _im_width;
1321 }
1322 /* Get the image scale */
1323 float im_scale() const
1324 {
1325 return _im_scale;
1326 }
1327 /* Get the value of how many best scores to select (before NMS) */
1328 int pre_nms_topN() const
1329 {
1330 return _pre_nms_topN;
1331 }
1332 /* Get the value of how many best scores to select (after NMS) */
1333 int post_nms_topN() const
1334 {
1335 return _post_nms_topN;
1336 }
1337 /* Get the NMS overlap threshold */
1338 float nms_thres() const
1339 {
1340 return _nms_thres;
1341 }
1342 /* Get the minimal size */
1343 float min_size() const
1344 {
1345 return _min_size;
1346 }
1347 /* Get the spatial scale to be applied to the feature maps */
1348 float spatial_scale() const
1349 {
1350 return _spatial_scale;
1351 }
1352 /* Get the values used to represent a ROI(Region of interest)*/
1353 size_t values_per_roi() const
1354 {
1355 return _values_per_roi;
1356 }
1357
1358private:
1359 float _im_height;
1360 float _im_width;
1361 float _im_scale;
1362 float _spatial_scale;
1363 int _pre_nms_topN;
1364 int _post_nms_topN;
1365 float _nms_thres;
1366 float _min_size;
1367 size_t _values_per_roi;
1368};
1369
1370/** ComputeAnchors information class */
1371class ComputeAnchorsInfo
1372{
1373public:
1374 /** Constructor
1375 *
1376 * @param[in] feat_width Feature map width
1377 * @param[in] feat_height Feature map height
1378 * @param[in] spatial_scale Feature map scale
1379 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region Of Interest). Defaults to 4
1380 */
1381 ComputeAnchorsInfo(float feat_width, float feat_height, float spatial_scale, size_t values_per_roi = 4)
1382 : _feat_height(feat_height),
1383 _feat_width(feat_width),
1384 _spatial_scale(spatial_scale),
1385 _values_per_roi(values_per_roi)
1386 {
1387 }
1388
1389 /* Get the height of the feature map */
1390 float feat_height() const
1391 {
1392 return _feat_height;
1393 }
1394
1395 /* Get the width of the feature map */
1396 float feat_width() const
1397 {
1398 return _feat_width;
1399 }
1400
1401 /* Get the scale of the feature map */
1402 float spatial_scale() const
1403 {
1404 return _spatial_scale;
1405 }
1406
1407 /* Get the values used to represent a ROI(Region Of Interest)*/
1408 size_t values_per_roi() const
1409 {
1410 return _values_per_roi;
1411 }
1412
1413private:
1414 float _feat_height;
1415 float _feat_width;
1416 float _spatial_scale;
1417 size_t _values_per_roi;
1418};
1419
giuros01c04a0e82018-10-03 12:44:35 +01001420/** Bounding Box Transform information class */
giuros01d696cb62018-11-16 10:39:59 +00001421class BoundingBoxTransformInfo final
giuros01c04a0e82018-10-03 12:44:35 +01001422{
1423public:
1424 /** Constructor
1425 *
giuros01d696cb62018-11-16 10:39:59 +00001426 * @param[in] img_width Width of the original image
1427 * @param[in] img_height Height, of the original image
1428 * @param[in] scale Scale of the original image
1429 * @param[in] apply_scale (Optional)Re-apply scaling after transforming the boxes. Defaults to false
1430 * @param[in] weights (Optional)Weights [wx, wy, ww, wh] for the deltas. Defaults to all ones
1431 * @param[in] correct_transform_coords (Optional)Correct bounding box transform coordinates. Defaults to false
1432 * @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 +01001433 */
giuros01d696cb62018-11-16 10:39:59 +00001434 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 =
1435 false,
1436 float bbox_xform_clip =
1437 4.135166556742356f)
1438 : _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 +01001439 {
1440 }
1441
1442 std::array<float, 4> weights() const
1443 {
1444 return _weights;
1445 }
1446
1447 float bbox_xform_clip() const
1448 {
1449 return _bbox_xform_clip;
1450 }
1451
1452 float img_height() const
1453 {
1454 return _img_height;
1455 }
1456
1457 float img_width() const
1458 {
1459 return _img_width;
1460 }
1461
1462 float scale() const
1463 {
1464 return _scale;
1465 }
1466
1467 bool apply_scale() const
1468 {
1469 return _apply_scale;
1470 }
1471
giuros01d696cb62018-11-16 10:39:59 +00001472 bool correct_transform_coords() const
1473 {
1474 return _correct_transform_coords;
1475 }
1476
giuros01c04a0e82018-10-03 12:44:35 +01001477private:
1478 float _img_width;
1479 float _img_height;
1480 float _scale;
1481 bool _apply_scale;
giuros01d696cb62018-11-16 10:39:59 +00001482 bool _correct_transform_coords;
giuros01c04a0e82018-10-03 12:44:35 +01001483 std::array<float, 4> _weights;
1484 float _bbox_xform_clip;
1485};
1486
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001487/** Activation Layer Information class */
1488class ActivationLayerInfo
1489{
1490public:
1491 /** Available activation functions */
1492 enum class ActivationFunction
1493 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001494 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
1495 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
1496 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
1497 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
1498 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
Manuel Bottini581c8982019-02-07 10:31:57 +00001499 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 +01001500 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
Georgios Pinitasfb0fdcd2019-08-22 17:10:04 +01001501 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 +01001502 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
1503 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
1504 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
Usama Arif6a98a6e2019-05-10 17:07:27 +01001505 LINEAR, /**< Linear ( \f$ f(x)= ax + b \f$ ) */
morgolock07df3d42020-02-27 11:46:28 +00001506 IDENTITY, /**< Identity ( \f$ f(x)= x \f$ ) */
1507 HARD_SWISH /**< Hard-swish ( \f$ f(x) = (x * relu6(x+3))/6 \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001508 };
1509
Giorgio Arena11674872018-02-07 15:38:12 +00001510 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001511 /** Default Constructor
1512 *
1513 * @param[in] f The activation function to use.
1514 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001515 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1516 * @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 +01001517 */
1518 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001519 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001520 {
1521 }
Alex Gildayc357c472018-03-21 13:54:09 +00001522 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001523 ActivationFunction activation() const
1524 {
1525 return _act;
1526 }
Alex Gildayc357c472018-03-21 13:54:09 +00001527 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001528 float a() const
1529 {
1530 return _a;
1531 }
Alex Gildayc357c472018-03-21 13:54:09 +00001532 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001533 float b() const
1534 {
1535 return _b;
1536 }
Alex Gildayc357c472018-03-21 13:54:09 +00001537 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001538 bool enabled() const
1539 {
1540 return _enabled;
1541 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001542
1543private:
Usama Arif6a98a6e2019-05-10 17:07:27 +01001544 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::IDENTITY };
Giorgio Arena11674872018-02-07 15:38:12 +00001545 float _a = {};
1546 float _b = {};
1547 bool _enabled = { false };
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001548};
1549
Giorgio Arena1856ff72020-02-07 13:46:45 +00001550/** Fully connected layer info */
1551struct FullyConnectedLayerInfo
1552{
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001553 /* Fused-activation parameters */
1554 ActivationLayerInfo activation_info{}; /**< Fused activation to apply after the matrix multiplication. */
1555 /* Information about weights */
1556 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
1557 bool transpose_weights{ true }; /**< Transpose weights if true. */
1558 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
1559 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01001560 bool constant_weights{ true }; /**< If false, weights can vary between runs. */
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001561 /* Other parameters */
1562 bool fp_mixed_precision{ false }; /**< Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy. */
Giorgio Arena1856ff72020-02-07 13:46:45 +00001563
1564 /** Sets the weights trained data layout
1565 *
1566 * @param[in] layout Data layout that the weights were trained with
1567 *
1568 * @return Updated object
1569 */
1570 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
1571 {
1572 weights_trained_layout = layout;
1573 return *this;
1574 }
1575 /** Sets the transpose weights flag
1576 *
1577 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
1578 *
1579 * @return Updated object
1580 */
1581 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
1582 {
1583 transpose_weights = should_transpose_weights;
1584 return *this;
1585 }
1586};
1587
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001588/** Normalization Layer Information class */
1589class NormalizationLayerInfo
1590{
1591public:
1592 /** Default Constructor
1593 *
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001594 * @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 +01001595 * @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 +00001596 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1597 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1598 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1599 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1600 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001601 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001602 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1603 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001604 {
1605 }
Alex Gildayc357c472018-03-21 13:54:09 +00001606 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001607 NormType type() const
1608 {
1609 return _type;
1610 }
Alex Gildayc357c472018-03-21 13:54:09 +00001611 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001612 uint32_t norm_size() const
1613 {
1614 return _norm_size;
1615 }
Alex Gildayc357c472018-03-21 13:54:09 +00001616 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001617 float alpha() const
1618 {
1619 return _alpha;
1620 }
Alex Gildayc357c472018-03-21 13:54:09 +00001621 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001622 float beta() const
1623 {
1624 return _beta;
1625 }
Alex Gildayc357c472018-03-21 13:54:09 +00001626 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001627 float kappa() const
1628 {
1629 return _kappa;
1630 }
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001631 /** Get the is_scaled value */
1632 bool is_scaled() const
1633 {
1634 return _is_scaled;
1635 }
Alex Gildayc357c472018-03-21 13:54:09 +00001636 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001637 bool is_cross_map() const
1638 {
1639 return _type == NormType::CROSS_MAP;
1640 }
Alex Gildayc357c472018-03-21 13:54:09 +00001641 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001642 bool is_in_map() const
1643 {
1644 return !is_cross_map();
1645 }
1646 /** Return the scaling factor of the normalization function.
1647 *
1648 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1649 * 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 +01001650 *
1651 * @return The normalization scaling factor.
1652 */
1653 float scale_coeff() const
1654 {
1655 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001656 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001657 }
1658
1659private:
1660 NormType _type;
1661 uint32_t _norm_size;
1662 float _alpha;
1663 float _beta;
1664 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001665 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001666};
1667
thecha012bfadd92020-08-12 17:25:51 +01001668class StridedSliceLayerInfo
1669{
1670public:
1671 /** Default Constructor
1672 *
1673 * @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.
1674 * @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.
1675 * @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.
1676 */
1677 StridedSliceLayerInfo(int32_t begin_mask = 0, int32_t end_mask = 0, int32_t shrink_axis_mask = 0)
1678 : _begin_mask(begin_mask), _end_mask(end_mask), _shrink_axis_mask(shrink_axis_mask)
1679 {
1680 }
1681
1682 /* Get the begin mask value */
1683 int32_t begin_mask() const
1684 {
1685 return _begin_mask;
1686 }
1687
1688 /* Get the end mask value */
1689 int32_t end_mask() const
1690 {
1691 return _end_mask;
1692 }
1693
1694 /* Get the shrink axis mask value */
1695 int32_t shrink_axis_mask() const
1696 {
1697 return _shrink_axis_mask;
1698 }
1699
1700private:
1701 int32_t _begin_mask;
1702 int32_t _end_mask;
1703 int32_t _shrink_axis_mask;
1704};
1705
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001706/** 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 +01001707class WeightsInfo
1708{
1709public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001710 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001711 WeightsInfo()
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001712 : _are_reshaped(false), _kernel_width(0), _kernel_height(0), _num_kernels(0), _retain_internal_weights(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001713 {
1714 }
1715 /** Constructor
1716 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001717 * @param[in] are_reshaped True if the weights have been reshaped
1718 * @param[in] kernel_width Kernel width.
1719 * @param[in] kernel_height Kernel height.
1720 * @param[in] num_kernels Number of convolution kernels.
1721 * @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 +01001722 */
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001723 WeightsInfo(bool are_reshaped, unsigned int kernel_width, unsigned int kernel_height, unsigned int num_kernels, bool retain_internal_weights = false)
1724 : _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 +01001725 {
1726 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001727 /** Flag which specifies if the weights tensor has been reshaped.
1728 *
1729 * @return True if the weights tensors has been reshaped
1730 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001731 bool are_reshaped() const
1732 {
1733 return _are_reshaped;
1734 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001735 /** Return the number of convolution kernels
1736 *
1737 * @return The number of convolution kernels
1738 */
1739 unsigned int num_kernels() const
1740 {
1741 return _num_kernels;
1742 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001743 /** Return the width and height of the kernel
1744 *
1745 * @return The width and height of the kernel
1746 */
1747 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001748 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001749 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001750 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001751 bool retain_internal_weights() const
1752 {
1753 return _retain_internal_weights;
1754 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001755
1756private:
SiCong Liebd8fb42020-08-18 11:03:14 +01001757 bool _are_reshaped;
1758 unsigned int _kernel_width;
1759 unsigned int _kernel_height;
1760 unsigned int _num_kernels;
1761 bool _retain_internal_weights;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001762};
1763
Gian Marco36a0a462018-01-12 10:21:40 +00001764/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
1765 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01001766 * The matrix A can only be reshaped through @ref opencl::kernels::ClGemmReshapeLhsMatrixKernel or @ref cpu::kernels::CpuGemmInterleave4x4Kernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01001767 * Note: Optionally just for @ref opencl::kernels::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 +00001768 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01001769 * The matrix B can only be reshaped through @ref opencl::kernels::ClGemmReshapeRhsMatrixKernel or @ref cpu::kernels::CpuGemmTranspose1xWKernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01001770 * Note: Optionally just for @ref opencl::kernels::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 +00001771 *
1772 */
1773class GEMMReshapeInfo final
1774{
1775public:
1776 /** Default constructor */
1777 GEMMReshapeInfo()
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001778 : _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 +00001779 {
1780 }
1781 /** Constructor
1782 *
1783 * @param[in] m Number of matrix A rows
1784 * @param[in] n Number of matrix B columns
1785 * @param[in] k Number of matrix A columns or matrix B rows
1786 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
1787 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001788 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
1789 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001790 * @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 +01001791 * to perform 1x1 convolutions with the NHWC data layout)
1792 * @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 +00001793 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001794 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 +01001795 : _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 +01001796 _reinterpret_input_as_3d(reinterpret_input_as_3d), _broadcast_bias(broadcast_bias)
Gian Marco36a0a462018-01-12 10:21:40 +00001797 {
1798 }
1799 /** Number of matrix A rows
1800 *
1801 * @return the number of matrix A rows
1802 */
1803 int m() const
1804 {
1805 return _m;
1806 }
1807 /** Number of matrix B columns
1808 *
1809 * @return the number of matrix B columns
1810 */
1811 int n() const
1812 {
1813 return _n;
1814 }
1815 /** Number of matrix A columns or matrix B rows
1816 *
1817 * @return the number of matrix A columns or matrix B rows
1818 */
1819 int k() const
1820 {
1821 return _k;
1822 }
1823 /** Multiplication factor for the width of the 1xW transposed block
1824 *
1825 * @return the multiplication factor for the width of the 1xW transposed block
1826 */
1827 int mult_transpose1xW_width() const
1828 {
1829 return _mult_transpose1xW_width;
1830 }
1831 /** Multiplication factor for the height of the 4x4 interleaved block
1832 *
1833 * @return the multiplication factor for the height of the 4x4 interleaved block
1834 */
1835 int mult_interleave4x4_height() const
1836 {
1837 return _mult_interleave4x4_height;
1838 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001839 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
1840 *
1841 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
1842 * m = depth_output_gemm3d * output_height
1843 *
1844 * @return the depth of the output tensor to be used with the GEMM3D kernel
1845 */
1846 int depth_output_gemm3d() const
1847 {
1848 return _depth_output_gemm3d;
1849 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001850 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
1851 *
1852 * @return True if the input tensor has to be reinterpreted as 3D tensor
1853 */
1854 bool reinterpret_input_as_3d() const
1855 {
1856 return _reinterpret_input_as_3d;
1857 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001858 /** Flag which specifies whether to broadcast the shape of the bias tensor.
1859 *
1860 * @return True if the shape of the bias tensor is to be broadcasted.
1861 */
1862 bool broadcast_bias() const
1863 {
1864 return _broadcast_bias;
1865 };
Gian Marco36a0a462018-01-12 10:21:40 +00001866
1867private:
SiCong Liebd8fb42020-08-18 11:03:14 +01001868 int _m;
1869 int _n;
1870 int _k;
1871 int _mult_transpose1xW_width;
1872 int _mult_interleave4x4_height;
1873 int _depth_output_gemm3d;
1874 bool _reinterpret_input_as_3d;
1875 bool _broadcast_bias;
Gian Marco36a0a462018-01-12 10:21:40 +00001876};
1877
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +01001878struct ConvolutionInfo
1879{
1880 ConvolutionInfo() = default;
1881 ConvolutionInfo(const PadStrideInfo &pad_stride_info, unsigned int depth_multiplier, const ActivationLayerInfo &act_info, const Size2D &dilation)
1882 : pad_stride_info(pad_stride_info), depth_multiplier(depth_multiplier), act_info(act_info), dilation(dilation)
1883 {
1884 }
1885 PadStrideInfo pad_stride_info{}; /**< Convolution info (Pads, strides,...) */
1886 unsigned int depth_multiplier{ 1 }; /**< Multiplier to apply to input's depth to retrieve the output depth. Defaults to 1 */
1887 ActivationLayerInfo act_info{}; /**< Fused activation to apply after convolution. */
1888 Size2D dilation{ Size2D(1, 1) }; /**< Dilation, in elements, across x and y. Defaults to (1, 1). */
1889};
1890
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001891/** GEMMLowp output stage type */
1892enum class GEMMLowpOutputStageType
1893{
Manuel Bottini959c26d2019-12-02 16:22:35 +00001894 NONE, /**< No quantization */
1895 QUANTIZE_DOWN, /**< Quantize using an integer multiplication */
1896 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize using a fixed point multiplication */
1897 QUANTIZE_DOWN_FLOAT /**< Quantize using a floating point multiplication */
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001898};
1899
1900/** GEMMLowp output stage info */
1901struct GEMMLowpOutputStageInfo
1902{
Giorgio Arena1856ff72020-02-07 13:46:45 +00001903 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
1904 int32_t gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
1905 int32_t gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1906 int32_t gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
1907 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 */
1908 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 */
1909 std::vector<int32_t> gemmlowp_multipliers{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1910 std::vector<int32_t> gemmlowp_shifts{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
Sheri Zhang1b14c752020-03-09 14:29:52 +00001911 float gemmlowp_real_multiplier{ 0 }; /**< GEMMLowp output stage real multiplier used for quantizing to QASYMM8 */
Giorgio Arena1856ff72020-02-07 13:46:45 +00001912 bool is_quantized_per_channel{ false }; /**< GEMMLowp quantized per-channel flag */
1913 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 +01001914};
1915
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00001916/** GEMM LHS (Left Hand Side) matrix information */
1917struct GEMMLHSMatrixInfo
1918{
morgolockaba2f912020-05-05 16:28:19 +01001919 GEMMLHSMatrixInfo() = default;
1920 GEMMLHSMatrixInfo(unsigned int m, unsigned int k, unsigned int v, bool trans, bool inter)
1921 : m0(m), k0(k), v0(v), transpose(trans), interleave(inter)
1922 {
1923 }
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00001924 unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
1925 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1926 unsigned int v0{ 1 }; /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
1927 bool transpose{ true }; /**< True if the (m0xk0) block has to be transposed before been stored */
1928 bool interleave{ true }; /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
1929};
1930
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00001931/** GEMM RHS (Right Hand Side) matrix information */
1932struct GEMMRHSMatrixInfo
1933{
morgolockaba2f912020-05-05 16:28:19 +01001934 GEMMRHSMatrixInfo() = default;
Gian Marco Iodicee3a849a2020-06-10 17:59:30 +01001935 GEMMRHSMatrixInfo(unsigned int n, unsigned int k, unsigned int h, bool trans, bool inter, bool export_to_cl_img)
1936 : n0(n), k0(k), h0(h), transpose(trans), interleave(inter), export_to_cl_image(export_to_cl_img)
morgolockaba2f912020-05-05 16:28:19 +01001937 {
1938 }
Gian Marco Iodicedd717c32020-05-28 10:22:03 +01001939 unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
1940 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1941 unsigned int h0{ 1 }; /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
1942 bool transpose{ true }; /**< True if the (k0xn0) block has to be transposed before been stored */
1943 bool interleave{ true }; /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
1944 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 +00001945};
1946
Gian Marco36a0a462018-01-12 10:21:40 +00001947/** GEMM information class. This class stores the necessary information to compute GEMM functions
1948 *
1949 * This object also contains the information about how matrix A and matrix B have been reshaped
1950 *
1951 */
Chunosov5124be52017-11-22 20:42:13 +07001952class GEMMInfo
1953{
1954public:
1955 /** Default constructor */
Georgios Pinitas37d080f2019-06-21 18:43:12 +01001956 GEMMInfo() noexcept
1957 : _is_a_reshaped(false),
1958 _is_b_reshaped(false),
1959 _reshape_b_only_on_first_run(true),
1960 _depth_output_gemm3d(0),
1961 _reinterpret_input_as_3d(false),
1962 _retain_internal_weights(false),
1963 _gemmlowp_output_stage(),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01001964 _fast_math(false),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01001965 _fp_mixed_precision(false),
1966 _broadcast_bias(false),
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01001967 _pretranpose_B(true),
1968 _activation_info(),
1969 _constant_weights(true)
Chunosov5124be52017-11-22 20:42:13 +07001970 {
1971 }
1972 /** Constructor
1973 *
1974 * @param[in] is_a_reshaped True if the matrix A has been reshaped
1975 * @param[in] is_b_reshaped True if the matrix B has been reshaped
1976 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001977 * @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 +00001978 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001979 * @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
1980 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01001981 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001982 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001983 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01001984 * @param[in] fast_math (Optional) Use a data type of shorter width to improve performance
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001985 * @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 +01001986 * @param[in] activation_info (Optional) Activation to apply after the matrix multiplication
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01001987 * @param[in] constant_weights (Optional) Weights have constant values throughout multiple executions
Chunosov5124be52017-11-22 20:42:13 +07001988 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001989 GEMMInfo(bool is_a_reshaped, bool is_b_reshaped, bool reshape_b_only_on_first_run, int depth_output_gemm3d = 0, bool reinterpret_input_as_3d = false, bool retain_internal_weights = false,
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01001990 GEMMLowpOutputStageInfo gemmlowp_output_stage = GEMMLowpOutputStageInfo(), bool fp_mixed_precision = false, bool fast_math = false, bool broadcast_bias = false,
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01001991 const ActivationLayerInfo &activation_info = ActivationLayerInfo(), bool constant_weights = true) noexcept
Georgios Pinitas37d080f2019-06-21 18:43:12 +01001992 : _is_a_reshaped(is_a_reshaped),
1993 _is_b_reshaped(is_b_reshaped),
1994 _reshape_b_only_on_first_run(reshape_b_only_on_first_run),
1995 _depth_output_gemm3d(depth_output_gemm3d),
1996 _reinterpret_input_as_3d(reinterpret_input_as_3d),
1997 _retain_internal_weights(retain_internal_weights),
1998 _gemmlowp_output_stage(gemmlowp_output_stage),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01001999 _fast_math(fast_math),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002000 _fp_mixed_precision(fp_mixed_precision),
2001 _broadcast_bias(broadcast_bias),
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01002002 _pretranpose_B(reshape_b_only_on_first_run),
2003 _activation_info(activation_info),
2004 _constant_weights(constant_weights)
Chunosov5124be52017-11-22 20:42:13 +07002005 {
2006 }
2007 /** Flag which specifies if the matrix A has been reshaped
2008 *
2009 * @return True if the matrix A has been reshaped
2010 */
2011 bool is_a_reshaped() const
2012 {
2013 return _is_a_reshaped;
2014 };
2015 /** Flag which specifies if the matrix B has been reshaped
2016 *
2017 * @return True if the matrix B has been reshaped
2018 */
2019 bool is_b_reshaped() const
2020 {
2021 return _is_b_reshaped;
2022 };
2023 /** Flag which specifies if the reshape of matrix B should executed only for the first
2024 *
2025 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
2026 *
2027 * @return True if the reshaped of matrix B happens only for the first run
2028 */
2029 bool reshape_b_only_on_first_run() const
2030 {
2031 return _reshape_b_only_on_first_run;
2032 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002033 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002034 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002035 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002036 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002037 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00002038 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002039 return _depth_output_gemm3d;
2040 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002041 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2042 *
2043 * @return True if the input tensor has to be reinterpreted as 3D tensor
2044 */
2045 bool reinterpret_input_as_3d() const
2046 {
2047 return _reinterpret_input_as_3d;
2048 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002049 /** Flag which specifies if the weights tensor has to be retained from previous run
2050 *
2051 * @return True if the weights tensor has to be retained
2052 */
2053 bool retain_internal_weights() const
2054 {
2055 return _retain_internal_weights;
2056 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002057 /** GEMMLowp output stage
2058 *
2059 * @return the GEMMLowp output stage info
2060 */
2061 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
2062 {
2063 return _gemmlowp_output_stage;
2064 };
Georgios Pinitasdbdea0d2019-10-16 19:21:40 +01002065 /** Sets GEMMLowp output stage
2066 *
2067 * @param[in] output_stage Output stage to set
2068 */
2069 void set_gemmlowp_output_stage(GEMMLowpOutputStageInfo &output_stage)
2070 {
2071 _gemmlowp_output_stage = output_stage;
2072 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002073 /** Flag which specifies if a wider accumulator should be used.
2074 *
2075 * @return True if a wider accumulator has to be used
2076 */
2077 bool fp_mixed_precision() const
2078 {
2079 return _fp_mixed_precision;
2080 };
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002081 /** Flag which specifies if a shorter accumulator to be used.
2082 *
2083 * @return True if a shorter accumulator has to be used
2084 */
2085 bool fast_math() const
2086 {
2087 return _fast_math;
2088 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002089 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2090 *
2091 * @return True if the shape of the bias tensor is to be broadcasted.
2092 */
2093 bool broadcast_bias() const
2094 {
2095 return _broadcast_bias;
2096 };
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002097 /** Flag which specifies whether b should be pre-transposed if supported.
2098 *
2099 * @return True if b should be pre-transposed else false.
2100 */
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01002101 bool pretranpose_B() const
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002102 {
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01002103 return _pretranpose_B;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002104 };
2105 /** Set pre-transpose b flag
2106 *
2107 * @param[in] flag Flag to set
2108 */
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01002109 void set_pretranpose_B(bool flag)
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002110 {
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01002111 _pretranpose_B = flag;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002112 }
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002113 /** Activation layer to apply after the matrix multiplication
2114 *
2115 * @return ActivationLayerInfo object
2116 */
2117 ActivationLayerInfo activation_info() const
2118 {
2119 return _activation_info;
2120 }
SiCongLi2e5fd632020-03-02 15:39:15 +00002121 /** Set activation layer info
2122 *
2123 * @param[in] activation_info ActivationLayerInfo object to set
2124 */
2125 void set_activation_info(const ActivationLayerInfo &activation_info)
2126 {
2127 _activation_info = activation_info;
2128 }
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01002129 /** Flag which specifies if the values of the weights tensor are constant throughout multiple executions or not
2130 *
2131 * @return True if the weights tensor is constant
2132 */
2133 bool constant_weights() const
2134 {
2135 return _constant_weights;
2136 };
Chunosov5124be52017-11-22 20:42:13 +07002137
2138private:
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002139 bool _is_a_reshaped;
2140 bool _is_b_reshaped;
2141 bool _reshape_b_only_on_first_run;
2142 int _depth_output_gemm3d;
2143 bool _reinterpret_input_as_3d;
2144 bool _retain_internal_weights;
2145 GEMMLowpOutputStageInfo _gemmlowp_output_stage;
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002146 bool _fast_math;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002147 bool _fp_mixed_precision;
2148 bool _broadcast_bias;
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01002149 bool _pretranpose_B;
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002150 ActivationLayerInfo _activation_info;
Pablo Marquez Tello9ac7b992021-09-15 10:14:20 +01002151 bool _constant_weights;
Chunosov5124be52017-11-22 20:42:13 +07002152};
2153
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00002154/** Winograd information */
2155struct WinogradInfo
2156{
2157 /** Default constructor
2158 *
2159 * @param[in] output_tile_sz Width and height of the output tile
2160 * @param[in] kernel_sz Width and height of the kernel
2161 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
2162 * @param[in] conv_info Convolution info (Pads, strides)
2163 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
2164 */
2165 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
2166 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
2167 {
2168 }
2169
2170 Size2D output_tile_size{}; /**< Width and height of the output tile */
2171 Size2D kernel_size{}; /**< Width and height of the kernel*/
2172 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
2173 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
2174 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
2175};
2176
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002177/** IO formatting information class*/
2178struct IOFormatInfo
2179{
2180 /** Precision type used when printing floating point numbers */
2181 enum class PrecisionType
2182 {
2183 Default, /**< Default precision to the one that the current stream has */
2184 Custom, /**< Custom precision specified by the user using the precision parameter */
2185 Full /**< The maximum precision of the floating point representation */
2186 };
2187
2188 /** Specifies the area to be printed, used by Tensor objects */
2189 enum class PrintRegion
2190 {
2191 ValidRegion, /**< Prints the valid region of the Tensor object */
2192 NoPadding, /**< Prints the Tensor object without the padding */
2193 Full /**< Print the tensor object including padding */
2194 };
2195
Alex Gildayc357c472018-03-21 13:54:09 +00002196 /** Construct a set of IO formatting information.
2197 *
2198 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
2199 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
2200 * @param[in] precision Precision value for float point numbers. Default: 10.
2201 * @param[in] align_columns Whether to align columns when printed. Default: true.
2202 * @param[in] element_delim Delimeter between elements. Default: " ".
2203 * @param[in] row_delim Delimenter between rows. Default: "\n".
2204 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002205 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
2206 PrecisionType precision_type = PrecisionType::Default,
2207 unsigned int precision = 10,
2208 bool align_columns = true,
2209 std::string element_delim = " ",
2210 std::string row_delim = "\n")
2211 : print_region(print_region),
2212 precision_type(precision_type),
2213 precision(precision),
2214 element_delim(element_delim),
2215 row_delim(row_delim),
2216 align_columns(align_columns)
2217 {
2218 }
2219
Alex Gildayc357c472018-03-21 13:54:09 +00002220 /** Area to be printed by Tensor objects */
2221 PrintRegion print_region;
2222 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002223 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00002224 /** Floating point precision */
2225 unsigned int precision;
2226 /** Element delimeter */
2227 std::string element_delim;
2228 /** Row delimeter */
2229 std::string row_delim;
2230 /** Align columns */
2231 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002232};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00002233} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +00002234#endif /* ARM_COMPUTE_TYPES_H */