blob: e8eed67c5829f6910f5c34978b046d4fd8c41023 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Mohammed Suhail Munshid538d162023-02-16 16:22:32 +00002 * Copyright (c) 2016-2023 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 */
Gian Marco Iodicea5cb79f2022-12-28 13:53:51 +0000139 INDIRECT, /**< Indirect convolution */
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000140 WINOGRAD, /**< Convolution using Winograd */
141 FFT /**< Convolution using FFT */
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000142};
143
Manuel Bottini05069f02019-09-26 17:18:26 +0100144/** Available DepthwiseConvolutionFunction*/
145enum class DepthwiseConvolutionFunction
146{
147 OPTIMIZED, /**< Optimized Depthwise Convolution */
148 GENERIC, /**< Generic Depthwise Convolution */
149};
150
giuros0146a49a02019-04-01 13:50:22 +0100151/** Available DeconvolutionMethod*/
152enum class DeconvolutionMethod
153{
Gunes Bayirec0113d2022-11-09 09:26:27 +0000154 GEMM, /**< Deconvolution using GEMM */
155 DIRECT, /**< Direct deconvolution */
156 UPSCALE_CONV2D /**< Deconvolution with Upscaling */
giuros0146a49a02019-04-01 13:50:22 +0100157};
158
Manuel Bottini2732cca2019-05-28 11:44:41 +0100159/** Available FuseBatchNormalizationType*/
160enum class FuseBatchNormalizationType
161{
162 CONVOLUTION, /**< For Convolution weights */
163 DEPTHWISECONVOLUTION /**< For Depthwise Convolution weights*/
164};
165
Usama Arif89890c62019-03-19 10:57:05 +0000166/** Padding mode to use for PadLayer */
167enum class PaddingMode
168{
169 CONSTANT,
170 REFLECT,
171 SYMMETRIC
172};
173
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000174/** Supported comparison operations */
175enum class ComparisonOperation
176{
177 Equal, /**< Equal comparison ( \f$ x == y \f$ ) */
178 NotEqual, /**< NotEqual comparison ( \f$ x != y \f$ ) */
179 Greater, /**< Greater comparison ( \f$ x > y \f$ ) */
180 GreaterEqual, /**< Greater equal comparison ( \f$ x >= y \f$ ) */
181 Less, /**< Less comparison ( \f$ x < y \f$ ) */
182 LessEqual /**< Less equal comparison ( \f$ x <= y \f$ ) */
183};
184
Alex Gildayc357c472018-03-21 13:54:09 +0000185/** Container for valid region of a window */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100186struct ValidRegion
187{
Alex Gildayc357c472018-03-21 13:54:09 +0000188 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100189 ValidRegion()
190 : anchor{}, shape{}
191 {
192 }
193
Alex Gildayc357c472018-03-21 13:54:09 +0000194 /** Allow instances of this class to be copy constructed */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100195 ValidRegion(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000196 /** Allow instances of this class to be move constructed */
197 ValidRegion(ValidRegion &&) = default;
198 /** Allow instances of this class to be copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100199 ValidRegion &operator=(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000200 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100201 ValidRegion &operator=(ValidRegion &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000202 /** Default destructor */
203 ~ValidRegion() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100204
Alex Gildayc357c472018-03-21 13:54:09 +0000205 /** Constructor for a valid region with default number of dimensions
206 *
207 * @param[in] an_anchor Anchor for the start of the valid region.
208 * @param[in] a_shape Shape of the valid region.
209 *
210 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000211 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
212 : anchor{ an_anchor }, shape{ a_shape }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100213 {
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000214 anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
215 }
216
Alex Gildayc357c472018-03-21 13:54:09 +0000217 /** Constructor for a valid region with specified number of dimensions
218 *
219 * @param[in] an_anchor Anchor for the start of the valid region.
220 * @param[in] a_shape Shape of the valid region.
221 * @param[in] num_dimensions Number of dimensions (must be >= number of dimensions of anchor and shape).
222 *
223 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000224 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
225 : anchor{ an_anchor }, shape{ a_shape }
226 {
227 ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
228 anchor.set_num_dimensions(num_dimensions);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100229 }
230
231 /** Return the start of the valid region for the given dimension @p d */
232 int start(unsigned int d) const
233 {
234 return anchor[d];
235 }
236
237 /** Return the end of the valid region for the given dimension @p d */
238 int end(unsigned int d) const
239 {
240 return anchor[d] + shape[d];
241 }
242
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000243 /** Accessor to set the value of anchor and shape for one of the dimensions.
244 *
245 * @param[in] dimension Dimension for which the value is set.
246 * @param[in] start Value to be set in anchor for the dimension.
247 * @param[in] size Value to be set in shape for the dimension.
248 *
249 * @return *this.
250 */
251 ValidRegion &set(size_t dimension, int start, size_t size)
252 {
253 anchor.set(dimension, start);
254 shape.set(dimension, size);
255 return *this;
256 }
257
SiCong Lib63b1192022-01-28 18:24:39 +0000258 /** Check whether two valid regions are equal.
259 *
260 * @param[in] lhs LHS valid region
261 * @param[in] rhs RHS valid region
262 *
263 * @return True if the valid regions are the same.
264 */
265 inline friend bool operator==(const ValidRegion &lhs, const ValidRegion &rhs);
266
Alex Gildayc357c472018-03-21 13:54:09 +0000267 Coordinates anchor; /**< Anchor for the start of the valid region. */
268 TensorShape shape; /**< Shape of the valid region. */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100269};
SiCong Lib63b1192022-01-28 18:24:39 +0000270inline bool operator==(const ValidRegion &lhs, const ValidRegion &rhs)
271{
272 return (lhs.anchor == rhs.anchor) && (lhs.shape == rhs.shape);
273}
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100274
275/** Methods available to handle borders */
276enum class BorderMode
277{
278 UNDEFINED, /**< Borders are left undefined */
279 CONSTANT, /**< Pixels outside the image are assumed to have a constant value */
280 REPLICATE /**< Pixels outside the image are assumed to have the same value as the closest image pixel */
281};
282
283/** Container for 2D border size */
284struct BorderSize
285{
286 /** Empty border, i.e. no border */
Pablo Marquez Tello383de022021-03-18 11:31:13 +0000287 constexpr BorderSize() noexcept
288 : top{ 0 },
289 right{ 0 },
290 bottom{ 0 },
291 left{ 0 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100292 {
293 }
294
295 /** Border with equal size around the 2D plane */
Pablo Marquez Tello383de022021-03-18 11:31:13 +0000296 explicit constexpr BorderSize(unsigned int size) noexcept
297 : top{ size },
298 right{ size },
299 bottom{ size },
300 left{ size }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100301 {
302 }
303
304 /** Border with same size for top/bottom and left/right */
305 constexpr BorderSize(unsigned int top_bottom, unsigned int left_right)
306 : top{ top_bottom }, right{ left_right }, bottom{ top_bottom }, left{ left_right }
307 {
308 }
309
310 /** Border with different sizes */
311 constexpr BorderSize(unsigned int top, unsigned int right, unsigned int bottom, unsigned int left)
312 : top{ top }, right{ right }, bottom{ bottom }, left{ left }
313 {
314 }
315
316 /** Check if the entire border is zero */
317 constexpr bool empty() const
318 {
319 return top == 0 && right == 0 && bottom == 0 && left == 0;
320 }
321
322 /** Check if the border is the same size on all sides */
323 constexpr bool uniform() const
324 {
325 return top == right && top == bottom && top == left;
326 }
327
Alex Gildayc357c472018-03-21 13:54:09 +0000328 /** Scale this border size.
329 *
330 * @param[in] scale Scale to multiply border size by.
331 *
332 * @return *this.
333 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100334 BorderSize &operator*=(float scale)
335 {
336 top *= scale;
337 right *= scale;
338 bottom *= scale;
339 left *= scale;
340
341 return *this;
342 }
343
Alex Gildayc357c472018-03-21 13:54:09 +0000344 /** Scale a copy of this border size.
345 *
346 * @param[in] scale Scale to multiply border size by.
347 *
348 * @return a scaled copy of this.
349 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100350 BorderSize operator*(float scale)
351 {
352 BorderSize size = *this;
353 size *= scale;
354
355 return size;
356 }
357
Giorgio Arena1e2af2a2020-10-15 17:39:41 +0100358 /** Check equality with another BorderSize struct
359 *
360 * @param[in] rhs other struct to check against
361 *
362 * @return true if they are equal
363 */
SiCong Lib63b1192022-01-28 18:24:39 +0000364 bool operator==(const BorderSize &rhs) const
Giorgio Arena1e2af2a2020-10-15 17:39:41 +0100365 {
366 return (top == rhs.top) && (right == rhs.right) && (bottom == rhs.bottom) && (left == rhs.left);
367 }
368
369 /** Check non-equality with another BorderSize struct
370 *
371 * @param[in] rhs other struct to check against
372 *
373 * @return true if they are different
374 */
SiCong Lib63b1192022-01-28 18:24:39 +0000375 bool operator!=(const BorderSize &rhs) const
Giorgio Arena1e2af2a2020-10-15 17:39:41 +0100376 {
377 return !(*this == rhs);
378 }
379
Alex Gildayc357c472018-03-21 13:54:09 +0000380 /** Limit this border size.
381 *
382 * @param[in] limit Border size to limit this border size to.
383 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100384 void limit(const BorderSize &limit)
385 {
386 top = std::min(top, limit.top);
387 right = std::min(right, limit.right);
388 bottom = std::min(bottom, limit.bottom);
389 left = std::min(left, limit.left);
390 }
391
Alex Gildayc357c472018-03-21 13:54:09 +0000392 unsigned int top; /**< top of the border */
393 unsigned int right; /**< right of the border */
394 unsigned int bottom; /**< bottom of the border */
395 unsigned int left; /**< left of the border */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100396};
397
Alex Gildayc357c472018-03-21 13:54:09 +0000398/** Container for 2D padding size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100399using PaddingSize = BorderSize;
400
SiCongLi1af54162021-10-06 15:25:57 +0100401/** Policy to handle integer overflow
402 * @note: This is ignored by floating point operations where the overflow behavior adheres to the IEEE-754 standard
403 * which states that in case of overflow ±infinity is returned for the round-to-nearest modes (and follows the
404 * rounding rules for the directed rounding modes) by default.
405 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100406enum class ConvertPolicy
407{
408 WRAP, /**< Wrap around */
409 SATURATE /**< Saturate */
410};
411
412/** Interpolation method */
413enum class InterpolationPolicy
414{
415 NEAREST_NEIGHBOR, /**< Output values are defined to match the source pixel whose center is nearest to the sample position */
416 BILINEAR, /**< Output values are defined by bilinear interpolation between the pixels */
417 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 */
418};
419
420/** Bilinear Interpolation method used by LKTracker */
421enum class BilinearInterpolation
422{
Alex Gildayc357c472018-03-21 13:54:09 +0000423 BILINEAR_OLD_NEW, /**< Old-new method */
424 BILINEAR_SCHARR /**< Scharr method */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100425};
426
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100427/** Rectangle type */
428struct Rectangle
429{
430 uint16_t x; /**< Top-left x coordinate */
431 uint16_t y; /**< Top-left y coordinate */
432 uint16_t width; /**< Width of the rectangle */
433 uint16_t height; /**< Height of the rectangle */
434};
435
436/** Coordinate type */
437struct Coordinates2D
438{
439 int32_t x; /**< X coordinates */
440 int32_t y; /**< Y coordinates */
441};
442
443/** Coordinate type */
444struct Coordinates3D
445{
446 uint32_t x; /**< X coordinates */
447 uint32_t y; /**< Y coordinates */
448 uint32_t z; /**< Z coordinates */
449};
450
Giuseppe Rossinid7647d42018-07-17 18:13:13 +0100451/** Padding information as a pair of unsigned int start/end */
452using PaddingInfo = std::pair<uint32_t, uint32_t>;
453
454/** List of padding information */
455using PaddingList = std::vector<PaddingInfo>;
456
giuros013175fcf2018-11-21 09:59:17 +0000457/** Information to produce a tiled version of a Tensor */
458using Multiples = std::vector<uint32_t>;
459
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100460/** Available channels */
461enum class Channel
462{
463 UNKNOWN, /** Unknown channel format */
464 C0, /**< First channel (used by formats with unknown channel types). */
465 C1, /**< Second channel (used by formats with unknown channel types). */
466 C2, /**< Third channel (used by formats with unknown channel types). */
467 C3, /**< Fourth channel (used by formats with unknown channel types). */
468 R, /**< Red channel. */
469 G, /**< Green channel. */
470 B, /**< Blue channel. */
471 A, /**< Alpha channel. */
472 Y, /**< Luma channel. */
473 U, /**< Cb/U channel. */
474 V /**< Cr/V/Value channel. */
475};
476
Georgios Pinitasd9769582017-08-03 10:19:40 +0100477/** Available reduction operations */
478enum class ReductionOperation
479{
Michalis Spyrou7930db42018-11-22 17:36:28 +0000480 ARG_IDX_MAX, /**< Index of the max value */
Manuel Bottinib412fab2018-12-10 17:40:23 +0000481 ARG_IDX_MIN, /**< Index of the min value */
482 MEAN_SUM, /**< Mean of sum */
483 PROD, /**< Product */
484 SUM_SQUARE, /**< Sum of squares */
Usama Arifa4a08ad2019-05-20 12:38:33 +0100485 SUM, /**< Sum */
486 MIN, /**< Min */
Usama Arif28f0dd92019-05-20 13:44:34 +0100487 MAX, /**< Max */
Georgios Pinitasd9769582017-08-03 10:19:40 +0100488};
489
giuros01164a2722018-11-20 18:34:46 +0000490/** Available element-wise operations */
491enum class ArithmeticOperation
492{
493 ADD, /**< (x + y) */
494 SUB, /**< (x - y) */
495 DIV, /**< (x / y) */
496 MIN, /**< Min(x, y) */
497 MAX, /**< Max(x, y) */
498 SQUARED_DIFF, /**< (x - y)^2 */
Usama Arif81e671e2019-05-13 13:33:14 +0100499 POWER, /**< x ^ y */
giuros011e6e1b82019-05-14 16:12:53 +0100500 PRELU, /**< y*x if x < 0, x otherwise */
giuros01164a2722018-11-20 18:34:46 +0000501};
502
Michalis Spyroue9362622018-11-23 17:41:37 +0000503/** Available element wise unary operations */
504enum class ElementWiseUnary
505{
Sang-Hoon Park75eea332020-11-13 13:44:13 +0000506 RSQRT, /**< Reverse square root */
507 EXP, /**< Exponential */
508 NEG, /**< Negate */
509 LOG, /**< Natural Logarithm */
510 ABS, /**< Absolute value */
511 SIN, /**< Sine */
512 ROUND, /**< Round */
513 LOGICAL_NOT, /**< Logical Not */
Michalis Spyroue9362622018-11-23 17:41:37 +0000514};
515
Manuel Bottini63bb7ca2020-12-02 13:22:14 +0000516/** Available bitwise operations */
517enum class BitwiseOperation
518{
519 AND, /**< Bitwise AND operation */
520 NOT, /**< Bitwise NOT operation */
521 OR, /**< Bitwise OR operation */
522 XOR, /**< Bitwise XOR operation */
523};
524
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100525/** The normalization type used for the normalization layer */
526enum class NormType
527{
528 IN_MAP_1D, /**< Normalization applied within the same map in 1D region */
529 IN_MAP_2D, /**< Normalization applied within the same map in 2D region */
530 CROSS_MAP /**< Normalization applied cross maps */
531};
532
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100533/** Detection window used for the object detection. The detection window keeps the following information:
534 *
535 * -# Geometry of the rectangular window (x/y of top-left corner and width/height)
536 * -# Index of the class used for evaluating which class the detection window belongs to
537 * -# Confidence value (score) obtained with the classifier
538 */
539struct DetectionWindow
540{
541 uint16_t x{ 0 }; /**< Top-left x coordinate */
542 uint16_t y{ 0 }; /**< Top-left y coordinate */
543 uint16_t width{ 0 }; /**< Width of the detection window */
544 uint16_t height{ 0 }; /**< Height of the detection window */
545 uint16_t idx_class{ 0 }; /**< Index of the class */
546 float score{ 0.f }; /**< Confidence value for the detection window */
547};
548
549/** Dimension rounding type when down-scaling on CNNs
550 * @note Used in pooling and convolution layer
551 */
552enum class DimensionRoundingType
553{
554 FLOOR, /**< Floor rounding */
555 CEIL /**< Ceil rounding */
556};
557
558/** Available pooling types */
559enum class PoolingType
560{
561 MAX, /**< Max Pooling */
Georgios Pinitascdf51452017-08-31 14:21:36 +0100562 AVG, /**< Average Pooling */
563 L2 /**< L2 Pooling */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100564};
565
Michalis Spyrou2709d612018-09-19 09:46:47 +0100566/** Available non maxima suppression types */
567enum class NMSType
568{
569 LINEAR, /**< Linear NMS */
570 GAUSSIAN, /**< Gaussian NMS */
571 ORIGINAL /**< Original NMS */
572};
573
574/** BoxWithNonMaximaSuppressionLimit Information class */
575class BoxNMSLimitInfo final
576{
577public:
578 /** Constructor
579 *
580 * @param[in] score_thresh (Optional) Score threshold.
581 * @param[in] nms (Optional) NMS value
582 * @param[in] detections (Optional) Number of detections
583 * @param[in] soft_nms_enabled (Optional) Enable SoftNMS
584 * @param[in] soft_nms_method (Optional) Soft NMS method
585 * @param[in] soft_nms_sigma (Optional) Soft NMS sigma value
586 * @param[in] soft_nms_min_score_thres (Optional) Soft NMS minimum score threshold
Manuel Bottini5209be52019-02-13 16:34:56 +0000587 * @param[in] suppress_size (Optional) Filter out boxes based on their size. Defaults to false
588 * @param[in] min_size (Optional) Smaller boxes than min_size will be filtered out. Defaults to 1
589 * @param[in] im_width (Optional) Boxes whose centers (on the x axis) is beyond im_width will be filtered. Defaults to 1
590 * @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 +0100591 */
592 BoxNMSLimitInfo(float score_thresh = 0.05f, float nms = 0.3f,
593 int detections = 100, bool soft_nms_enabled = false,
594 NMSType soft_nms_method = NMSType::LINEAR,
Manuel Bottini5209be52019-02-13 16:34:56 +0000595 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 +0100596 : _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 +0000597 _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 +0100598 {
599 }
600 /** Get the score threshold */
601 float score_thresh() const
602 {
603 return _score_thresh;
604 }
605 /** Get the NMS */
606 float nms() const
607 {
608 return _nms;
609 }
610 /** Get the number of detections */
611 int detections_per_im() const
612 {
613 return _detections_per_im;
614 }
615 /** Check if soft NMS is enabled */
616 bool soft_nms_enabled() const
617 {
618 return _soft_nms_enabled;
619 }
620 /** Get soft NMS method */
621 NMSType soft_nms_method() const
622 {
623 return _soft_nms_method;
624 }
625 /** Get soft NMS sigma */
626 float soft_nms_sigma() const
627 {
628 return _soft_nms_sigma;
629 }
630 /** Get soft nms min score threshold */
631 float soft_nms_min_score_thres() const
632 {
633 return _soft_nms_min_score_thres;
634 }
Manuel Bottini5209be52019-02-13 16:34:56 +0000635 /** Get if NMS will suppress boxes based on their size/position */
636 bool suppress_size() const
637 {
638 return _suppress_size;
639 }
640 /** Get size suppression threshold */
641 float min_size() const
642 {
643 return _min_size;
644 }
645 /** Get image width (NMS may suppress boxes whose center sits beyond the image width) */
646 float im_width() const
647 {
648 return _im_width;
649 }
650 /** Get image height (NMS may suppress boxes whose center sits beyond the image height) */
651 float im_height() const
652 {
653 return _im_height;
654 }
Michalis Spyrou2709d612018-09-19 09:46:47 +0100655
656private:
657 float _score_thresh;
658 float _nms;
659 int _detections_per_im;
660 bool _soft_nms_enabled;
661 NMSType _soft_nms_method;
662 float _soft_nms_sigma;
663 float _soft_nms_min_score_thres;
Manuel Bottini5209be52019-02-13 16:34:56 +0000664 bool _suppress_size;
665 float _min_size;
666 float _im_width;
667 float _im_height;
Michalis Spyrou2709d612018-09-19 09:46:47 +0100668};
669
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100670/** Padding and stride information class */
671class PadStrideInfo
672{
673public:
674 /** Constructor
675 *
676 * @param[in] stride_x (Optional) Stride, in elements, across x. Defaults to 1.
677 * @param[in] stride_y (Optional) Stride, in elements, across y. Defaults to 1.
678 * @param[in] pad_x (Optional) Padding, in elements, across x. Defaults to 0.
679 * @param[in] pad_y (Optional) Padding, in elements, across y. Defaults to 0.
680 * @param[in] round (Optional) Dimensions rounding. Defaults to @ref FLOOR.
681 */
682 PadStrideInfo(unsigned int stride_x = 1, unsigned int stride_y = 1,
683 unsigned int pad_x = 0, unsigned int pad_y = 0,
684 DimensionRoundingType round = DimensionRoundingType::FLOOR)
685 : _stride(std::make_pair(stride_x, stride_y)),
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100686 _pad_left(pad_x),
687 _pad_top(pad_y),
688 _pad_right(pad_x),
689 _pad_bottom(pad_y),
690 _round_type(round)
691 {
692 }
693 /** Constructor
694 *
695 * @param[in] stride_x Stride, in elements, across x.
696 * @param[in] stride_y Stride, in elements, across y.
697 * @param[in] pad_left Padding across x on the left, in elements.
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100698 * @param[in] pad_right Padding across x on the right, in elements.
Freddie Liardetded36632021-09-03 15:08:23 +0100699 * @param[in] pad_top Padding across y on the top, in elements.
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100700 * @param[in] pad_bottom Padding across y on the bottom, in elements.
701 * @param[in] round Dimensions rounding.
702 */
703 PadStrideInfo(unsigned int stride_x, unsigned int stride_y,
704 unsigned int pad_left, unsigned int pad_right,
705 unsigned int pad_top, unsigned int pad_bottom,
706 DimensionRoundingType round)
707 : _stride(std::make_pair(stride_x, stride_y)),
708 _pad_left(pad_left),
709 _pad_top(pad_top),
710 _pad_right(pad_right),
711 _pad_bottom(pad_bottom),
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100712 _round_type(round)
713 {
714 }
Alex Gildayc357c472018-03-21 13:54:09 +0000715 /** Get the stride.
716 *
717 * @return a pair: stride x, stride y.
718 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100719 std::pair<unsigned int, unsigned int> stride() const
720 {
721 return _stride;
722 }
Alex Gildayc357c472018-03-21 13:54:09 +0000723 /** Check whether the padding is symmetric.
724 *
725 * @return True if the padding is symmetric.
726 */
Anthony Barbier21f67d62018-02-16 15:17:48 +0000727 bool padding_is_symmetric() const
728 {
729 return (_pad_left == _pad_right) && (_pad_top == _pad_bottom);
730 }
Alex Gildayc357c472018-03-21 13:54:09 +0000731 /** Get the padding.
732 *
733 * @note This should only be used when the padding is symmetric.
734 *
735 * @return a pair: padding left/right, padding top/bottom
736 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100737 std::pair<unsigned int, unsigned int> pad() const
738 {
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100739 //this accessor should be used only when padding is symmetric
Anthony Barbier21f67d62018-02-16 15:17:48 +0000740 ARM_COMPUTE_ERROR_ON(!padding_is_symmetric());
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100741 return std::make_pair(_pad_left, _pad_top);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100742 }
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100743
Alex Gildayc357c472018-03-21 13:54:09 +0000744 /** Get the left padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100745 unsigned int pad_left() const
746 {
747 return _pad_left;
748 }
Alex Gildayc357c472018-03-21 13:54:09 +0000749 /** Get the right padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100750 unsigned int pad_right() const
751 {
752 return _pad_right;
753 }
Alex Gildayc357c472018-03-21 13:54:09 +0000754 /** Get the top padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100755 unsigned int pad_top() const
756 {
757 return _pad_top;
758 }
Alex Gildayc357c472018-03-21 13:54:09 +0000759 /** Get the bottom padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100760 unsigned int pad_bottom() const
761 {
762 return _pad_bottom;
763 }
764
Alex Gildayc357c472018-03-21 13:54:09 +0000765 /** Get the rounding type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100766 DimensionRoundingType round() const
767 {
768 return _round_type;
769 }
770
Alex Gildayc357c472018-03-21 13:54:09 +0000771 /** Check whether this has any padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100772 bool has_padding() const
773 {
774 return (_pad_left != 0 || _pad_top != 0 || _pad_right != 0 || _pad_bottom != 0);
775 }
776
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100777private:
778 std::pair<unsigned int, unsigned int> _stride;
Pablo Marquez Tello16789a12022-07-25 14:41:26 +0100779 unsigned int _pad_left;
780 unsigned int _pad_top;
781 unsigned int _pad_right;
782 unsigned int _pad_bottom;
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100783
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100784 DimensionRoundingType _round_type;
785};
786
SiCong Lif44bbc52022-08-29 18:25:51 +0100787/** Padding information for 2D operations like Conv2d */
788struct Padding2D
789{
790 Padding2D() = default;
791 Padding2D(size_t left, size_t right, size_t top, size_t bottom)
792 : left(left), right(right), top(top), bottom(bottom)
793 {
794 }
795 size_t left = { 0 }; /**< Padding across the width dimension on the left, in elements. */
796 size_t right = { 0 }; /**< Padding across the width dimension on the right, in elements. */
797 size_t top = { 0 }; /**< Padding across the height dimension on the top, in elements. */
798 size_t bottom = { 0 }; /**< Padding across the height dimension on the bottom, in elements. */
799};
800
Adnan AlSinane4563a02021-09-01 15:32:03 +0100801/** Padding information for 3D operations like Conv3d */
802struct Padding3D
803{
Freddie Liardetebefe522021-11-25 16:19:28 +0000804 Padding3D() noexcept
Giorgio Arenac9fe9fc2021-10-06 12:54:29 +0100805 {
806 }
807
808 Padding3D(size_t pad_x, size_t pad_y, size_t pad_z)
809 : left(pad_x), right(pad_x), top(pad_y), bottom(pad_y), front(pad_z), back(pad_z)
810 {
811 }
812
813 Padding3D(size_t left, size_t right, size_t top, size_t bottom, size_t front, size_t back)
814 : left(left), right(right), top(top), bottom(bottom), front(front), back(back)
815 {
816 }
817
Adnan AlSinane4563a02021-09-01 15:32:03 +0100818 size_t left = { 0 }; /**< Padding across the width dimenstion on the left, in elements. */
819 size_t right = { 0 }; /**< Padding across the width dimenstion on the right, in elements. */
820 size_t top = { 0 }; /**< Padding across the height dimenstion on the top, in elements. */
821 size_t bottom = { 0 }; /**< Padding across the height dimenstion on the bottom, in elements. */
822 size_t front = { 0 }; /**< Padding across the depth dimenstion on the front, in elements. */
823 size_t back = { 0 }; /**< Padding across the depth dimenstion on the back, in elements. */
824};
825
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100826/** PriorBox layer info */
827class PriorBoxLayerInfo final
828{
829public:
830 /** Default Constructor */
831 PriorBoxLayerInfo()
832 : _min_sizes(),
833 _variances(),
834 _offset(),
835 _flip(true),
836 _clip(false),
837 _max_sizes(),
838 _aspect_ratios(),
839 _img_size(),
840 _steps()
841 {
842 }
843 /** Constructor
844 *
845 * @param[in] min_sizes Min sizes vector.
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100846 * @param[in] variances Variances vector.
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100847 * @param[in] offset Offset value.
848 * @param[in] flip (Optional) Flip the aspect ratios.
849 * @param[in] clip (Optional) Clip coordinates so that they're within [0,1].
850 * @param[in] max_sizes (Optional) Max sizes vector.
851 * @param[in] aspect_ratios (Optional) Aspect ratios of the boxes.
852 * @param[in] img_size (Optional) Image size.
853 * @param[in] steps (Optional) Step values.
854 */
855 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 +0000856 const std::vector<float> &max_sizes = {}, const std::vector<float> &aspect_ratios = {},
857 const Coordinates2D &img_size = Coordinates2D{ 0, 0 }, const std::array<float, 2> &steps = { { 0.f, 0.f } })
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100858 : _min_sizes(min_sizes),
859 _variances(variances),
860 _offset(offset),
861 _flip(flip),
862 _clip(clip),
863 _max_sizes(max_sizes),
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100864 _aspect_ratios(),
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100865 _img_size(img_size),
866 _steps(steps)
867 {
868 _aspect_ratios.push_back(1.);
869 for(unsigned int i = 0; i < aspect_ratios.size(); ++i)
870 {
871 float ar = aspect_ratios[i];
872 bool already_exist = false;
873 for(auto ar_new : _aspect_ratios)
874 {
875 if(fabs(ar - ar_new) < 1e-6)
876 {
877 already_exist = true;
878 break;
879 }
880 }
881 if(!already_exist)
882 {
883 _aspect_ratios.push_back(ar);
884 if(flip)
885 {
886 _aspect_ratios.push_back(1.f / ar);
887 }
888 }
889 }
890 }
891 /** Get min sizes. */
892 std::vector<float> min_sizes() const
893 {
894 return _min_sizes;
895 }
896 /** Get min variances. */
897 std::vector<float> variances() const
898 {
899 return _variances;
900 }
901 /** Get the step coordinates */
902 std::array<float, 2> steps() const
903 {
904 return _steps;
905 }
906 /** Get the image size coordinates */
907 Coordinates2D img_size() const
908 {
909 return _img_size;
910 }
911 /** Get the offset */
912 float offset() const
913 {
914 return _offset;
915 }
916 /** Get the flip value */
917 bool flip() const
918 {
919 return _flip;
920 }
921 /** Get the clip value */
922 bool clip() const
923 {
924 return _clip;
925 }
926 /** Get max sizes. */
927 std::vector<float> max_sizes() const
928 {
929 return _max_sizes;
930 }
931 /** Get aspect ratios. */
932 std::vector<float> aspect_ratios() const
933 {
934 return _aspect_ratios;
935 }
936
937private:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +0100938 std::vector<float> _min_sizes;
939 std::vector<float> _variances;
940 float _offset;
941 bool _flip;
942 bool _clip;
943 std::vector<float> _max_sizes;
944 std::vector<float> _aspect_ratios;
945 Coordinates2D _img_size;
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100946 std::array<float, 2> _steps;
947};
948
Isabella Gottardia7acb3c2019-01-08 13:48:44 +0000949// Bounding Box [xmin, ymin, xmax, ymax]
950using BBox = std::array<float, 4>;
951// LabelBBox used for map label and bounding box
952using LabelBBox = std::map<int, std::vector<BBox>>;
953
Isabella Gottardi05e56442018-11-16 11:26:52 +0000954/** Available Detection Output code types */
955enum class DetectionOutputLayerCodeType
956{
957 CORNER, /**< Use box corners */
958 CENTER_SIZE, /**< Use box centers and size */
959 CORNER_SIZE, /**< Use box centers and size */
960 TF_CENTER /**< Use box centers and size but flip x and y co-ordinates */
961};
962
963/** Detection Output layer info */
964class DetectionOutputLayerInfo final
965{
966public:
967 /** Default Constructor */
968 DetectionOutputLayerInfo()
969 : _num_classes(),
970 _share_location(),
971 _code_type(DetectionOutputLayerCodeType::CORNER),
972 _keep_top_k(),
973 _nms_threshold(),
974 _top_k(),
975 _background_label_id(),
976 _confidence_threshold(),
977 _variance_encoded_in_target(false),
978 _eta(),
979 _num_loc_classes()
980 {
981 _num_loc_classes = _share_location ? 1 : _num_classes;
982 }
983 /** Constructor
984 *
985 * @param[in] num_classes Number of classes to be predicted.
986 * @param[in] share_location If true, bounding box are shared among different classes.
987 * @param[in] code_type Type of coding method for bbox.
988 * @param[in] keep_top_k Number of total bounding boxes to be kept per image after NMS step.
989 * @param[in] nms_threshold Threshold to be used in NMS.
990 * @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.
991 * @param[in] background_label_id (Optional) Background label ID. If there is no background class, set it as -1.
992 * @param[in] confidence_threshold (Optional) Only consider detections whose confidences are larger than a threshold. Default set to -FLT_MAX.
993 * @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.
994 * @param[in] eta (Optional) Eta.
995 */
996 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,
997 float confidence_threshold = std::numeric_limits<float>::lowest(), bool variance_encoded_in_target = false, float eta = 1)
998 : _num_classes(num_classes),
999 _share_location(share_location),
1000 _code_type(code_type),
1001 _keep_top_k(keep_top_k),
1002 _nms_threshold(nms_threshold),
1003 _top_k(top_k),
1004 _background_label_id(background_label_id),
1005 _confidence_threshold(confidence_threshold),
1006 _variance_encoded_in_target(variance_encoded_in_target),
1007 _eta(eta),
1008 _num_loc_classes()
1009 {
1010 _num_loc_classes = _share_location ? 1 : _num_classes;
1011 }
1012 /** Get num classes. */
1013 int num_classes() const
1014 {
1015 return _num_classes;
1016 }
1017 /** Get share location. */
1018 bool share_location() const
1019 {
1020 return _share_location;
1021 }
1022 /** Get detection output code type. */
1023 DetectionOutputLayerCodeType code_type() const
1024 {
1025 return _code_type;
1026 }
1027 /** Get if variance encoded in target. */
1028 bool variance_encoded_in_target() const
1029 {
1030 return _variance_encoded_in_target;
1031 }
1032 /** Get the number of total bounding boxes to be kept per image. */
1033 int keep_top_k() const
1034 {
1035 return _keep_top_k;
1036 }
1037 /** Get nms threshold. */
1038 float nms_threshold() const
1039 {
1040 return _nms_threshold;
1041 }
1042 /** Get eta. */
1043 float eta() const
1044 {
1045 return _eta;
1046 }
1047 /** Get background label ID. */
1048 int background_label_id() const
1049 {
1050 return _background_label_id;
1051 }
1052 /** Get confidence threshold. */
1053 float confidence_threshold() const
1054 {
1055 return _confidence_threshold;
1056 }
1057 /** Get top K. */
1058 int top_k() const
1059 {
1060 return _top_k;
1061 }
1062 /** Get number of location classes. */
1063 int num_loc_classes() const
1064 {
1065 return _num_loc_classes;
1066 }
1067
1068private:
1069 int _num_classes;
1070 bool _share_location;
1071 DetectionOutputLayerCodeType _code_type;
1072 int _keep_top_k;
1073 float _nms_threshold;
1074 int _top_k;
1075 int _background_label_id;
1076 float _confidence_threshold;
1077 bool _variance_encoded_in_target;
1078 float _eta;
1079 int _num_loc_classes;
1080};
1081
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001082/** Detection Output layer info */
1083class DetectionPostProcessLayerInfo final
1084{
1085public:
1086 /** Default Constructor */
1087 DetectionPostProcessLayerInfo()
1088 : _max_detections(),
1089 _max_classes_per_detection(),
1090 _nms_score_threshold(),
1091 _iou_threshold(),
1092 _num_classes(),
1093 _scales_values(),
1094 _use_regular_nms(),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001095 _detection_per_class(),
1096 _dequantize_scores()
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001097 {
1098 }
1099 /** Constructor
1100 *
1101 * @param[in] max_detections Number of total detection.
1102 * @param[in] max_classes_per_detection Number of total classes to be kept after NMS step. Used in the Fast Non-Max-Suppression
1103 * @param[in] nms_score_threshold Threshold to be used in NMS
1104 * @param[in] iou_threshold Threshold to be used during the intersection over union.
1105 * @param[in] num_classes Number of classes.
1106 * @param[in] scales_values Scales values used for decode center size boxes.
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001107 * @param[in] use_regular_nms (Optional) Boolean to determinate if use regular or fast nms. Defaults to false.
1108 * @param[in] detection_per_class (Optional) Number of detection per class. Used in the Regular Non-Max-Suppression. Defaults to 100.
1109 * @param[in] dequantize_scores (Optional) If the scores need to be dequantized. Defaults to true.
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001110 */
1111 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 +01001112 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 +00001113 : _max_detections(max_detections),
1114 _max_classes_per_detection(max_classes_per_detection),
1115 _nms_score_threshold(nms_score_threshold),
1116 _iou_threshold(iou_threshold),
1117 _num_classes(num_classes),
1118 _scales_values(scales_values),
1119 _use_regular_nms(use_regular_nms),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001120 _detection_per_class(detection_per_class),
1121 _dequantize_scores(dequantize_scores)
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001122 {
1123 }
1124 /** Get max detections. */
1125 unsigned int max_detections() const
1126 {
1127 return _max_detections;
1128 }
1129 /** Get max_classes per detection. Used in the Fast Non-Max-Suppression.*/
1130 unsigned int max_classes_per_detection() const
1131 {
1132 return _max_classes_per_detection;
1133 }
1134 /** Get detection per class. Used in the Regular Non-Max-Suppression */
1135 unsigned int detection_per_class() const
1136 {
1137 return _detection_per_class;
1138 }
1139 /** Get nms threshold. */
1140 float nms_score_threshold() const
1141 {
1142 return _nms_score_threshold;
1143 }
1144 /** Get intersection over union threshold. */
1145 float iou_threshold() const
1146 {
1147 return _iou_threshold;
1148 }
1149 /** Get num classes. */
1150 unsigned int num_classes() const
1151 {
1152 return _num_classes;
1153 }
1154 /** Get if use regular nms. */
1155 bool use_regular_nms() const
1156 {
1157 return _use_regular_nms;
1158 }
1159 /** Get y scale value. */
1160 float scale_value_y() const
1161 {
1162 // Saved as [y,x,h,w]
1163 return _scales_values[0];
1164 }
1165 /** Get x scale value. */
1166 float scale_value_x() const
1167 {
1168 // Saved as [y,x,h,w]
1169 return _scales_values[1];
1170 }
1171 /** Get h scale value. */
1172 float scale_value_h() const
1173 {
1174 // Saved as [y,x,h,w]
1175 return _scales_values[2];
1176 }
1177 /** Get w scale value. */
1178 float scale_value_w() const
1179 {
1180 // Saved as [y,x,h,w]
1181 return _scales_values[3];
1182 }
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001183 /** Get dequantize_scores value. */
1184 bool dequantize_scores() const
1185 {
1186 return _dequantize_scores;
1187 }
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001188
1189private:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001190 unsigned int _max_detections;
1191 unsigned int _max_classes_per_detection;
1192 float _nms_score_threshold;
1193 float _iou_threshold;
1194 unsigned int _num_classes;
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001195 std::array<float, 4> _scales_values;
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001196 bool _use_regular_nms;
1197 unsigned int _detection_per_class;
1198 bool _dequantize_scores;
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001199};
1200
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001201/** Pooling Layer Information struct*/
1202struct PoolingLayerInfo
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001203{
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001204 /** Default Constructor */
1205 PoolingLayerInfo()
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001206 : pool_type(PoolingType::MAX),
1207 pool_size(Size2D()),
1208 data_layout(DataLayout::UNKNOWN),
1209 pad_stride_info(PadStrideInfo()),
1210 exclude_padding(false),
1211 is_global_pooling(false),
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001212 fp_mixed_precision(false),
1213 use_inf_as_limit(true)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001214 {
1215 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001216 /** Constructor
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001217 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001218 * @param[in] pool_type Pooling type @ref PoolingType.
1219 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001220 * @param[in] data_layout Data layout used by the layer @ref DataLayout
1221 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1222 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1223 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1224 * Defaults to false;
1225 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001226 * @param[in] use_inf_as_limit (Optional) Use inf to represent the limits of datatypes range, instead of using "lowest" property of the data type.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001227 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001228 explicit PoolingLayerInfo(PoolingType pool_type,
1229 unsigned int pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001230 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001231 PadStrideInfo pad_stride_info = PadStrideInfo(),
1232 bool exclude_padding = false,
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001233 bool fp_mixed_precision = false,
1234 bool use_inf_as_limit = true)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001235 : pool_type(pool_type),
1236 pool_size(Size2D(pool_size, pool_size)),
1237 data_layout(data_layout),
1238 pad_stride_info(pad_stride_info),
1239 exclude_padding(exclude_padding),
1240 is_global_pooling(false),
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001241 fp_mixed_precision(fp_mixed_precision),
1242 use_inf_as_limit(use_inf_as_limit)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001243 {
1244 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001245
1246 /** Constructor
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001247 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001248 * @param[in] pool_type Pooling type @ref PoolingType.
1249 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001250 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001251 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1252 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1253 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1254 * Defaults to false;
1255 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001256 * @param[in] use_inf_as_limit (Optional) Use inf to represent the limits of datatypes range, instead of using "lowest" property of the data type.
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001257 */
1258 explicit PoolingLayerInfo(PoolingType pool_type,
1259 Size2D pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001260 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001261 PadStrideInfo pad_stride_info = PadStrideInfo(),
1262 bool exclude_padding = false,
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001263 bool fp_mixed_precision = false,
1264 bool use_inf_as_limit = true)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001265 : pool_type(pool_type),
1266 pool_size(pool_size),
1267 data_layout(data_layout),
1268 pad_stride_info(pad_stride_info),
1269 exclude_padding(exclude_padding),
1270 is_global_pooling(false),
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001271 fp_mixed_precision(fp_mixed_precision),
1272 use_inf_as_limit(use_inf_as_limit)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001273 {
1274 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001275
1276 /** Constructor
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001277 *
1278 * @note This constructor is used for global pooling
1279 *
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001280 * @param[in] pool_type Pooling type @ref PoolingType.
1281 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001282 */
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001283 explicit PoolingLayerInfo(PoolingType pool_type, DataLayout data_layout)
1284 : pool_type(pool_type),
1285 pool_size(Size2D()),
1286 data_layout(data_layout),
1287 pad_stride_info(PadStrideInfo(1, 1, 0, 0)),
1288 exclude_padding(false),
1289 is_global_pooling(true),
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001290 fp_mixed_precision(false),
1291 use_inf_as_limit(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001292 {
1293 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001294
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001295 PoolingType pool_type;
1296 Size2D pool_size;
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001297 DataLayout data_layout;
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001298 PadStrideInfo pad_stride_info;
1299 bool exclude_padding;
1300 bool is_global_pooling;
1301 bool fp_mixed_precision;
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001302 bool use_inf_as_limit;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001303};
1304
ramelg0137515692022-02-26 22:06:20 +00001305/** Pooling Layer Information struct*/
1306struct Pooling3dLayerInfo
1307{
1308 /** Default Constructor */
Michalis Spyrou50e48aa2022-04-21 16:42:56 +01001309 Pooling3dLayerInfo() noexcept
ramelg0137515692022-02-26 22:06:20 +00001310 : pool_type(PoolingType::MAX),
1311 pool_size(Size3D()),
1312 stride(Size3D()),
1313 padding(Padding3D()),
1314 exclude_padding(false),
1315 is_global_pooling(false),
1316 fp_mixed_precision(false),
1317 round_type(DimensionRoundingType::FLOOR)
1318 {
1319 }
1320 /** Constructor
1321 *
1322 * @param[in] pool_type Pooling type @ref PoolingType.
1323 * @param[in] pool_size Pooling size, in elements, across x, y and z.
1324 * @param[in] stride (Optional) stride information @ref Size3D
1325 * @param[in] padding (Optional) padding information @ref Padding3D
1326 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1327 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1328 * Defaults to false;
1329 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1330 * @param[in] round_type (Optional) Dimensions rounding. Defaults to @ref FLOOR
1331 */
1332 explicit Pooling3dLayerInfo(PoolingType pool_type,
1333 unsigned int pool_size,
1334 Size3D stride = Size3D(1U, 1U, 1U),
1335 Padding3D padding = Padding3D(),
1336 bool exclude_padding = false,
1337 bool fp_mixed_precision = false,
1338 DimensionRoundingType round_type = DimensionRoundingType::FLOOR)
1339 : pool_type(pool_type),
1340 pool_size(Size3D(pool_size, pool_size, pool_size)),
1341 stride(stride),
1342 padding(padding),
1343 exclude_padding(exclude_padding),
1344 is_global_pooling(false),
1345 fp_mixed_precision(fp_mixed_precision),
1346 round_type(round_type)
1347 {
1348 }
1349
1350 /** Constructor
1351 *
1352 * @param[in] pool_type Pooling type @ref PoolingType.
1353 * @param[in] pool_size Pooling size, in elements, across x, y and z.
1354 * @param[in] stride (Optional) stride information @ref Size3D
1355 * @param[in] padding (Optional) padding information @ref Padding3D
1356 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1357 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1358 * Defaults to false;
1359 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1360 * @param[in] round_type (Optional) Dimensions rounding. Defaults to @ref FLOOR
1361 */
1362 explicit Pooling3dLayerInfo(PoolingType pool_type,
1363 Size3D pool_size,
1364 Size3D stride = Size3D(1U, 1U, 1U),
1365 Padding3D padding = Padding3D(),
1366 bool exclude_padding = false,
1367 bool fp_mixed_precision = false,
1368 DimensionRoundingType round_type = DimensionRoundingType::FLOOR)
1369 : pool_type(pool_type),
1370 pool_size(pool_size),
1371 stride(stride),
1372 padding(padding),
1373 exclude_padding(exclude_padding),
1374 is_global_pooling(false),
1375 fp_mixed_precision(fp_mixed_precision),
1376 round_type(round_type)
1377 {
1378 }
1379
1380 /** Constructor
1381 *
1382 * @note This constructor is used for global pooling
1383 *
1384 * @param[in] pool_type Pooling type @ref PoolingType.
1385 */
1386 explicit Pooling3dLayerInfo(PoolingType pool_type)
1387 : pool_type(pool_type),
1388 pool_size(Size3D()),
1389 stride(Size3D(1U, 1U, 1U)),
1390 padding(Padding3D(0, 0, 0)),
1391 exclude_padding(false),
1392 is_global_pooling(true),
1393 fp_mixed_precision(false),
1394 round_type(DimensionRoundingType::FLOOR)
1395 {
1396 }
1397
1398 PoolingType pool_type;
1399 Size3D pool_size;
1400 Size3D stride;
1401 Padding3D padding;
1402 bool exclude_padding;
1403 bool is_global_pooling;
1404 bool fp_mixed_precision;
1405 DimensionRoundingType round_type;
1406};
1407
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001408/** ROI Pooling Layer Information class */
giuros0118870812018-09-13 09:31:40 +01001409class ROIPoolingLayerInfo final
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001410{
1411public:
giuros0118870812018-09-13 09:31:40 +01001412 /** Constructor
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001413 *
giuros0118870812018-09-13 09:31:40 +01001414 * @param[in] pooled_width Pooled width of the layer.
1415 * @param[in] pooled_height Pooled height of the layer.
1416 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
1417 * @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 +01001418 */
giuros0118870812018-09-13 09:31:40 +01001419 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale, unsigned int sampling_ratio = 0)
1420 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale), _sampling_ratio(sampling_ratio)
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001421 {
1422 }
Alex Gildayc357c472018-03-21 13:54:09 +00001423 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001424 unsigned int pooled_width() const
1425 {
1426 return _pooled_width;
1427 }
Alex Gildayc357c472018-03-21 13:54:09 +00001428 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001429 unsigned int pooled_height() const
1430 {
1431 return _pooled_height;
1432 }
Alex Gildayc357c472018-03-21 13:54:09 +00001433 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001434 float spatial_scale() const
1435 {
1436 return _spatial_scale;
1437 }
giuros0118870812018-09-13 09:31:40 +01001438 /** Get sampling ratio */
1439 unsigned int sampling_ratio() const
1440 {
1441 return _sampling_ratio;
1442 }
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001443
1444private:
1445 unsigned int _pooled_width;
1446 unsigned int _pooled_height;
1447 float _spatial_scale;
giuros0118870812018-09-13 09:31:40 +01001448 unsigned int _sampling_ratio;
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001449};
1450
Manuel Bottini5209be52019-02-13 16:34:56 +00001451/** Generate Proposals Information class */
1452class GenerateProposalsInfo
1453{
1454public:
1455 /** Constructor
1456 *
1457 * @param[in] im_width Width of the original image
1458 * @param[in] im_height Height of the original image
1459 * @param[in] im_scale Scale applied to the original image
1460 * @param[in] spatial_scale (Optional)Scale applied to the feature map. Defaults to 1.0
1461 * @param[in] pre_nms_topN (Optional)Number of the best scores to be selected from the transformations. Defaults to 6000.
1462 * @param[in] post_nms_topN (Optional)Number of the best scores to be selected from the NMS operation. Defaults to 300.
1463 * @param[in] nms_thres (Optional)NMS overlap threshold. Defaults to 0.7.
1464 * @param[in] min_size (Optional)Size used to validate the anchors produced. Defaults to 16.
1465 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region of interest). Defaults to 4.
1466 */
1467 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,
1468 size_t values_per_roi = 4)
1469 : _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),
1470 _min_size(min_size), _values_per_roi(values_per_roi)
1471 {
1472 }
1473
1474 /* Get the original height */
1475 float im_height() const
1476 {
1477 return _im_height;
1478 }
1479 /* Get the original width */
1480 float im_width() const
1481 {
1482 return _im_width;
1483 }
1484 /* Get the image scale */
1485 float im_scale() const
1486 {
1487 return _im_scale;
1488 }
1489 /* Get the value of how many best scores to select (before NMS) */
1490 int pre_nms_topN() const
1491 {
1492 return _pre_nms_topN;
1493 }
1494 /* Get the value of how many best scores to select (after NMS) */
1495 int post_nms_topN() const
1496 {
1497 return _post_nms_topN;
1498 }
1499 /* Get the NMS overlap threshold */
1500 float nms_thres() const
1501 {
1502 return _nms_thres;
1503 }
1504 /* Get the minimal size */
1505 float min_size() const
1506 {
1507 return _min_size;
1508 }
1509 /* Get the spatial scale to be applied to the feature maps */
1510 float spatial_scale() const
1511 {
1512 return _spatial_scale;
1513 }
1514 /* Get the values used to represent a ROI(Region of interest)*/
1515 size_t values_per_roi() const
1516 {
1517 return _values_per_roi;
1518 }
1519
1520private:
1521 float _im_height;
1522 float _im_width;
1523 float _im_scale;
1524 float _spatial_scale;
1525 int _pre_nms_topN;
1526 int _post_nms_topN;
1527 float _nms_thres;
1528 float _min_size;
1529 size_t _values_per_roi;
1530};
1531
1532/** ComputeAnchors information class */
1533class ComputeAnchorsInfo
1534{
1535public:
1536 /** Constructor
1537 *
1538 * @param[in] feat_width Feature map width
1539 * @param[in] feat_height Feature map height
1540 * @param[in] spatial_scale Feature map scale
1541 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region Of Interest). Defaults to 4
1542 */
1543 ComputeAnchorsInfo(float feat_width, float feat_height, float spatial_scale, size_t values_per_roi = 4)
1544 : _feat_height(feat_height),
1545 _feat_width(feat_width),
1546 _spatial_scale(spatial_scale),
1547 _values_per_roi(values_per_roi)
1548 {
1549 }
1550
1551 /* Get the height of the feature map */
1552 float feat_height() const
1553 {
1554 return _feat_height;
1555 }
1556
1557 /* Get the width of the feature map */
1558 float feat_width() const
1559 {
1560 return _feat_width;
1561 }
1562
1563 /* Get the scale of the feature map */
1564 float spatial_scale() const
1565 {
1566 return _spatial_scale;
1567 }
1568
1569 /* Get the values used to represent a ROI(Region Of Interest)*/
1570 size_t values_per_roi() const
1571 {
1572 return _values_per_roi;
1573 }
1574
1575private:
1576 float _feat_height;
1577 float _feat_width;
1578 float _spatial_scale;
1579 size_t _values_per_roi;
1580};
1581
giuros01c04a0e82018-10-03 12:44:35 +01001582/** Bounding Box Transform information class */
giuros01d696cb62018-11-16 10:39:59 +00001583class BoundingBoxTransformInfo final
giuros01c04a0e82018-10-03 12:44:35 +01001584{
1585public:
1586 /** Constructor
1587 *
giuros01d696cb62018-11-16 10:39:59 +00001588 * @param[in] img_width Width of the original image
1589 * @param[in] img_height Height, of the original image
1590 * @param[in] scale Scale of the original image
1591 * @param[in] apply_scale (Optional)Re-apply scaling after transforming the boxes. Defaults to false
1592 * @param[in] weights (Optional)Weights [wx, wy, ww, wh] for the deltas. Defaults to all ones
1593 * @param[in] correct_transform_coords (Optional)Correct bounding box transform coordinates. Defaults to false
1594 * @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 +01001595 */
giuros01d696cb62018-11-16 10:39:59 +00001596 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 =
1597 false,
1598 float bbox_xform_clip =
1599 4.135166556742356f)
1600 : _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 +01001601 {
1602 }
1603
1604 std::array<float, 4> weights() const
1605 {
1606 return _weights;
1607 }
1608
1609 float bbox_xform_clip() const
1610 {
1611 return _bbox_xform_clip;
1612 }
1613
1614 float img_height() const
1615 {
1616 return _img_height;
1617 }
1618
1619 float img_width() const
1620 {
1621 return _img_width;
1622 }
1623
1624 float scale() const
1625 {
1626 return _scale;
1627 }
1628
1629 bool apply_scale() const
1630 {
1631 return _apply_scale;
1632 }
1633
giuros01d696cb62018-11-16 10:39:59 +00001634 bool correct_transform_coords() const
1635 {
1636 return _correct_transform_coords;
1637 }
1638
giuros01c04a0e82018-10-03 12:44:35 +01001639private:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001640 float _img_width;
1641 float _img_height;
1642 float _scale;
1643 bool _apply_scale;
1644 bool _correct_transform_coords;
giuros01c04a0e82018-10-03 12:44:35 +01001645 std::array<float, 4> _weights;
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001646 float _bbox_xform_clip;
giuros01c04a0e82018-10-03 12:44:35 +01001647};
1648
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001649/** Activation Layer Information class */
1650class ActivationLayerInfo
1651{
1652public:
1653 /** Available activation functions */
1654 enum class ActivationFunction
1655 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001656 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
1657 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
1658 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
1659 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
1660 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
Manuel Bottini581c8982019-02-07 10:31:57 +00001661 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 +01001662 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
Georgios Pinitasfb0fdcd2019-08-22 17:10:04 +01001663 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 +01001664 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
1665 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
1666 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
Usama Arif6a98a6e2019-05-10 17:07:27 +01001667 LINEAR, /**< Linear ( \f$ f(x)= ax + b \f$ ) */
morgolock07df3d42020-02-27 11:46:28 +00001668 IDENTITY, /**< Identity ( \f$ f(x)= x \f$ ) */
Jonathan Deakind6b8a712022-08-23 11:44:18 +01001669 HARD_SWISH, /**< Hard-swish ( \f$ f(x) = (x \text{ReLU6}(x+3))/6 = x \min(\max(0,x+3),6)/6 \f$ ) */
SiCong Lif44bbc52022-08-29 18:25:51 +01001670 SWISH, /**< Swish ( \f$ f(x) = \frac{x}{1 + e^{-ax}} = x \text{logistic}(ax) \f$ ) */
Murray Kornelsen926f5022022-07-13 21:22:39 -04001671 GELU /**< GELU ( \f$ f(x) = x * 1/2 * 1 + erf(x / \sqrt{2}) \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001672 };
1673
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001674 /** Lookup table */
1675 using LookupTable256 = std::array<qasymm8_t, 256>;
1676
Giorgio Arena11674872018-02-07 15:38:12 +00001677 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001678 /** Default Constructor
1679 *
1680 * @param[in] f The activation function to use.
1681 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001682 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1683 * @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 +01001684 */
1685 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001686 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001687 {
1688 }
Alex Gildayc357c472018-03-21 13:54:09 +00001689 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001690 ActivationFunction activation() const
1691 {
1692 return _act;
1693 }
Alex Gildayc357c472018-03-21 13:54:09 +00001694 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001695 float a() const
1696 {
1697 return _a;
1698 }
Alex Gildayc357c472018-03-21 13:54:09 +00001699 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001700 float b() const
1701 {
1702 return _b;
1703 }
Alex Gildayc357c472018-03-21 13:54:09 +00001704 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001705 bool enabled() const
1706 {
1707 return _enabled;
1708 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001709
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001710#ifdef __aarch64__
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001711 const LookupTable256 &lut() const
1712 {
1713 return _lut;
1714 }
1715
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001716 void init_lut(DataType data_type, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001717 {
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001718 if(_act == ActivationFunction::HARD_SWISH)
1719 {
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001720 if(data_type == DataType::QASYMM8)
1721 {
1722 qasymm8_hard_swish_populate_table(_lut, qi_in, qi_out);
1723 }
1724 else
1725 {
1726 qasymm8_signed_hard_swish_populate_table(_lut, qi_in, qi_out);
1727 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001728 }
1729 else if(_act == ActivationFunction::LEAKY_RELU)
1730 {
1731 qasymm8_leaky_relu_populate_table(_lut, qi_in, qi_out, _a);
1732 }
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001733 else if(_act == ActivationFunction::LOGISTIC)
1734 {
1735 if(data_type == DataType::QASYMM8)
1736 {
1737 qasymm8_logistic_populate_table(_lut, qi_in, qi_out);
1738 }
1739 else
1740 {
1741 qasymm8_signed_logistic_populate_table(_lut, qi_in, qi_out);
1742 }
1743 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001744 }
1745#endif // __aarch64__
1746
1747 static inline bool is_lut_supported(ActivationFunction act_func, DataType data_type)
1748 {
1749#ifdef __aarch64__
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001750 switch(act_func)
1751 {
1752 case ActivationFunction::HARD_SWISH:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001753 return data_type == DataType::QASYMM8 || data_type == DataType::QASYMM8_SIGNED;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001754 case ActivationFunction::LEAKY_RELU:
1755 return data_type == DataType::QASYMM8;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001756 case ActivationFunction::LOGISTIC:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001757 return data_type == DataType::QASYMM8 || data_type == DataType::QASYMM8_SIGNED;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001758 default:
1759 return false;
1760 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001761#else // __aarch64__
1762 ARM_COMPUTE_UNUSED(act_func);
1763 ARM_COMPUTE_UNUSED(data_type);
1764 return false;
1765#endif // __aarch64__
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001766 }
1767
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001768private:
Usama Arif6a98a6e2019-05-10 17:07:27 +01001769 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::IDENTITY };
Giorgio Arena11674872018-02-07 15:38:12 +00001770 float _a = {};
1771 float _b = {};
1772 bool _enabled = { false };
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001773
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001774#ifdef __aarch64__
1775 LookupTable256 _lut = {};
1776
1777 static inline void qasymm8_hard_swish_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001778 {
1779 for(size_t i = 0; i < lut.size(); ++i)
1780 {
1781 lut[i] = qasymm8_hard_swish(i, qi_in, qi_out);
1782 }
1783 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001784
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001785 static inline void qasymm8_signed_hard_swish_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1786 {
1787 for(size_t i = 0; i < lut.size(); ++i)
1788 {
1789 lut[i] = qasymm8_signed_hard_swish(i, qi_in, qi_out);
1790 }
1791 }
1792
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001793 static inline void qasymm8_leaky_relu_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out, float alpha)
1794 {
1795 for(size_t i = 0; i < lut.size(); ++i)
1796 {
1797 lut[i] = qasymm8_leaky_relu(i, qi_in, qi_out, alpha);
1798 }
1799 }
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001800
1801 static inline void qasymm8_logistic_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1802 {
1803 for(size_t i = 0; i < lut.size(); ++i)
1804 {
1805 lut[i] = qasymm8_logistic(i, qi_in, qi_out);
1806 }
1807 }
1808
1809 static inline void qasymm8_signed_logistic_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1810 {
1811 for(size_t i = 0; i < lut.size(); ++i)
1812 {
1813 lut[i] = qasymm8_signed_logistic(static_cast<int8_t>(i), qi_in, qi_out);
1814 }
1815 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001816#endif // __aarch64__
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001817};
1818
Giorgio Arena1856ff72020-02-07 13:46:45 +00001819/** Fully connected layer info */
1820struct FullyConnectedLayerInfo
1821{
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001822 /* Fused-activation parameters */
1823 ActivationLayerInfo activation_info{}; /**< Fused activation to apply after the matrix multiplication. */
1824 /* Information about weights */
1825 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
1826 bool transpose_weights{ true }; /**< Transpose weights if true. */
1827 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
1828 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
cfRodf2c022e2021-11-05 11:29:53 +00001829 bool enable_fast_math{ false }; /**< Enable fast math computation. */
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001830 /* Other parameters */
1831 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 +00001832
1833 /** Sets the weights trained data layout
1834 *
1835 * @param[in] layout Data layout that the weights were trained with
1836 *
1837 * @return Updated object
1838 */
1839 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
1840 {
1841 weights_trained_layout = layout;
1842 return *this;
1843 }
1844 /** Sets the transpose weights flag
1845 *
1846 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
1847 *
1848 * @return Updated object
1849 */
1850 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
1851 {
1852 transpose_weights = should_transpose_weights;
1853 return *this;
1854 }
1855};
1856
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001857/** Normalization Layer Information class */
1858class NormalizationLayerInfo
1859{
1860public:
1861 /** Default Constructor
1862 *
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001863 * @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 +01001864 * @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 +00001865 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1866 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1867 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1868 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1869 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001870 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001871 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1872 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001873 {
1874 }
Alex Gildayc357c472018-03-21 13:54:09 +00001875 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001876 NormType type() const
1877 {
1878 return _type;
1879 }
Alex Gildayc357c472018-03-21 13:54:09 +00001880 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001881 uint32_t norm_size() const
1882 {
1883 return _norm_size;
1884 }
Alex Gildayc357c472018-03-21 13:54:09 +00001885 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001886 float alpha() const
1887 {
1888 return _alpha;
1889 }
Alex Gildayc357c472018-03-21 13:54:09 +00001890 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001891 float beta() const
1892 {
1893 return _beta;
1894 }
Alex Gildayc357c472018-03-21 13:54:09 +00001895 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001896 float kappa() const
1897 {
1898 return _kappa;
1899 }
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001900 /** Get the is_scaled value */
1901 bool is_scaled() const
1902 {
1903 return _is_scaled;
1904 }
Alex Gildayc357c472018-03-21 13:54:09 +00001905 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001906 bool is_cross_map() const
1907 {
1908 return _type == NormType::CROSS_MAP;
1909 }
Alex Gildayc357c472018-03-21 13:54:09 +00001910 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001911 bool is_in_map() const
1912 {
1913 return !is_cross_map();
1914 }
1915 /** Return the scaling factor of the normalization function.
1916 *
1917 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1918 * 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 +01001919 *
1920 * @return The normalization scaling factor.
1921 */
1922 float scale_coeff() const
1923 {
1924 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001925 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001926 }
1927
1928private:
1929 NormType _type;
1930 uint32_t _norm_size;
1931 float _alpha;
1932 float _beta;
1933 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001934 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001935};
1936
thecha012bfadd92020-08-12 17:25:51 +01001937class StridedSliceLayerInfo
1938{
1939public:
1940 /** Default Constructor
1941 *
1942 * @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.
1943 * @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.
1944 * @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.
1945 */
1946 StridedSliceLayerInfo(int32_t begin_mask = 0, int32_t end_mask = 0, int32_t shrink_axis_mask = 0)
1947 : _begin_mask(begin_mask), _end_mask(end_mask), _shrink_axis_mask(shrink_axis_mask)
1948 {
1949 }
1950
1951 /* Get the begin mask value */
1952 int32_t begin_mask() const
1953 {
1954 return _begin_mask;
1955 }
1956
1957 /* Get the end mask value */
1958 int32_t end_mask() const
1959 {
1960 return _end_mask;
1961 }
1962
1963 /* Get the shrink axis mask value */
1964 int32_t shrink_axis_mask() const
1965 {
1966 return _shrink_axis_mask;
1967 }
1968
1969private:
1970 int32_t _begin_mask;
1971 int32_t _end_mask;
1972 int32_t _shrink_axis_mask;
1973};
1974
Ramy Elgammal91780022022-07-20 14:57:37 +01001975/** Memory layouts for the weights tensor.
1976 *
1977 * * UNSPECIFIED is used to select kernels that do not run in
1978 * variable weights mode.
1979 *
1980 * * ANY is used to query the kernel database to retrieve any of the
1981 * kernels that runs in variable weights mode. Once a kernel is
1982 * found, the specific format expected by the kernel can be
1983 * retrieved by the user for reordering the weights tensor
1984 * accordingly.
1985 *
1986 * The other values OHWIo{interleave_by}i{block_by} describe the
1987 * memory layout of a 4D tensor with layout OHWI that has been
1988 * transformed into a 4D tensor with dimensions O'HWI' where:
1989 *
1990 * O' = first multiple of {interleave_by} s.t. O<=O'
1991 * I' = first multiple of {block_by} s.t. I<=I'
1992 *
1993 * The total size of the dst tensor is O' x H x W x I'
1994 *
1995 * The access function of the tensor with layout
1996 * OHWIo{interleave_by}i{block_by} and size O'HWI' is a 6-parameter
1997 * access function, where the 6 parameters are computed as follows:
1998 *
1999 * x5 = floor(o/{interleave_by}) RANGE [0, O'/{interleave_by} -1] SIZE: O'/{interleave_by}
2000 *
2001 * x4 = h RANGE [0, H-1] SIZE: H
2002 * x3 = w RANGE [0, W-1] SIZE: W
2003 * x2 = floor(i/{block_by}) RANGE [0, I'/{block_by} -1] SIZE: I'/{block_by}
2004 * x1 = o%{interleave_by} RANGE [0, {interleave_by} -1] SIZE: {interleave_by}
2005 * x0 = i%{block_by} RANGE [0, {block_by} -1] SIZE: {block_by}
2006 * TOTAL SIZE: O' * H * W * I'
2007 *
2008 * 4D 6D
2009 * ----------------- -----------------------------------
2010 * value(o, h, w, i) = x5 * H * W * I' * {interleave_by}
2011 * + x4 * W * I' * {interleave_by}
2012 * + x3 * I' * {interleave_by}
2013 * + x2 * {interleave_by} * {block_by}
2014 * + x1 * {block_by}
2015 * + x0
2016 *
2017 * Notice that in arm_gemm the 4D tensor of dimension O'HWI' created
2018 * for the OHWIo{interleave_by}i{block_by} format is in reality seen
2019 * as a 2D tensor, where the number of rows is O'/{interleave_by}
2020 * and the number of columns is {interleave_by} * H * W * I'.
2021 *
2022 * The postfix *_bf16 is for the memory layout needed for the
2023 * fast-mode kernels, in which the weights are passed in bfloat16
2024 * format.
2025 */
2026enum class WeightFormat
2027{
2028 UNSPECIFIED = 0x1,
2029 ANY = 0x2,
2030 OHWI = 0x100100,
2031 OHWIo2 = 0x100200,
2032 OHWIo4 = 0x100400,
2033 OHWIo8 = 0x100800,
2034 OHWIo16 = 0x101000,
2035 OHWIo32 = 0x102000,
2036 OHWIo64 = 0x104000,
2037 OHWIo128 = 0x108000,
2038 OHWIo4i2 = 0x200400,
2039 OHWIo4i2_bf16 = 0x200410,
2040 OHWIo8i2 = 0x200800,
2041 OHWIo8i2_bf16 = 0x200810,
2042 OHWIo16i2 = 0x201000,
2043 OHWIo16i2_bf16 = 0x201010,
2044 OHWIo32i2 = 0x202000,
2045 OHWIo32i2_bf16 = 0x202010,
2046 OHWIo64i2 = 0x204000,
2047 OHWIo64i2_bf16 = 0x204010,
2048 OHWIo4i4 = 0x400400,
2049 OHWIo4i4_bf16 = 0x400410,
2050 OHWIo8i4 = 0x400800,
2051 OHWIo8i4_bf16 = 0x400810,
2052 OHWIo16i4 = 0x401000,
2053 OHWIo16i4_bf16 = 0x401010,
2054 OHWIo32i4 = 0x402000,
2055 OHWIo32i4_bf16 = 0x402010,
2056 OHWIo64i4 = 0x404000,
2057 OHWIo64i4_bf16 = 0x404010,
2058 OHWIo2i8 = 0x800200,
2059 OHWIo4i8 = 0x800400,
2060 OHWIo8i8 = 0x800800,
2061 OHWIo16i8 = 0x801000,
2062 OHWIo32i8 = 0x802000,
2063 OHWIo64i8 = 0x804000
2064};
2065// OHWIo<interleave_by>i<block_by>
2066inline int interleave_by(const WeightFormat wf)
2067{
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002068 return (static_cast<int>(wf) >> 8) & 0xFFF;
Ramy Elgammal91780022022-07-20 14:57:37 +01002069}
2070inline int block_by(const WeightFormat wf)
2071{
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002072 return (static_cast<int>(wf) >> 20) & 0xF;
Ramy Elgammal91780022022-07-20 14:57:37 +01002073}
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002074inline bool is_fixed_format(const WeightFormat &wf)
Ramy Elgammal91780022022-07-20 14:57:37 +01002075{
2076 return wf != WeightFormat::UNSPECIFIED && wf != WeightFormat::ANY;
2077}
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002078inline bool is_fixed_format_fast_math(const WeightFormat &wf)
2079{
2080 return (static_cast<int>(wf) >> 4) & 0x1;
2081}
Ramy Elgammal91780022022-07-20 14:57:37 +01002082
Gian Marco Iodice559d7712017-08-08 08:38:09 +01002083/** 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 +01002084class WeightsInfo
2085{
2086public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002087 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002088 WeightsInfo()
Ramy Elgammal91780022022-07-20 14:57:37 +01002089 : _are_reshaped(false), _kernel_width(0), _kernel_height(0), _num_kernels(0), _retain_internal_weights(false), _weight_format(arm_compute::WeightFormat::UNSPECIFIED)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002090 {
2091 }
2092 /** Constructor
2093 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01002094 * @param[in] are_reshaped True if the weights have been reshaped
2095 * @param[in] kernel_width Kernel width.
2096 * @param[in] kernel_height Kernel height.
2097 * @param[in] num_kernels Number of convolution kernels.
2098 * @param[in] retain_internal_weights (Optional) True if internal reshaped weights must be retained. Used for reconfiguration purposes. Default is false.
Ramy Elgammal91780022022-07-20 14:57:37 +01002099 * @param[in] weight_format (Optional) arm_gemm:WeightFormat enumeration requested by the user. Default is arm_compute::WeightFormat::UNSPECIFIED.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002100 */
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002101 WeightsInfo(bool are_reshaped, unsigned int kernel_width, unsigned int kernel_height, unsigned int num_kernels, bool retain_internal_weights = false,
Ramy Elgammal91780022022-07-20 14:57:37 +01002102 arm_compute::WeightFormat weight_format = arm_compute::WeightFormat::UNSPECIFIED)
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002103 : _are_reshaped(are_reshaped), _kernel_width(kernel_width), _kernel_height(kernel_height), _num_kernels(num_kernels), _retain_internal_weights(retain_internal_weights), _weight_format(weight_format)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002104 {
2105 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002106 /** Flag which specifies if the weights tensor has been reshaped.
2107 *
2108 * @return True if the weights tensors has been reshaped
2109 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002110 bool are_reshaped() const
2111 {
2112 return _are_reshaped;
2113 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01002114 /** Return the number of convolution kernels
2115 *
2116 * @return The number of convolution kernels
2117 */
2118 unsigned int num_kernels() const
2119 {
2120 return _num_kernels;
2121 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002122 /** Return the width and height of the kernel
2123 *
2124 * @return The width and height of the kernel
2125 */
2126 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002127 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002128 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002129 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01002130 bool retain_internal_weights() const
2131 {
2132 return _retain_internal_weights;
2133 }
Ramy Elgammal91780022022-07-20 14:57:37 +01002134 arm_compute::WeightFormat weight_format() const
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002135 {
2136 return _weight_format;
2137 }
Milos Puzovic13b623e2022-07-27 17:53:21 +00002138 void set_weight_format(arm_compute::WeightFormat weight_format)
2139 {
2140 _weight_format = weight_format;
2141 }
2142
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002143 unsigned int kernel_width() const
2144 {
2145 return _kernel_width;
2146 }
2147 unsigned int kernel_height() const
2148 {
2149 return _kernel_height;
2150 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002151
2152private:
Ramy Elgammal91780022022-07-20 14:57:37 +01002153 bool _are_reshaped;
2154 unsigned int _kernel_width;
2155 unsigned int _kernel_height;
2156 unsigned int _num_kernels;
2157 bool _retain_internal_weights;
2158 arm_compute::WeightFormat _weight_format;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002159};
2160
Gian Marco36a0a462018-01-12 10:21:40 +00002161/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
2162 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01002163 * The matrix A can only be reshaped through @ref opencl::kernels::ClGemmReshapeLhsMatrixKernel or @ref cpu::kernels::CpuGemmInterleave4x4Kernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01002164 * 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 +00002165 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01002166 * The matrix B can only be reshaped through @ref opencl::kernels::ClGemmReshapeRhsMatrixKernel or @ref cpu::kernels::CpuGemmTranspose1xWKernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01002167 * 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 +00002168 *
2169 */
2170class GEMMReshapeInfo final
2171{
2172public:
2173 /** Default constructor */
2174 GEMMReshapeInfo()
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002175 : _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 +00002176 {
2177 }
2178 /** Constructor
2179 *
2180 * @param[in] m Number of matrix A rows
2181 * @param[in] n Number of matrix B columns
2182 * @param[in] k Number of matrix A columns or matrix B rows
2183 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
2184 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002185 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
2186 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002187 * @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 +01002188 * to perform 1x1 convolutions with the NHWC data layout)
2189 * @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 +00002190 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002191 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 +01002192 : _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 +01002193 _reinterpret_input_as_3d(reinterpret_input_as_3d), _broadcast_bias(broadcast_bias)
Gian Marco36a0a462018-01-12 10:21:40 +00002194 {
2195 }
2196 /** Number of matrix A rows
2197 *
2198 * @return the number of matrix A rows
2199 */
2200 int m() const
2201 {
2202 return _m;
2203 }
2204 /** Number of matrix B columns
2205 *
2206 * @return the number of matrix B columns
2207 */
2208 int n() const
2209 {
2210 return _n;
2211 }
2212 /** Number of matrix A columns or matrix B rows
2213 *
2214 * @return the number of matrix A columns or matrix B rows
2215 */
2216 int k() const
2217 {
2218 return _k;
2219 }
2220 /** Multiplication factor for the width of the 1xW transposed block
2221 *
2222 * @return the multiplication factor for the width of the 1xW transposed block
2223 */
2224 int mult_transpose1xW_width() const
2225 {
2226 return _mult_transpose1xW_width;
2227 }
2228 /** Multiplication factor for the height of the 4x4 interleaved block
2229 *
2230 * @return the multiplication factor for the height of the 4x4 interleaved block
2231 */
2232 int mult_interleave4x4_height() const
2233 {
2234 return _mult_interleave4x4_height;
2235 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002236 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
2237 *
2238 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
2239 * m = depth_output_gemm3d * output_height
2240 *
2241 * @return the depth of the output tensor to be used with the GEMM3D kernel
2242 */
2243 int depth_output_gemm3d() const
2244 {
2245 return _depth_output_gemm3d;
2246 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002247 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2248 *
2249 * @return True if the input tensor has to be reinterpreted as 3D tensor
2250 */
2251 bool reinterpret_input_as_3d() const
2252 {
2253 return _reinterpret_input_as_3d;
2254 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002255 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2256 *
2257 * @return True if the shape of the bias tensor is to be broadcasted.
2258 */
2259 bool broadcast_bias() const
2260 {
2261 return _broadcast_bias;
2262 };
Gian Marco36a0a462018-01-12 10:21:40 +00002263
2264private:
SiCong Liebd8fb42020-08-18 11:03:14 +01002265 int _m;
2266 int _n;
2267 int _k;
2268 int _mult_transpose1xW_width;
2269 int _mult_interleave4x4_height;
2270 int _depth_output_gemm3d;
2271 bool _reinterpret_input_as_3d;
2272 bool _broadcast_bias;
Gian Marco36a0a462018-01-12 10:21:40 +00002273};
2274
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +01002275struct ConvolutionInfo
2276{
2277 ConvolutionInfo() = default;
2278 ConvolutionInfo(const PadStrideInfo &pad_stride_info, unsigned int depth_multiplier, const ActivationLayerInfo &act_info, const Size2D &dilation)
2279 : pad_stride_info(pad_stride_info), depth_multiplier(depth_multiplier), act_info(act_info), dilation(dilation)
2280 {
2281 }
2282 PadStrideInfo pad_stride_info{}; /**< Convolution info (Pads, strides,...) */
2283 unsigned int depth_multiplier{ 1 }; /**< Multiplier to apply to input's depth to retrieve the output depth. Defaults to 1 */
2284 ActivationLayerInfo act_info{}; /**< Fused activation to apply after convolution. */
2285 Size2D dilation{ Size2D(1, 1) }; /**< Dilation, in elements, across x and y. Defaults to (1, 1). */
2286};
2287
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002288/** GEMMLowp output stage type */
2289enum class GEMMLowpOutputStageType
2290{
Manuel Bottini959c26d2019-12-02 16:22:35 +00002291 NONE, /**< No quantization */
2292 QUANTIZE_DOWN, /**< Quantize using an integer multiplication */
2293 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize using a fixed point multiplication */
2294 QUANTIZE_DOWN_FLOAT /**< Quantize using a floating point multiplication */
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002295};
2296
2297/** GEMMLowp output stage info */
2298struct GEMMLowpOutputStageInfo
2299{
Giorgio Arena1856ff72020-02-07 13:46:45 +00002300 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
2301 int32_t gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
2302 int32_t gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
2303 int32_t gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
2304 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 */
2305 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 */
2306 std::vector<int32_t> gemmlowp_multipliers{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
2307 std::vector<int32_t> gemmlowp_shifts{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
Sheri Zhang1b14c752020-03-09 14:29:52 +00002308 float gemmlowp_real_multiplier{ 0 }; /**< GEMMLowp output stage real multiplier used for quantizing to QASYMM8 */
Giorgio Arena1856ff72020-02-07 13:46:45 +00002309 bool is_quantized_per_channel{ false }; /**< GEMMLowp quantized per-channel flag */
2310 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 +01002311};
2312
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00002313/** GEMM LHS (Left Hand Side) matrix information */
2314struct GEMMLHSMatrixInfo
2315{
morgolockaba2f912020-05-05 16:28:19 +01002316 GEMMLHSMatrixInfo() = default;
2317 GEMMLHSMatrixInfo(unsigned int m, unsigned int k, unsigned int v, bool trans, bool inter)
2318 : m0(m), k0(k), v0(v), transpose(trans), interleave(inter)
2319 {
2320 }
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00002321 unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
2322 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
2323 unsigned int v0{ 1 }; /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
2324 bool transpose{ true }; /**< True if the (m0xk0) block has to be transposed before been stored */
2325 bool interleave{ true }; /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
2326};
2327
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00002328/** GEMM RHS (Right Hand Side) matrix information */
2329struct GEMMRHSMatrixInfo
2330{
morgolockaba2f912020-05-05 16:28:19 +01002331 GEMMRHSMatrixInfo() = default;
Gian Marco Iodicee3a849a2020-06-10 17:59:30 +01002332 GEMMRHSMatrixInfo(unsigned int n, unsigned int k, unsigned int h, bool trans, bool inter, bool export_to_cl_img)
2333 : n0(n), k0(k), h0(h), transpose(trans), interleave(inter), export_to_cl_image(export_to_cl_img)
morgolockaba2f912020-05-05 16:28:19 +01002334 {
2335 }
Gian Marco Iodicedd717c32020-05-28 10:22:03 +01002336 unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
2337 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
2338 unsigned int h0{ 1 }; /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
2339 bool transpose{ true }; /**< True if the (k0xn0) block has to be transposed before been stored */
2340 bool interleave{ true }; /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
2341 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 +00002342};
2343
SiCongLi579ca842021-10-18 09:38:33 +01002344class ITensorInfo;
Gian Marco36a0a462018-01-12 10:21:40 +00002345/** GEMM information class. This class stores the necessary information to compute GEMM functions
2346 *
2347 * This object also contains the information about how matrix A and matrix B have been reshaped
2348 *
2349 */
Chunosov5124be52017-11-22 20:42:13 +07002350class GEMMInfo
2351{
2352public:
2353 /** Default constructor */
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002354 GEMMInfo() noexcept
2355 : _is_a_reshaped(false),
2356 _is_b_reshaped(false),
2357 _reshape_b_only_on_first_run(true),
2358 _depth_output_gemm3d(0),
2359 _reinterpret_input_as_3d(false),
2360 _retain_internal_weights(false),
2361 _gemmlowp_output_stage(),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002362 _fast_math(false),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002363 _fp_mixed_precision(false),
2364 _broadcast_bias(false),
Adnan AlSinanc5849582022-05-05 11:13:19 +01002365 _pretranspose_A(false),
2366 _pretranspose_B(false),
SiCongLi579ca842021-10-18 09:38:33 +01002367 _activation_info(),
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002368 _post_ops(),
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002369 _fixed_format(false),
Ramy Elgammal91780022022-07-20 14:57:37 +01002370 _weight_format(arm_compute::WeightFormat::UNSPECIFIED)
Chunosov5124be52017-11-22 20:42:13 +07002371 {
2372 }
2373 /** Constructor
2374 *
2375 * @param[in] is_a_reshaped True if the matrix A has been reshaped
2376 * @param[in] is_b_reshaped True if the matrix B has been reshaped
2377 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002378 * @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 +00002379 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002380 * @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
2381 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002382 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002383 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002384 * @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 +01002385 * @param[in] fast_math (Optional) Use a data type of shorter width to improve performance
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002386 * @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 +01002387 * @param[in] activation_info (Optional) Activation to apply after the matrix multiplication
SiCongLi579ca842021-10-18 09:38:33 +01002388 * @param[in] post_ops (Optional) A sequence of post operations that are performed after the main operation.
Ramy Elgammal91780022022-07-20 14:57:37 +01002389 * @param[in] fixed_format (Optional) Specify the selection of fixed format kernels for variable weights support in GEMM. These kernels expect the weights tensor to be in amemory format that is fixed by the kernel itself. For more information, see arm_compute::WeightFormat.
2390 * @param[in] weight_format (Optional) arm_gemm:WeightFormat enumeration requested by the user. Default is arm_compute::WeightFormat::UNSPECIFIED.
Chunosov5124be52017-11-22 20:42:13 +07002391 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002392 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 +01002393 GEMMLowpOutputStageInfo gemmlowp_output_stage = GEMMLowpOutputStageInfo(), bool fp_mixed_precision = false, bool fast_math = false, bool broadcast_bias = false,
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002394 const ActivationLayerInfo &activation_info = ActivationLayerInfo(), const experimental::PostOpList<ITensorInfo *> &post_ops = experimental::PostOpList<ITensorInfo *>(),
Ramy Elgammal91780022022-07-20 14:57:37 +01002395 bool fixed_format = false, arm_compute::WeightFormat weight_format = arm_compute::WeightFormat::UNSPECIFIED) noexcept
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002396 : _is_a_reshaped(is_a_reshaped),
2397 _is_b_reshaped(is_b_reshaped),
2398 _reshape_b_only_on_first_run(reshape_b_only_on_first_run),
2399 _depth_output_gemm3d(depth_output_gemm3d),
2400 _reinterpret_input_as_3d(reinterpret_input_as_3d),
2401 _retain_internal_weights(retain_internal_weights),
2402 _gemmlowp_output_stage(gemmlowp_output_stage),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002403 _fast_math(fast_math),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002404 _fp_mixed_precision(fp_mixed_precision),
2405 _broadcast_bias(broadcast_bias),
Adnan AlSinanc5849582022-05-05 11:13:19 +01002406 _pretranspose_A(false),
2407 _pretranspose_B(false),
SiCongLi579ca842021-10-18 09:38:33 +01002408 _activation_info(activation_info),
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002409 _post_ops(post_ops),
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002410 _fixed_format(fixed_format),
2411 _weight_format(weight_format)
Chunosov5124be52017-11-22 20:42:13 +07002412 {
2413 }
2414 /** Flag which specifies if the matrix A has been reshaped
2415 *
2416 * @return True if the matrix A has been reshaped
2417 */
2418 bool is_a_reshaped() const
2419 {
2420 return _is_a_reshaped;
2421 };
2422 /** Flag which specifies if the matrix B has been reshaped
2423 *
2424 * @return True if the matrix B has been reshaped
2425 */
2426 bool is_b_reshaped() const
2427 {
2428 return _is_b_reshaped;
2429 };
2430 /** Flag which specifies if the reshape of matrix B should executed only for the first
2431 *
2432 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
2433 *
2434 * @return True if the reshaped of matrix B happens only for the first run
2435 */
2436 bool reshape_b_only_on_first_run() const
2437 {
2438 return _reshape_b_only_on_first_run;
2439 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002440 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002441 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002442 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002443 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002444 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00002445 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002446 return _depth_output_gemm3d;
2447 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002448 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2449 *
2450 * @return True if the input tensor has to be reinterpreted as 3D tensor
2451 */
2452 bool reinterpret_input_as_3d() const
2453 {
2454 return _reinterpret_input_as_3d;
2455 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002456 /** Flag which specifies if the weights tensor has to be retained from previous run
2457 *
2458 * @return True if the weights tensor has to be retained
2459 */
2460 bool retain_internal_weights() const
2461 {
2462 return _retain_internal_weights;
2463 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002464 /** GEMMLowp output stage
2465 *
2466 * @return the GEMMLowp output stage info
2467 */
2468 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
2469 {
2470 return _gemmlowp_output_stage;
2471 };
Georgios Pinitasdbdea0d2019-10-16 19:21:40 +01002472 /** Sets GEMMLowp output stage
2473 *
2474 * @param[in] output_stage Output stage to set
2475 */
2476 void set_gemmlowp_output_stage(GEMMLowpOutputStageInfo &output_stage)
2477 {
2478 _gemmlowp_output_stage = output_stage;
2479 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002480 /** Flag which specifies if a wider accumulator should be used.
2481 *
2482 * @return True if a wider accumulator has to be used
2483 */
2484 bool fp_mixed_precision() const
2485 {
2486 return _fp_mixed_precision;
2487 };
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002488 /** Flag which specifies if a shorter accumulator to be used.
2489 *
2490 * @return True if a shorter accumulator has to be used
2491 */
2492 bool fast_math() const
2493 {
2494 return _fast_math;
2495 };
cfRodf2c022e2021-11-05 11:29:53 +00002496 /** Set fast math flag
2497 *
2498 * @param[in] fast_math Flag to set
2499 */
2500 void set_fast_math(bool fast_math)
2501 {
2502 _fast_math = fast_math;
2503 }
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002504 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2505 *
2506 * @return True if the shape of the bias tensor is to be broadcasted.
2507 */
2508 bool broadcast_bias() const
2509 {
2510 return _broadcast_bias;
2511 };
Adnan AlSinanc5849582022-05-05 11:13:19 +01002512 /** Flag which specifies whether A should be pre-transposed if supported.
2513 *
2514 * @return True if A should be pre-transposed else false.
2515 */
2516 bool pretranspose_A() const
2517 {
2518 return _pretranspose_A;
2519 };
2520 /** Set pre-transpose A flag
2521 *
2522 * @param[in] flag Flag to set
2523 */
2524 void set_pretranspose_A(bool flag)
2525 {
2526 _pretranspose_A = flag;
2527 }
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002528 /** Flag which specifies whether b should be pre-transposed if supported.
2529 *
2530 * @return True if b should be pre-transposed else false.
2531 */
ramelg01cbbb0382021-09-17 17:36:57 +01002532 bool pretranspose_B() const
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002533 {
ramelg01cbbb0382021-09-17 17:36:57 +01002534 return _pretranspose_B;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002535 };
2536 /** Set pre-transpose b flag
2537 *
2538 * @param[in] flag Flag to set
2539 */
ramelg01cbbb0382021-09-17 17:36:57 +01002540 void set_pretranspose_B(bool flag)
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002541 {
ramelg01cbbb0382021-09-17 17:36:57 +01002542 _pretranspose_B = flag;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002543 }
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002544 /** Activation layer to apply after the matrix multiplication
2545 *
2546 * @return ActivationLayerInfo object
2547 */
2548 ActivationLayerInfo activation_info() const
2549 {
2550 return _activation_info;
2551 }
SiCongLi2e5fd632020-03-02 15:39:15 +00002552 /** Set activation layer info
2553 *
2554 * @param[in] activation_info ActivationLayerInfo object to set
2555 */
2556 void set_activation_info(const ActivationLayerInfo &activation_info)
2557 {
2558 _activation_info = activation_info;
2559 }
SiCongLi579ca842021-10-18 09:38:33 +01002560 /** Post operations to apply after the matrix multiplication
2561 *
2562 * @return experimental::PostOpList object
2563 */
2564 const experimental::PostOpList<ITensorInfo *> &post_ops() const
2565 {
2566 return _post_ops;
2567 }
2568 /** Set post ops
2569 *
2570 * @param[in] post_ops experimental::PostOpList object to set
2571 */
2572 void set_post_ops(const experimental::PostOpList<ITensorInfo *> &post_ops)
2573 {
2574 _post_ops = post_ops;
2575 }
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002576 /** Flag which specifies if the GEMM operation is running fixed-format kernels.
2577 *
2578 * @return True if the GEMM operation is running fixed-format kernel else false.
2579 */
2580 bool fixed_format() const
2581 {
2582 return _fixed_format;
2583 }
Chunosov5124be52017-11-22 20:42:13 +07002584
Milos Puzovic13b623e2022-07-27 17:53:21 +00002585 /** Set fixed-format flag
2586 *
2587 * @param[in] fixed_format sets whether or not to use fixed-format kernels
2588 */
2589 void set_fixed_format(bool fixed_format)
2590 {
2591 _fixed_format = fixed_format;
2592 }
2593
Ramy Elgammal91780022022-07-20 14:57:37 +01002594 arm_compute::WeightFormat weight_format() const
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002595 {
2596 return _weight_format;
2597 }
2598
Milos Puzovic13b623e2022-07-27 17:53:21 +00002599 /** Set weight format to be used
2600 *
2601 * @param[in] weight_format arm_compute::WeightFormat enumeration
2602 */
2603 void set_weight_format(arm_compute::WeightFormat weight_format)
2604 {
2605 _weight_format = weight_format;
2606 }
2607
Chunosov5124be52017-11-22 20:42:13 +07002608private:
SiCongLi579ca842021-10-18 09:38:33 +01002609 bool _is_a_reshaped;
2610 bool _is_b_reshaped;
2611 bool _reshape_b_only_on_first_run;
2612 int _depth_output_gemm3d;
2613 bool _reinterpret_input_as_3d;
2614 bool _retain_internal_weights;
2615 GEMMLowpOutputStageInfo _gemmlowp_output_stage;
2616 bool _fast_math;
2617 bool _fp_mixed_precision;
2618 bool _broadcast_bias;
Adnan AlSinanc5849582022-05-05 11:13:19 +01002619 bool _pretranspose_A;
SiCongLi579ca842021-10-18 09:38:33 +01002620 bool _pretranspose_B;
2621 ActivationLayerInfo _activation_info;
2622 experimental::PostOpList<ITensorInfo *> _post_ops;
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002623 bool _fixed_format;
Ramy Elgammal91780022022-07-20 14:57:37 +01002624 arm_compute::WeightFormat _weight_format;
Chunosov5124be52017-11-22 20:42:13 +07002625};
2626
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00002627/** Winograd information */
2628struct WinogradInfo
2629{
2630 /** Default constructor
2631 *
2632 * @param[in] output_tile_sz Width and height of the output tile
2633 * @param[in] kernel_sz Width and height of the kernel
2634 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
2635 * @param[in] conv_info Convolution info (Pads, strides)
2636 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
2637 */
2638 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
2639 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
2640 {
2641 }
2642
2643 Size2D output_tile_size{}; /**< Width and height of the output tile */
2644 Size2D kernel_size{}; /**< Width and height of the kernel*/
2645 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
2646 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
2647 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
2648};
2649
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002650/** IO formatting information class*/
2651struct IOFormatInfo
2652{
2653 /** Precision type used when printing floating point numbers */
2654 enum class PrecisionType
2655 {
2656 Default, /**< Default precision to the one that the current stream has */
2657 Custom, /**< Custom precision specified by the user using the precision parameter */
2658 Full /**< The maximum precision of the floating point representation */
2659 };
2660
2661 /** Specifies the area to be printed, used by Tensor objects */
2662 enum class PrintRegion
2663 {
2664 ValidRegion, /**< Prints the valid region of the Tensor object */
2665 NoPadding, /**< Prints the Tensor object without the padding */
2666 Full /**< Print the tensor object including padding */
2667 };
2668
Alex Gildayc357c472018-03-21 13:54:09 +00002669 /** Construct a set of IO formatting information.
2670 *
2671 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
2672 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
2673 * @param[in] precision Precision value for float point numbers. Default: 10.
2674 * @param[in] align_columns Whether to align columns when printed. Default: true.
2675 * @param[in] element_delim Delimeter between elements. Default: " ".
2676 * @param[in] row_delim Delimenter between rows. Default: "\n".
2677 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002678 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
2679 PrecisionType precision_type = PrecisionType::Default,
2680 unsigned int precision = 10,
2681 bool align_columns = true,
2682 std::string element_delim = " ",
2683 std::string row_delim = "\n")
2684 : print_region(print_region),
2685 precision_type(precision_type),
2686 precision(precision),
2687 element_delim(element_delim),
2688 row_delim(row_delim),
2689 align_columns(align_columns)
2690 {
2691 }
2692
Alex Gildayc357c472018-03-21 13:54:09 +00002693 /** Area to be printed by Tensor objects */
2694 PrintRegion print_region;
2695 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002696 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00002697 /** Floating point precision */
2698 unsigned int precision;
2699 /** Element delimeter */
2700 std::string element_delim;
2701 /** Row delimeter */
2702 std::string row_delim;
2703 /** Align columns */
2704 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002705};
Mohammed Suhail Munshid538d162023-02-16 16:22:32 +00002706
2707/** Class for holding information related to matrix multiplication function
2708 */
2709class MatMulInfo
2710{
2711public:
2712 /* Get Adjoint LHS flag value */
2713 bool adj_lhs() const
2714 {
2715 return _adj_lhs;
2716 }
2717 /* Get Adjoint RHS flag value */
2718 bool adj_rhs() const
2719 {
2720 return _adj_rhs;
2721 }
2722 /* Get Fused Activation Layer Info */
2723 ActivationLayerInfo fused_activation() const
2724 {
2725 return _fused_act;
2726 }
2727 /* Set Adjoint LHS flag */
2728 MatMulInfo& adj_lhs(bool adj_lhs)
2729 {
2730 _adj_lhs = adj_lhs;
2731 return *this;
2732 }
2733 /* Set Adjoint RHS flag */
2734 MatMulInfo& adj_rhs(bool adj_rhs)
2735 {
2736 _adj_rhs = adj_rhs;
2737 return *this;
2738 }
2739 /* Set Fused Activation Layer Info */
2740 MatMulInfo& fused_activation(const ActivationLayerInfo& act_info)
2741 {
2742 _fused_act = act_info;
2743 return *this;
2744 }
2745private:
2746 bool _adj_lhs{false};
2747 bool _adj_rhs{false};
2748 ActivationLayerInfo _fused_act{}; // disabled by default
2749};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00002750} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +00002751#endif /* ARM_COMPUTE_TYPES_H */