blob: 47df44cb6783fd37e05ced2590f7913b8bb1728d [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"
SiCongLi579ca842021-10-18 09:38:33 +010033#include "arm_compute/core/experimental/IPostOp.h"
Sang-Hoon Park11fedda2020-01-15 14:44:04 +000034#include "arm_compute/core/utils/misc/Macros.h"
Georgios Pinitase8291ac2020-02-26 09:58:13 +000035#include "support/Bfloat16.h"
Georgios Pinitas583137c2017-08-31 18:12:42 +010036#include "support/Half.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010037
Michel Iwaniec5dfeae62017-11-29 10:48:23 +000038#include <cmath>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010039#include <cstddef>
40#include <cstdint>
Isabella Gottardia7acb3c2019-01-08 13:48:44 +000041#include <map>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010042#include <string>
43#include <utility>
44
45namespace arm_compute
46{
Georgios Pinitas583137c2017-08-31 18:12:42 +010047/** 16-bit floating point type */
48using half = half_float::half;
49
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000050/** Permutation vector */
51using PermutationVector = Strides;
Georgios Pinitas77589b52018-08-21 14:41:35 +010052/** Bidirectional strides */
53using BiStrides = Coordinates;
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000054
Anthony Barbier6ff3b192017-09-04 18:44:23 +010055/** Image colour formats */
56enum class Format
57{
Daniil Efremov02bf80d2017-11-22 00:26:51 +070058 UNKNOWN, /**< Unknown image format */
59 U8, /**< 1 channel, 1 U8 per channel */
60 S16, /**< 1 channel, 1 S16 per channel */
61 U16, /**< 1 channel, 1 U16 per channel */
62 S32, /**< 1 channel, 1 S32 per channel */
63 U32, /**< 1 channel, 1 U32 per channel */
Georgios Pinitase8291ac2020-02-26 09:58:13 +000064 BFLOAT16, /**< 16-bit brain floating-point number */
Daniil Efremov02bf80d2017-11-22 00:26:51 +070065 F16, /**< 1 channel, 1 F16 per channel */
66 F32, /**< 1 channel, 1 F32 per channel */
67 UV88, /**< 2 channel, 1 U8 per channel */
68 RGB888, /**< 3 channels, 1 U8 per channel */
69 RGBA8888, /**< 4 channels, 1 U8 per channel */
70 YUV444, /**< A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes */
71 YUYV422, /**< A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes */
72 NV12, /**< A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling */
73 NV21, /**< A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling */
74 IYUV, /**< A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes */
75 UYVY422 /**< A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010076};
77
78/** Available data types */
79enum class DataType
80{
Georgios Pinitas8217c8e2019-11-11 18:24:22 +000081 UNKNOWN, /**< Unknown data type */
82 U8, /**< unsigned 8-bit number */
83 S8, /**< signed 8-bit number */
84 QSYMM8, /**< quantized, symmetric fixed-point 8-bit number */
85 QASYMM8, /**< quantized, asymmetric fixed-point 8-bit number unsigned */
86 QASYMM8_SIGNED, /**< quantized, asymmetric fixed-point 8-bit number signed */
87 QSYMM8_PER_CHANNEL, /**< quantized, symmetric per channel fixed-point 8-bit number */
88 U16, /**< unsigned 16-bit number */
89 S16, /**< signed 16-bit number */
90 QSYMM16, /**< quantized, symmetric fixed-point 16-bit number */
91 QASYMM16, /**< quantized, asymmetric fixed-point 16-bit number */
92 U32, /**< unsigned 32-bit number */
93 S32, /**< signed 32-bit number */
94 U64, /**< unsigned 64-bit number */
95 S64, /**< signed 64-bit number */
Georgios Pinitase8291ac2020-02-26 09:58:13 +000096 BFLOAT16, /**< 16-bit brain floating-point number */
Georgios Pinitas8217c8e2019-11-11 18:24:22 +000097 F16, /**< 16-bit floating-point number */
98 F32, /**< 32-bit floating-point number */
99 F64, /**< 64-bit floating-point number */
100 SIZET /**< size_t */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100101};
102
Daniil Efremov02bf80d2017-11-22 00:26:51 +0700103/** Available Sampling Policies */
104enum class SamplingPolicy
105{
106 CENTER, /**< Samples are taken at pixel center */
107 TOP_LEFT /**< Samples are taken at pixel top left corner */
108};
109
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000110/** [DataLayout enum definition] **/
111
Georgios Pinitas4074c992018-01-30 18:13:46 +0000112/** Supported tensor data layouts */
113enum class DataLayout
114{
Alex Gildayc357c472018-03-21 13:54:09 +0000115 UNKNOWN, /**< Unknown data layout */
116 NCHW, /**< Num samples, channels, height, width */
Adnan AlSinane4563a02021-09-01 15:32:03 +0100117 NHWC, /**< Num samples, height, width, channels */
Giorgio Arenac9fe9fc2021-10-06 12:54:29 +0100118 NCDHW, /**< Num samples, channels, depth, height, width */
Adnan AlSinane4563a02021-09-01 15:32:03 +0100119 NDHWC /**< Num samples, depth, height, width, channels */
Georgios Pinitas4074c992018-01-30 18:13:46 +0000120};
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000121/** [DataLayout enum definition] **/
Georgios Pinitas4074c992018-01-30 18:13:46 +0000122
Isabella Gottardid17a6772018-02-27 17:41:55 +0000123/** Supported tensor data layout dimensions */
124enum class DataLayoutDimension
125{
Alex Gildayc357c472018-03-21 13:54:09 +0000126 CHANNEL, /**< channel */
127 HEIGHT, /**< height */
128 WIDTH, /**< width */
Giorgio Arenac9fe9fc2021-10-06 12:54:29 +0100129 DEPTH, /**< depth */
Alex Gildayc357c472018-03-21 13:54:09 +0000130 BATCHES /**< batches */
Isabella Gottardid17a6772018-02-27 17:41:55 +0000131};
132
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000133/** Available ConvolutionMethod*/
134enum class ConvolutionMethod
135{
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000136 GEMM, /**< Convolution using GEMM */
137 GEMM_CONV2D, /**< Direct 2D GEMM convolution */
138 DIRECT, /**< Direct convolution */
139 WINOGRAD, /**< Convolution using Winograd */
140 FFT /**< Convolution using FFT */
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000141};
142
Manuel Bottini05069f02019-09-26 17:18:26 +0100143/** Available DepthwiseConvolutionFunction*/
144enum class DepthwiseConvolutionFunction
145{
146 OPTIMIZED, /**< Optimized Depthwise Convolution */
147 GENERIC, /**< Generic Depthwise Convolution */
148};
149
giuros0146a49a02019-04-01 13:50:22 +0100150/** Available DeconvolutionMethod*/
151enum class DeconvolutionMethod
152{
153 GEMM, /**< Deconvolution using GEMM */
154 DIRECT, /**< Direct deconvolution */
155};
156
Manuel Bottini2732cca2019-05-28 11:44:41 +0100157/** Available FuseBatchNormalizationType*/
158enum class FuseBatchNormalizationType
159{
160 CONVOLUTION, /**< For Convolution weights */
161 DEPTHWISECONVOLUTION /**< For Depthwise Convolution weights*/
162};
163
Usama Arif89890c62019-03-19 10:57:05 +0000164/** Padding mode to use for PadLayer */
165enum class PaddingMode
166{
167 CONSTANT,
168 REFLECT,
169 SYMMETRIC
170};
171
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000172/** Supported comparison operations */
173enum class ComparisonOperation
174{
175 Equal, /**< Equal comparison ( \f$ x == y \f$ ) */
176 NotEqual, /**< NotEqual comparison ( \f$ x != y \f$ ) */
177 Greater, /**< Greater comparison ( \f$ x > y \f$ ) */
178 GreaterEqual, /**< Greater equal comparison ( \f$ x >= y \f$ ) */
179 Less, /**< Less comparison ( \f$ x < y \f$ ) */
180 LessEqual /**< Less equal comparison ( \f$ x <= y \f$ ) */
181};
182
Alex Gildayc357c472018-03-21 13:54:09 +0000183/** Container for valid region of a window */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100184struct ValidRegion
185{
Alex Gildayc357c472018-03-21 13:54:09 +0000186 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100187 ValidRegion()
188 : anchor{}, shape{}
189 {
190 }
191
Alex Gildayc357c472018-03-21 13:54:09 +0000192 /** Allow instances of this class to be copy constructed */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100193 ValidRegion(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000194 /** Allow instances of this class to be move constructed */
195 ValidRegion(ValidRegion &&) = default;
196 /** Allow instances of this class to be copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100197 ValidRegion &operator=(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000198 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100199 ValidRegion &operator=(ValidRegion &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000200 /** Default destructor */
201 ~ValidRegion() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100202
Alex Gildayc357c472018-03-21 13:54:09 +0000203 /** Constructor for a valid region with default number of dimensions
204 *
205 * @param[in] an_anchor Anchor for the start of the valid region.
206 * @param[in] a_shape Shape of the valid region.
207 *
208 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000209 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
210 : anchor{ an_anchor }, shape{ a_shape }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100211 {
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000212 anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
213 }
214
Alex Gildayc357c472018-03-21 13:54:09 +0000215 /** Constructor for a valid region with specified number of dimensions
216 *
217 * @param[in] an_anchor Anchor for the start of the valid region.
218 * @param[in] a_shape Shape of the valid region.
219 * @param[in] num_dimensions Number of dimensions (must be >= number of dimensions of anchor and shape).
220 *
221 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000222 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
223 : anchor{ an_anchor }, shape{ a_shape }
224 {
225 ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
226 anchor.set_num_dimensions(num_dimensions);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100227 }
228
229 /** Return the start of the valid region for the given dimension @p d */
230 int start(unsigned int d) const
231 {
232 return anchor[d];
233 }
234
235 /** Return the end of the valid region for the given dimension @p d */
236 int end(unsigned int d) const
237 {
238 return anchor[d] + shape[d];
239 }
240
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000241 /** Accessor to set the value of anchor and shape for one of the dimensions.
242 *
243 * @param[in] dimension Dimension for which the value is set.
244 * @param[in] start Value to be set in anchor for the dimension.
245 * @param[in] size Value to be set in shape for the dimension.
246 *
247 * @return *this.
248 */
249 ValidRegion &set(size_t dimension, int start, size_t size)
250 {
251 anchor.set(dimension, start);
252 shape.set(dimension, size);
253 return *this;
254 }
255
Alex Gildayc357c472018-03-21 13:54:09 +0000256 Coordinates anchor; /**< Anchor for the start of the valid region. */
257 TensorShape shape; /**< Shape of the valid region. */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100258};
259
260/** Methods available to handle borders */
261enum class BorderMode
262{
263 UNDEFINED, /**< Borders are left undefined */
264 CONSTANT, /**< Pixels outside the image are assumed to have a constant value */
265 REPLICATE /**< Pixels outside the image are assumed to have the same value as the closest image pixel */
266};
267
268/** Container for 2D border size */
269struct BorderSize
270{
271 /** Empty border, i.e. no border */
Pablo Marquez Tello383de022021-03-18 11:31:13 +0000272 constexpr BorderSize() noexcept
273 : top{ 0 },
274 right{ 0 },
275 bottom{ 0 },
276 left{ 0 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100277 {
278 }
279
280 /** Border with equal size around the 2D plane */
Pablo Marquez Tello383de022021-03-18 11:31:13 +0000281 explicit constexpr BorderSize(unsigned int size) noexcept
282 : top{ size },
283 right{ size },
284 bottom{ size },
285 left{ size }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100286 {
287 }
288
289 /** Border with same size for top/bottom and left/right */
290 constexpr BorderSize(unsigned int top_bottom, unsigned int left_right)
291 : top{ top_bottom }, right{ left_right }, bottom{ top_bottom }, left{ left_right }
292 {
293 }
294
295 /** Border with different sizes */
296 constexpr BorderSize(unsigned int top, unsigned int right, unsigned int bottom, unsigned int left)
297 : top{ top }, right{ right }, bottom{ bottom }, left{ left }
298 {
299 }
300
301 /** Check if the entire border is zero */
302 constexpr bool empty() const
303 {
304 return top == 0 && right == 0 && bottom == 0 && left == 0;
305 }
306
307 /** Check if the border is the same size on all sides */
308 constexpr bool uniform() const
309 {
310 return top == right && top == bottom && top == left;
311 }
312
Alex Gildayc357c472018-03-21 13:54:09 +0000313 /** Scale this border size.
314 *
315 * @param[in] scale Scale to multiply border size by.
316 *
317 * @return *this.
318 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100319 BorderSize &operator*=(float scale)
320 {
321 top *= scale;
322 right *= scale;
323 bottom *= scale;
324 left *= scale;
325
326 return *this;
327 }
328
Alex Gildayc357c472018-03-21 13:54:09 +0000329 /** Scale a copy of this border size.
330 *
331 * @param[in] scale Scale to multiply border size by.
332 *
333 * @return a scaled copy of this.
334 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100335 BorderSize operator*(float scale)
336 {
337 BorderSize size = *this;
338 size *= scale;
339
340 return size;
341 }
342
Giorgio Arena1e2af2a2020-10-15 17:39:41 +0100343 /** Check equality with another BorderSize struct
344 *
345 * @param[in] rhs other struct to check against
346 *
347 * @return true if they are equal
348 */
349 bool operator==(const BorderSize &rhs)
350 {
351 return (top == rhs.top) && (right == rhs.right) && (bottom == rhs.bottom) && (left == rhs.left);
352 }
353
354 /** Check non-equality with another BorderSize struct
355 *
356 * @param[in] rhs other struct to check against
357 *
358 * @return true if they are different
359 */
360 bool operator!=(const BorderSize &rhs)
361 {
362 return !(*this == rhs);
363 }
364
Alex Gildayc357c472018-03-21 13:54:09 +0000365 /** Limit this border size.
366 *
367 * @param[in] limit Border size to limit this border size to.
368 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100369 void limit(const BorderSize &limit)
370 {
371 top = std::min(top, limit.top);
372 right = std::min(right, limit.right);
373 bottom = std::min(bottom, limit.bottom);
374 left = std::min(left, limit.left);
375 }
376
Alex Gildayc357c472018-03-21 13:54:09 +0000377 unsigned int top; /**< top of the border */
378 unsigned int right; /**< right of the border */
379 unsigned int bottom; /**< bottom of the border */
380 unsigned int left; /**< left of the border */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100381};
382
Alex Gildayc357c472018-03-21 13:54:09 +0000383/** Container for 2D padding size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100384using PaddingSize = BorderSize;
385
SiCongLi1af54162021-10-06 15:25:57 +0100386/** Policy to handle integer overflow
387 * @note: This is ignored by floating point operations where the overflow behavior adheres to the IEEE-754 standard
388 * which states that in case of overflow ±infinity is returned for the round-to-nearest modes (and follows the
389 * rounding rules for the directed rounding modes) by default.
390 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100391enum class ConvertPolicy
392{
393 WRAP, /**< Wrap around */
394 SATURATE /**< Saturate */
395};
396
397/** Interpolation method */
398enum class InterpolationPolicy
399{
400 NEAREST_NEIGHBOR, /**< Output values are defined to match the source pixel whose center is nearest to the sample position */
401 BILINEAR, /**< Output values are defined by bilinear interpolation between the pixels */
402 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 */
403};
404
405/** Bilinear Interpolation method used by LKTracker */
406enum class BilinearInterpolation
407{
Alex Gildayc357c472018-03-21 13:54:09 +0000408 BILINEAR_OLD_NEW, /**< Old-new method */
409 BILINEAR_SCHARR /**< Scharr method */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100410};
411
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100412/** Rectangle type */
413struct Rectangle
414{
415 uint16_t x; /**< Top-left x coordinate */
416 uint16_t y; /**< Top-left y coordinate */
417 uint16_t width; /**< Width of the rectangle */
418 uint16_t height; /**< Height of the rectangle */
419};
420
421/** Coordinate type */
422struct Coordinates2D
423{
424 int32_t x; /**< X coordinates */
425 int32_t y; /**< Y coordinates */
426};
427
428/** Coordinate type */
429struct Coordinates3D
430{
431 uint32_t x; /**< X coordinates */
432 uint32_t y; /**< Y coordinates */
433 uint32_t z; /**< Z coordinates */
434};
435
Giuseppe Rossinid7647d42018-07-17 18:13:13 +0100436/** Padding information as a pair of unsigned int start/end */
437using PaddingInfo = std::pair<uint32_t, uint32_t>;
438
439/** List of padding information */
440using PaddingList = std::vector<PaddingInfo>;
441
giuros013175fcf2018-11-21 09:59:17 +0000442/** Information to produce a tiled version of a Tensor */
443using Multiples = std::vector<uint32_t>;
444
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100445/** Available channels */
446enum class Channel
447{
448 UNKNOWN, /** Unknown channel format */
449 C0, /**< First channel (used by formats with unknown channel types). */
450 C1, /**< Second channel (used by formats with unknown channel types). */
451 C2, /**< Third channel (used by formats with unknown channel types). */
452 C3, /**< Fourth channel (used by formats with unknown channel types). */
453 R, /**< Red channel. */
454 G, /**< Green channel. */
455 B, /**< Blue channel. */
456 A, /**< Alpha channel. */
457 Y, /**< Luma channel. */
458 U, /**< Cb/U channel. */
459 V /**< Cr/V/Value channel. */
460};
461
Georgios Pinitasd9769582017-08-03 10:19:40 +0100462/** Available reduction operations */
463enum class ReductionOperation
464{
Michalis Spyrou7930db42018-11-22 17:36:28 +0000465 ARG_IDX_MAX, /**< Index of the max value */
Manuel Bottinib412fab2018-12-10 17:40:23 +0000466 ARG_IDX_MIN, /**< Index of the min value */
467 MEAN_SUM, /**< Mean of sum */
468 PROD, /**< Product */
469 SUM_SQUARE, /**< Sum of squares */
Usama Arifa4a08ad2019-05-20 12:38:33 +0100470 SUM, /**< Sum */
471 MIN, /**< Min */
Usama Arif28f0dd92019-05-20 13:44:34 +0100472 MAX, /**< Max */
Georgios Pinitasd9769582017-08-03 10:19:40 +0100473};
474
giuros01164a2722018-11-20 18:34:46 +0000475/** Available element-wise operations */
476enum class ArithmeticOperation
477{
478 ADD, /**< (x + y) */
479 SUB, /**< (x - y) */
480 DIV, /**< (x / y) */
481 MIN, /**< Min(x, y) */
482 MAX, /**< Max(x, y) */
483 SQUARED_DIFF, /**< (x - y)^2 */
Usama Arif81e671e2019-05-13 13:33:14 +0100484 POWER, /**< x ^ y */
giuros011e6e1b82019-05-14 16:12:53 +0100485 PRELU, /**< y*x if x < 0, x otherwise */
giuros01164a2722018-11-20 18:34:46 +0000486};
487
Michalis Spyroue9362622018-11-23 17:41:37 +0000488/** Available element wise unary operations */
489enum class ElementWiseUnary
490{
Sang-Hoon Park75eea332020-11-13 13:44:13 +0000491 RSQRT, /**< Reverse square root */
492 EXP, /**< Exponential */
493 NEG, /**< Negate */
494 LOG, /**< Natural Logarithm */
495 ABS, /**< Absolute value */
496 SIN, /**< Sine */
497 ROUND, /**< Round */
498 LOGICAL_NOT, /**< Logical Not */
Michalis Spyroue9362622018-11-23 17:41:37 +0000499};
500
Manuel Bottini63bb7ca2020-12-02 13:22:14 +0000501/** Available bitwise operations */
502enum class BitwiseOperation
503{
504 AND, /**< Bitwise AND operation */
505 NOT, /**< Bitwise NOT operation */
506 OR, /**< Bitwise OR operation */
507 XOR, /**< Bitwise XOR operation */
508};
509
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100510/** The normalization type used for the normalization layer */
511enum class NormType
512{
513 IN_MAP_1D, /**< Normalization applied within the same map in 1D region */
514 IN_MAP_2D, /**< Normalization applied within the same map in 2D region */
515 CROSS_MAP /**< Normalization applied cross maps */
516};
517
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100518/** Detection window used for the object detection. The detection window keeps the following information:
519 *
520 * -# Geometry of the rectangular window (x/y of top-left corner and width/height)
521 * -# Index of the class used for evaluating which class the detection window belongs to
522 * -# Confidence value (score) obtained with the classifier
523 */
524struct DetectionWindow
525{
526 uint16_t x{ 0 }; /**< Top-left x coordinate */
527 uint16_t y{ 0 }; /**< Top-left y coordinate */
528 uint16_t width{ 0 }; /**< Width of the detection window */
529 uint16_t height{ 0 }; /**< Height of the detection window */
530 uint16_t idx_class{ 0 }; /**< Index of the class */
531 float score{ 0.f }; /**< Confidence value for the detection window */
532};
533
534/** Dimension rounding type when down-scaling on CNNs
535 * @note Used in pooling and convolution layer
536 */
537enum class DimensionRoundingType
538{
539 FLOOR, /**< Floor rounding */
540 CEIL /**< Ceil rounding */
541};
542
543/** Available pooling types */
544enum class PoolingType
545{
546 MAX, /**< Max Pooling */
Georgios Pinitascdf51452017-08-31 14:21:36 +0100547 AVG, /**< Average Pooling */
548 L2 /**< L2 Pooling */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100549};
550
Michalis Spyrou2709d612018-09-19 09:46:47 +0100551/** Available non maxima suppression types */
552enum class NMSType
553{
554 LINEAR, /**< Linear NMS */
555 GAUSSIAN, /**< Gaussian NMS */
556 ORIGINAL /**< Original NMS */
557};
558
559/** BoxWithNonMaximaSuppressionLimit Information class */
560class BoxNMSLimitInfo final
561{
562public:
563 /** Constructor
564 *
565 * @param[in] score_thresh (Optional) Score threshold.
566 * @param[in] nms (Optional) NMS value
567 * @param[in] detections (Optional) Number of detections
568 * @param[in] soft_nms_enabled (Optional) Enable SoftNMS
569 * @param[in] soft_nms_method (Optional) Soft NMS method
570 * @param[in] soft_nms_sigma (Optional) Soft NMS sigma value
571 * @param[in] soft_nms_min_score_thres (Optional) Soft NMS minimum score threshold
Manuel Bottini5209be52019-02-13 16:34:56 +0000572 * @param[in] suppress_size (Optional) Filter out boxes based on their size. Defaults to false
573 * @param[in] min_size (Optional) Smaller boxes than min_size will be filtered out. Defaults to 1
574 * @param[in] im_width (Optional) Boxes whose centers (on the x axis) is beyond im_width will be filtered. Defaults to 1
575 * @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 +0100576 */
577 BoxNMSLimitInfo(float score_thresh = 0.05f, float nms = 0.3f,
578 int detections = 100, bool soft_nms_enabled = false,
579 NMSType soft_nms_method = NMSType::LINEAR,
Manuel Bottini5209be52019-02-13 16:34:56 +0000580 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 +0100581 : _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 +0000582 _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 +0100583 {
584 }
585 /** Get the score threshold */
586 float score_thresh() const
587 {
588 return _score_thresh;
589 }
590 /** Get the NMS */
591 float nms() const
592 {
593 return _nms;
594 }
595 /** Get the number of detections */
596 int detections_per_im() const
597 {
598 return _detections_per_im;
599 }
600 /** Check if soft NMS is enabled */
601 bool soft_nms_enabled() const
602 {
603 return _soft_nms_enabled;
604 }
605 /** Get soft NMS method */
606 NMSType soft_nms_method() const
607 {
608 return _soft_nms_method;
609 }
610 /** Get soft NMS sigma */
611 float soft_nms_sigma() const
612 {
613 return _soft_nms_sigma;
614 }
615 /** Get soft nms min score threshold */
616 float soft_nms_min_score_thres() const
617 {
618 return _soft_nms_min_score_thres;
619 }
Manuel Bottini5209be52019-02-13 16:34:56 +0000620 /** Get if NMS will suppress boxes based on their size/position */
621 bool suppress_size() const
622 {
623 return _suppress_size;
624 }
625 /** Get size suppression threshold */
626 float min_size() const
627 {
628 return _min_size;
629 }
630 /** Get image width (NMS may suppress boxes whose center sits beyond the image width) */
631 float im_width() const
632 {
633 return _im_width;
634 }
635 /** Get image height (NMS may suppress boxes whose center sits beyond the image height) */
636 float im_height() const
637 {
638 return _im_height;
639 }
Michalis Spyrou2709d612018-09-19 09:46:47 +0100640
641private:
642 float _score_thresh;
643 float _nms;
644 int _detections_per_im;
645 bool _soft_nms_enabled;
646 NMSType _soft_nms_method;
647 float _soft_nms_sigma;
648 float _soft_nms_min_score_thres;
Manuel Bottini5209be52019-02-13 16:34:56 +0000649 bool _suppress_size;
650 float _min_size;
651 float _im_width;
652 float _im_height;
Michalis Spyrou2709d612018-09-19 09:46:47 +0100653};
654
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100655/** Padding and stride information class */
656class PadStrideInfo
657{
658public:
659 /** Constructor
660 *
661 * @param[in] stride_x (Optional) Stride, in elements, across x. Defaults to 1.
662 * @param[in] stride_y (Optional) Stride, in elements, across y. Defaults to 1.
663 * @param[in] pad_x (Optional) Padding, in elements, across x. Defaults to 0.
664 * @param[in] pad_y (Optional) Padding, in elements, across y. Defaults to 0.
665 * @param[in] round (Optional) Dimensions rounding. Defaults to @ref FLOOR.
666 */
667 PadStrideInfo(unsigned int stride_x = 1, unsigned int stride_y = 1,
668 unsigned int pad_x = 0, unsigned int pad_y = 0,
669 DimensionRoundingType round = DimensionRoundingType::FLOOR)
670 : _stride(std::make_pair(stride_x, stride_y)),
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100671 _pad_left(pad_x),
672 _pad_top(pad_y),
673 _pad_right(pad_x),
674 _pad_bottom(pad_y),
675 _round_type(round)
676 {
677 }
678 /** Constructor
679 *
680 * @param[in] stride_x Stride, in elements, across x.
681 * @param[in] stride_y Stride, in elements, across y.
682 * @param[in] pad_left Padding across x on the left, in elements.
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100683 * @param[in] pad_right Padding across x on the right, in elements.
Freddie Liardetded36632021-09-03 15:08:23 +0100684 * @param[in] pad_top Padding across y on the top, in elements.
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100685 * @param[in] pad_bottom Padding across y on the bottom, in elements.
686 * @param[in] round Dimensions rounding.
687 */
688 PadStrideInfo(unsigned int stride_x, unsigned int stride_y,
689 unsigned int pad_left, unsigned int pad_right,
690 unsigned int pad_top, unsigned int pad_bottom,
691 DimensionRoundingType round)
692 : _stride(std::make_pair(stride_x, stride_y)),
693 _pad_left(pad_left),
694 _pad_top(pad_top),
695 _pad_right(pad_right),
696 _pad_bottom(pad_bottom),
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100697 _round_type(round)
698 {
699 }
Alex Gildayc357c472018-03-21 13:54:09 +0000700 /** Get the stride.
701 *
702 * @return a pair: stride x, stride y.
703 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100704 std::pair<unsigned int, unsigned int> stride() const
705 {
706 return _stride;
707 }
Alex Gildayc357c472018-03-21 13:54:09 +0000708 /** Check whether the padding is symmetric.
709 *
710 * @return True if the padding is symmetric.
711 */
Anthony Barbier21f67d62018-02-16 15:17:48 +0000712 bool padding_is_symmetric() const
713 {
714 return (_pad_left == _pad_right) && (_pad_top == _pad_bottom);
715 }
Alex Gildayc357c472018-03-21 13:54:09 +0000716 /** Get the padding.
717 *
718 * @note This should only be used when the padding is symmetric.
719 *
720 * @return a pair: padding left/right, padding top/bottom
721 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100722 std::pair<unsigned int, unsigned int> pad() const
723 {
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100724 //this accessor should be used only when padding is symmetric
Anthony Barbier21f67d62018-02-16 15:17:48 +0000725 ARM_COMPUTE_ERROR_ON(!padding_is_symmetric());
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100726 return std::make_pair(_pad_left, _pad_top);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100727 }
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100728
Alex Gildayc357c472018-03-21 13:54:09 +0000729 /** Get the left padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100730 unsigned int pad_left() const
731 {
732 return _pad_left;
733 }
Alex Gildayc357c472018-03-21 13:54:09 +0000734 /** Get the right padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100735 unsigned int pad_right() const
736 {
737 return _pad_right;
738 }
Alex Gildayc357c472018-03-21 13:54:09 +0000739 /** Get the top padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100740 unsigned int pad_top() const
741 {
742 return _pad_top;
743 }
Alex Gildayc357c472018-03-21 13:54:09 +0000744 /** Get the bottom padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100745 unsigned int pad_bottom() const
746 {
747 return _pad_bottom;
748 }
749
Alex Gildayc357c472018-03-21 13:54:09 +0000750 /** Get the rounding type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100751 DimensionRoundingType round() const
752 {
753 return _round_type;
754 }
755
Alex Gildayc357c472018-03-21 13:54:09 +0000756 /** Check whether this has any padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100757 bool has_padding() const
758 {
759 return (_pad_left != 0 || _pad_top != 0 || _pad_right != 0 || _pad_bottom != 0);
760 }
761
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100762private:
763 std::pair<unsigned int, unsigned int> _stride;
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100764 unsigned int _pad_left;
765 unsigned int _pad_top;
766 unsigned int _pad_right;
767 unsigned int _pad_bottom;
768
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100769 DimensionRoundingType _round_type;
770};
771
Adnan AlSinane4563a02021-09-01 15:32:03 +0100772/** Padding information for 3D operations like Conv3d */
773struct Padding3D
774{
Giorgio Arenac9fe9fc2021-10-06 12:54:29 +0100775 Padding3D()
776 {
777 }
778
779 Padding3D(size_t pad_x, size_t pad_y, size_t pad_z)
780 : left(pad_x), right(pad_x), top(pad_y), bottom(pad_y), front(pad_z), back(pad_z)
781 {
782 }
783
784 Padding3D(size_t left, size_t right, size_t top, size_t bottom, size_t front, size_t back)
785 : left(left), right(right), top(top), bottom(bottom), front(front), back(back)
786 {
787 }
788
Adnan AlSinane4563a02021-09-01 15:32:03 +0100789 size_t left = { 0 }; /**< Padding across the width dimenstion on the left, in elements. */
790 size_t right = { 0 }; /**< Padding across the width dimenstion on the right, in elements. */
791 size_t top = { 0 }; /**< Padding across the height dimenstion on the top, in elements. */
792 size_t bottom = { 0 }; /**< Padding across the height dimenstion on the bottom, in elements. */
793 size_t front = { 0 }; /**< Padding across the depth dimenstion on the front, in elements. */
794 size_t back = { 0 }; /**< Padding across the depth dimenstion on the back, in elements. */
795};
796
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100797/** PriorBox layer info */
798class PriorBoxLayerInfo final
799{
800public:
801 /** Default Constructor */
802 PriorBoxLayerInfo()
803 : _min_sizes(),
804 _variances(),
805 _offset(),
806 _flip(true),
807 _clip(false),
808 _max_sizes(),
809 _aspect_ratios(),
810 _img_size(),
811 _steps()
812 {
813 }
814 /** Constructor
815 *
816 * @param[in] min_sizes Min sizes vector.
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100817 * @param[in] variances Variances vector.
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100818 * @param[in] offset Offset value.
819 * @param[in] flip (Optional) Flip the aspect ratios.
820 * @param[in] clip (Optional) Clip coordinates so that they're within [0,1].
821 * @param[in] max_sizes (Optional) Max sizes vector.
822 * @param[in] aspect_ratios (Optional) Aspect ratios of the boxes.
823 * @param[in] img_size (Optional) Image size.
824 * @param[in] steps (Optional) Step values.
825 */
826 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 +0000827 const std::vector<float> &max_sizes = {}, const std::vector<float> &aspect_ratios = {},
828 const Coordinates2D &img_size = Coordinates2D{ 0, 0 }, const std::array<float, 2> &steps = { { 0.f, 0.f } })
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100829 : _min_sizes(min_sizes),
830 _variances(variances),
831 _offset(offset),
832 _flip(flip),
833 _clip(clip),
834 _max_sizes(max_sizes),
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100835 _aspect_ratios(),
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100836 _img_size(img_size),
837 _steps(steps)
838 {
839 _aspect_ratios.push_back(1.);
840 for(unsigned int i = 0; i < aspect_ratios.size(); ++i)
841 {
842 float ar = aspect_ratios[i];
843 bool already_exist = false;
844 for(auto ar_new : _aspect_ratios)
845 {
846 if(fabs(ar - ar_new) < 1e-6)
847 {
848 already_exist = true;
849 break;
850 }
851 }
852 if(!already_exist)
853 {
854 _aspect_ratios.push_back(ar);
855 if(flip)
856 {
857 _aspect_ratios.push_back(1.f / ar);
858 }
859 }
860 }
861 }
862 /** Get min sizes. */
863 std::vector<float> min_sizes() const
864 {
865 return _min_sizes;
866 }
867 /** Get min variances. */
868 std::vector<float> variances() const
869 {
870 return _variances;
871 }
872 /** Get the step coordinates */
873 std::array<float, 2> steps() const
874 {
875 return _steps;
876 }
877 /** Get the image size coordinates */
878 Coordinates2D img_size() const
879 {
880 return _img_size;
881 }
882 /** Get the offset */
883 float offset() const
884 {
885 return _offset;
886 }
887 /** Get the flip value */
888 bool flip() const
889 {
890 return _flip;
891 }
892 /** Get the clip value */
893 bool clip() const
894 {
895 return _clip;
896 }
897 /** Get max sizes. */
898 std::vector<float> max_sizes() const
899 {
900 return _max_sizes;
901 }
902 /** Get aspect ratios. */
903 std::vector<float> aspect_ratios() const
904 {
905 return _aspect_ratios;
906 }
907
908private:
909 std::vector<float> _min_sizes;
910 std::vector<float> _variances;
911 float _offset;
912 bool _flip;
913 bool _clip;
914 std::vector<float> _max_sizes;
915 std::vector<float> _aspect_ratios;
916 Coordinates2D _img_size;
917 std::array<float, 2> _steps;
918};
919
Isabella Gottardia7acb3c2019-01-08 13:48:44 +0000920// Bounding Box [xmin, ymin, xmax, ymax]
921using BBox = std::array<float, 4>;
922// LabelBBox used for map label and bounding box
923using LabelBBox = std::map<int, std::vector<BBox>>;
924
Isabella Gottardi05e56442018-11-16 11:26:52 +0000925/** Available Detection Output code types */
926enum class DetectionOutputLayerCodeType
927{
928 CORNER, /**< Use box corners */
929 CENTER_SIZE, /**< Use box centers and size */
930 CORNER_SIZE, /**< Use box centers and size */
931 TF_CENTER /**< Use box centers and size but flip x and y co-ordinates */
932};
933
934/** Detection Output layer info */
935class DetectionOutputLayerInfo final
936{
937public:
938 /** Default Constructor */
939 DetectionOutputLayerInfo()
940 : _num_classes(),
941 _share_location(),
942 _code_type(DetectionOutputLayerCodeType::CORNER),
943 _keep_top_k(),
944 _nms_threshold(),
945 _top_k(),
946 _background_label_id(),
947 _confidence_threshold(),
948 _variance_encoded_in_target(false),
949 _eta(),
950 _num_loc_classes()
951 {
952 _num_loc_classes = _share_location ? 1 : _num_classes;
953 }
954 /** Constructor
955 *
956 * @param[in] num_classes Number of classes to be predicted.
957 * @param[in] share_location If true, bounding box are shared among different classes.
958 * @param[in] code_type Type of coding method for bbox.
959 * @param[in] keep_top_k Number of total bounding boxes to be kept per image after NMS step.
960 * @param[in] nms_threshold Threshold to be used in NMS.
961 * @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.
962 * @param[in] background_label_id (Optional) Background label ID. If there is no background class, set it as -1.
963 * @param[in] confidence_threshold (Optional) Only consider detections whose confidences are larger than a threshold. Default set to -FLT_MAX.
964 * @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.
965 * @param[in] eta (Optional) Eta.
966 */
967 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,
968 float confidence_threshold = std::numeric_limits<float>::lowest(), bool variance_encoded_in_target = false, float eta = 1)
969 : _num_classes(num_classes),
970 _share_location(share_location),
971 _code_type(code_type),
972 _keep_top_k(keep_top_k),
973 _nms_threshold(nms_threshold),
974 _top_k(top_k),
975 _background_label_id(background_label_id),
976 _confidence_threshold(confidence_threshold),
977 _variance_encoded_in_target(variance_encoded_in_target),
978 _eta(eta),
979 _num_loc_classes()
980 {
981 _num_loc_classes = _share_location ? 1 : _num_classes;
982 }
983 /** Get num classes. */
984 int num_classes() const
985 {
986 return _num_classes;
987 }
988 /** Get share location. */
989 bool share_location() const
990 {
991 return _share_location;
992 }
993 /** Get detection output code type. */
994 DetectionOutputLayerCodeType code_type() const
995 {
996 return _code_type;
997 }
998 /** Get if variance encoded in target. */
999 bool variance_encoded_in_target() const
1000 {
1001 return _variance_encoded_in_target;
1002 }
1003 /** Get the number of total bounding boxes to be kept per image. */
1004 int keep_top_k() const
1005 {
1006 return _keep_top_k;
1007 }
1008 /** Get nms threshold. */
1009 float nms_threshold() const
1010 {
1011 return _nms_threshold;
1012 }
1013 /** Get eta. */
1014 float eta() const
1015 {
1016 return _eta;
1017 }
1018 /** Get background label ID. */
1019 int background_label_id() const
1020 {
1021 return _background_label_id;
1022 }
1023 /** Get confidence threshold. */
1024 float confidence_threshold() const
1025 {
1026 return _confidence_threshold;
1027 }
1028 /** Get top K. */
1029 int top_k() const
1030 {
1031 return _top_k;
1032 }
1033 /** Get number of location classes. */
1034 int num_loc_classes() const
1035 {
1036 return _num_loc_classes;
1037 }
1038
1039private:
1040 int _num_classes;
1041 bool _share_location;
1042 DetectionOutputLayerCodeType _code_type;
1043 int _keep_top_k;
1044 float _nms_threshold;
1045 int _top_k;
1046 int _background_label_id;
1047 float _confidence_threshold;
1048 bool _variance_encoded_in_target;
1049 float _eta;
1050 int _num_loc_classes;
1051};
1052
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001053/** Detection Output layer info */
1054class DetectionPostProcessLayerInfo final
1055{
1056public:
1057 /** Default Constructor */
1058 DetectionPostProcessLayerInfo()
1059 : _max_detections(),
1060 _max_classes_per_detection(),
1061 _nms_score_threshold(),
1062 _iou_threshold(),
1063 _num_classes(),
1064 _scales_values(),
1065 _use_regular_nms(),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001066 _detection_per_class(),
1067 _dequantize_scores()
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001068 {
1069 }
1070 /** Constructor
1071 *
1072 * @param[in] max_detections Number of total detection.
1073 * @param[in] max_classes_per_detection Number of total classes to be kept after NMS step. Used in the Fast Non-Max-Suppression
1074 * @param[in] nms_score_threshold Threshold to be used in NMS
1075 * @param[in] iou_threshold Threshold to be used during the intersection over union.
1076 * @param[in] num_classes Number of classes.
1077 * @param[in] scales_values Scales values used for decode center size boxes.
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001078 * @param[in] use_regular_nms (Optional) Boolean to determinate if use regular or fast nms. Defaults to false.
1079 * @param[in] detection_per_class (Optional) Number of detection per class. Used in the Regular Non-Max-Suppression. Defaults to 100.
1080 * @param[in] dequantize_scores (Optional) If the scores need to be dequantized. Defaults to true.
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001081 */
1082 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 +01001083 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 +00001084 : _max_detections(max_detections),
1085 _max_classes_per_detection(max_classes_per_detection),
1086 _nms_score_threshold(nms_score_threshold),
1087 _iou_threshold(iou_threshold),
1088 _num_classes(num_classes),
1089 _scales_values(scales_values),
1090 _use_regular_nms(use_regular_nms),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001091 _detection_per_class(detection_per_class),
1092 _dequantize_scores(dequantize_scores)
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001093 {
1094 }
1095 /** Get max detections. */
1096 unsigned int max_detections() const
1097 {
1098 return _max_detections;
1099 }
1100 /** Get max_classes per detection. Used in the Fast Non-Max-Suppression.*/
1101 unsigned int max_classes_per_detection() const
1102 {
1103 return _max_classes_per_detection;
1104 }
1105 /** Get detection per class. Used in the Regular Non-Max-Suppression */
1106 unsigned int detection_per_class() const
1107 {
1108 return _detection_per_class;
1109 }
1110 /** Get nms threshold. */
1111 float nms_score_threshold() const
1112 {
1113 return _nms_score_threshold;
1114 }
1115 /** Get intersection over union threshold. */
1116 float iou_threshold() const
1117 {
1118 return _iou_threshold;
1119 }
1120 /** Get num classes. */
1121 unsigned int num_classes() const
1122 {
1123 return _num_classes;
1124 }
1125 /** Get if use regular nms. */
1126 bool use_regular_nms() const
1127 {
1128 return _use_regular_nms;
1129 }
1130 /** Get y scale value. */
1131 float scale_value_y() const
1132 {
1133 // Saved as [y,x,h,w]
1134 return _scales_values[0];
1135 }
1136 /** Get x scale value. */
1137 float scale_value_x() const
1138 {
1139 // Saved as [y,x,h,w]
1140 return _scales_values[1];
1141 }
1142 /** Get h scale value. */
1143 float scale_value_h() const
1144 {
1145 // Saved as [y,x,h,w]
1146 return _scales_values[2];
1147 }
1148 /** Get w scale value. */
1149 float scale_value_w() const
1150 {
1151 // Saved as [y,x,h,w]
1152 return _scales_values[3];
1153 }
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001154 /** Get dequantize_scores value. */
1155 bool dequantize_scores() const
1156 {
1157 return _dequantize_scores;
1158 }
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001159
1160private:
1161 unsigned int _max_detections;
1162 unsigned int _max_classes_per_detection;
1163 float _nms_score_threshold;
1164 float _iou_threshold;
1165 unsigned int _num_classes;
1166 std::array<float, 4> _scales_values;
1167 bool _use_regular_nms;
1168 unsigned int _detection_per_class;
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001169 bool _dequantize_scores;
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001170};
1171
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001172/** Pooling Layer Information struct*/
1173struct PoolingLayerInfo
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001174{
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001175 /** Default Constructor */
1176 PoolingLayerInfo()
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001177 : pool_type(PoolingType::MAX),
1178 pool_size(Size2D()),
1179 data_layout(DataLayout::UNKNOWN),
1180 pad_stride_info(PadStrideInfo()),
1181 exclude_padding(false),
1182 is_global_pooling(false),
1183 fp_mixed_precision(false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001184 {
1185 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001186 /** Constructor
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001187 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001188 * @param[in] pool_type Pooling type @ref PoolingType.
1189 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001190 * @param[in] data_layout Data layout used by the layer @ref DataLayout
1191 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1192 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1193 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1194 * Defaults to false;
1195 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1196 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001197 explicit PoolingLayerInfo(PoolingType pool_type,
1198 unsigned int pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001199 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001200 PadStrideInfo pad_stride_info = PadStrideInfo(),
1201 bool exclude_padding = false,
1202 bool fp_mixed_precision = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001203 : pool_type(pool_type),
1204 pool_size(Size2D(pool_size, pool_size)),
1205 data_layout(data_layout),
1206 pad_stride_info(pad_stride_info),
1207 exclude_padding(exclude_padding),
1208 is_global_pooling(false),
1209 fp_mixed_precision(fp_mixed_precision)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001210 {
1211 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001212
1213 /** Constructor
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001214 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001215 * @param[in] pool_type Pooling type @ref PoolingType.
1216 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001217 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001218 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1219 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1220 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1221 * Defaults to false;
1222 * @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 +00001223 */
1224 explicit PoolingLayerInfo(PoolingType pool_type,
1225 Size2D pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001226 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001227 PadStrideInfo pad_stride_info = PadStrideInfo(),
1228 bool exclude_padding = false,
1229 bool fp_mixed_precision = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001230 : pool_type(pool_type),
1231 pool_size(pool_size),
1232 data_layout(data_layout),
1233 pad_stride_info(pad_stride_info),
1234 exclude_padding(exclude_padding),
1235 is_global_pooling(false),
1236 fp_mixed_precision(fp_mixed_precision)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001237 {
1238 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001239
1240 /** Constructor
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001241 *
1242 * @note This constructor is used for global pooling
1243 *
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001244 * @param[in] pool_type Pooling type @ref PoolingType.
1245 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001246 */
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001247 explicit PoolingLayerInfo(PoolingType pool_type, DataLayout data_layout)
1248 : pool_type(pool_type),
1249 pool_size(Size2D()),
1250 data_layout(data_layout),
1251 pad_stride_info(PadStrideInfo(1, 1, 0, 0)),
1252 exclude_padding(false),
1253 is_global_pooling(true),
1254 fp_mixed_precision(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001255 {
1256 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001257
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001258 PoolingType pool_type;
1259 Size2D pool_size;
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001260 DataLayout data_layout;
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001261 PadStrideInfo pad_stride_info;
1262 bool exclude_padding;
1263 bool is_global_pooling;
1264 bool fp_mixed_precision;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001265};
1266
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001267/** ROI Pooling Layer Information class */
giuros0118870812018-09-13 09:31:40 +01001268class ROIPoolingLayerInfo final
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001269{
1270public:
giuros0118870812018-09-13 09:31:40 +01001271 /** Constructor
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001272 *
giuros0118870812018-09-13 09:31:40 +01001273 * @param[in] pooled_width Pooled width of the layer.
1274 * @param[in] pooled_height Pooled height of the layer.
1275 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
1276 * @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 +01001277 */
giuros0118870812018-09-13 09:31:40 +01001278 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale, unsigned int sampling_ratio = 0)
1279 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale), _sampling_ratio(sampling_ratio)
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001280 {
1281 }
Alex Gildayc357c472018-03-21 13:54:09 +00001282 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001283 unsigned int pooled_width() const
1284 {
1285 return _pooled_width;
1286 }
Alex Gildayc357c472018-03-21 13:54:09 +00001287 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001288 unsigned int pooled_height() const
1289 {
1290 return _pooled_height;
1291 }
Alex Gildayc357c472018-03-21 13:54:09 +00001292 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001293 float spatial_scale() const
1294 {
1295 return _spatial_scale;
1296 }
giuros0118870812018-09-13 09:31:40 +01001297 /** Get sampling ratio */
1298 unsigned int sampling_ratio() const
1299 {
1300 return _sampling_ratio;
1301 }
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001302
1303private:
1304 unsigned int _pooled_width;
1305 unsigned int _pooled_height;
1306 float _spatial_scale;
giuros0118870812018-09-13 09:31:40 +01001307 unsigned int _sampling_ratio;
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001308};
1309
Manuel Bottini5209be52019-02-13 16:34:56 +00001310/** Generate Proposals Information class */
1311class GenerateProposalsInfo
1312{
1313public:
1314 /** Constructor
1315 *
1316 * @param[in] im_width Width of the original image
1317 * @param[in] im_height Height of the original image
1318 * @param[in] im_scale Scale applied to the original image
1319 * @param[in] spatial_scale (Optional)Scale applied to the feature map. Defaults to 1.0
1320 * @param[in] pre_nms_topN (Optional)Number of the best scores to be selected from the transformations. Defaults to 6000.
1321 * @param[in] post_nms_topN (Optional)Number of the best scores to be selected from the NMS operation. Defaults to 300.
1322 * @param[in] nms_thres (Optional)NMS overlap threshold. Defaults to 0.7.
1323 * @param[in] min_size (Optional)Size used to validate the anchors produced. Defaults to 16.
1324 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region of interest). Defaults to 4.
1325 */
1326 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,
1327 size_t values_per_roi = 4)
1328 : _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),
1329 _min_size(min_size), _values_per_roi(values_per_roi)
1330 {
1331 }
1332
1333 /* Get the original height */
1334 float im_height() const
1335 {
1336 return _im_height;
1337 }
1338 /* Get the original width */
1339 float im_width() const
1340 {
1341 return _im_width;
1342 }
1343 /* Get the image scale */
1344 float im_scale() const
1345 {
1346 return _im_scale;
1347 }
1348 /* Get the value of how many best scores to select (before NMS) */
1349 int pre_nms_topN() const
1350 {
1351 return _pre_nms_topN;
1352 }
1353 /* Get the value of how many best scores to select (after NMS) */
1354 int post_nms_topN() const
1355 {
1356 return _post_nms_topN;
1357 }
1358 /* Get the NMS overlap threshold */
1359 float nms_thres() const
1360 {
1361 return _nms_thres;
1362 }
1363 /* Get the minimal size */
1364 float min_size() const
1365 {
1366 return _min_size;
1367 }
1368 /* Get the spatial scale to be applied to the feature maps */
1369 float spatial_scale() const
1370 {
1371 return _spatial_scale;
1372 }
1373 /* Get the values used to represent a ROI(Region of interest)*/
1374 size_t values_per_roi() const
1375 {
1376 return _values_per_roi;
1377 }
1378
1379private:
1380 float _im_height;
1381 float _im_width;
1382 float _im_scale;
1383 float _spatial_scale;
1384 int _pre_nms_topN;
1385 int _post_nms_topN;
1386 float _nms_thres;
1387 float _min_size;
1388 size_t _values_per_roi;
1389};
1390
1391/** ComputeAnchors information class */
1392class ComputeAnchorsInfo
1393{
1394public:
1395 /** Constructor
1396 *
1397 * @param[in] feat_width Feature map width
1398 * @param[in] feat_height Feature map height
1399 * @param[in] spatial_scale Feature map scale
1400 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region Of Interest). Defaults to 4
1401 */
1402 ComputeAnchorsInfo(float feat_width, float feat_height, float spatial_scale, size_t values_per_roi = 4)
1403 : _feat_height(feat_height),
1404 _feat_width(feat_width),
1405 _spatial_scale(spatial_scale),
1406 _values_per_roi(values_per_roi)
1407 {
1408 }
1409
1410 /* Get the height of the feature map */
1411 float feat_height() const
1412 {
1413 return _feat_height;
1414 }
1415
1416 /* Get the width of the feature map */
1417 float feat_width() const
1418 {
1419 return _feat_width;
1420 }
1421
1422 /* Get the scale of the feature map */
1423 float spatial_scale() const
1424 {
1425 return _spatial_scale;
1426 }
1427
1428 /* Get the values used to represent a ROI(Region Of Interest)*/
1429 size_t values_per_roi() const
1430 {
1431 return _values_per_roi;
1432 }
1433
1434private:
1435 float _feat_height;
1436 float _feat_width;
1437 float _spatial_scale;
1438 size_t _values_per_roi;
1439};
1440
giuros01c04a0e82018-10-03 12:44:35 +01001441/** Bounding Box Transform information class */
giuros01d696cb62018-11-16 10:39:59 +00001442class BoundingBoxTransformInfo final
giuros01c04a0e82018-10-03 12:44:35 +01001443{
1444public:
1445 /** Constructor
1446 *
giuros01d696cb62018-11-16 10:39:59 +00001447 * @param[in] img_width Width of the original image
1448 * @param[in] img_height Height, of the original image
1449 * @param[in] scale Scale of the original image
1450 * @param[in] apply_scale (Optional)Re-apply scaling after transforming the boxes. Defaults to false
1451 * @param[in] weights (Optional)Weights [wx, wy, ww, wh] for the deltas. Defaults to all ones
1452 * @param[in] correct_transform_coords (Optional)Correct bounding box transform coordinates. Defaults to false
1453 * @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 +01001454 */
giuros01d696cb62018-11-16 10:39:59 +00001455 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 =
1456 false,
1457 float bbox_xform_clip =
1458 4.135166556742356f)
1459 : _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 +01001460 {
1461 }
1462
1463 std::array<float, 4> weights() const
1464 {
1465 return _weights;
1466 }
1467
1468 float bbox_xform_clip() const
1469 {
1470 return _bbox_xform_clip;
1471 }
1472
1473 float img_height() const
1474 {
1475 return _img_height;
1476 }
1477
1478 float img_width() const
1479 {
1480 return _img_width;
1481 }
1482
1483 float scale() const
1484 {
1485 return _scale;
1486 }
1487
1488 bool apply_scale() const
1489 {
1490 return _apply_scale;
1491 }
1492
giuros01d696cb62018-11-16 10:39:59 +00001493 bool correct_transform_coords() const
1494 {
1495 return _correct_transform_coords;
1496 }
1497
giuros01c04a0e82018-10-03 12:44:35 +01001498private:
1499 float _img_width;
1500 float _img_height;
1501 float _scale;
1502 bool _apply_scale;
giuros01d696cb62018-11-16 10:39:59 +00001503 bool _correct_transform_coords;
giuros01c04a0e82018-10-03 12:44:35 +01001504 std::array<float, 4> _weights;
1505 float _bbox_xform_clip;
1506};
1507
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001508/** Activation Layer Information class */
1509class ActivationLayerInfo
1510{
1511public:
1512 /** Available activation functions */
1513 enum class ActivationFunction
1514 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001515 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
1516 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
1517 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
1518 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
1519 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
Manuel Bottini581c8982019-02-07 10:31:57 +00001520 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 +01001521 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
Georgios Pinitasfb0fdcd2019-08-22 17:10:04 +01001522 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 +01001523 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
1524 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
1525 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
Usama Arif6a98a6e2019-05-10 17:07:27 +01001526 LINEAR, /**< Linear ( \f$ f(x)= ax + b \f$ ) */
morgolock07df3d42020-02-27 11:46:28 +00001527 IDENTITY, /**< Identity ( \f$ f(x)= x \f$ ) */
1528 HARD_SWISH /**< Hard-swish ( \f$ f(x) = (x * relu6(x+3))/6 \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001529 };
1530
Giorgio Arena11674872018-02-07 15:38:12 +00001531 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001532 /** Default Constructor
1533 *
1534 * @param[in] f The activation function to use.
1535 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001536 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1537 * @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 +01001538 */
1539 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001540 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001541 {
1542 }
Alex Gildayc357c472018-03-21 13:54:09 +00001543 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001544 ActivationFunction activation() const
1545 {
1546 return _act;
1547 }
Alex Gildayc357c472018-03-21 13:54:09 +00001548 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001549 float a() const
1550 {
1551 return _a;
1552 }
Alex Gildayc357c472018-03-21 13:54:09 +00001553 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001554 float b() const
1555 {
1556 return _b;
1557 }
Alex Gildayc357c472018-03-21 13:54:09 +00001558 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001559 bool enabled() const
1560 {
1561 return _enabled;
1562 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001563
1564private:
Usama Arif6a98a6e2019-05-10 17:07:27 +01001565 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::IDENTITY };
Giorgio Arena11674872018-02-07 15:38:12 +00001566 float _a = {};
1567 float _b = {};
1568 bool _enabled = { false };
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001569};
1570
Giorgio Arena1856ff72020-02-07 13:46:45 +00001571/** Fully connected layer info */
1572struct FullyConnectedLayerInfo
1573{
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001574 /* Fused-activation parameters */
1575 ActivationLayerInfo activation_info{}; /**< Fused activation to apply after the matrix multiplication. */
1576 /* Information about weights */
1577 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
1578 bool transpose_weights{ true }; /**< Transpose weights if true. */
1579 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
1580 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
cfRodf2c022e2021-11-05 11:29:53 +00001581 bool enable_fast_math{ false }; /**< Enable fast math computation. */
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001582 /* Other parameters */
1583 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 +00001584
1585 /** Sets the weights trained data layout
1586 *
1587 * @param[in] layout Data layout that the weights were trained with
1588 *
1589 * @return Updated object
1590 */
1591 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
1592 {
1593 weights_trained_layout = layout;
1594 return *this;
1595 }
1596 /** Sets the transpose weights flag
1597 *
1598 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
1599 *
1600 * @return Updated object
1601 */
1602 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
1603 {
1604 transpose_weights = should_transpose_weights;
1605 return *this;
1606 }
1607};
1608
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001609/** Normalization Layer Information class */
1610class NormalizationLayerInfo
1611{
1612public:
1613 /** Default Constructor
1614 *
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001615 * @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 +01001616 * @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 +00001617 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1618 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1619 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1620 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1621 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001622 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001623 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1624 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001625 {
1626 }
Alex Gildayc357c472018-03-21 13:54:09 +00001627 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001628 NormType type() const
1629 {
1630 return _type;
1631 }
Alex Gildayc357c472018-03-21 13:54:09 +00001632 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001633 uint32_t norm_size() const
1634 {
1635 return _norm_size;
1636 }
Alex Gildayc357c472018-03-21 13:54:09 +00001637 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001638 float alpha() const
1639 {
1640 return _alpha;
1641 }
Alex Gildayc357c472018-03-21 13:54:09 +00001642 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001643 float beta() const
1644 {
1645 return _beta;
1646 }
Alex Gildayc357c472018-03-21 13:54:09 +00001647 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001648 float kappa() const
1649 {
1650 return _kappa;
1651 }
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001652 /** Get the is_scaled value */
1653 bool is_scaled() const
1654 {
1655 return _is_scaled;
1656 }
Alex Gildayc357c472018-03-21 13:54:09 +00001657 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001658 bool is_cross_map() const
1659 {
1660 return _type == NormType::CROSS_MAP;
1661 }
Alex Gildayc357c472018-03-21 13:54:09 +00001662 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001663 bool is_in_map() const
1664 {
1665 return !is_cross_map();
1666 }
1667 /** Return the scaling factor of the normalization function.
1668 *
1669 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1670 * 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 +01001671 *
1672 * @return The normalization scaling factor.
1673 */
1674 float scale_coeff() const
1675 {
1676 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001677 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001678 }
1679
1680private:
1681 NormType _type;
1682 uint32_t _norm_size;
1683 float _alpha;
1684 float _beta;
1685 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001686 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001687};
1688
thecha012bfadd92020-08-12 17:25:51 +01001689class StridedSliceLayerInfo
1690{
1691public:
1692 /** Default Constructor
1693 *
1694 * @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.
1695 * @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.
1696 * @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.
1697 */
1698 StridedSliceLayerInfo(int32_t begin_mask = 0, int32_t end_mask = 0, int32_t shrink_axis_mask = 0)
1699 : _begin_mask(begin_mask), _end_mask(end_mask), _shrink_axis_mask(shrink_axis_mask)
1700 {
1701 }
1702
1703 /* Get the begin mask value */
1704 int32_t begin_mask() const
1705 {
1706 return _begin_mask;
1707 }
1708
1709 /* Get the end mask value */
1710 int32_t end_mask() const
1711 {
1712 return _end_mask;
1713 }
1714
1715 /* Get the shrink axis mask value */
1716 int32_t shrink_axis_mask() const
1717 {
1718 return _shrink_axis_mask;
1719 }
1720
1721private:
1722 int32_t _begin_mask;
1723 int32_t _end_mask;
1724 int32_t _shrink_axis_mask;
1725};
1726
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001727/** 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 +01001728class WeightsInfo
1729{
1730public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001731 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001732 WeightsInfo()
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001733 : _are_reshaped(false), _kernel_width(0), _kernel_height(0), _num_kernels(0), _retain_internal_weights(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001734 {
1735 }
1736 /** Constructor
1737 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001738 * @param[in] are_reshaped True if the weights have been reshaped
1739 * @param[in] kernel_width Kernel width.
1740 * @param[in] kernel_height Kernel height.
1741 * @param[in] num_kernels Number of convolution kernels.
1742 * @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 +01001743 */
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001744 WeightsInfo(bool are_reshaped, unsigned int kernel_width, unsigned int kernel_height, unsigned int num_kernels, bool retain_internal_weights = false)
1745 : _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 +01001746 {
1747 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001748 /** Flag which specifies if the weights tensor has been reshaped.
1749 *
1750 * @return True if the weights tensors has been reshaped
1751 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001752 bool are_reshaped() const
1753 {
1754 return _are_reshaped;
1755 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001756 /** Return the number of convolution kernels
1757 *
1758 * @return The number of convolution kernels
1759 */
1760 unsigned int num_kernels() const
1761 {
1762 return _num_kernels;
1763 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001764 /** Return the width and height of the kernel
1765 *
1766 * @return The width and height of the kernel
1767 */
1768 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001769 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001770 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001771 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001772 bool retain_internal_weights() const
1773 {
1774 return _retain_internal_weights;
1775 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001776
1777private:
SiCong Liebd8fb42020-08-18 11:03:14 +01001778 bool _are_reshaped;
1779 unsigned int _kernel_width;
1780 unsigned int _kernel_height;
1781 unsigned int _num_kernels;
1782 bool _retain_internal_weights;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001783};
1784
Gian Marco36a0a462018-01-12 10:21:40 +00001785/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
1786 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01001787 * The matrix A can only be reshaped through @ref opencl::kernels::ClGemmReshapeLhsMatrixKernel or @ref cpu::kernels::CpuGemmInterleave4x4Kernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01001788 * 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 +00001789 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01001790 * The matrix B can only be reshaped through @ref opencl::kernels::ClGemmReshapeRhsMatrixKernel or @ref cpu::kernels::CpuGemmTranspose1xWKernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01001791 * 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 +00001792 *
1793 */
1794class GEMMReshapeInfo final
1795{
1796public:
1797 /** Default constructor */
1798 GEMMReshapeInfo()
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001799 : _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 +00001800 {
1801 }
1802 /** Constructor
1803 *
1804 * @param[in] m Number of matrix A rows
1805 * @param[in] n Number of matrix B columns
1806 * @param[in] k Number of matrix A columns or matrix B rows
1807 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
1808 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001809 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
1810 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001811 * @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 +01001812 * to perform 1x1 convolutions with the NHWC data layout)
1813 * @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 +00001814 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001815 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 +01001816 : _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 +01001817 _reinterpret_input_as_3d(reinterpret_input_as_3d), _broadcast_bias(broadcast_bias)
Gian Marco36a0a462018-01-12 10:21:40 +00001818 {
1819 }
1820 /** Number of matrix A rows
1821 *
1822 * @return the number of matrix A rows
1823 */
1824 int m() const
1825 {
1826 return _m;
1827 }
1828 /** Number of matrix B columns
1829 *
1830 * @return the number of matrix B columns
1831 */
1832 int n() const
1833 {
1834 return _n;
1835 }
1836 /** Number of matrix A columns or matrix B rows
1837 *
1838 * @return the number of matrix A columns or matrix B rows
1839 */
1840 int k() const
1841 {
1842 return _k;
1843 }
1844 /** Multiplication factor for the width of the 1xW transposed block
1845 *
1846 * @return the multiplication factor for the width of the 1xW transposed block
1847 */
1848 int mult_transpose1xW_width() const
1849 {
1850 return _mult_transpose1xW_width;
1851 }
1852 /** Multiplication factor for the height of the 4x4 interleaved block
1853 *
1854 * @return the multiplication factor for the height of the 4x4 interleaved block
1855 */
1856 int mult_interleave4x4_height() const
1857 {
1858 return _mult_interleave4x4_height;
1859 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001860 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
1861 *
1862 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
1863 * m = depth_output_gemm3d * output_height
1864 *
1865 * @return the depth of the output tensor to be used with the GEMM3D kernel
1866 */
1867 int depth_output_gemm3d() const
1868 {
1869 return _depth_output_gemm3d;
1870 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001871 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
1872 *
1873 * @return True if the input tensor has to be reinterpreted as 3D tensor
1874 */
1875 bool reinterpret_input_as_3d() const
1876 {
1877 return _reinterpret_input_as_3d;
1878 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001879 /** Flag which specifies whether to broadcast the shape of the bias tensor.
1880 *
1881 * @return True if the shape of the bias tensor is to be broadcasted.
1882 */
1883 bool broadcast_bias() const
1884 {
1885 return _broadcast_bias;
1886 };
Gian Marco36a0a462018-01-12 10:21:40 +00001887
1888private:
SiCong Liebd8fb42020-08-18 11:03:14 +01001889 int _m;
1890 int _n;
1891 int _k;
1892 int _mult_transpose1xW_width;
1893 int _mult_interleave4x4_height;
1894 int _depth_output_gemm3d;
1895 bool _reinterpret_input_as_3d;
1896 bool _broadcast_bias;
Gian Marco36a0a462018-01-12 10:21:40 +00001897};
1898
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +01001899struct ConvolutionInfo
1900{
1901 ConvolutionInfo() = default;
1902 ConvolutionInfo(const PadStrideInfo &pad_stride_info, unsigned int depth_multiplier, const ActivationLayerInfo &act_info, const Size2D &dilation)
1903 : pad_stride_info(pad_stride_info), depth_multiplier(depth_multiplier), act_info(act_info), dilation(dilation)
1904 {
1905 }
1906 PadStrideInfo pad_stride_info{}; /**< Convolution info (Pads, strides,...) */
1907 unsigned int depth_multiplier{ 1 }; /**< Multiplier to apply to input's depth to retrieve the output depth. Defaults to 1 */
1908 ActivationLayerInfo act_info{}; /**< Fused activation to apply after convolution. */
1909 Size2D dilation{ Size2D(1, 1) }; /**< Dilation, in elements, across x and y. Defaults to (1, 1). */
1910};
1911
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001912/** GEMMLowp output stage type */
1913enum class GEMMLowpOutputStageType
1914{
Manuel Bottini959c26d2019-12-02 16:22:35 +00001915 NONE, /**< No quantization */
1916 QUANTIZE_DOWN, /**< Quantize using an integer multiplication */
1917 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize using a fixed point multiplication */
1918 QUANTIZE_DOWN_FLOAT /**< Quantize using a floating point multiplication */
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001919};
1920
1921/** GEMMLowp output stage info */
1922struct GEMMLowpOutputStageInfo
1923{
Giorgio Arena1856ff72020-02-07 13:46:45 +00001924 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
1925 int32_t gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
1926 int32_t gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1927 int32_t gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
1928 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 */
1929 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 */
1930 std::vector<int32_t> gemmlowp_multipliers{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1931 std::vector<int32_t> gemmlowp_shifts{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
Sheri Zhang1b14c752020-03-09 14:29:52 +00001932 float gemmlowp_real_multiplier{ 0 }; /**< GEMMLowp output stage real multiplier used for quantizing to QASYMM8 */
Giorgio Arena1856ff72020-02-07 13:46:45 +00001933 bool is_quantized_per_channel{ false }; /**< GEMMLowp quantized per-channel flag */
1934 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 +01001935};
1936
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00001937/** GEMM LHS (Left Hand Side) matrix information */
1938struct GEMMLHSMatrixInfo
1939{
morgolockaba2f912020-05-05 16:28:19 +01001940 GEMMLHSMatrixInfo() = default;
1941 GEMMLHSMatrixInfo(unsigned int m, unsigned int k, unsigned int v, bool trans, bool inter)
1942 : m0(m), k0(k), v0(v), transpose(trans), interleave(inter)
1943 {
1944 }
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00001945 unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
1946 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1947 unsigned int v0{ 1 }; /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
1948 bool transpose{ true }; /**< True if the (m0xk0) block has to be transposed before been stored */
1949 bool interleave{ true }; /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
1950};
1951
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00001952/** GEMM RHS (Right Hand Side) matrix information */
1953struct GEMMRHSMatrixInfo
1954{
morgolockaba2f912020-05-05 16:28:19 +01001955 GEMMRHSMatrixInfo() = default;
Gian Marco Iodicee3a849a2020-06-10 17:59:30 +01001956 GEMMRHSMatrixInfo(unsigned int n, unsigned int k, unsigned int h, bool trans, bool inter, bool export_to_cl_img)
1957 : n0(n), k0(k), h0(h), transpose(trans), interleave(inter), export_to_cl_image(export_to_cl_img)
morgolockaba2f912020-05-05 16:28:19 +01001958 {
1959 }
Gian Marco Iodicedd717c32020-05-28 10:22:03 +01001960 unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
1961 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1962 unsigned int h0{ 1 }; /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
1963 bool transpose{ true }; /**< True if the (k0xn0) block has to be transposed before been stored */
1964 bool interleave{ true }; /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
1965 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 +00001966};
1967
SiCongLi579ca842021-10-18 09:38:33 +01001968class ITensorInfo;
Gian Marco36a0a462018-01-12 10:21:40 +00001969/** GEMM information class. This class stores the necessary information to compute GEMM functions
1970 *
1971 * This object also contains the information about how matrix A and matrix B have been reshaped
1972 *
1973 */
Chunosov5124be52017-11-22 20:42:13 +07001974class GEMMInfo
1975{
1976public:
1977 /** Default constructor */
Georgios Pinitas37d080f2019-06-21 18:43:12 +01001978 GEMMInfo() noexcept
1979 : _is_a_reshaped(false),
1980 _is_b_reshaped(false),
1981 _reshape_b_only_on_first_run(true),
1982 _depth_output_gemm3d(0),
1983 _reinterpret_input_as_3d(false),
1984 _retain_internal_weights(false),
1985 _gemmlowp_output_stage(),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01001986 _fast_math(false),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01001987 _fp_mixed_precision(false),
1988 _broadcast_bias(false),
ramelg01cbbb0382021-09-17 17:36:57 +01001989 _pretranspose_B(true),
SiCongLi579ca842021-10-18 09:38:33 +01001990 _activation_info(),
1991 _post_ops()
Chunosov5124be52017-11-22 20:42:13 +07001992 {
1993 }
1994 /** Constructor
1995 *
1996 * @param[in] is_a_reshaped True if the matrix A has been reshaped
1997 * @param[in] is_b_reshaped True if the matrix B has been reshaped
1998 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001999 * @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 +00002000 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002001 * @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
2002 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002003 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002004 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002005 * @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 +01002006 * @param[in] fast_math (Optional) Use a data type of shorter width to improve performance
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002007 * @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 +01002008 * @param[in] activation_info (Optional) Activation to apply after the matrix multiplication
SiCongLi579ca842021-10-18 09:38:33 +01002009 * @param[in] post_ops (Optional) A sequence of post operations that are performed after the main operation.
Chunosov5124be52017-11-22 20:42:13 +07002010 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002011 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 +01002012 GEMMLowpOutputStageInfo gemmlowp_output_stage = GEMMLowpOutputStageInfo(), bool fp_mixed_precision = false, bool fast_math = false, bool broadcast_bias = false,
SiCongLi579ca842021-10-18 09:38:33 +01002013 const ActivationLayerInfo &activation_info = ActivationLayerInfo(), const experimental::PostOpList<ITensorInfo *> &post_ops = experimental::PostOpList<ITensorInfo *>()) noexcept
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002014 : _is_a_reshaped(is_a_reshaped),
2015 _is_b_reshaped(is_b_reshaped),
2016 _reshape_b_only_on_first_run(reshape_b_only_on_first_run),
2017 _depth_output_gemm3d(depth_output_gemm3d),
2018 _reinterpret_input_as_3d(reinterpret_input_as_3d),
2019 _retain_internal_weights(retain_internal_weights),
2020 _gemmlowp_output_stage(gemmlowp_output_stage),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002021 _fast_math(fast_math),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002022 _fp_mixed_precision(fp_mixed_precision),
2023 _broadcast_bias(broadcast_bias),
ramelg01cbbb0382021-09-17 17:36:57 +01002024 _pretranspose_B(reshape_b_only_on_first_run),
SiCongLi579ca842021-10-18 09:38:33 +01002025 _activation_info(activation_info),
2026 _post_ops(post_ops)
Chunosov5124be52017-11-22 20:42:13 +07002027 {
2028 }
2029 /** Flag which specifies if the matrix A has been reshaped
2030 *
2031 * @return True if the matrix A has been reshaped
2032 */
2033 bool is_a_reshaped() const
2034 {
2035 return _is_a_reshaped;
2036 };
2037 /** Flag which specifies if the matrix B has been reshaped
2038 *
2039 * @return True if the matrix B has been reshaped
2040 */
2041 bool is_b_reshaped() const
2042 {
2043 return _is_b_reshaped;
2044 };
2045 /** Flag which specifies if the reshape of matrix B should executed only for the first
2046 *
2047 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
2048 *
2049 * @return True if the reshaped of matrix B happens only for the first run
2050 */
2051 bool reshape_b_only_on_first_run() const
2052 {
2053 return _reshape_b_only_on_first_run;
2054 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002055 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002056 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002057 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002058 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002059 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00002060 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002061 return _depth_output_gemm3d;
2062 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002063 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2064 *
2065 * @return True if the input tensor has to be reinterpreted as 3D tensor
2066 */
2067 bool reinterpret_input_as_3d() const
2068 {
2069 return _reinterpret_input_as_3d;
2070 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002071 /** Flag which specifies if the weights tensor has to be retained from previous run
2072 *
2073 * @return True if the weights tensor has to be retained
2074 */
2075 bool retain_internal_weights() const
2076 {
2077 return _retain_internal_weights;
2078 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002079 /** GEMMLowp output stage
2080 *
2081 * @return the GEMMLowp output stage info
2082 */
2083 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
2084 {
2085 return _gemmlowp_output_stage;
2086 };
Georgios Pinitasdbdea0d2019-10-16 19:21:40 +01002087 /** Sets GEMMLowp output stage
2088 *
2089 * @param[in] output_stage Output stage to set
2090 */
2091 void set_gemmlowp_output_stage(GEMMLowpOutputStageInfo &output_stage)
2092 {
2093 _gemmlowp_output_stage = output_stage;
2094 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002095 /** Flag which specifies if a wider accumulator should be used.
2096 *
2097 * @return True if a wider accumulator has to be used
2098 */
2099 bool fp_mixed_precision() const
2100 {
2101 return _fp_mixed_precision;
2102 };
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002103 /** Flag which specifies if a shorter accumulator to be used.
2104 *
2105 * @return True if a shorter accumulator has to be used
2106 */
2107 bool fast_math() const
2108 {
2109 return _fast_math;
2110 };
cfRodf2c022e2021-11-05 11:29:53 +00002111 /** Set fast math flag
2112 *
2113 * @param[in] fast_math Flag to set
2114 */
2115 void set_fast_math(bool fast_math)
2116 {
2117 _fast_math = fast_math;
2118 }
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002119 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2120 *
2121 * @return True if the shape of the bias tensor is to be broadcasted.
2122 */
2123 bool broadcast_bias() const
2124 {
2125 return _broadcast_bias;
2126 };
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002127 /** Flag which specifies whether b should be pre-transposed if supported.
2128 *
2129 * @return True if b should be pre-transposed else false.
2130 */
ramelg01cbbb0382021-09-17 17:36:57 +01002131 bool pretranspose_B() const
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002132 {
ramelg01cbbb0382021-09-17 17:36:57 +01002133 return _pretranspose_B;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002134 };
2135 /** Set pre-transpose b flag
2136 *
2137 * @param[in] flag Flag to set
2138 */
ramelg01cbbb0382021-09-17 17:36:57 +01002139 void set_pretranspose_B(bool flag)
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002140 {
ramelg01cbbb0382021-09-17 17:36:57 +01002141 _pretranspose_B = flag;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002142 }
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002143 /** Activation layer to apply after the matrix multiplication
2144 *
2145 * @return ActivationLayerInfo object
2146 */
2147 ActivationLayerInfo activation_info() const
2148 {
2149 return _activation_info;
2150 }
SiCongLi2e5fd632020-03-02 15:39:15 +00002151 /** Set activation layer info
2152 *
2153 * @param[in] activation_info ActivationLayerInfo object to set
2154 */
2155 void set_activation_info(const ActivationLayerInfo &activation_info)
2156 {
2157 _activation_info = activation_info;
2158 }
SiCongLi579ca842021-10-18 09:38:33 +01002159 /** Post operations to apply after the matrix multiplication
2160 *
2161 * @return experimental::PostOpList object
2162 */
2163 const experimental::PostOpList<ITensorInfo *> &post_ops() const
2164 {
2165 return _post_ops;
2166 }
2167 /** Set post ops
2168 *
2169 * @param[in] post_ops experimental::PostOpList object to set
2170 */
2171 void set_post_ops(const experimental::PostOpList<ITensorInfo *> &post_ops)
2172 {
2173 _post_ops = post_ops;
2174 }
Chunosov5124be52017-11-22 20:42:13 +07002175
2176private:
SiCongLi579ca842021-10-18 09:38:33 +01002177 bool _is_a_reshaped;
2178 bool _is_b_reshaped;
2179 bool _reshape_b_only_on_first_run;
2180 int _depth_output_gemm3d;
2181 bool _reinterpret_input_as_3d;
2182 bool _retain_internal_weights;
2183 GEMMLowpOutputStageInfo _gemmlowp_output_stage;
2184 bool _fast_math;
2185 bool _fp_mixed_precision;
2186 bool _broadcast_bias;
2187 bool _pretranspose_B;
2188 ActivationLayerInfo _activation_info;
2189 experimental::PostOpList<ITensorInfo *> _post_ops;
Chunosov5124be52017-11-22 20:42:13 +07002190};
2191
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00002192/** Winograd information */
2193struct WinogradInfo
2194{
2195 /** Default constructor
2196 *
2197 * @param[in] output_tile_sz Width and height of the output tile
2198 * @param[in] kernel_sz Width and height of the kernel
2199 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
2200 * @param[in] conv_info Convolution info (Pads, strides)
2201 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
2202 */
2203 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
2204 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
2205 {
2206 }
2207
2208 Size2D output_tile_size{}; /**< Width and height of the output tile */
2209 Size2D kernel_size{}; /**< Width and height of the kernel*/
2210 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
2211 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
2212 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
2213};
2214
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002215/** IO formatting information class*/
2216struct IOFormatInfo
2217{
2218 /** Precision type used when printing floating point numbers */
2219 enum class PrecisionType
2220 {
2221 Default, /**< Default precision to the one that the current stream has */
2222 Custom, /**< Custom precision specified by the user using the precision parameter */
2223 Full /**< The maximum precision of the floating point representation */
2224 };
2225
2226 /** Specifies the area to be printed, used by Tensor objects */
2227 enum class PrintRegion
2228 {
2229 ValidRegion, /**< Prints the valid region of the Tensor object */
2230 NoPadding, /**< Prints the Tensor object without the padding */
2231 Full /**< Print the tensor object including padding */
2232 };
2233
Alex Gildayc357c472018-03-21 13:54:09 +00002234 /** Construct a set of IO formatting information.
2235 *
2236 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
2237 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
2238 * @param[in] precision Precision value for float point numbers. Default: 10.
2239 * @param[in] align_columns Whether to align columns when printed. Default: true.
2240 * @param[in] element_delim Delimeter between elements. Default: " ".
2241 * @param[in] row_delim Delimenter between rows. Default: "\n".
2242 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002243 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
2244 PrecisionType precision_type = PrecisionType::Default,
2245 unsigned int precision = 10,
2246 bool align_columns = true,
2247 std::string element_delim = " ",
2248 std::string row_delim = "\n")
2249 : print_region(print_region),
2250 precision_type(precision_type),
2251 precision(precision),
2252 element_delim(element_delim),
2253 row_delim(row_delim),
2254 align_columns(align_columns)
2255 {
2256 }
2257
Alex Gildayc357c472018-03-21 13:54:09 +00002258 /** Area to be printed by Tensor objects */
2259 PrintRegion print_region;
2260 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002261 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00002262 /** Floating point precision */
2263 unsigned int precision;
2264 /** Element delimeter */
2265 std::string element_delim;
2266 /** Row delimeter */
2267 std::string row_delim;
2268 /** Align columns */
2269 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002270};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00002271} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +00002272#endif /* ARM_COMPUTE_TYPES_H */