blob: 946b8a6cb63d83cce63cbd9370ce882b3b95dff8 [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),
Adnan AlSinanbbf2e742023-02-22 12:15:14 +00001213 use_inf_as_limit(true),
1214 use_kernel_indices(false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001215 {
1216 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001217 /** Constructor
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001218 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001219 * @param[in] pool_type Pooling type @ref PoolingType.
1220 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001221 * @param[in] data_layout Data layout used by the layer @ref DataLayout
1222 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1223 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1224 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1225 * Defaults to false;
1226 * @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 +00001227 * @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.
Adnan AlSinanbbf2e742023-02-22 12:15:14 +00001228 * @param[in] use_kernel_indices (Optional) Use kernel indices instead of using source indices while computing indices tensor.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001229 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001230 explicit PoolingLayerInfo(PoolingType pool_type,
1231 unsigned int pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001232 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001233 PadStrideInfo pad_stride_info = PadStrideInfo(),
1234 bool exclude_padding = false,
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001235 bool fp_mixed_precision = false,
Adnan AlSinanbbf2e742023-02-22 12:15:14 +00001236 bool use_inf_as_limit = true,
1237 bool use_kernel_indices = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001238 : pool_type(pool_type),
1239 pool_size(Size2D(pool_size, pool_size)),
1240 data_layout(data_layout),
1241 pad_stride_info(pad_stride_info),
1242 exclude_padding(exclude_padding),
1243 is_global_pooling(false),
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001244 fp_mixed_precision(fp_mixed_precision),
Adnan AlSinanbbf2e742023-02-22 12:15:14 +00001245 use_inf_as_limit(use_inf_as_limit),
1246 use_kernel_indices(use_kernel_indices)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001247 {
1248 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001249
1250 /** Constructor
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001251 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001252 * @param[in] pool_type Pooling type @ref PoolingType.
1253 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001254 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001255 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1256 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1257 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1258 * Defaults to false;
1259 * @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 +00001260 * @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.
Adnan AlSinanbbf2e742023-02-22 12:15:14 +00001261 * @param[in] use_kernel_indices (Optional) Use kernel indices instead of using source indices while computing indices tensor.
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001262 */
1263 explicit PoolingLayerInfo(PoolingType pool_type,
1264 Size2D pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001265 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001266 PadStrideInfo pad_stride_info = PadStrideInfo(),
1267 bool exclude_padding = false,
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001268 bool fp_mixed_precision = false,
Adnan AlSinanbbf2e742023-02-22 12:15:14 +00001269 bool use_inf_as_limit = true,
1270 bool use_kernel_indices = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001271 : pool_type(pool_type),
1272 pool_size(pool_size),
1273 data_layout(data_layout),
1274 pad_stride_info(pad_stride_info),
1275 exclude_padding(exclude_padding),
1276 is_global_pooling(false),
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001277 fp_mixed_precision(fp_mixed_precision),
Adnan AlSinanbbf2e742023-02-22 12:15:14 +00001278 use_inf_as_limit(use_inf_as_limit),
1279 use_kernel_indices(use_kernel_indices)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001280 {
1281 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001282
1283 /** Constructor
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001284 *
1285 * @note This constructor is used for global pooling
1286 *
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001287 * @param[in] pool_type Pooling type @ref PoolingType.
1288 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001289 */
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001290 explicit PoolingLayerInfo(PoolingType pool_type, DataLayout data_layout)
1291 : pool_type(pool_type),
1292 pool_size(Size2D()),
1293 data_layout(data_layout),
1294 pad_stride_info(PadStrideInfo(1, 1, 0, 0)),
1295 exclude_padding(false),
1296 is_global_pooling(true),
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001297 fp_mixed_precision(false),
Adnan AlSinanbbf2e742023-02-22 12:15:14 +00001298 use_inf_as_limit(true),
1299 use_kernel_indices(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001300 {
1301 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001302
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001303 PoolingType pool_type;
1304 Size2D pool_size;
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001305 DataLayout data_layout;
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001306 PadStrideInfo pad_stride_info;
1307 bool exclude_padding;
1308 bool is_global_pooling;
1309 bool fp_mixed_precision;
Adnan AlSinan227db8d2023-02-14 14:24:09 +00001310 bool use_inf_as_limit;
Adnan AlSinanbbf2e742023-02-22 12:15:14 +00001311 bool use_kernel_indices;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001312};
1313
ramelg0137515692022-02-26 22:06:20 +00001314/** Pooling Layer Information struct*/
1315struct Pooling3dLayerInfo
1316{
1317 /** Default Constructor */
Michalis Spyrou50e48aa2022-04-21 16:42:56 +01001318 Pooling3dLayerInfo() noexcept
ramelg0137515692022-02-26 22:06:20 +00001319 : pool_type(PoolingType::MAX),
1320 pool_size(Size3D()),
1321 stride(Size3D()),
1322 padding(Padding3D()),
1323 exclude_padding(false),
1324 is_global_pooling(false),
1325 fp_mixed_precision(false),
1326 round_type(DimensionRoundingType::FLOOR)
1327 {
1328 }
1329 /** Constructor
1330 *
1331 * @param[in] pool_type Pooling type @ref PoolingType.
1332 * @param[in] pool_size Pooling size, in elements, across x, y and z.
1333 * @param[in] stride (Optional) stride information @ref Size3D
1334 * @param[in] padding (Optional) padding information @ref Padding3D
1335 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1336 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1337 * Defaults to false;
1338 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1339 * @param[in] round_type (Optional) Dimensions rounding. Defaults to @ref FLOOR
1340 */
1341 explicit Pooling3dLayerInfo(PoolingType pool_type,
1342 unsigned int pool_size,
1343 Size3D stride = Size3D(1U, 1U, 1U),
1344 Padding3D padding = Padding3D(),
1345 bool exclude_padding = false,
1346 bool fp_mixed_precision = false,
1347 DimensionRoundingType round_type = DimensionRoundingType::FLOOR)
1348 : pool_type(pool_type),
1349 pool_size(Size3D(pool_size, pool_size, pool_size)),
1350 stride(stride),
1351 padding(padding),
1352 exclude_padding(exclude_padding),
1353 is_global_pooling(false),
1354 fp_mixed_precision(fp_mixed_precision),
1355 round_type(round_type)
1356 {
1357 }
1358
1359 /** Constructor
1360 *
1361 * @param[in] pool_type Pooling type @ref PoolingType.
1362 * @param[in] pool_size Pooling size, in elements, across x, y and z.
1363 * @param[in] stride (Optional) stride information @ref Size3D
1364 * @param[in] padding (Optional) padding information @ref Padding3D
1365 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1366 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1367 * Defaults to false;
1368 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1369 * @param[in] round_type (Optional) Dimensions rounding. Defaults to @ref FLOOR
1370 */
1371 explicit Pooling3dLayerInfo(PoolingType pool_type,
1372 Size3D pool_size,
1373 Size3D stride = Size3D(1U, 1U, 1U),
1374 Padding3D padding = Padding3D(),
1375 bool exclude_padding = false,
1376 bool fp_mixed_precision = false,
1377 DimensionRoundingType round_type = DimensionRoundingType::FLOOR)
1378 : pool_type(pool_type),
1379 pool_size(pool_size),
1380 stride(stride),
1381 padding(padding),
1382 exclude_padding(exclude_padding),
1383 is_global_pooling(false),
1384 fp_mixed_precision(fp_mixed_precision),
1385 round_type(round_type)
1386 {
1387 }
1388
1389 /** Constructor
1390 *
1391 * @note This constructor is used for global pooling
1392 *
1393 * @param[in] pool_type Pooling type @ref PoolingType.
1394 */
1395 explicit Pooling3dLayerInfo(PoolingType pool_type)
1396 : pool_type(pool_type),
1397 pool_size(Size3D()),
1398 stride(Size3D(1U, 1U, 1U)),
1399 padding(Padding3D(0, 0, 0)),
1400 exclude_padding(false),
1401 is_global_pooling(true),
1402 fp_mixed_precision(false),
1403 round_type(DimensionRoundingType::FLOOR)
1404 {
1405 }
1406
1407 PoolingType pool_type;
1408 Size3D pool_size;
1409 Size3D stride;
1410 Padding3D padding;
1411 bool exclude_padding;
1412 bool is_global_pooling;
1413 bool fp_mixed_precision;
1414 DimensionRoundingType round_type;
1415};
1416
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001417/** ROI Pooling Layer Information class */
giuros0118870812018-09-13 09:31:40 +01001418class ROIPoolingLayerInfo final
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001419{
1420public:
giuros0118870812018-09-13 09:31:40 +01001421 /** Constructor
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001422 *
giuros0118870812018-09-13 09:31:40 +01001423 * @param[in] pooled_width Pooled width of the layer.
1424 * @param[in] pooled_height Pooled height of the layer.
1425 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
1426 * @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 +01001427 */
giuros0118870812018-09-13 09:31:40 +01001428 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale, unsigned int sampling_ratio = 0)
1429 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale), _sampling_ratio(sampling_ratio)
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001430 {
1431 }
Alex Gildayc357c472018-03-21 13:54:09 +00001432 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001433 unsigned int pooled_width() const
1434 {
1435 return _pooled_width;
1436 }
Alex Gildayc357c472018-03-21 13:54:09 +00001437 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001438 unsigned int pooled_height() const
1439 {
1440 return _pooled_height;
1441 }
Alex Gildayc357c472018-03-21 13:54:09 +00001442 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001443 float spatial_scale() const
1444 {
1445 return _spatial_scale;
1446 }
giuros0118870812018-09-13 09:31:40 +01001447 /** Get sampling ratio */
1448 unsigned int sampling_ratio() const
1449 {
1450 return _sampling_ratio;
1451 }
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001452
1453private:
1454 unsigned int _pooled_width;
1455 unsigned int _pooled_height;
1456 float _spatial_scale;
giuros0118870812018-09-13 09:31:40 +01001457 unsigned int _sampling_ratio;
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001458};
1459
Manuel Bottini5209be52019-02-13 16:34:56 +00001460/** Generate Proposals Information class */
1461class GenerateProposalsInfo
1462{
1463public:
1464 /** Constructor
1465 *
1466 * @param[in] im_width Width of the original image
1467 * @param[in] im_height Height of the original image
1468 * @param[in] im_scale Scale applied to the original image
1469 * @param[in] spatial_scale (Optional)Scale applied to the feature map. Defaults to 1.0
1470 * @param[in] pre_nms_topN (Optional)Number of the best scores to be selected from the transformations. Defaults to 6000.
1471 * @param[in] post_nms_topN (Optional)Number of the best scores to be selected from the NMS operation. Defaults to 300.
1472 * @param[in] nms_thres (Optional)NMS overlap threshold. Defaults to 0.7.
1473 * @param[in] min_size (Optional)Size used to validate the anchors produced. Defaults to 16.
1474 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region of interest). Defaults to 4.
1475 */
1476 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,
1477 size_t values_per_roi = 4)
1478 : _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),
1479 _min_size(min_size), _values_per_roi(values_per_roi)
1480 {
1481 }
1482
1483 /* Get the original height */
1484 float im_height() const
1485 {
1486 return _im_height;
1487 }
1488 /* Get the original width */
1489 float im_width() const
1490 {
1491 return _im_width;
1492 }
1493 /* Get the image scale */
1494 float im_scale() const
1495 {
1496 return _im_scale;
1497 }
1498 /* Get the value of how many best scores to select (before NMS) */
1499 int pre_nms_topN() const
1500 {
1501 return _pre_nms_topN;
1502 }
1503 /* Get the value of how many best scores to select (after NMS) */
1504 int post_nms_topN() const
1505 {
1506 return _post_nms_topN;
1507 }
1508 /* Get the NMS overlap threshold */
1509 float nms_thres() const
1510 {
1511 return _nms_thres;
1512 }
1513 /* Get the minimal size */
1514 float min_size() const
1515 {
1516 return _min_size;
1517 }
1518 /* Get the spatial scale to be applied to the feature maps */
1519 float spatial_scale() const
1520 {
1521 return _spatial_scale;
1522 }
1523 /* Get the values used to represent a ROI(Region of interest)*/
1524 size_t values_per_roi() const
1525 {
1526 return _values_per_roi;
1527 }
1528
1529private:
1530 float _im_height;
1531 float _im_width;
1532 float _im_scale;
1533 float _spatial_scale;
1534 int _pre_nms_topN;
1535 int _post_nms_topN;
1536 float _nms_thres;
1537 float _min_size;
1538 size_t _values_per_roi;
1539};
1540
1541/** ComputeAnchors information class */
1542class ComputeAnchorsInfo
1543{
1544public:
1545 /** Constructor
1546 *
1547 * @param[in] feat_width Feature map width
1548 * @param[in] feat_height Feature map height
1549 * @param[in] spatial_scale Feature map scale
1550 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region Of Interest). Defaults to 4
1551 */
1552 ComputeAnchorsInfo(float feat_width, float feat_height, float spatial_scale, size_t values_per_roi = 4)
1553 : _feat_height(feat_height),
1554 _feat_width(feat_width),
1555 _spatial_scale(spatial_scale),
1556 _values_per_roi(values_per_roi)
1557 {
1558 }
1559
1560 /* Get the height of the feature map */
1561 float feat_height() const
1562 {
1563 return _feat_height;
1564 }
1565
1566 /* Get the width of the feature map */
1567 float feat_width() const
1568 {
1569 return _feat_width;
1570 }
1571
1572 /* Get the scale of the feature map */
1573 float spatial_scale() const
1574 {
1575 return _spatial_scale;
1576 }
1577
1578 /* Get the values used to represent a ROI(Region Of Interest)*/
1579 size_t values_per_roi() const
1580 {
1581 return _values_per_roi;
1582 }
1583
1584private:
1585 float _feat_height;
1586 float _feat_width;
1587 float _spatial_scale;
1588 size_t _values_per_roi;
1589};
1590
giuros01c04a0e82018-10-03 12:44:35 +01001591/** Bounding Box Transform information class */
giuros01d696cb62018-11-16 10:39:59 +00001592class BoundingBoxTransformInfo final
giuros01c04a0e82018-10-03 12:44:35 +01001593{
1594public:
1595 /** Constructor
1596 *
giuros01d696cb62018-11-16 10:39:59 +00001597 * @param[in] img_width Width of the original image
1598 * @param[in] img_height Height, of the original image
1599 * @param[in] scale Scale of the original image
1600 * @param[in] apply_scale (Optional)Re-apply scaling after transforming the boxes. Defaults to false
1601 * @param[in] weights (Optional)Weights [wx, wy, ww, wh] for the deltas. Defaults to all ones
1602 * @param[in] correct_transform_coords (Optional)Correct bounding box transform coordinates. Defaults to false
1603 * @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 +01001604 */
giuros01d696cb62018-11-16 10:39:59 +00001605 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 =
1606 false,
1607 float bbox_xform_clip =
1608 4.135166556742356f)
1609 : _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 +01001610 {
1611 }
1612
1613 std::array<float, 4> weights() const
1614 {
1615 return _weights;
1616 }
1617
1618 float bbox_xform_clip() const
1619 {
1620 return _bbox_xform_clip;
1621 }
1622
1623 float img_height() const
1624 {
1625 return _img_height;
1626 }
1627
1628 float img_width() const
1629 {
1630 return _img_width;
1631 }
1632
1633 float scale() const
1634 {
1635 return _scale;
1636 }
1637
1638 bool apply_scale() const
1639 {
1640 return _apply_scale;
1641 }
1642
giuros01d696cb62018-11-16 10:39:59 +00001643 bool correct_transform_coords() const
1644 {
1645 return _correct_transform_coords;
1646 }
1647
giuros01c04a0e82018-10-03 12:44:35 +01001648private:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001649 float _img_width;
1650 float _img_height;
1651 float _scale;
1652 bool _apply_scale;
1653 bool _correct_transform_coords;
giuros01c04a0e82018-10-03 12:44:35 +01001654 std::array<float, 4> _weights;
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001655 float _bbox_xform_clip;
giuros01c04a0e82018-10-03 12:44:35 +01001656};
1657
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001658/** Activation Layer Information class */
1659class ActivationLayerInfo
1660{
1661public:
1662 /** Available activation functions */
1663 enum class ActivationFunction
1664 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001665 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
1666 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
1667 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
1668 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
1669 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
Manuel Bottini581c8982019-02-07 10:31:57 +00001670 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 +01001671 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
Georgios Pinitasfb0fdcd2019-08-22 17:10:04 +01001672 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 +01001673 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
1674 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
1675 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
Usama Arif6a98a6e2019-05-10 17:07:27 +01001676 LINEAR, /**< Linear ( \f$ f(x)= ax + b \f$ ) */
morgolock07df3d42020-02-27 11:46:28 +00001677 IDENTITY, /**< Identity ( \f$ f(x)= x \f$ ) */
Jonathan Deakind6b8a712022-08-23 11:44:18 +01001678 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 +01001679 SWISH, /**< Swish ( \f$ f(x) = \frac{x}{1 + e^{-ax}} = x \text{logistic}(ax) \f$ ) */
Murray Kornelsen926f5022022-07-13 21:22:39 -04001680 GELU /**< GELU ( \f$ f(x) = x * 1/2 * 1 + erf(x / \sqrt{2}) \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001681 };
1682
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001683 /** Lookup table */
1684 using LookupTable256 = std::array<qasymm8_t, 256>;
1685
Giorgio Arena11674872018-02-07 15:38:12 +00001686 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001687 /** Default Constructor
1688 *
1689 * @param[in] f The activation function to use.
1690 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001691 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1692 * @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 +01001693 */
1694 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001695 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001696 {
1697 }
Alex Gildayc357c472018-03-21 13:54:09 +00001698 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001699 ActivationFunction activation() const
1700 {
1701 return _act;
1702 }
Alex Gildayc357c472018-03-21 13:54:09 +00001703 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001704 float a() const
1705 {
1706 return _a;
1707 }
Alex Gildayc357c472018-03-21 13:54:09 +00001708 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001709 float b() const
1710 {
1711 return _b;
1712 }
Alex Gildayc357c472018-03-21 13:54:09 +00001713 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001714 bool enabled() const
1715 {
1716 return _enabled;
1717 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001718
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001719#ifdef __aarch64__
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001720 const LookupTable256 &lut() const
1721 {
1722 return _lut;
1723 }
1724
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001725 void init_lut(DataType data_type, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001726 {
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001727 if(_act == ActivationFunction::HARD_SWISH)
1728 {
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001729 if(data_type == DataType::QASYMM8)
1730 {
1731 qasymm8_hard_swish_populate_table(_lut, qi_in, qi_out);
1732 }
1733 else
1734 {
1735 qasymm8_signed_hard_swish_populate_table(_lut, qi_in, qi_out);
1736 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001737 }
1738 else if(_act == ActivationFunction::LEAKY_RELU)
1739 {
1740 qasymm8_leaky_relu_populate_table(_lut, qi_in, qi_out, _a);
1741 }
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001742 else if(_act == ActivationFunction::LOGISTIC)
1743 {
1744 if(data_type == DataType::QASYMM8)
1745 {
1746 qasymm8_logistic_populate_table(_lut, qi_in, qi_out);
1747 }
1748 else
1749 {
1750 qasymm8_signed_logistic_populate_table(_lut, qi_in, qi_out);
1751 }
1752 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001753 }
1754#endif // __aarch64__
1755
1756 static inline bool is_lut_supported(ActivationFunction act_func, DataType data_type)
1757 {
1758#ifdef __aarch64__
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001759 switch(act_func)
1760 {
1761 case ActivationFunction::HARD_SWISH:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001762 return data_type == DataType::QASYMM8 || data_type == DataType::QASYMM8_SIGNED;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001763 case ActivationFunction::LEAKY_RELU:
1764 return data_type == DataType::QASYMM8;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001765 case ActivationFunction::LOGISTIC:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001766 return data_type == DataType::QASYMM8 || data_type == DataType::QASYMM8_SIGNED;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001767 default:
1768 return false;
1769 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001770#else // __aarch64__
1771 ARM_COMPUTE_UNUSED(act_func);
1772 ARM_COMPUTE_UNUSED(data_type);
1773 return false;
1774#endif // __aarch64__
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001775 }
1776
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001777private:
Usama Arif6a98a6e2019-05-10 17:07:27 +01001778 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::IDENTITY };
Giorgio Arena11674872018-02-07 15:38:12 +00001779 float _a = {};
1780 float _b = {};
1781 bool _enabled = { false };
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001782
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001783#ifdef __aarch64__
1784 LookupTable256 _lut = {};
1785
1786 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 +01001787 {
1788 for(size_t i = 0; i < lut.size(); ++i)
1789 {
1790 lut[i] = qasymm8_hard_swish(i, qi_in, qi_out);
1791 }
1792 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001793
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001794 static inline void qasymm8_signed_hard_swish_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1795 {
1796 for(size_t i = 0; i < lut.size(); ++i)
1797 {
1798 lut[i] = qasymm8_signed_hard_swish(i, qi_in, qi_out);
1799 }
1800 }
1801
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001802 static inline void qasymm8_leaky_relu_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out, float alpha)
1803 {
1804 for(size_t i = 0; i < lut.size(); ++i)
1805 {
1806 lut[i] = qasymm8_leaky_relu(i, qi_in, qi_out, alpha);
1807 }
1808 }
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001809
1810 static inline void qasymm8_logistic_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1811 {
1812 for(size_t i = 0; i < lut.size(); ++i)
1813 {
1814 lut[i] = qasymm8_logistic(i, qi_in, qi_out);
1815 }
1816 }
1817
1818 static inline void qasymm8_signed_logistic_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1819 {
1820 for(size_t i = 0; i < lut.size(); ++i)
1821 {
1822 lut[i] = qasymm8_signed_logistic(static_cast<int8_t>(i), qi_in, qi_out);
1823 }
1824 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001825#endif // __aarch64__
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001826};
1827
Giorgio Arena1856ff72020-02-07 13:46:45 +00001828/** Fully connected layer info */
1829struct FullyConnectedLayerInfo
1830{
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001831 /* Fused-activation parameters */
1832 ActivationLayerInfo activation_info{}; /**< Fused activation to apply after the matrix multiplication. */
1833 /* Information about weights */
1834 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
1835 bool transpose_weights{ true }; /**< Transpose weights if true. */
1836 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
1837 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
cfRodf2c022e2021-11-05 11:29:53 +00001838 bool enable_fast_math{ false }; /**< Enable fast math computation. */
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001839 /* Other parameters */
1840 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 +00001841
1842 /** Sets the weights trained data layout
1843 *
1844 * @param[in] layout Data layout that the weights were trained with
1845 *
1846 * @return Updated object
1847 */
1848 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
1849 {
1850 weights_trained_layout = layout;
1851 return *this;
1852 }
1853 /** Sets the transpose weights flag
1854 *
1855 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
1856 *
1857 * @return Updated object
1858 */
1859 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
1860 {
1861 transpose_weights = should_transpose_weights;
1862 return *this;
1863 }
1864};
1865
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001866/** Normalization Layer Information class */
1867class NormalizationLayerInfo
1868{
1869public:
1870 /** Default Constructor
1871 *
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001872 * @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 +01001873 * @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 +00001874 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1875 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1876 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1877 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1878 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001879 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001880 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1881 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001882 {
1883 }
Alex Gildayc357c472018-03-21 13:54:09 +00001884 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001885 NormType type() const
1886 {
1887 return _type;
1888 }
Alex Gildayc357c472018-03-21 13:54:09 +00001889 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001890 uint32_t norm_size() const
1891 {
1892 return _norm_size;
1893 }
Alex Gildayc357c472018-03-21 13:54:09 +00001894 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001895 float alpha() const
1896 {
1897 return _alpha;
1898 }
Alex Gildayc357c472018-03-21 13:54:09 +00001899 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001900 float beta() const
1901 {
1902 return _beta;
1903 }
Alex Gildayc357c472018-03-21 13:54:09 +00001904 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001905 float kappa() const
1906 {
1907 return _kappa;
1908 }
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001909 /** Get the is_scaled value */
1910 bool is_scaled() const
1911 {
1912 return _is_scaled;
1913 }
Alex Gildayc357c472018-03-21 13:54:09 +00001914 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001915 bool is_cross_map() const
1916 {
1917 return _type == NormType::CROSS_MAP;
1918 }
Alex Gildayc357c472018-03-21 13:54:09 +00001919 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001920 bool is_in_map() const
1921 {
1922 return !is_cross_map();
1923 }
1924 /** Return the scaling factor of the normalization function.
1925 *
1926 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1927 * 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 +01001928 *
1929 * @return The normalization scaling factor.
1930 */
1931 float scale_coeff() const
1932 {
1933 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001934 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001935 }
1936
1937private:
1938 NormType _type;
1939 uint32_t _norm_size;
1940 float _alpha;
1941 float _beta;
1942 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001943 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001944};
1945
thecha012bfadd92020-08-12 17:25:51 +01001946class StridedSliceLayerInfo
1947{
1948public:
1949 /** Default Constructor
1950 *
1951 * @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.
1952 * @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.
1953 * @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.
1954 */
1955 StridedSliceLayerInfo(int32_t begin_mask = 0, int32_t end_mask = 0, int32_t shrink_axis_mask = 0)
1956 : _begin_mask(begin_mask), _end_mask(end_mask), _shrink_axis_mask(shrink_axis_mask)
1957 {
1958 }
1959
1960 /* Get the begin mask value */
1961 int32_t begin_mask() const
1962 {
1963 return _begin_mask;
1964 }
1965
1966 /* Get the end mask value */
1967 int32_t end_mask() const
1968 {
1969 return _end_mask;
1970 }
1971
1972 /* Get the shrink axis mask value */
1973 int32_t shrink_axis_mask() const
1974 {
1975 return _shrink_axis_mask;
1976 }
1977
1978private:
1979 int32_t _begin_mask;
1980 int32_t _end_mask;
1981 int32_t _shrink_axis_mask;
1982};
1983
Ramy Elgammal91780022022-07-20 14:57:37 +01001984/** Memory layouts for the weights tensor.
1985 *
1986 * * UNSPECIFIED is used to select kernels that do not run in
1987 * variable weights mode.
1988 *
1989 * * ANY is used to query the kernel database to retrieve any of the
1990 * kernels that runs in variable weights mode. Once a kernel is
1991 * found, the specific format expected by the kernel can be
1992 * retrieved by the user for reordering the weights tensor
1993 * accordingly.
1994 *
1995 * The other values OHWIo{interleave_by}i{block_by} describe the
1996 * memory layout of a 4D tensor with layout OHWI that has been
1997 * transformed into a 4D tensor with dimensions O'HWI' where:
1998 *
1999 * O' = first multiple of {interleave_by} s.t. O<=O'
2000 * I' = first multiple of {block_by} s.t. I<=I'
2001 *
2002 * The total size of the dst tensor is O' x H x W x I'
2003 *
2004 * The access function of the tensor with layout
2005 * OHWIo{interleave_by}i{block_by} and size O'HWI' is a 6-parameter
2006 * access function, where the 6 parameters are computed as follows:
2007 *
2008 * x5 = floor(o/{interleave_by}) RANGE [0, O'/{interleave_by} -1] SIZE: O'/{interleave_by}
2009 *
2010 * x4 = h RANGE [0, H-1] SIZE: H
2011 * x3 = w RANGE [0, W-1] SIZE: W
2012 * x2 = floor(i/{block_by}) RANGE [0, I'/{block_by} -1] SIZE: I'/{block_by}
2013 * x1 = o%{interleave_by} RANGE [0, {interleave_by} -1] SIZE: {interleave_by}
2014 * x0 = i%{block_by} RANGE [0, {block_by} -1] SIZE: {block_by}
2015 * TOTAL SIZE: O' * H * W * I'
2016 *
2017 * 4D 6D
2018 * ----------------- -----------------------------------
2019 * value(o, h, w, i) = x5 * H * W * I' * {interleave_by}
2020 * + x4 * W * I' * {interleave_by}
2021 * + x3 * I' * {interleave_by}
2022 * + x2 * {interleave_by} * {block_by}
2023 * + x1 * {block_by}
2024 * + x0
2025 *
2026 * Notice that in arm_gemm the 4D tensor of dimension O'HWI' created
2027 * for the OHWIo{interleave_by}i{block_by} format is in reality seen
2028 * as a 2D tensor, where the number of rows is O'/{interleave_by}
2029 * and the number of columns is {interleave_by} * H * W * I'.
2030 *
2031 * The postfix *_bf16 is for the memory layout needed for the
2032 * fast-mode kernels, in which the weights are passed in bfloat16
2033 * format.
2034 */
2035enum class WeightFormat
2036{
2037 UNSPECIFIED = 0x1,
2038 ANY = 0x2,
2039 OHWI = 0x100100,
2040 OHWIo2 = 0x100200,
2041 OHWIo4 = 0x100400,
2042 OHWIo8 = 0x100800,
2043 OHWIo16 = 0x101000,
2044 OHWIo32 = 0x102000,
2045 OHWIo64 = 0x104000,
2046 OHWIo128 = 0x108000,
2047 OHWIo4i2 = 0x200400,
2048 OHWIo4i2_bf16 = 0x200410,
2049 OHWIo8i2 = 0x200800,
2050 OHWIo8i2_bf16 = 0x200810,
2051 OHWIo16i2 = 0x201000,
2052 OHWIo16i2_bf16 = 0x201010,
2053 OHWIo32i2 = 0x202000,
2054 OHWIo32i2_bf16 = 0x202010,
2055 OHWIo64i2 = 0x204000,
2056 OHWIo64i2_bf16 = 0x204010,
2057 OHWIo4i4 = 0x400400,
2058 OHWIo4i4_bf16 = 0x400410,
2059 OHWIo8i4 = 0x400800,
2060 OHWIo8i4_bf16 = 0x400810,
2061 OHWIo16i4 = 0x401000,
2062 OHWIo16i4_bf16 = 0x401010,
2063 OHWIo32i4 = 0x402000,
2064 OHWIo32i4_bf16 = 0x402010,
2065 OHWIo64i4 = 0x404000,
2066 OHWIo64i4_bf16 = 0x404010,
2067 OHWIo2i8 = 0x800200,
2068 OHWIo4i8 = 0x800400,
2069 OHWIo8i8 = 0x800800,
2070 OHWIo16i8 = 0x801000,
2071 OHWIo32i8 = 0x802000,
2072 OHWIo64i8 = 0x804000
2073};
2074// OHWIo<interleave_by>i<block_by>
2075inline int interleave_by(const WeightFormat wf)
2076{
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002077 return (static_cast<int>(wf) >> 8) & 0xFFF;
Ramy Elgammal91780022022-07-20 14:57:37 +01002078}
2079inline int block_by(const WeightFormat wf)
2080{
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002081 return (static_cast<int>(wf) >> 20) & 0xF;
Ramy Elgammal91780022022-07-20 14:57:37 +01002082}
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002083inline bool is_fixed_format(const WeightFormat &wf)
Ramy Elgammal91780022022-07-20 14:57:37 +01002084{
2085 return wf != WeightFormat::UNSPECIFIED && wf != WeightFormat::ANY;
2086}
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002087inline bool is_fixed_format_fast_math(const WeightFormat &wf)
2088{
2089 return (static_cast<int>(wf) >> 4) & 0x1;
2090}
Ramy Elgammal91780022022-07-20 14:57:37 +01002091
Gian Marco Iodice559d7712017-08-08 08:38:09 +01002092/** 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 +01002093class WeightsInfo
2094{
2095public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002096 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002097 WeightsInfo()
Ramy Elgammal91780022022-07-20 14:57:37 +01002098 : _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 +01002099 {
2100 }
2101 /** Constructor
2102 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01002103 * @param[in] are_reshaped True if the weights have been reshaped
2104 * @param[in] kernel_width Kernel width.
2105 * @param[in] kernel_height Kernel height.
2106 * @param[in] num_kernels Number of convolution kernels.
2107 * @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 +01002108 * @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 +01002109 */
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002110 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 +01002111 arm_compute::WeightFormat weight_format = arm_compute::WeightFormat::UNSPECIFIED)
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002112 : _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 +01002113 {
2114 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002115 /** Flag which specifies if the weights tensor has been reshaped.
2116 *
2117 * @return True if the weights tensors has been reshaped
2118 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002119 bool are_reshaped() const
2120 {
2121 return _are_reshaped;
2122 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01002123 /** Return the number of convolution kernels
2124 *
2125 * @return The number of convolution kernels
2126 */
2127 unsigned int num_kernels() const
2128 {
2129 return _num_kernels;
2130 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002131 /** Return the width and height of the kernel
2132 *
2133 * @return The width and height of the kernel
2134 */
2135 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002136 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002137 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002138 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01002139 bool retain_internal_weights() const
2140 {
2141 return _retain_internal_weights;
2142 }
Ramy Elgammal91780022022-07-20 14:57:37 +01002143 arm_compute::WeightFormat weight_format() const
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002144 {
2145 return _weight_format;
2146 }
Milos Puzovic13b623e2022-07-27 17:53:21 +00002147 void set_weight_format(arm_compute::WeightFormat weight_format)
2148 {
2149 _weight_format = weight_format;
2150 }
2151
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002152 unsigned int kernel_width() const
2153 {
2154 return _kernel_width;
2155 }
2156 unsigned int kernel_height() const
2157 {
2158 return _kernel_height;
2159 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002160
2161private:
Ramy Elgammal91780022022-07-20 14:57:37 +01002162 bool _are_reshaped;
2163 unsigned int _kernel_width;
2164 unsigned int _kernel_height;
2165 unsigned int _num_kernels;
2166 bool _retain_internal_weights;
2167 arm_compute::WeightFormat _weight_format;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002168};
2169
Gian Marco36a0a462018-01-12 10:21:40 +00002170/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
2171 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01002172 * The matrix A can only be reshaped through @ref opencl::kernels::ClGemmReshapeLhsMatrixKernel or @ref cpu::kernels::CpuGemmInterleave4x4Kernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01002173 * 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 +00002174 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01002175 * The matrix B can only be reshaped through @ref opencl::kernels::ClGemmReshapeRhsMatrixKernel or @ref cpu::kernels::CpuGemmTranspose1xWKernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01002176 * 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 +00002177 *
2178 */
2179class GEMMReshapeInfo final
2180{
2181public:
2182 /** Default constructor */
2183 GEMMReshapeInfo()
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002184 : _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 +00002185 {
2186 }
2187 /** Constructor
2188 *
2189 * @param[in] m Number of matrix A rows
2190 * @param[in] n Number of matrix B columns
2191 * @param[in] k Number of matrix A columns or matrix B rows
2192 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
2193 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002194 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
2195 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002196 * @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 +01002197 * to perform 1x1 convolutions with the NHWC data layout)
2198 * @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 +00002199 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002200 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 +01002201 : _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 +01002202 _reinterpret_input_as_3d(reinterpret_input_as_3d), _broadcast_bias(broadcast_bias)
Gian Marco36a0a462018-01-12 10:21:40 +00002203 {
2204 }
2205 /** Number of matrix A rows
2206 *
2207 * @return the number of matrix A rows
2208 */
2209 int m() const
2210 {
2211 return _m;
2212 }
2213 /** Number of matrix B columns
2214 *
2215 * @return the number of matrix B columns
2216 */
2217 int n() const
2218 {
2219 return _n;
2220 }
2221 /** Number of matrix A columns or matrix B rows
2222 *
2223 * @return the number of matrix A columns or matrix B rows
2224 */
2225 int k() const
2226 {
2227 return _k;
2228 }
2229 /** Multiplication factor for the width of the 1xW transposed block
2230 *
2231 * @return the multiplication factor for the width of the 1xW transposed block
2232 */
2233 int mult_transpose1xW_width() const
2234 {
2235 return _mult_transpose1xW_width;
2236 }
2237 /** Multiplication factor for the height of the 4x4 interleaved block
2238 *
2239 * @return the multiplication factor for the height of the 4x4 interleaved block
2240 */
2241 int mult_interleave4x4_height() const
2242 {
2243 return _mult_interleave4x4_height;
2244 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002245 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
2246 *
2247 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
2248 * m = depth_output_gemm3d * output_height
2249 *
2250 * @return the depth of the output tensor to be used with the GEMM3D kernel
2251 */
2252 int depth_output_gemm3d() const
2253 {
2254 return _depth_output_gemm3d;
2255 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002256 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2257 *
2258 * @return True if the input tensor has to be reinterpreted as 3D tensor
2259 */
2260 bool reinterpret_input_as_3d() const
2261 {
2262 return _reinterpret_input_as_3d;
2263 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002264 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2265 *
2266 * @return True if the shape of the bias tensor is to be broadcasted.
2267 */
2268 bool broadcast_bias() const
2269 {
2270 return _broadcast_bias;
2271 };
Gian Marco36a0a462018-01-12 10:21:40 +00002272
2273private:
SiCong Liebd8fb42020-08-18 11:03:14 +01002274 int _m;
2275 int _n;
2276 int _k;
2277 int _mult_transpose1xW_width;
2278 int _mult_interleave4x4_height;
2279 int _depth_output_gemm3d;
2280 bool _reinterpret_input_as_3d;
2281 bool _broadcast_bias;
Gian Marco36a0a462018-01-12 10:21:40 +00002282};
2283
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +01002284struct ConvolutionInfo
2285{
2286 ConvolutionInfo() = default;
2287 ConvolutionInfo(const PadStrideInfo &pad_stride_info, unsigned int depth_multiplier, const ActivationLayerInfo &act_info, const Size2D &dilation)
2288 : pad_stride_info(pad_stride_info), depth_multiplier(depth_multiplier), act_info(act_info), dilation(dilation)
2289 {
2290 }
2291 PadStrideInfo pad_stride_info{}; /**< Convolution info (Pads, strides,...) */
2292 unsigned int depth_multiplier{ 1 }; /**< Multiplier to apply to input's depth to retrieve the output depth. Defaults to 1 */
2293 ActivationLayerInfo act_info{}; /**< Fused activation to apply after convolution. */
2294 Size2D dilation{ Size2D(1, 1) }; /**< Dilation, in elements, across x and y. Defaults to (1, 1). */
2295};
2296
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002297/** GEMMLowp output stage type */
2298enum class GEMMLowpOutputStageType
2299{
Manuel Bottini959c26d2019-12-02 16:22:35 +00002300 NONE, /**< No quantization */
2301 QUANTIZE_DOWN, /**< Quantize using an integer multiplication */
2302 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize using a fixed point multiplication */
2303 QUANTIZE_DOWN_FLOAT /**< Quantize using a floating point multiplication */
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002304};
2305
2306/** GEMMLowp output stage info */
2307struct GEMMLowpOutputStageInfo
2308{
Giorgio Arena1856ff72020-02-07 13:46:45 +00002309 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
2310 int32_t gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
2311 int32_t gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
2312 int32_t gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
2313 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 */
2314 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 */
2315 std::vector<int32_t> gemmlowp_multipliers{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
2316 std::vector<int32_t> gemmlowp_shifts{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
Sheri Zhang1b14c752020-03-09 14:29:52 +00002317 float gemmlowp_real_multiplier{ 0 }; /**< GEMMLowp output stage real multiplier used for quantizing to QASYMM8 */
Giorgio Arena1856ff72020-02-07 13:46:45 +00002318 bool is_quantized_per_channel{ false }; /**< GEMMLowp quantized per-channel flag */
2319 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 +01002320};
2321
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00002322/** GEMM LHS (Left Hand Side) matrix information */
2323struct GEMMLHSMatrixInfo
2324{
morgolockaba2f912020-05-05 16:28:19 +01002325 GEMMLHSMatrixInfo() = default;
2326 GEMMLHSMatrixInfo(unsigned int m, unsigned int k, unsigned int v, bool trans, bool inter)
2327 : m0(m), k0(k), v0(v), transpose(trans), interleave(inter)
2328 {
2329 }
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00002330 unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
2331 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
2332 unsigned int v0{ 1 }; /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
2333 bool transpose{ true }; /**< True if the (m0xk0) block has to be transposed before been stored */
2334 bool interleave{ true }; /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
2335};
2336
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00002337/** GEMM RHS (Right Hand Side) matrix information */
2338struct GEMMRHSMatrixInfo
2339{
morgolockaba2f912020-05-05 16:28:19 +01002340 GEMMRHSMatrixInfo() = default;
Gian Marco Iodicee3a849a2020-06-10 17:59:30 +01002341 GEMMRHSMatrixInfo(unsigned int n, unsigned int k, unsigned int h, bool trans, bool inter, bool export_to_cl_img)
2342 : n0(n), k0(k), h0(h), transpose(trans), interleave(inter), export_to_cl_image(export_to_cl_img)
morgolockaba2f912020-05-05 16:28:19 +01002343 {
2344 }
Gian Marco Iodicedd717c32020-05-28 10:22:03 +01002345 unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
2346 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
2347 unsigned int h0{ 1 }; /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
2348 bool transpose{ true }; /**< True if the (k0xn0) block has to be transposed before been stored */
2349 bool interleave{ true }; /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
2350 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 +00002351};
2352
SiCongLi579ca842021-10-18 09:38:33 +01002353class ITensorInfo;
Gian Marco36a0a462018-01-12 10:21:40 +00002354/** GEMM information class. This class stores the necessary information to compute GEMM functions
2355 *
2356 * This object also contains the information about how matrix A and matrix B have been reshaped
2357 *
2358 */
Chunosov5124be52017-11-22 20:42:13 +07002359class GEMMInfo
2360{
2361public:
2362 /** Default constructor */
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002363 GEMMInfo() noexcept
2364 : _is_a_reshaped(false),
2365 _is_b_reshaped(false),
2366 _reshape_b_only_on_first_run(true),
2367 _depth_output_gemm3d(0),
2368 _reinterpret_input_as_3d(false),
2369 _retain_internal_weights(false),
2370 _gemmlowp_output_stage(),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002371 _fast_math(false),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002372 _fp_mixed_precision(false),
2373 _broadcast_bias(false),
Adnan AlSinanc5849582022-05-05 11:13:19 +01002374 _pretranspose_A(false),
2375 _pretranspose_B(false),
SiCongLi579ca842021-10-18 09:38:33 +01002376 _activation_info(),
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002377 _post_ops(),
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002378 _fixed_format(false),
Ramy Elgammal91780022022-07-20 14:57:37 +01002379 _weight_format(arm_compute::WeightFormat::UNSPECIFIED)
Chunosov5124be52017-11-22 20:42:13 +07002380 {
2381 }
2382 /** Constructor
2383 *
2384 * @param[in] is_a_reshaped True if the matrix A has been reshaped
2385 * @param[in] is_b_reshaped True if the matrix B has been reshaped
2386 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002387 * @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 +00002388 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002389 * @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
2390 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002391 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002392 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002393 * @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 +01002394 * @param[in] fast_math (Optional) Use a data type of shorter width to improve performance
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002395 * @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 +01002396 * @param[in] activation_info (Optional) Activation to apply after the matrix multiplication
SiCongLi579ca842021-10-18 09:38:33 +01002397 * @param[in] post_ops (Optional) A sequence of post operations that are performed after the main operation.
Ramy Elgammal91780022022-07-20 14:57:37 +01002398 * @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.
2399 * @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 +07002400 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002401 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 +01002402 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 +00002403 const ActivationLayerInfo &activation_info = ActivationLayerInfo(), const experimental::PostOpList<ITensorInfo *> &post_ops = experimental::PostOpList<ITensorInfo *>(),
Ramy Elgammal91780022022-07-20 14:57:37 +01002404 bool fixed_format = false, arm_compute::WeightFormat weight_format = arm_compute::WeightFormat::UNSPECIFIED) noexcept
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002405 : _is_a_reshaped(is_a_reshaped),
2406 _is_b_reshaped(is_b_reshaped),
2407 _reshape_b_only_on_first_run(reshape_b_only_on_first_run),
2408 _depth_output_gemm3d(depth_output_gemm3d),
2409 _reinterpret_input_as_3d(reinterpret_input_as_3d),
2410 _retain_internal_weights(retain_internal_weights),
2411 _gemmlowp_output_stage(gemmlowp_output_stage),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002412 _fast_math(fast_math),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002413 _fp_mixed_precision(fp_mixed_precision),
2414 _broadcast_bias(broadcast_bias),
Adnan AlSinanc5849582022-05-05 11:13:19 +01002415 _pretranspose_A(false),
2416 _pretranspose_B(false),
SiCongLi579ca842021-10-18 09:38:33 +01002417 _activation_info(activation_info),
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002418 _post_ops(post_ops),
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002419 _fixed_format(fixed_format),
2420 _weight_format(weight_format)
Chunosov5124be52017-11-22 20:42:13 +07002421 {
2422 }
2423 /** Flag which specifies if the matrix A has been reshaped
2424 *
2425 * @return True if the matrix A has been reshaped
2426 */
2427 bool is_a_reshaped() const
2428 {
2429 return _is_a_reshaped;
2430 };
2431 /** Flag which specifies if the matrix B has been reshaped
2432 *
2433 * @return True if the matrix B has been reshaped
2434 */
2435 bool is_b_reshaped() const
2436 {
2437 return _is_b_reshaped;
2438 };
2439 /** Flag which specifies if the reshape of matrix B should executed only for the first
2440 *
2441 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
2442 *
2443 * @return True if the reshaped of matrix B happens only for the first run
2444 */
2445 bool reshape_b_only_on_first_run() const
2446 {
2447 return _reshape_b_only_on_first_run;
2448 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002449 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002450 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002451 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002452 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002453 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00002454 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002455 return _depth_output_gemm3d;
2456 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002457 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2458 *
2459 * @return True if the input tensor has to be reinterpreted as 3D tensor
2460 */
2461 bool reinterpret_input_as_3d() const
2462 {
2463 return _reinterpret_input_as_3d;
2464 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002465 /** Flag which specifies if the weights tensor has to be retained from previous run
2466 *
2467 * @return True if the weights tensor has to be retained
2468 */
2469 bool retain_internal_weights() const
2470 {
2471 return _retain_internal_weights;
2472 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002473 /** GEMMLowp output stage
2474 *
2475 * @return the GEMMLowp output stage info
2476 */
2477 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
2478 {
2479 return _gemmlowp_output_stage;
2480 };
Georgios Pinitasdbdea0d2019-10-16 19:21:40 +01002481 /** Sets GEMMLowp output stage
2482 *
2483 * @param[in] output_stage Output stage to set
2484 */
2485 void set_gemmlowp_output_stage(GEMMLowpOutputStageInfo &output_stage)
2486 {
2487 _gemmlowp_output_stage = output_stage;
2488 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002489 /** Flag which specifies if a wider accumulator should be used.
2490 *
2491 * @return True if a wider accumulator has to be used
2492 */
2493 bool fp_mixed_precision() const
2494 {
2495 return _fp_mixed_precision;
2496 };
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002497 /** Flag which specifies if a shorter accumulator to be used.
2498 *
2499 * @return True if a shorter accumulator has to be used
2500 */
2501 bool fast_math() const
2502 {
2503 return _fast_math;
2504 };
cfRodf2c022e2021-11-05 11:29:53 +00002505 /** Set fast math flag
2506 *
2507 * @param[in] fast_math Flag to set
2508 */
2509 void set_fast_math(bool fast_math)
2510 {
2511 _fast_math = fast_math;
2512 }
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002513 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2514 *
2515 * @return True if the shape of the bias tensor is to be broadcasted.
2516 */
2517 bool broadcast_bias() const
2518 {
2519 return _broadcast_bias;
2520 };
Adnan AlSinanc5849582022-05-05 11:13:19 +01002521 /** Flag which specifies whether A should be pre-transposed if supported.
2522 *
2523 * @return True if A should be pre-transposed else false.
2524 */
2525 bool pretranspose_A() const
2526 {
2527 return _pretranspose_A;
2528 };
2529 /** Set pre-transpose A flag
2530 *
2531 * @param[in] flag Flag to set
2532 */
2533 void set_pretranspose_A(bool flag)
2534 {
2535 _pretranspose_A = flag;
2536 }
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002537 /** Flag which specifies whether b should be pre-transposed if supported.
2538 *
2539 * @return True if b should be pre-transposed else false.
2540 */
ramelg01cbbb0382021-09-17 17:36:57 +01002541 bool pretranspose_B() const
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002542 {
ramelg01cbbb0382021-09-17 17:36:57 +01002543 return _pretranspose_B;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002544 };
2545 /** Set pre-transpose b flag
2546 *
2547 * @param[in] flag Flag to set
2548 */
ramelg01cbbb0382021-09-17 17:36:57 +01002549 void set_pretranspose_B(bool flag)
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002550 {
ramelg01cbbb0382021-09-17 17:36:57 +01002551 _pretranspose_B = flag;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002552 }
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002553 /** Activation layer to apply after the matrix multiplication
2554 *
2555 * @return ActivationLayerInfo object
2556 */
2557 ActivationLayerInfo activation_info() const
2558 {
2559 return _activation_info;
2560 }
SiCongLi2e5fd632020-03-02 15:39:15 +00002561 /** Set activation layer info
2562 *
2563 * @param[in] activation_info ActivationLayerInfo object to set
2564 */
2565 void set_activation_info(const ActivationLayerInfo &activation_info)
2566 {
2567 _activation_info = activation_info;
2568 }
SiCongLi579ca842021-10-18 09:38:33 +01002569 /** Post operations to apply after the matrix multiplication
2570 *
2571 * @return experimental::PostOpList object
2572 */
2573 const experimental::PostOpList<ITensorInfo *> &post_ops() const
2574 {
2575 return _post_ops;
2576 }
2577 /** Set post ops
2578 *
2579 * @param[in] post_ops experimental::PostOpList object to set
2580 */
2581 void set_post_ops(const experimental::PostOpList<ITensorInfo *> &post_ops)
2582 {
2583 _post_ops = post_ops;
2584 }
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002585 /** Flag which specifies if the GEMM operation is running fixed-format kernels.
2586 *
2587 * @return True if the GEMM operation is running fixed-format kernel else false.
2588 */
2589 bool fixed_format() const
2590 {
2591 return _fixed_format;
2592 }
Chunosov5124be52017-11-22 20:42:13 +07002593
Milos Puzovic13b623e2022-07-27 17:53:21 +00002594 /** Set fixed-format flag
2595 *
2596 * @param[in] fixed_format sets whether or not to use fixed-format kernels
2597 */
2598 void set_fixed_format(bool fixed_format)
2599 {
2600 _fixed_format = fixed_format;
2601 }
2602
Ramy Elgammal91780022022-07-20 14:57:37 +01002603 arm_compute::WeightFormat weight_format() const
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002604 {
2605 return _weight_format;
2606 }
2607
Milos Puzovic13b623e2022-07-27 17:53:21 +00002608 /** Set weight format to be used
2609 *
2610 * @param[in] weight_format arm_compute::WeightFormat enumeration
2611 */
2612 void set_weight_format(arm_compute::WeightFormat weight_format)
2613 {
2614 _weight_format = weight_format;
2615 }
2616
Chunosov5124be52017-11-22 20:42:13 +07002617private:
SiCongLi579ca842021-10-18 09:38:33 +01002618 bool _is_a_reshaped;
2619 bool _is_b_reshaped;
2620 bool _reshape_b_only_on_first_run;
2621 int _depth_output_gemm3d;
2622 bool _reinterpret_input_as_3d;
2623 bool _retain_internal_weights;
2624 GEMMLowpOutputStageInfo _gemmlowp_output_stage;
2625 bool _fast_math;
2626 bool _fp_mixed_precision;
2627 bool _broadcast_bias;
Adnan AlSinanc5849582022-05-05 11:13:19 +01002628 bool _pretranspose_A;
SiCongLi579ca842021-10-18 09:38:33 +01002629 bool _pretranspose_B;
2630 ActivationLayerInfo _activation_info;
2631 experimental::PostOpList<ITensorInfo *> _post_ops;
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002632 bool _fixed_format;
Ramy Elgammal91780022022-07-20 14:57:37 +01002633 arm_compute::WeightFormat _weight_format;
Chunosov5124be52017-11-22 20:42:13 +07002634};
2635
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00002636/** Winograd information */
2637struct WinogradInfo
2638{
2639 /** Default constructor
2640 *
2641 * @param[in] output_tile_sz Width and height of the output tile
2642 * @param[in] kernel_sz Width and height of the kernel
2643 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
2644 * @param[in] conv_info Convolution info (Pads, strides)
2645 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
2646 */
2647 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
2648 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
2649 {
2650 }
2651
2652 Size2D output_tile_size{}; /**< Width and height of the output tile */
2653 Size2D kernel_size{}; /**< Width and height of the kernel*/
2654 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
2655 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
2656 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
2657};
2658
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002659/** IO formatting information class*/
2660struct IOFormatInfo
2661{
2662 /** Precision type used when printing floating point numbers */
2663 enum class PrecisionType
2664 {
2665 Default, /**< Default precision to the one that the current stream has */
2666 Custom, /**< Custom precision specified by the user using the precision parameter */
2667 Full /**< The maximum precision of the floating point representation */
2668 };
2669
2670 /** Specifies the area to be printed, used by Tensor objects */
2671 enum class PrintRegion
2672 {
2673 ValidRegion, /**< Prints the valid region of the Tensor object */
2674 NoPadding, /**< Prints the Tensor object without the padding */
2675 Full /**< Print the tensor object including padding */
2676 };
2677
Alex Gildayc357c472018-03-21 13:54:09 +00002678 /** Construct a set of IO formatting information.
2679 *
2680 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
2681 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
2682 * @param[in] precision Precision value for float point numbers. Default: 10.
2683 * @param[in] align_columns Whether to align columns when printed. Default: true.
2684 * @param[in] element_delim Delimeter between elements. Default: " ".
2685 * @param[in] row_delim Delimenter between rows. Default: "\n".
2686 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002687 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
2688 PrecisionType precision_type = PrecisionType::Default,
2689 unsigned int precision = 10,
2690 bool align_columns = true,
2691 std::string element_delim = " ",
2692 std::string row_delim = "\n")
2693 : print_region(print_region),
2694 precision_type(precision_type),
2695 precision(precision),
2696 element_delim(element_delim),
2697 row_delim(row_delim),
2698 align_columns(align_columns)
2699 {
2700 }
2701
Alex Gildayc357c472018-03-21 13:54:09 +00002702 /** Area to be printed by Tensor objects */
2703 PrintRegion print_region;
2704 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002705 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00002706 /** Floating point precision */
2707 unsigned int precision;
2708 /** Element delimeter */
2709 std::string element_delim;
2710 /** Row delimeter */
2711 std::string row_delim;
2712 /** Align columns */
2713 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002714};
Mohammed Suhail Munshid538d162023-02-16 16:22:32 +00002715
2716/** Class for holding information related to matrix multiplication function
2717 */
2718class MatMulInfo
2719{
2720public:
2721 /* Get Adjoint LHS flag value */
2722 bool adj_lhs() const
2723 {
2724 return _adj_lhs;
2725 }
2726 /* Get Adjoint RHS flag value */
2727 bool adj_rhs() const
2728 {
2729 return _adj_rhs;
2730 }
2731 /* Get Fused Activation Layer Info */
2732 ActivationLayerInfo fused_activation() const
2733 {
2734 return _fused_act;
2735 }
2736 /* Set Adjoint LHS flag */
2737 MatMulInfo& adj_lhs(bool adj_lhs)
2738 {
2739 _adj_lhs = adj_lhs;
2740 return *this;
2741 }
2742 /* Set Adjoint RHS flag */
2743 MatMulInfo& adj_rhs(bool adj_rhs)
2744 {
2745 _adj_rhs = adj_rhs;
2746 return *this;
2747 }
2748 /* Set Fused Activation Layer Info */
2749 MatMulInfo& fused_activation(const ActivationLayerInfo& act_info)
2750 {
2751 _fused_act = act_info;
2752 return *this;
2753 }
2754private:
2755 bool _adj_lhs{false};
2756 bool _adj_rhs{false};
2757 ActivationLayerInfo _fused_act{}; // disabled by default
2758};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00002759} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +00002760#endif /* ARM_COMPUTE_TYPES_H */