blob: 36dba2cc004be747268ff2d5dc133c8ea22eaca9 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Gunes Bayir918a9fb2022-02-15 11:40:13 +00002 * Copyright (c) 2016-2022 Arm Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
Michalis Spyrouf4643372019-11-29 16:17:13 +000024#ifndef ARM_COMPUTE_TYPES_H
25#define ARM_COMPUTE_TYPES_H
Anthony Barbier6ff3b192017-09-04 18:44:23 +010026
27#include "arm_compute/core/Coordinates.h"
Georgios Pinitas4c5469b2019-05-21 13:32:43 +010028#include "arm_compute/core/QuantizationInfo.h"
Isabella Gottardi6e464c32018-01-26 12:32:45 +000029#include "arm_compute/core/Size2D.h"
Adnan AlSinane4563a02021-09-01 15:32:03 +010030#include "arm_compute/core/Size3D.h"
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000031#include "arm_compute/core/Strides.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010032#include "arm_compute/core/TensorShape.h"
SiCongLi579ca842021-10-18 09:38:33 +010033#include "arm_compute/core/experimental/IPostOp.h"
Sang-Hoon Park11fedda2020-01-15 14:44:04 +000034#include "arm_compute/core/utils/misc/Macros.h"
Georgios Pinitase8291ac2020-02-26 09:58:13 +000035#include "support/Bfloat16.h"
Georgios Pinitas583137c2017-08-31 18:12:42 +010036#include "support/Half.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010037
Michel Iwaniec5dfeae62017-11-29 10:48:23 +000038#include <cmath>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010039#include <cstddef>
40#include <cstdint>
Isabella Gottardia7acb3c2019-01-08 13:48:44 +000041#include <map>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010042#include <string>
43#include <utility>
44
45namespace arm_compute
46{
Georgios Pinitas583137c2017-08-31 18:12:42 +010047/** 16-bit floating point type */
48using half = half_float::half;
49
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000050/** Permutation vector */
51using PermutationVector = Strides;
Georgios Pinitas77589b52018-08-21 14:41:35 +010052/** Bidirectional strides */
53using BiStrides = Coordinates;
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000054
Anthony Barbier6ff3b192017-09-04 18:44:23 +010055/** Image colour formats */
56enum class Format
57{
Daniil Efremov02bf80d2017-11-22 00:26:51 +070058 UNKNOWN, /**< Unknown image format */
59 U8, /**< 1 channel, 1 U8 per channel */
60 S16, /**< 1 channel, 1 S16 per channel */
61 U16, /**< 1 channel, 1 U16 per channel */
62 S32, /**< 1 channel, 1 S32 per channel */
63 U32, /**< 1 channel, 1 U32 per channel */
Georgios Pinitase8291ac2020-02-26 09:58:13 +000064 BFLOAT16, /**< 16-bit brain floating-point number */
Daniil Efremov02bf80d2017-11-22 00:26:51 +070065 F16, /**< 1 channel, 1 F16 per channel */
66 F32, /**< 1 channel, 1 F32 per channel */
67 UV88, /**< 2 channel, 1 U8 per channel */
68 RGB888, /**< 3 channels, 1 U8 per channel */
69 RGBA8888, /**< 4 channels, 1 U8 per channel */
70 YUV444, /**< A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes */
71 YUYV422, /**< A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes */
72 NV12, /**< A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling */
73 NV21, /**< A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling */
74 IYUV, /**< A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes */
75 UYVY422 /**< A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010076};
77
78/** Available data types */
79enum class DataType
80{
Georgios Pinitas8217c8e2019-11-11 18:24:22 +000081 UNKNOWN, /**< Unknown data type */
82 U8, /**< unsigned 8-bit number */
83 S8, /**< signed 8-bit number */
84 QSYMM8, /**< quantized, symmetric fixed-point 8-bit number */
85 QASYMM8, /**< quantized, asymmetric fixed-point 8-bit number unsigned */
86 QASYMM8_SIGNED, /**< quantized, asymmetric fixed-point 8-bit number signed */
87 QSYMM8_PER_CHANNEL, /**< quantized, symmetric per channel fixed-point 8-bit number */
88 U16, /**< unsigned 16-bit number */
89 S16, /**< signed 16-bit number */
90 QSYMM16, /**< quantized, symmetric fixed-point 16-bit number */
91 QASYMM16, /**< quantized, asymmetric fixed-point 16-bit number */
92 U32, /**< unsigned 32-bit number */
93 S32, /**< signed 32-bit number */
94 U64, /**< unsigned 64-bit number */
95 S64, /**< signed 64-bit number */
Georgios Pinitase8291ac2020-02-26 09:58:13 +000096 BFLOAT16, /**< 16-bit brain floating-point number */
Georgios Pinitas8217c8e2019-11-11 18:24:22 +000097 F16, /**< 16-bit floating-point number */
98 F32, /**< 32-bit floating-point number */
99 F64, /**< 64-bit floating-point number */
100 SIZET /**< size_t */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100101};
102
Daniil Efremov02bf80d2017-11-22 00:26:51 +0700103/** Available Sampling Policies */
104enum class SamplingPolicy
105{
106 CENTER, /**< Samples are taken at pixel center */
107 TOP_LEFT /**< Samples are taken at pixel top left corner */
108};
109
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000110/** [DataLayout enum definition] **/
111
Georgios Pinitas4074c992018-01-30 18:13:46 +0000112/** Supported tensor data layouts */
113enum class DataLayout
114{
Alex Gildayc357c472018-03-21 13:54:09 +0000115 UNKNOWN, /**< Unknown data layout */
116 NCHW, /**< Num samples, channels, height, width */
Adnan AlSinane4563a02021-09-01 15:32:03 +0100117 NHWC, /**< Num samples, height, width, channels */
Giorgio Arenac9fe9fc2021-10-06 12:54:29 +0100118 NCDHW, /**< Num samples, channels, depth, height, width */
Adnan AlSinane4563a02021-09-01 15:32:03 +0100119 NDHWC /**< Num samples, depth, height, width, channels */
Georgios Pinitas4074c992018-01-30 18:13:46 +0000120};
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000121/** [DataLayout enum definition] **/
Georgios Pinitas4074c992018-01-30 18:13:46 +0000122
Isabella Gottardid17a6772018-02-27 17:41:55 +0000123/** Supported tensor data layout dimensions */
124enum class DataLayoutDimension
125{
Alex Gildayc357c472018-03-21 13:54:09 +0000126 CHANNEL, /**< channel */
127 HEIGHT, /**< height */
128 WIDTH, /**< width */
Giorgio Arenac9fe9fc2021-10-06 12:54:29 +0100129 DEPTH, /**< depth */
Alex Gildayc357c472018-03-21 13:54:09 +0000130 BATCHES /**< batches */
Isabella Gottardid17a6772018-02-27 17:41:55 +0000131};
132
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000133/** Available ConvolutionMethod*/
134enum class ConvolutionMethod
135{
Georgios Pinitasc0b6f762020-11-02 01:37:17 +0000136 GEMM, /**< Convolution using GEMM */
137 GEMM_CONV2D, /**< Direct 2D GEMM convolution */
138 DIRECT, /**< Direct convolution */
139 WINOGRAD, /**< Convolution using Winograd */
140 FFT /**< Convolution using FFT */
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000141};
142
Manuel Bottini05069f02019-09-26 17:18:26 +0100143/** Available DepthwiseConvolutionFunction*/
144enum class DepthwiseConvolutionFunction
145{
146 OPTIMIZED, /**< Optimized Depthwise Convolution */
147 GENERIC, /**< Generic Depthwise Convolution */
148};
149
giuros0146a49a02019-04-01 13:50:22 +0100150/** Available DeconvolutionMethod*/
151enum class DeconvolutionMethod
152{
153 GEMM, /**< Deconvolution using GEMM */
154 DIRECT, /**< Direct deconvolution */
155};
156
Manuel Bottini2732cca2019-05-28 11:44:41 +0100157/** Available FuseBatchNormalizationType*/
158enum class FuseBatchNormalizationType
159{
160 CONVOLUTION, /**< For Convolution weights */
161 DEPTHWISECONVOLUTION /**< For Depthwise Convolution weights*/
162};
163
Usama Arif89890c62019-03-19 10:57:05 +0000164/** Padding mode to use for PadLayer */
165enum class PaddingMode
166{
167 CONSTANT,
168 REFLECT,
169 SYMMETRIC
170};
171
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000172/** Supported comparison operations */
173enum class ComparisonOperation
174{
175 Equal, /**< Equal comparison ( \f$ x == y \f$ ) */
176 NotEqual, /**< NotEqual comparison ( \f$ x != y \f$ ) */
177 Greater, /**< Greater comparison ( \f$ x > y \f$ ) */
178 GreaterEqual, /**< Greater equal comparison ( \f$ x >= y \f$ ) */
179 Less, /**< Less comparison ( \f$ x < y \f$ ) */
180 LessEqual /**< Less equal comparison ( \f$ x <= y \f$ ) */
181};
182
Alex Gildayc357c472018-03-21 13:54:09 +0000183/** Container for valid region of a window */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100184struct ValidRegion
185{
Alex Gildayc357c472018-03-21 13:54:09 +0000186 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100187 ValidRegion()
188 : anchor{}, shape{}
189 {
190 }
191
Alex Gildayc357c472018-03-21 13:54:09 +0000192 /** Allow instances of this class to be copy constructed */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100193 ValidRegion(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000194 /** Allow instances of this class to be move constructed */
195 ValidRegion(ValidRegion &&) = default;
196 /** Allow instances of this class to be copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100197 ValidRegion &operator=(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000198 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100199 ValidRegion &operator=(ValidRegion &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000200 /** Default destructor */
201 ~ValidRegion() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100202
Alex Gildayc357c472018-03-21 13:54:09 +0000203 /** Constructor for a valid region with default number of dimensions
204 *
205 * @param[in] an_anchor Anchor for the start of the valid region.
206 * @param[in] a_shape Shape of the valid region.
207 *
208 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000209 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
210 : anchor{ an_anchor }, shape{ a_shape }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100211 {
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000212 anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
213 }
214
Alex Gildayc357c472018-03-21 13:54:09 +0000215 /** Constructor for a valid region with specified number of dimensions
216 *
217 * @param[in] an_anchor Anchor for the start of the valid region.
218 * @param[in] a_shape Shape of the valid region.
219 * @param[in] num_dimensions Number of dimensions (must be >= number of dimensions of anchor and shape).
220 *
221 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000222 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
223 : anchor{ an_anchor }, shape{ a_shape }
224 {
225 ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
226 anchor.set_num_dimensions(num_dimensions);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100227 }
228
229 /** Return the start of the valid region for the given dimension @p d */
230 int start(unsigned int d) const
231 {
232 return anchor[d];
233 }
234
235 /** Return the end of the valid region for the given dimension @p d */
236 int end(unsigned int d) const
237 {
238 return anchor[d] + shape[d];
239 }
240
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000241 /** Accessor to set the value of anchor and shape for one of the dimensions.
242 *
243 * @param[in] dimension Dimension for which the value is set.
244 * @param[in] start Value to be set in anchor for the dimension.
245 * @param[in] size Value to be set in shape for the dimension.
246 *
247 * @return *this.
248 */
249 ValidRegion &set(size_t dimension, int start, size_t size)
250 {
251 anchor.set(dimension, start);
252 shape.set(dimension, size);
253 return *this;
254 }
255
SiCong Lib63b1192022-01-28 18:24:39 +0000256 /** Check whether two valid regions are equal.
257 *
258 * @param[in] lhs LHS valid region
259 * @param[in] rhs RHS valid region
260 *
261 * @return True if the valid regions are the same.
262 */
263 inline friend bool operator==(const ValidRegion &lhs, const ValidRegion &rhs);
264
Alex Gildayc357c472018-03-21 13:54:09 +0000265 Coordinates anchor; /**< Anchor for the start of the valid region. */
266 TensorShape shape; /**< Shape of the valid region. */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100267};
SiCong Lib63b1192022-01-28 18:24:39 +0000268inline bool operator==(const ValidRegion &lhs, const ValidRegion &rhs)
269{
270 return (lhs.anchor == rhs.anchor) && (lhs.shape == rhs.shape);
271}
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100272
273/** Methods available to handle borders */
274enum class BorderMode
275{
276 UNDEFINED, /**< Borders are left undefined */
277 CONSTANT, /**< Pixels outside the image are assumed to have a constant value */
278 REPLICATE /**< Pixels outside the image are assumed to have the same value as the closest image pixel */
279};
280
281/** Container for 2D border size */
282struct BorderSize
283{
284 /** Empty border, i.e. no border */
Pablo Marquez Tello383de022021-03-18 11:31:13 +0000285 constexpr BorderSize() noexcept
286 : top{ 0 },
287 right{ 0 },
288 bottom{ 0 },
289 left{ 0 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100290 {
291 }
292
293 /** Border with equal size around the 2D plane */
Pablo Marquez Tello383de022021-03-18 11:31:13 +0000294 explicit constexpr BorderSize(unsigned int size) noexcept
295 : top{ size },
296 right{ size },
297 bottom{ size },
298 left{ size }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100299 {
300 }
301
302 /** Border with same size for top/bottom and left/right */
303 constexpr BorderSize(unsigned int top_bottom, unsigned int left_right)
304 : top{ top_bottom }, right{ left_right }, bottom{ top_bottom }, left{ left_right }
305 {
306 }
307
308 /** Border with different sizes */
309 constexpr BorderSize(unsigned int top, unsigned int right, unsigned int bottom, unsigned int left)
310 : top{ top }, right{ right }, bottom{ bottom }, left{ left }
311 {
312 }
313
314 /** Check if the entire border is zero */
315 constexpr bool empty() const
316 {
317 return top == 0 && right == 0 && bottom == 0 && left == 0;
318 }
319
320 /** Check if the border is the same size on all sides */
321 constexpr bool uniform() const
322 {
323 return top == right && top == bottom && top == left;
324 }
325
Alex Gildayc357c472018-03-21 13:54:09 +0000326 /** Scale this border size.
327 *
328 * @param[in] scale Scale to multiply border size by.
329 *
330 * @return *this.
331 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100332 BorderSize &operator*=(float scale)
333 {
334 top *= scale;
335 right *= scale;
336 bottom *= scale;
337 left *= scale;
338
339 return *this;
340 }
341
Alex Gildayc357c472018-03-21 13:54:09 +0000342 /** Scale a copy of this border size.
343 *
344 * @param[in] scale Scale to multiply border size by.
345 *
346 * @return a scaled copy of this.
347 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100348 BorderSize operator*(float scale)
349 {
350 BorderSize size = *this;
351 size *= scale;
352
353 return size;
354 }
355
Giorgio Arena1e2af2a2020-10-15 17:39:41 +0100356 /** Check equality with another BorderSize struct
357 *
358 * @param[in] rhs other struct to check against
359 *
360 * @return true if they are equal
361 */
SiCong Lib63b1192022-01-28 18:24:39 +0000362 bool operator==(const BorderSize &rhs) const
Giorgio Arena1e2af2a2020-10-15 17:39:41 +0100363 {
364 return (top == rhs.top) && (right == rhs.right) && (bottom == rhs.bottom) && (left == rhs.left);
365 }
366
367 /** Check non-equality with another BorderSize struct
368 *
369 * @param[in] rhs other struct to check against
370 *
371 * @return true if they are different
372 */
SiCong Lib63b1192022-01-28 18:24:39 +0000373 bool operator!=(const BorderSize &rhs) const
Giorgio Arena1e2af2a2020-10-15 17:39:41 +0100374 {
375 return !(*this == rhs);
376 }
377
Alex Gildayc357c472018-03-21 13:54:09 +0000378 /** Limit this border size.
379 *
380 * @param[in] limit Border size to limit this border size to.
381 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100382 void limit(const BorderSize &limit)
383 {
384 top = std::min(top, limit.top);
385 right = std::min(right, limit.right);
386 bottom = std::min(bottom, limit.bottom);
387 left = std::min(left, limit.left);
388 }
389
Alex Gildayc357c472018-03-21 13:54:09 +0000390 unsigned int top; /**< top of the border */
391 unsigned int right; /**< right of the border */
392 unsigned int bottom; /**< bottom of the border */
393 unsigned int left; /**< left of the border */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100394};
395
Alex Gildayc357c472018-03-21 13:54:09 +0000396/** Container for 2D padding size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100397using PaddingSize = BorderSize;
398
SiCongLi1af54162021-10-06 15:25:57 +0100399/** Policy to handle integer overflow
400 * @note: This is ignored by floating point operations where the overflow behavior adheres to the IEEE-754 standard
401 * which states that in case of overflow ±infinity is returned for the round-to-nearest modes (and follows the
402 * rounding rules for the directed rounding modes) by default.
403 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100404enum class ConvertPolicy
405{
406 WRAP, /**< Wrap around */
407 SATURATE /**< Saturate */
408};
409
410/** Interpolation method */
411enum class InterpolationPolicy
412{
413 NEAREST_NEIGHBOR, /**< Output values are defined to match the source pixel whose center is nearest to the sample position */
414 BILINEAR, /**< Output values are defined by bilinear interpolation between the pixels */
415 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 */
416};
417
418/** Bilinear Interpolation method used by LKTracker */
419enum class BilinearInterpolation
420{
Alex Gildayc357c472018-03-21 13:54:09 +0000421 BILINEAR_OLD_NEW, /**< Old-new method */
422 BILINEAR_SCHARR /**< Scharr method */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100423};
424
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100425/** Rectangle type */
426struct Rectangle
427{
428 uint16_t x; /**< Top-left x coordinate */
429 uint16_t y; /**< Top-left y coordinate */
430 uint16_t width; /**< Width of the rectangle */
431 uint16_t height; /**< Height of the rectangle */
432};
433
434/** Coordinate type */
435struct Coordinates2D
436{
437 int32_t x; /**< X coordinates */
438 int32_t y; /**< Y coordinates */
439};
440
441/** Coordinate type */
442struct Coordinates3D
443{
444 uint32_t x; /**< X coordinates */
445 uint32_t y; /**< Y coordinates */
446 uint32_t z; /**< Z coordinates */
447};
448
Giuseppe Rossinid7647d42018-07-17 18:13:13 +0100449/** Padding information as a pair of unsigned int start/end */
450using PaddingInfo = std::pair<uint32_t, uint32_t>;
451
452/** List of padding information */
453using PaddingList = std::vector<PaddingInfo>;
454
giuros013175fcf2018-11-21 09:59:17 +0000455/** Information to produce a tiled version of a Tensor */
456using Multiples = std::vector<uint32_t>;
457
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100458/** Available channels */
459enum class Channel
460{
461 UNKNOWN, /** Unknown channel format */
462 C0, /**< First channel (used by formats with unknown channel types). */
463 C1, /**< Second channel (used by formats with unknown channel types). */
464 C2, /**< Third channel (used by formats with unknown channel types). */
465 C3, /**< Fourth channel (used by formats with unknown channel types). */
466 R, /**< Red channel. */
467 G, /**< Green channel. */
468 B, /**< Blue channel. */
469 A, /**< Alpha channel. */
470 Y, /**< Luma channel. */
471 U, /**< Cb/U channel. */
472 V /**< Cr/V/Value channel. */
473};
474
Georgios Pinitasd9769582017-08-03 10:19:40 +0100475/** Available reduction operations */
476enum class ReductionOperation
477{
Michalis Spyrou7930db42018-11-22 17:36:28 +0000478 ARG_IDX_MAX, /**< Index of the max value */
Manuel Bottinib412fab2018-12-10 17:40:23 +0000479 ARG_IDX_MIN, /**< Index of the min value */
480 MEAN_SUM, /**< Mean of sum */
481 PROD, /**< Product */
482 SUM_SQUARE, /**< Sum of squares */
Usama Arifa4a08ad2019-05-20 12:38:33 +0100483 SUM, /**< Sum */
484 MIN, /**< Min */
Usama Arif28f0dd92019-05-20 13:44:34 +0100485 MAX, /**< Max */
Georgios Pinitasd9769582017-08-03 10:19:40 +0100486};
487
giuros01164a2722018-11-20 18:34:46 +0000488/** Available element-wise operations */
489enum class ArithmeticOperation
490{
491 ADD, /**< (x + y) */
492 SUB, /**< (x - y) */
493 DIV, /**< (x / y) */
494 MIN, /**< Min(x, y) */
495 MAX, /**< Max(x, y) */
496 SQUARED_DIFF, /**< (x - y)^2 */
Usama Arif81e671e2019-05-13 13:33:14 +0100497 POWER, /**< x ^ y */
giuros011e6e1b82019-05-14 16:12:53 +0100498 PRELU, /**< y*x if x < 0, x otherwise */
giuros01164a2722018-11-20 18:34:46 +0000499};
500
Michalis Spyroue9362622018-11-23 17:41:37 +0000501/** Available element wise unary operations */
502enum class ElementWiseUnary
503{
Sang-Hoon Park75eea332020-11-13 13:44:13 +0000504 RSQRT, /**< Reverse square root */
505 EXP, /**< Exponential */
506 NEG, /**< Negate */
507 LOG, /**< Natural Logarithm */
508 ABS, /**< Absolute value */
509 SIN, /**< Sine */
510 ROUND, /**< Round */
511 LOGICAL_NOT, /**< Logical Not */
Michalis Spyroue9362622018-11-23 17:41:37 +0000512};
513
Manuel Bottini63bb7ca2020-12-02 13:22:14 +0000514/** Available bitwise operations */
515enum class BitwiseOperation
516{
517 AND, /**< Bitwise AND operation */
518 NOT, /**< Bitwise NOT operation */
519 OR, /**< Bitwise OR operation */
520 XOR, /**< Bitwise XOR operation */
521};
522
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100523/** The normalization type used for the normalization layer */
524enum class NormType
525{
526 IN_MAP_1D, /**< Normalization applied within the same map in 1D region */
527 IN_MAP_2D, /**< Normalization applied within the same map in 2D region */
528 CROSS_MAP /**< Normalization applied cross maps */
529};
530
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100531/** Detection window used for the object detection. The detection window keeps the following information:
532 *
533 * -# Geometry of the rectangular window (x/y of top-left corner and width/height)
534 * -# Index of the class used for evaluating which class the detection window belongs to
535 * -# Confidence value (score) obtained with the classifier
536 */
537struct DetectionWindow
538{
539 uint16_t x{ 0 }; /**< Top-left x coordinate */
540 uint16_t y{ 0 }; /**< Top-left y coordinate */
541 uint16_t width{ 0 }; /**< Width of the detection window */
542 uint16_t height{ 0 }; /**< Height of the detection window */
543 uint16_t idx_class{ 0 }; /**< Index of the class */
544 float score{ 0.f }; /**< Confidence value for the detection window */
545};
546
547/** Dimension rounding type when down-scaling on CNNs
548 * @note Used in pooling and convolution layer
549 */
550enum class DimensionRoundingType
551{
552 FLOOR, /**< Floor rounding */
553 CEIL /**< Ceil rounding */
554};
555
556/** Available pooling types */
557enum class PoolingType
558{
559 MAX, /**< Max Pooling */
Georgios Pinitascdf51452017-08-31 14:21:36 +0100560 AVG, /**< Average Pooling */
561 L2 /**< L2 Pooling */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100562};
563
Michalis Spyrou2709d612018-09-19 09:46:47 +0100564/** Available non maxima suppression types */
565enum class NMSType
566{
567 LINEAR, /**< Linear NMS */
568 GAUSSIAN, /**< Gaussian NMS */
569 ORIGINAL /**< Original NMS */
570};
571
572/** BoxWithNonMaximaSuppressionLimit Information class */
573class BoxNMSLimitInfo final
574{
575public:
576 /** Constructor
577 *
578 * @param[in] score_thresh (Optional) Score threshold.
579 * @param[in] nms (Optional) NMS value
580 * @param[in] detections (Optional) Number of detections
581 * @param[in] soft_nms_enabled (Optional) Enable SoftNMS
582 * @param[in] soft_nms_method (Optional) Soft NMS method
583 * @param[in] soft_nms_sigma (Optional) Soft NMS sigma value
584 * @param[in] soft_nms_min_score_thres (Optional) Soft NMS minimum score threshold
Manuel Bottini5209be52019-02-13 16:34:56 +0000585 * @param[in] suppress_size (Optional) Filter out boxes based on their size. Defaults to false
586 * @param[in] min_size (Optional) Smaller boxes than min_size will be filtered out. Defaults to 1
587 * @param[in] im_width (Optional) Boxes whose centers (on the x axis) is beyond im_width will be filtered. Defaults to 1
588 * @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 +0100589 */
590 BoxNMSLimitInfo(float score_thresh = 0.05f, float nms = 0.3f,
591 int detections = 100, bool soft_nms_enabled = false,
592 NMSType soft_nms_method = NMSType::LINEAR,
Manuel Bottini5209be52019-02-13 16:34:56 +0000593 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 +0100594 : _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 +0000595 _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 +0100596 {
597 }
598 /** Get the score threshold */
599 float score_thresh() const
600 {
601 return _score_thresh;
602 }
603 /** Get the NMS */
604 float nms() const
605 {
606 return _nms;
607 }
608 /** Get the number of detections */
609 int detections_per_im() const
610 {
611 return _detections_per_im;
612 }
613 /** Check if soft NMS is enabled */
614 bool soft_nms_enabled() const
615 {
616 return _soft_nms_enabled;
617 }
618 /** Get soft NMS method */
619 NMSType soft_nms_method() const
620 {
621 return _soft_nms_method;
622 }
623 /** Get soft NMS sigma */
624 float soft_nms_sigma() const
625 {
626 return _soft_nms_sigma;
627 }
628 /** Get soft nms min score threshold */
629 float soft_nms_min_score_thres() const
630 {
631 return _soft_nms_min_score_thres;
632 }
Manuel Bottini5209be52019-02-13 16:34:56 +0000633 /** Get if NMS will suppress boxes based on their size/position */
634 bool suppress_size() const
635 {
636 return _suppress_size;
637 }
638 /** Get size suppression threshold */
639 float min_size() const
640 {
641 return _min_size;
642 }
643 /** Get image width (NMS may suppress boxes whose center sits beyond the image width) */
644 float im_width() const
645 {
646 return _im_width;
647 }
648 /** Get image height (NMS may suppress boxes whose center sits beyond the image height) */
649 float im_height() const
650 {
651 return _im_height;
652 }
Michalis Spyrou2709d612018-09-19 09:46:47 +0100653
654private:
655 float _score_thresh;
656 float _nms;
657 int _detections_per_im;
658 bool _soft_nms_enabled;
659 NMSType _soft_nms_method;
660 float _soft_nms_sigma;
661 float _soft_nms_min_score_thres;
Manuel Bottini5209be52019-02-13 16:34:56 +0000662 bool _suppress_size;
663 float _min_size;
664 float _im_width;
665 float _im_height;
Michalis Spyrou2709d612018-09-19 09:46:47 +0100666};
667
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100668/** Padding and stride information class */
669class PadStrideInfo
670{
671public:
672 /** Constructor
673 *
674 * @param[in] stride_x (Optional) Stride, in elements, across x. Defaults to 1.
675 * @param[in] stride_y (Optional) Stride, in elements, across y. Defaults to 1.
676 * @param[in] pad_x (Optional) Padding, in elements, across x. Defaults to 0.
677 * @param[in] pad_y (Optional) Padding, in elements, across y. Defaults to 0.
678 * @param[in] round (Optional) Dimensions rounding. Defaults to @ref FLOOR.
679 */
680 PadStrideInfo(unsigned int stride_x = 1, unsigned int stride_y = 1,
681 unsigned int pad_x = 0, unsigned int pad_y = 0,
682 DimensionRoundingType round = DimensionRoundingType::FLOOR)
683 : _stride(std::make_pair(stride_x, stride_y)),
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100684 _pad_left(pad_x),
685 _pad_top(pad_y),
686 _pad_right(pad_x),
687 _pad_bottom(pad_y),
688 _round_type(round)
689 {
690 }
691 /** Constructor
692 *
693 * @param[in] stride_x Stride, in elements, across x.
694 * @param[in] stride_y Stride, in elements, across y.
695 * @param[in] pad_left Padding across x on the left, in elements.
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100696 * @param[in] pad_right Padding across x on the right, in elements.
Freddie Liardetded36632021-09-03 15:08:23 +0100697 * @param[in] pad_top Padding across y on the top, in elements.
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100698 * @param[in] pad_bottom Padding across y on the bottom, in elements.
699 * @param[in] round Dimensions rounding.
700 */
701 PadStrideInfo(unsigned int stride_x, unsigned int stride_y,
702 unsigned int pad_left, unsigned int pad_right,
703 unsigned int pad_top, unsigned int pad_bottom,
704 DimensionRoundingType round)
705 : _stride(std::make_pair(stride_x, stride_y)),
706 _pad_left(pad_left),
707 _pad_top(pad_top),
708 _pad_right(pad_right),
709 _pad_bottom(pad_bottom),
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100710 _round_type(round)
711 {
712 }
Alex Gildayc357c472018-03-21 13:54:09 +0000713 /** Get the stride.
714 *
715 * @return a pair: stride x, stride y.
716 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100717 std::pair<unsigned int, unsigned int> stride() const
718 {
719 return _stride;
720 }
Alex Gildayc357c472018-03-21 13:54:09 +0000721 /** Check whether the padding is symmetric.
722 *
723 * @return True if the padding is symmetric.
724 */
Anthony Barbier21f67d62018-02-16 15:17:48 +0000725 bool padding_is_symmetric() const
726 {
727 return (_pad_left == _pad_right) && (_pad_top == _pad_bottom);
728 }
Alex Gildayc357c472018-03-21 13:54:09 +0000729 /** Get the padding.
730 *
731 * @note This should only be used when the padding is symmetric.
732 *
733 * @return a pair: padding left/right, padding top/bottom
734 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100735 std::pair<unsigned int, unsigned int> pad() const
736 {
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100737 //this accessor should be used only when padding is symmetric
Anthony Barbier21f67d62018-02-16 15:17:48 +0000738 ARM_COMPUTE_ERROR_ON(!padding_is_symmetric());
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100739 return std::make_pair(_pad_left, _pad_top);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100740 }
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100741
Alex Gildayc357c472018-03-21 13:54:09 +0000742 /** Get the left padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100743 unsigned int pad_left() const
744 {
745 return _pad_left;
746 }
Alex Gildayc357c472018-03-21 13:54:09 +0000747 /** Get the right padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100748 unsigned int pad_right() const
749 {
750 return _pad_right;
751 }
Alex Gildayc357c472018-03-21 13:54:09 +0000752 /** Get the top padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100753 unsigned int pad_top() const
754 {
755 return _pad_top;
756 }
Alex Gildayc357c472018-03-21 13:54:09 +0000757 /** Get the bottom padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100758 unsigned int pad_bottom() const
759 {
760 return _pad_bottom;
761 }
762
Alex Gildayc357c472018-03-21 13:54:09 +0000763 /** Get the rounding type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100764 DimensionRoundingType round() const
765 {
766 return _round_type;
767 }
768
Alex Gildayc357c472018-03-21 13:54:09 +0000769 /** Check whether this has any padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100770 bool has_padding() const
771 {
772 return (_pad_left != 0 || _pad_top != 0 || _pad_right != 0 || _pad_bottom != 0);
773 }
774
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100775private:
776 std::pair<unsigned int, unsigned int> _stride;
Pablo Marquez Tello16789a12022-07-25 14:41:26 +0100777 unsigned int _pad_left;
778 unsigned int _pad_top;
779 unsigned int _pad_right;
780 unsigned int _pad_bottom;
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100781
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100782 DimensionRoundingType _round_type;
783};
784
Adnan AlSinane4563a02021-09-01 15:32:03 +0100785/** Padding information for 3D operations like Conv3d */
786struct Padding3D
787{
Freddie Liardetebefe522021-11-25 16:19:28 +0000788 Padding3D() noexcept
Giorgio Arenac9fe9fc2021-10-06 12:54:29 +0100789 {
790 }
791
792 Padding3D(size_t pad_x, size_t pad_y, size_t pad_z)
793 : left(pad_x), right(pad_x), top(pad_y), bottom(pad_y), front(pad_z), back(pad_z)
794 {
795 }
796
797 Padding3D(size_t left, size_t right, size_t top, size_t bottom, size_t front, size_t back)
798 : left(left), right(right), top(top), bottom(bottom), front(front), back(back)
799 {
800 }
801
Adnan AlSinane4563a02021-09-01 15:32:03 +0100802 size_t left = { 0 }; /**< Padding across the width dimenstion on the left, in elements. */
803 size_t right = { 0 }; /**< Padding across the width dimenstion on the right, in elements. */
804 size_t top = { 0 }; /**< Padding across the height dimenstion on the top, in elements. */
805 size_t bottom = { 0 }; /**< Padding across the height dimenstion on the bottom, in elements. */
806 size_t front = { 0 }; /**< Padding across the depth dimenstion on the front, in elements. */
807 size_t back = { 0 }; /**< Padding across the depth dimenstion on the back, in elements. */
808};
809
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100810/** PriorBox layer info */
811class PriorBoxLayerInfo final
812{
813public:
814 /** Default Constructor */
815 PriorBoxLayerInfo()
816 : _min_sizes(),
817 _variances(),
818 _offset(),
819 _flip(true),
820 _clip(false),
821 _max_sizes(),
822 _aspect_ratios(),
823 _img_size(),
824 _steps()
825 {
826 }
827 /** Constructor
828 *
829 * @param[in] min_sizes Min sizes vector.
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100830 * @param[in] variances Variances vector.
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100831 * @param[in] offset Offset value.
832 * @param[in] flip (Optional) Flip the aspect ratios.
833 * @param[in] clip (Optional) Clip coordinates so that they're within [0,1].
834 * @param[in] max_sizes (Optional) Max sizes vector.
835 * @param[in] aspect_ratios (Optional) Aspect ratios of the boxes.
836 * @param[in] img_size (Optional) Image size.
837 * @param[in] steps (Optional) Step values.
838 */
839 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 +0000840 const std::vector<float> &max_sizes = {}, const std::vector<float> &aspect_ratios = {},
841 const Coordinates2D &img_size = Coordinates2D{ 0, 0 }, const std::array<float, 2> &steps = { { 0.f, 0.f } })
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100842 : _min_sizes(min_sizes),
843 _variances(variances),
844 _offset(offset),
845 _flip(flip),
846 _clip(clip),
847 _max_sizes(max_sizes),
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100848 _aspect_ratios(),
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100849 _img_size(img_size),
850 _steps(steps)
851 {
852 _aspect_ratios.push_back(1.);
853 for(unsigned int i = 0; i < aspect_ratios.size(); ++i)
854 {
855 float ar = aspect_ratios[i];
856 bool already_exist = false;
857 for(auto ar_new : _aspect_ratios)
858 {
859 if(fabs(ar - ar_new) < 1e-6)
860 {
861 already_exist = true;
862 break;
863 }
864 }
865 if(!already_exist)
866 {
867 _aspect_ratios.push_back(ar);
868 if(flip)
869 {
870 _aspect_ratios.push_back(1.f / ar);
871 }
872 }
873 }
874 }
875 /** Get min sizes. */
876 std::vector<float> min_sizes() const
877 {
878 return _min_sizes;
879 }
880 /** Get min variances. */
881 std::vector<float> variances() const
882 {
883 return _variances;
884 }
885 /** Get the step coordinates */
886 std::array<float, 2> steps() const
887 {
888 return _steps;
889 }
890 /** Get the image size coordinates */
891 Coordinates2D img_size() const
892 {
893 return _img_size;
894 }
895 /** Get the offset */
896 float offset() const
897 {
898 return _offset;
899 }
900 /** Get the flip value */
901 bool flip() const
902 {
903 return _flip;
904 }
905 /** Get the clip value */
906 bool clip() const
907 {
908 return _clip;
909 }
910 /** Get max sizes. */
911 std::vector<float> max_sizes() const
912 {
913 return _max_sizes;
914 }
915 /** Get aspect ratios. */
916 std::vector<float> aspect_ratios() const
917 {
918 return _aspect_ratios;
919 }
920
921private:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +0100922 std::vector<float> _min_sizes;
923 std::vector<float> _variances;
924 float _offset;
925 bool _flip;
926 bool _clip;
927 std::vector<float> _max_sizes;
928 std::vector<float> _aspect_ratios;
929 Coordinates2D _img_size;
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100930 std::array<float, 2> _steps;
931};
932
Isabella Gottardia7acb3c2019-01-08 13:48:44 +0000933// Bounding Box [xmin, ymin, xmax, ymax]
934using BBox = std::array<float, 4>;
935// LabelBBox used for map label and bounding box
936using LabelBBox = std::map<int, std::vector<BBox>>;
937
Isabella Gottardi05e56442018-11-16 11:26:52 +0000938/** Available Detection Output code types */
939enum class DetectionOutputLayerCodeType
940{
941 CORNER, /**< Use box corners */
942 CENTER_SIZE, /**< Use box centers and size */
943 CORNER_SIZE, /**< Use box centers and size */
944 TF_CENTER /**< Use box centers and size but flip x and y co-ordinates */
945};
946
947/** Detection Output layer info */
948class DetectionOutputLayerInfo final
949{
950public:
951 /** Default Constructor */
952 DetectionOutputLayerInfo()
953 : _num_classes(),
954 _share_location(),
955 _code_type(DetectionOutputLayerCodeType::CORNER),
956 _keep_top_k(),
957 _nms_threshold(),
958 _top_k(),
959 _background_label_id(),
960 _confidence_threshold(),
961 _variance_encoded_in_target(false),
962 _eta(),
963 _num_loc_classes()
964 {
965 _num_loc_classes = _share_location ? 1 : _num_classes;
966 }
967 /** Constructor
968 *
969 * @param[in] num_classes Number of classes to be predicted.
970 * @param[in] share_location If true, bounding box are shared among different classes.
971 * @param[in] code_type Type of coding method for bbox.
972 * @param[in] keep_top_k Number of total bounding boxes to be kept per image after NMS step.
973 * @param[in] nms_threshold Threshold to be used in NMS.
974 * @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.
975 * @param[in] background_label_id (Optional) Background label ID. If there is no background class, set it as -1.
976 * @param[in] confidence_threshold (Optional) Only consider detections whose confidences are larger than a threshold. Default set to -FLT_MAX.
977 * @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.
978 * @param[in] eta (Optional) Eta.
979 */
980 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,
981 float confidence_threshold = std::numeric_limits<float>::lowest(), bool variance_encoded_in_target = false, float eta = 1)
982 : _num_classes(num_classes),
983 _share_location(share_location),
984 _code_type(code_type),
985 _keep_top_k(keep_top_k),
986 _nms_threshold(nms_threshold),
987 _top_k(top_k),
988 _background_label_id(background_label_id),
989 _confidence_threshold(confidence_threshold),
990 _variance_encoded_in_target(variance_encoded_in_target),
991 _eta(eta),
992 _num_loc_classes()
993 {
994 _num_loc_classes = _share_location ? 1 : _num_classes;
995 }
996 /** Get num classes. */
997 int num_classes() const
998 {
999 return _num_classes;
1000 }
1001 /** Get share location. */
1002 bool share_location() const
1003 {
1004 return _share_location;
1005 }
1006 /** Get detection output code type. */
1007 DetectionOutputLayerCodeType code_type() const
1008 {
1009 return _code_type;
1010 }
1011 /** Get if variance encoded in target. */
1012 bool variance_encoded_in_target() const
1013 {
1014 return _variance_encoded_in_target;
1015 }
1016 /** Get the number of total bounding boxes to be kept per image. */
1017 int keep_top_k() const
1018 {
1019 return _keep_top_k;
1020 }
1021 /** Get nms threshold. */
1022 float nms_threshold() const
1023 {
1024 return _nms_threshold;
1025 }
1026 /** Get eta. */
1027 float eta() const
1028 {
1029 return _eta;
1030 }
1031 /** Get background label ID. */
1032 int background_label_id() const
1033 {
1034 return _background_label_id;
1035 }
1036 /** Get confidence threshold. */
1037 float confidence_threshold() const
1038 {
1039 return _confidence_threshold;
1040 }
1041 /** Get top K. */
1042 int top_k() const
1043 {
1044 return _top_k;
1045 }
1046 /** Get number of location classes. */
1047 int num_loc_classes() const
1048 {
1049 return _num_loc_classes;
1050 }
1051
1052private:
1053 int _num_classes;
1054 bool _share_location;
1055 DetectionOutputLayerCodeType _code_type;
1056 int _keep_top_k;
1057 float _nms_threshold;
1058 int _top_k;
1059 int _background_label_id;
1060 float _confidence_threshold;
1061 bool _variance_encoded_in_target;
1062 float _eta;
1063 int _num_loc_classes;
1064};
1065
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001066/** Detection Output layer info */
1067class DetectionPostProcessLayerInfo final
1068{
1069public:
1070 /** Default Constructor */
1071 DetectionPostProcessLayerInfo()
1072 : _max_detections(),
1073 _max_classes_per_detection(),
1074 _nms_score_threshold(),
1075 _iou_threshold(),
1076 _num_classes(),
1077 _scales_values(),
1078 _use_regular_nms(),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001079 _detection_per_class(),
1080 _dequantize_scores()
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001081 {
1082 }
1083 /** Constructor
1084 *
1085 * @param[in] max_detections Number of total detection.
1086 * @param[in] max_classes_per_detection Number of total classes to be kept after NMS step. Used in the Fast Non-Max-Suppression
1087 * @param[in] nms_score_threshold Threshold to be used in NMS
1088 * @param[in] iou_threshold Threshold to be used during the intersection over union.
1089 * @param[in] num_classes Number of classes.
1090 * @param[in] scales_values Scales values used for decode center size boxes.
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001091 * @param[in] use_regular_nms (Optional) Boolean to determinate if use regular or fast nms. Defaults to false.
1092 * @param[in] detection_per_class (Optional) Number of detection per class. Used in the Regular Non-Max-Suppression. Defaults to 100.
1093 * @param[in] dequantize_scores (Optional) If the scores need to be dequantized. Defaults to true.
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001094 */
1095 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 +01001096 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 +00001097 : _max_detections(max_detections),
1098 _max_classes_per_detection(max_classes_per_detection),
1099 _nms_score_threshold(nms_score_threshold),
1100 _iou_threshold(iou_threshold),
1101 _num_classes(num_classes),
1102 _scales_values(scales_values),
1103 _use_regular_nms(use_regular_nms),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001104 _detection_per_class(detection_per_class),
1105 _dequantize_scores(dequantize_scores)
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001106 {
1107 }
1108 /** Get max detections. */
1109 unsigned int max_detections() const
1110 {
1111 return _max_detections;
1112 }
1113 /** Get max_classes per detection. Used in the Fast Non-Max-Suppression.*/
1114 unsigned int max_classes_per_detection() const
1115 {
1116 return _max_classes_per_detection;
1117 }
1118 /** Get detection per class. Used in the Regular Non-Max-Suppression */
1119 unsigned int detection_per_class() const
1120 {
1121 return _detection_per_class;
1122 }
1123 /** Get nms threshold. */
1124 float nms_score_threshold() const
1125 {
1126 return _nms_score_threshold;
1127 }
1128 /** Get intersection over union threshold. */
1129 float iou_threshold() const
1130 {
1131 return _iou_threshold;
1132 }
1133 /** Get num classes. */
1134 unsigned int num_classes() const
1135 {
1136 return _num_classes;
1137 }
1138 /** Get if use regular nms. */
1139 bool use_regular_nms() const
1140 {
1141 return _use_regular_nms;
1142 }
1143 /** Get y scale value. */
1144 float scale_value_y() const
1145 {
1146 // Saved as [y,x,h,w]
1147 return _scales_values[0];
1148 }
1149 /** Get x scale value. */
1150 float scale_value_x() const
1151 {
1152 // Saved as [y,x,h,w]
1153 return _scales_values[1];
1154 }
1155 /** Get h scale value. */
1156 float scale_value_h() const
1157 {
1158 // Saved as [y,x,h,w]
1159 return _scales_values[2];
1160 }
1161 /** Get w scale value. */
1162 float scale_value_w() const
1163 {
1164 // Saved as [y,x,h,w]
1165 return _scales_values[3];
1166 }
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001167 /** Get dequantize_scores value. */
1168 bool dequantize_scores() const
1169 {
1170 return _dequantize_scores;
1171 }
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001172
1173private:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001174 unsigned int _max_detections;
1175 unsigned int _max_classes_per_detection;
1176 float _nms_score_threshold;
1177 float _iou_threshold;
1178 unsigned int _num_classes;
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001179 std::array<float, 4> _scales_values;
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001180 bool _use_regular_nms;
1181 unsigned int _detection_per_class;
1182 bool _dequantize_scores;
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001183};
1184
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001185/** Pooling Layer Information struct*/
1186struct PoolingLayerInfo
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001187{
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001188 /** Default Constructor */
1189 PoolingLayerInfo()
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001190 : pool_type(PoolingType::MAX),
1191 pool_size(Size2D()),
1192 data_layout(DataLayout::UNKNOWN),
1193 pad_stride_info(PadStrideInfo()),
1194 exclude_padding(false),
1195 is_global_pooling(false),
1196 fp_mixed_precision(false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001197 {
1198 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001199 /** Constructor
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001200 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001201 * @param[in] pool_type Pooling type @ref PoolingType.
1202 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001203 * @param[in] data_layout Data layout used by the layer @ref DataLayout
1204 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1205 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1206 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1207 * Defaults to false;
1208 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1209 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001210 explicit PoolingLayerInfo(PoolingType pool_type,
1211 unsigned int pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001212 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001213 PadStrideInfo pad_stride_info = PadStrideInfo(),
1214 bool exclude_padding = false,
1215 bool fp_mixed_precision = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001216 : pool_type(pool_type),
1217 pool_size(Size2D(pool_size, pool_size)),
1218 data_layout(data_layout),
1219 pad_stride_info(pad_stride_info),
1220 exclude_padding(exclude_padding),
1221 is_global_pooling(false),
1222 fp_mixed_precision(fp_mixed_precision)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001223 {
1224 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001225
1226 /** Constructor
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001227 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001228 * @param[in] pool_type Pooling type @ref PoolingType.
1229 * @param[in] pool_size Pooling size, in elements, across x and y.
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001230 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001231 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1232 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1233 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1234 * Defaults to false;
1235 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001236 */
1237 explicit PoolingLayerInfo(PoolingType pool_type,
1238 Size2D pool_size,
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001239 DataLayout data_layout,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001240 PadStrideInfo pad_stride_info = PadStrideInfo(),
1241 bool exclude_padding = false,
1242 bool fp_mixed_precision = false)
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001243 : pool_type(pool_type),
1244 pool_size(pool_size),
1245 data_layout(data_layout),
1246 pad_stride_info(pad_stride_info),
1247 exclude_padding(exclude_padding),
1248 is_global_pooling(false),
1249 fp_mixed_precision(fp_mixed_precision)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001250 {
1251 }
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001252
1253 /** Constructor
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001254 *
1255 * @note This constructor is used for global pooling
1256 *
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001257 * @param[in] pool_type Pooling type @ref PoolingType.
1258 * @param[in] data_layout Data layout used by the layer @ref DataLayout
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001259 */
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001260 explicit PoolingLayerInfo(PoolingType pool_type, DataLayout data_layout)
1261 : pool_type(pool_type),
1262 pool_size(Size2D()),
1263 data_layout(data_layout),
1264 pad_stride_info(PadStrideInfo(1, 1, 0, 0)),
1265 exclude_padding(false),
1266 is_global_pooling(true),
1267 fp_mixed_precision(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001268 {
1269 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001270
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001271 PoolingType pool_type;
1272 Size2D pool_size;
Sang-Hoon Park11fedda2020-01-15 14:44:04 +00001273 DataLayout data_layout;
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +00001274 PadStrideInfo pad_stride_info;
1275 bool exclude_padding;
1276 bool is_global_pooling;
1277 bool fp_mixed_precision;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001278};
1279
ramelg0137515692022-02-26 22:06:20 +00001280/** Pooling Layer Information struct*/
1281struct Pooling3dLayerInfo
1282{
1283 /** Default Constructor */
Michalis Spyrou50e48aa2022-04-21 16:42:56 +01001284 Pooling3dLayerInfo() noexcept
ramelg0137515692022-02-26 22:06:20 +00001285 : pool_type(PoolingType::MAX),
1286 pool_size(Size3D()),
1287 stride(Size3D()),
1288 padding(Padding3D()),
1289 exclude_padding(false),
1290 is_global_pooling(false),
1291 fp_mixed_precision(false),
1292 round_type(DimensionRoundingType::FLOOR)
1293 {
1294 }
1295 /** Constructor
1296 *
1297 * @param[in] pool_type Pooling type @ref PoolingType.
1298 * @param[in] pool_size Pooling size, in elements, across x, y and z.
1299 * @param[in] stride (Optional) stride information @ref Size3D
1300 * @param[in] padding (Optional) padding information @ref Padding3D
1301 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1302 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1303 * Defaults to false;
1304 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1305 * @param[in] round_type (Optional) Dimensions rounding. Defaults to @ref FLOOR
1306 */
1307 explicit Pooling3dLayerInfo(PoolingType pool_type,
1308 unsigned int pool_size,
1309 Size3D stride = Size3D(1U, 1U, 1U),
1310 Padding3D padding = Padding3D(),
1311 bool exclude_padding = false,
1312 bool fp_mixed_precision = false,
1313 DimensionRoundingType round_type = DimensionRoundingType::FLOOR)
1314 : pool_type(pool_type),
1315 pool_size(Size3D(pool_size, pool_size, pool_size)),
1316 stride(stride),
1317 padding(padding),
1318 exclude_padding(exclude_padding),
1319 is_global_pooling(false),
1320 fp_mixed_precision(fp_mixed_precision),
1321 round_type(round_type)
1322 {
1323 }
1324
1325 /** Constructor
1326 *
1327 * @param[in] pool_type Pooling type @ref PoolingType.
1328 * @param[in] pool_size Pooling size, in elements, across x, y and z.
1329 * @param[in] stride (Optional) stride information @ref Size3D
1330 * @param[in] padding (Optional) padding information @ref Padding3D
1331 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1332 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1333 * Defaults to false;
1334 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
1335 * @param[in] round_type (Optional) Dimensions rounding. Defaults to @ref FLOOR
1336 */
1337 explicit Pooling3dLayerInfo(PoolingType pool_type,
1338 Size3D pool_size,
1339 Size3D stride = Size3D(1U, 1U, 1U),
1340 Padding3D padding = Padding3D(),
1341 bool exclude_padding = false,
1342 bool fp_mixed_precision = false,
1343 DimensionRoundingType round_type = DimensionRoundingType::FLOOR)
1344 : pool_type(pool_type),
1345 pool_size(pool_size),
1346 stride(stride),
1347 padding(padding),
1348 exclude_padding(exclude_padding),
1349 is_global_pooling(false),
1350 fp_mixed_precision(fp_mixed_precision),
1351 round_type(round_type)
1352 {
1353 }
1354
1355 /** Constructor
1356 *
1357 * @note This constructor is used for global pooling
1358 *
1359 * @param[in] pool_type Pooling type @ref PoolingType.
1360 */
1361 explicit Pooling3dLayerInfo(PoolingType pool_type)
1362 : pool_type(pool_type),
1363 pool_size(Size3D()),
1364 stride(Size3D(1U, 1U, 1U)),
1365 padding(Padding3D(0, 0, 0)),
1366 exclude_padding(false),
1367 is_global_pooling(true),
1368 fp_mixed_precision(false),
1369 round_type(DimensionRoundingType::FLOOR)
1370 {
1371 }
1372
1373 PoolingType pool_type;
1374 Size3D pool_size;
1375 Size3D stride;
1376 Padding3D padding;
1377 bool exclude_padding;
1378 bool is_global_pooling;
1379 bool fp_mixed_precision;
1380 DimensionRoundingType round_type;
1381};
1382
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001383/** ROI Pooling Layer Information class */
giuros0118870812018-09-13 09:31:40 +01001384class ROIPoolingLayerInfo final
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001385{
1386public:
giuros0118870812018-09-13 09:31:40 +01001387 /** Constructor
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001388 *
giuros0118870812018-09-13 09:31:40 +01001389 * @param[in] pooled_width Pooled width of the layer.
1390 * @param[in] pooled_height Pooled height of the layer.
1391 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
1392 * @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 +01001393 */
giuros0118870812018-09-13 09:31:40 +01001394 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale, unsigned int sampling_ratio = 0)
1395 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale), _sampling_ratio(sampling_ratio)
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001396 {
1397 }
Alex Gildayc357c472018-03-21 13:54:09 +00001398 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001399 unsigned int pooled_width() const
1400 {
1401 return _pooled_width;
1402 }
Alex Gildayc357c472018-03-21 13:54:09 +00001403 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001404 unsigned int pooled_height() const
1405 {
1406 return _pooled_height;
1407 }
Alex Gildayc357c472018-03-21 13:54:09 +00001408 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001409 float spatial_scale() const
1410 {
1411 return _spatial_scale;
1412 }
giuros0118870812018-09-13 09:31:40 +01001413 /** Get sampling ratio */
1414 unsigned int sampling_ratio() const
1415 {
1416 return _sampling_ratio;
1417 }
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001418
1419private:
1420 unsigned int _pooled_width;
1421 unsigned int _pooled_height;
1422 float _spatial_scale;
giuros0118870812018-09-13 09:31:40 +01001423 unsigned int _sampling_ratio;
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001424};
1425
Manuel Bottini5209be52019-02-13 16:34:56 +00001426/** Generate Proposals Information class */
1427class GenerateProposalsInfo
1428{
1429public:
1430 /** Constructor
1431 *
1432 * @param[in] im_width Width of the original image
1433 * @param[in] im_height Height of the original image
1434 * @param[in] im_scale Scale applied to the original image
1435 * @param[in] spatial_scale (Optional)Scale applied to the feature map. Defaults to 1.0
1436 * @param[in] pre_nms_topN (Optional)Number of the best scores to be selected from the transformations. Defaults to 6000.
1437 * @param[in] post_nms_topN (Optional)Number of the best scores to be selected from the NMS operation. Defaults to 300.
1438 * @param[in] nms_thres (Optional)NMS overlap threshold. Defaults to 0.7.
1439 * @param[in] min_size (Optional)Size used to validate the anchors produced. Defaults to 16.
1440 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region of interest). Defaults to 4.
1441 */
1442 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,
1443 size_t values_per_roi = 4)
1444 : _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),
1445 _min_size(min_size), _values_per_roi(values_per_roi)
1446 {
1447 }
1448
1449 /* Get the original height */
1450 float im_height() const
1451 {
1452 return _im_height;
1453 }
1454 /* Get the original width */
1455 float im_width() const
1456 {
1457 return _im_width;
1458 }
1459 /* Get the image scale */
1460 float im_scale() const
1461 {
1462 return _im_scale;
1463 }
1464 /* Get the value of how many best scores to select (before NMS) */
1465 int pre_nms_topN() const
1466 {
1467 return _pre_nms_topN;
1468 }
1469 /* Get the value of how many best scores to select (after NMS) */
1470 int post_nms_topN() const
1471 {
1472 return _post_nms_topN;
1473 }
1474 /* Get the NMS overlap threshold */
1475 float nms_thres() const
1476 {
1477 return _nms_thres;
1478 }
1479 /* Get the minimal size */
1480 float min_size() const
1481 {
1482 return _min_size;
1483 }
1484 /* Get the spatial scale to be applied to the feature maps */
1485 float spatial_scale() const
1486 {
1487 return _spatial_scale;
1488 }
1489 /* Get the values used to represent a ROI(Region of interest)*/
1490 size_t values_per_roi() const
1491 {
1492 return _values_per_roi;
1493 }
1494
1495private:
1496 float _im_height;
1497 float _im_width;
1498 float _im_scale;
1499 float _spatial_scale;
1500 int _pre_nms_topN;
1501 int _post_nms_topN;
1502 float _nms_thres;
1503 float _min_size;
1504 size_t _values_per_roi;
1505};
1506
1507/** ComputeAnchors information class */
1508class ComputeAnchorsInfo
1509{
1510public:
1511 /** Constructor
1512 *
1513 * @param[in] feat_width Feature map width
1514 * @param[in] feat_height Feature map height
1515 * @param[in] spatial_scale Feature map scale
1516 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region Of Interest). Defaults to 4
1517 */
1518 ComputeAnchorsInfo(float feat_width, float feat_height, float spatial_scale, size_t values_per_roi = 4)
1519 : _feat_height(feat_height),
1520 _feat_width(feat_width),
1521 _spatial_scale(spatial_scale),
1522 _values_per_roi(values_per_roi)
1523 {
1524 }
1525
1526 /* Get the height of the feature map */
1527 float feat_height() const
1528 {
1529 return _feat_height;
1530 }
1531
1532 /* Get the width of the feature map */
1533 float feat_width() const
1534 {
1535 return _feat_width;
1536 }
1537
1538 /* Get the scale of the feature map */
1539 float spatial_scale() const
1540 {
1541 return _spatial_scale;
1542 }
1543
1544 /* Get the values used to represent a ROI(Region Of Interest)*/
1545 size_t values_per_roi() const
1546 {
1547 return _values_per_roi;
1548 }
1549
1550private:
1551 float _feat_height;
1552 float _feat_width;
1553 float _spatial_scale;
1554 size_t _values_per_roi;
1555};
1556
giuros01c04a0e82018-10-03 12:44:35 +01001557/** Bounding Box Transform information class */
giuros01d696cb62018-11-16 10:39:59 +00001558class BoundingBoxTransformInfo final
giuros01c04a0e82018-10-03 12:44:35 +01001559{
1560public:
1561 /** Constructor
1562 *
giuros01d696cb62018-11-16 10:39:59 +00001563 * @param[in] img_width Width of the original image
1564 * @param[in] img_height Height, of the original image
1565 * @param[in] scale Scale of the original image
1566 * @param[in] apply_scale (Optional)Re-apply scaling after transforming the boxes. Defaults to false
1567 * @param[in] weights (Optional)Weights [wx, wy, ww, wh] for the deltas. Defaults to all ones
1568 * @param[in] correct_transform_coords (Optional)Correct bounding box transform coordinates. Defaults to false
1569 * @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 +01001570 */
giuros01d696cb62018-11-16 10:39:59 +00001571 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 =
1572 false,
1573 float bbox_xform_clip =
1574 4.135166556742356f)
1575 : _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 +01001576 {
1577 }
1578
1579 std::array<float, 4> weights() const
1580 {
1581 return _weights;
1582 }
1583
1584 float bbox_xform_clip() const
1585 {
1586 return _bbox_xform_clip;
1587 }
1588
1589 float img_height() const
1590 {
1591 return _img_height;
1592 }
1593
1594 float img_width() const
1595 {
1596 return _img_width;
1597 }
1598
1599 float scale() const
1600 {
1601 return _scale;
1602 }
1603
1604 bool apply_scale() const
1605 {
1606 return _apply_scale;
1607 }
1608
giuros01d696cb62018-11-16 10:39:59 +00001609 bool correct_transform_coords() const
1610 {
1611 return _correct_transform_coords;
1612 }
1613
giuros01c04a0e82018-10-03 12:44:35 +01001614private:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001615 float _img_width;
1616 float _img_height;
1617 float _scale;
1618 bool _apply_scale;
1619 bool _correct_transform_coords;
giuros01c04a0e82018-10-03 12:44:35 +01001620 std::array<float, 4> _weights;
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001621 float _bbox_xform_clip;
giuros01c04a0e82018-10-03 12:44:35 +01001622};
1623
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001624/** Activation Layer Information class */
1625class ActivationLayerInfo
1626{
1627public:
1628 /** Available activation functions */
1629 enum class ActivationFunction
1630 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001631 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
1632 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
1633 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
1634 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
1635 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
Manuel Bottini581c8982019-02-07 10:31:57 +00001636 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 +01001637 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
Georgios Pinitasfb0fdcd2019-08-22 17:10:04 +01001638 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 +01001639 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
1640 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
1641 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
Usama Arif6a98a6e2019-05-10 17:07:27 +01001642 LINEAR, /**< Linear ( \f$ f(x)= ax + b \f$ ) */
morgolock07df3d42020-02-27 11:46:28 +00001643 IDENTITY, /**< Identity ( \f$ f(x)= x \f$ ) */
Murray Kornelsen926f5022022-07-13 21:22:39 -04001644 HARD_SWISH, /**< Hard-swish ( \f$ f(x) = (x * relu6(x+3))/6 \f$ ) */
1645 GELU /**< GELU ( \f$ f(x) = x * 1/2 * 1 + erf(x / \sqrt{2}) \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001646 };
1647
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001648 /** Lookup table */
1649 using LookupTable256 = std::array<qasymm8_t, 256>;
1650
Giorgio Arena11674872018-02-07 15:38:12 +00001651 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001652 /** Default Constructor
1653 *
1654 * @param[in] f The activation function to use.
1655 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001656 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1657 * @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 +01001658 */
1659 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001660 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001661 {
1662 }
Alex Gildayc357c472018-03-21 13:54:09 +00001663 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001664 ActivationFunction activation() const
1665 {
1666 return _act;
1667 }
Alex Gildayc357c472018-03-21 13:54:09 +00001668 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001669 float a() const
1670 {
1671 return _a;
1672 }
Alex Gildayc357c472018-03-21 13:54:09 +00001673 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001674 float b() const
1675 {
1676 return _b;
1677 }
Alex Gildayc357c472018-03-21 13:54:09 +00001678 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001679 bool enabled() const
1680 {
1681 return _enabled;
1682 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001683
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001684#ifdef __aarch64__
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001685 const LookupTable256 &lut() const
1686 {
1687 return _lut;
1688 }
1689
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001690 void init_lut(DataType data_type, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001691 {
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001692 if(_act == ActivationFunction::HARD_SWISH)
1693 {
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001694 if(data_type == DataType::QASYMM8)
1695 {
1696 qasymm8_hard_swish_populate_table(_lut, qi_in, qi_out);
1697 }
1698 else
1699 {
1700 qasymm8_signed_hard_swish_populate_table(_lut, qi_in, qi_out);
1701 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001702 }
1703 else if(_act == ActivationFunction::LEAKY_RELU)
1704 {
1705 qasymm8_leaky_relu_populate_table(_lut, qi_in, qi_out, _a);
1706 }
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001707 else if(_act == ActivationFunction::LOGISTIC)
1708 {
1709 if(data_type == DataType::QASYMM8)
1710 {
1711 qasymm8_logistic_populate_table(_lut, qi_in, qi_out);
1712 }
1713 else
1714 {
1715 qasymm8_signed_logistic_populate_table(_lut, qi_in, qi_out);
1716 }
1717 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001718 }
1719#endif // __aarch64__
1720
1721 static inline bool is_lut_supported(ActivationFunction act_func, DataType data_type)
1722 {
1723#ifdef __aarch64__
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001724 switch(act_func)
1725 {
1726 case ActivationFunction::HARD_SWISH:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001727 return data_type == DataType::QASYMM8 || data_type == DataType::QASYMM8_SIGNED;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001728 case ActivationFunction::LEAKY_RELU:
1729 return data_type == DataType::QASYMM8;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001730 case ActivationFunction::LOGISTIC:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001731 return data_type == DataType::QASYMM8 || data_type == DataType::QASYMM8_SIGNED;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001732 default:
1733 return false;
1734 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001735#else // __aarch64__
1736 ARM_COMPUTE_UNUSED(act_func);
1737 ARM_COMPUTE_UNUSED(data_type);
1738 return false;
1739#endif // __aarch64__
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001740 }
1741
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001742private:
Usama Arif6a98a6e2019-05-10 17:07:27 +01001743 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::IDENTITY };
Giorgio Arena11674872018-02-07 15:38:12 +00001744 float _a = {};
1745 float _b = {};
1746 bool _enabled = { false };
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001747
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001748#ifdef __aarch64__
1749 LookupTable256 _lut = {};
1750
1751 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 +01001752 {
1753 for(size_t i = 0; i < lut.size(); ++i)
1754 {
1755 lut[i] = qasymm8_hard_swish(i, qi_in, qi_out);
1756 }
1757 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001758
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001759 static inline void qasymm8_signed_hard_swish_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1760 {
1761 for(size_t i = 0; i < lut.size(); ++i)
1762 {
1763 lut[i] = qasymm8_signed_hard_swish(i, qi_in, qi_out);
1764 }
1765 }
1766
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001767 static inline void qasymm8_leaky_relu_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out, float alpha)
1768 {
1769 for(size_t i = 0; i < lut.size(); ++i)
1770 {
1771 lut[i] = qasymm8_leaky_relu(i, qi_in, qi_out, alpha);
1772 }
1773 }
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001774
1775 static inline void qasymm8_logistic_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1776 {
1777 for(size_t i = 0; i < lut.size(); ++i)
1778 {
1779 lut[i] = qasymm8_logistic(i, qi_in, qi_out);
1780 }
1781 }
1782
1783 static inline void qasymm8_signed_logistic_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1784 {
1785 for(size_t i = 0; i < lut.size(); ++i)
1786 {
1787 lut[i] = qasymm8_signed_logistic(static_cast<int8_t>(i), qi_in, qi_out);
1788 }
1789 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001790#endif // __aarch64__
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001791};
1792
Giorgio Arena1856ff72020-02-07 13:46:45 +00001793/** Fully connected layer info */
1794struct FullyConnectedLayerInfo
1795{
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001796 /* Fused-activation parameters */
1797 ActivationLayerInfo activation_info{}; /**< Fused activation to apply after the matrix multiplication. */
1798 /* Information about weights */
1799 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
1800 bool transpose_weights{ true }; /**< Transpose weights if true. */
1801 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
1802 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
cfRodf2c022e2021-11-05 11:29:53 +00001803 bool enable_fast_math{ false }; /**< Enable fast math computation. */
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001804 /* Other parameters */
1805 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 +00001806
1807 /** Sets the weights trained data layout
1808 *
1809 * @param[in] layout Data layout that the weights were trained with
1810 *
1811 * @return Updated object
1812 */
1813 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
1814 {
1815 weights_trained_layout = layout;
1816 return *this;
1817 }
1818 /** Sets the transpose weights flag
1819 *
1820 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
1821 *
1822 * @return Updated object
1823 */
1824 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
1825 {
1826 transpose_weights = should_transpose_weights;
1827 return *this;
1828 }
1829};
1830
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001831/** Normalization Layer Information class */
1832class NormalizationLayerInfo
1833{
1834public:
1835 /** Default Constructor
1836 *
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001837 * @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 +01001838 * @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 +00001839 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1840 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1841 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1842 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1843 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001844 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001845 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1846 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001847 {
1848 }
Alex Gildayc357c472018-03-21 13:54:09 +00001849 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001850 NormType type() const
1851 {
1852 return _type;
1853 }
Alex Gildayc357c472018-03-21 13:54:09 +00001854 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001855 uint32_t norm_size() const
1856 {
1857 return _norm_size;
1858 }
Alex Gildayc357c472018-03-21 13:54:09 +00001859 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001860 float alpha() const
1861 {
1862 return _alpha;
1863 }
Alex Gildayc357c472018-03-21 13:54:09 +00001864 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001865 float beta() const
1866 {
1867 return _beta;
1868 }
Alex Gildayc357c472018-03-21 13:54:09 +00001869 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001870 float kappa() const
1871 {
1872 return _kappa;
1873 }
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001874 /** Get the is_scaled value */
1875 bool is_scaled() const
1876 {
1877 return _is_scaled;
1878 }
Alex Gildayc357c472018-03-21 13:54:09 +00001879 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001880 bool is_cross_map() const
1881 {
1882 return _type == NormType::CROSS_MAP;
1883 }
Alex Gildayc357c472018-03-21 13:54:09 +00001884 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001885 bool is_in_map() const
1886 {
1887 return !is_cross_map();
1888 }
1889 /** Return the scaling factor of the normalization function.
1890 *
1891 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1892 * 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 +01001893 *
1894 * @return The normalization scaling factor.
1895 */
1896 float scale_coeff() const
1897 {
1898 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001899 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001900 }
1901
1902private:
1903 NormType _type;
1904 uint32_t _norm_size;
1905 float _alpha;
1906 float _beta;
1907 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001908 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001909};
1910
thecha012bfadd92020-08-12 17:25:51 +01001911class StridedSliceLayerInfo
1912{
1913public:
1914 /** Default Constructor
1915 *
1916 * @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.
1917 * @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.
1918 * @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.
1919 */
1920 StridedSliceLayerInfo(int32_t begin_mask = 0, int32_t end_mask = 0, int32_t shrink_axis_mask = 0)
1921 : _begin_mask(begin_mask), _end_mask(end_mask), _shrink_axis_mask(shrink_axis_mask)
1922 {
1923 }
1924
1925 /* Get the begin mask value */
1926 int32_t begin_mask() const
1927 {
1928 return _begin_mask;
1929 }
1930
1931 /* Get the end mask value */
1932 int32_t end_mask() const
1933 {
1934 return _end_mask;
1935 }
1936
1937 /* Get the shrink axis mask value */
1938 int32_t shrink_axis_mask() const
1939 {
1940 return _shrink_axis_mask;
1941 }
1942
1943private:
1944 int32_t _begin_mask;
1945 int32_t _end_mask;
1946 int32_t _shrink_axis_mask;
1947};
1948
Ramy Elgammal91780022022-07-20 14:57:37 +01001949/** Memory layouts for the weights tensor.
1950 *
1951 * * UNSPECIFIED is used to select kernels that do not run in
1952 * variable weights mode.
1953 *
1954 * * ANY is used to query the kernel database to retrieve any of the
1955 * kernels that runs in variable weights mode. Once a kernel is
1956 * found, the specific format expected by the kernel can be
1957 * retrieved by the user for reordering the weights tensor
1958 * accordingly.
1959 *
1960 * The other values OHWIo{interleave_by}i{block_by} describe the
1961 * memory layout of a 4D tensor with layout OHWI that has been
1962 * transformed into a 4D tensor with dimensions O'HWI' where:
1963 *
1964 * O' = first multiple of {interleave_by} s.t. O<=O'
1965 * I' = first multiple of {block_by} s.t. I<=I'
1966 *
1967 * The total size of the dst tensor is O' x H x W x I'
1968 *
1969 * The access function of the tensor with layout
1970 * OHWIo{interleave_by}i{block_by} and size O'HWI' is a 6-parameter
1971 * access function, where the 6 parameters are computed as follows:
1972 *
1973 * x5 = floor(o/{interleave_by}) RANGE [0, O'/{interleave_by} -1] SIZE: O'/{interleave_by}
1974 *
1975 * x4 = h RANGE [0, H-1] SIZE: H
1976 * x3 = w RANGE [0, W-1] SIZE: W
1977 * x2 = floor(i/{block_by}) RANGE [0, I'/{block_by} -1] SIZE: I'/{block_by}
1978 * x1 = o%{interleave_by} RANGE [0, {interleave_by} -1] SIZE: {interleave_by}
1979 * x0 = i%{block_by} RANGE [0, {block_by} -1] SIZE: {block_by}
1980 * TOTAL SIZE: O' * H * W * I'
1981 *
1982 * 4D 6D
1983 * ----------------- -----------------------------------
1984 * value(o, h, w, i) = x5 * H * W * I' * {interleave_by}
1985 * + x4 * W * I' * {interleave_by}
1986 * + x3 * I' * {interleave_by}
1987 * + x2 * {interleave_by} * {block_by}
1988 * + x1 * {block_by}
1989 * + x0
1990 *
1991 * Notice that in arm_gemm the 4D tensor of dimension O'HWI' created
1992 * for the OHWIo{interleave_by}i{block_by} format is in reality seen
1993 * as a 2D tensor, where the number of rows is O'/{interleave_by}
1994 * and the number of columns is {interleave_by} * H * W * I'.
1995 *
1996 * The postfix *_bf16 is for the memory layout needed for the
1997 * fast-mode kernels, in which the weights are passed in bfloat16
1998 * format.
1999 */
2000enum class WeightFormat
2001{
2002 UNSPECIFIED = 0x1,
2003 ANY = 0x2,
2004 OHWI = 0x100100,
2005 OHWIo2 = 0x100200,
2006 OHWIo4 = 0x100400,
2007 OHWIo8 = 0x100800,
2008 OHWIo16 = 0x101000,
2009 OHWIo32 = 0x102000,
2010 OHWIo64 = 0x104000,
2011 OHWIo128 = 0x108000,
2012 OHWIo4i2 = 0x200400,
2013 OHWIo4i2_bf16 = 0x200410,
2014 OHWIo8i2 = 0x200800,
2015 OHWIo8i2_bf16 = 0x200810,
2016 OHWIo16i2 = 0x201000,
2017 OHWIo16i2_bf16 = 0x201010,
2018 OHWIo32i2 = 0x202000,
2019 OHWIo32i2_bf16 = 0x202010,
2020 OHWIo64i2 = 0x204000,
2021 OHWIo64i2_bf16 = 0x204010,
2022 OHWIo4i4 = 0x400400,
2023 OHWIo4i4_bf16 = 0x400410,
2024 OHWIo8i4 = 0x400800,
2025 OHWIo8i4_bf16 = 0x400810,
2026 OHWIo16i4 = 0x401000,
2027 OHWIo16i4_bf16 = 0x401010,
2028 OHWIo32i4 = 0x402000,
2029 OHWIo32i4_bf16 = 0x402010,
2030 OHWIo64i4 = 0x404000,
2031 OHWIo64i4_bf16 = 0x404010,
2032 OHWIo2i8 = 0x800200,
2033 OHWIo4i8 = 0x800400,
2034 OHWIo8i8 = 0x800800,
2035 OHWIo16i8 = 0x801000,
2036 OHWIo32i8 = 0x802000,
2037 OHWIo64i8 = 0x804000
2038};
2039// OHWIo<interleave_by>i<block_by>
2040inline int interleave_by(const WeightFormat wf)
2041{
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002042 return (static_cast<int>(wf) >> 8) & 0xFFF;
Ramy Elgammal91780022022-07-20 14:57:37 +01002043}
2044inline int block_by(const WeightFormat wf)
2045{
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002046 return (static_cast<int>(wf) >> 20) & 0xF;
Ramy Elgammal91780022022-07-20 14:57:37 +01002047}
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002048inline bool is_fixed_format(const WeightFormat &wf)
Ramy Elgammal91780022022-07-20 14:57:37 +01002049{
2050 return wf != WeightFormat::UNSPECIFIED && wf != WeightFormat::ANY;
2051}
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002052inline bool is_fixed_format_fast_math(const WeightFormat &wf)
2053{
2054 return (static_cast<int>(wf) >> 4) & 0x1;
2055}
Ramy Elgammal91780022022-07-20 14:57:37 +01002056
Gian Marco Iodice559d7712017-08-08 08:38:09 +01002057/** 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 +01002058class WeightsInfo
2059{
2060public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002061 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002062 WeightsInfo()
Ramy Elgammal91780022022-07-20 14:57:37 +01002063 : _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 +01002064 {
2065 }
2066 /** Constructor
2067 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01002068 * @param[in] are_reshaped True if the weights have been reshaped
2069 * @param[in] kernel_width Kernel width.
2070 * @param[in] kernel_height Kernel height.
2071 * @param[in] num_kernels Number of convolution kernels.
2072 * @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 +01002073 * @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 +01002074 */
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002075 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 +01002076 arm_compute::WeightFormat weight_format = arm_compute::WeightFormat::UNSPECIFIED)
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002077 : _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 +01002078 {
2079 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002080 /** Flag which specifies if the weights tensor has been reshaped.
2081 *
2082 * @return True if the weights tensors has been reshaped
2083 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002084 bool are_reshaped() const
2085 {
2086 return _are_reshaped;
2087 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01002088 /** Return the number of convolution kernels
2089 *
2090 * @return The number of convolution kernels
2091 */
2092 unsigned int num_kernels() const
2093 {
2094 return _num_kernels;
2095 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002096 /** Return the width and height of the kernel
2097 *
2098 * @return The width and height of the kernel
2099 */
2100 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002101 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002102 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002103 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01002104 bool retain_internal_weights() const
2105 {
2106 return _retain_internal_weights;
2107 }
Ramy Elgammal91780022022-07-20 14:57:37 +01002108 arm_compute::WeightFormat weight_format() const
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002109 {
2110 return _weight_format;
2111 }
Milos Puzovic13b623e2022-07-27 17:53:21 +00002112 void set_weight_format(arm_compute::WeightFormat weight_format)
2113 {
2114 _weight_format = weight_format;
2115 }
2116
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002117 unsigned int kernel_width() const
2118 {
2119 return _kernel_width;
2120 }
2121 unsigned int kernel_height() const
2122 {
2123 return _kernel_height;
2124 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002125
2126private:
Ramy Elgammal91780022022-07-20 14:57:37 +01002127 bool _are_reshaped;
2128 unsigned int _kernel_width;
2129 unsigned int _kernel_height;
2130 unsigned int _num_kernels;
2131 bool _retain_internal_weights;
2132 arm_compute::WeightFormat _weight_format;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002133};
2134
Gian Marco36a0a462018-01-12 10:21:40 +00002135/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
2136 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01002137 * The matrix A can only be reshaped through @ref opencl::kernels::ClGemmReshapeLhsMatrixKernel or @ref cpu::kernels::CpuGemmInterleave4x4Kernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01002138 * 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 +00002139 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01002140 * The matrix B can only be reshaped through @ref opencl::kernels::ClGemmReshapeRhsMatrixKernel or @ref cpu::kernels::CpuGemmTranspose1xWKernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01002141 * 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 +00002142 *
2143 */
2144class GEMMReshapeInfo final
2145{
2146public:
2147 /** Default constructor */
2148 GEMMReshapeInfo()
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002149 : _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 +00002150 {
2151 }
2152 /** Constructor
2153 *
2154 * @param[in] m Number of matrix A rows
2155 * @param[in] n Number of matrix B columns
2156 * @param[in] k Number of matrix A columns or matrix B rows
2157 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
2158 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002159 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
2160 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002161 * @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 +01002162 * to perform 1x1 convolutions with the NHWC data layout)
2163 * @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 +00002164 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002165 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 +01002166 : _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 +01002167 _reinterpret_input_as_3d(reinterpret_input_as_3d), _broadcast_bias(broadcast_bias)
Gian Marco36a0a462018-01-12 10:21:40 +00002168 {
2169 }
2170 /** Number of matrix A rows
2171 *
2172 * @return the number of matrix A rows
2173 */
2174 int m() const
2175 {
2176 return _m;
2177 }
2178 /** Number of matrix B columns
2179 *
2180 * @return the number of matrix B columns
2181 */
2182 int n() const
2183 {
2184 return _n;
2185 }
2186 /** Number of matrix A columns or matrix B rows
2187 *
2188 * @return the number of matrix A columns or matrix B rows
2189 */
2190 int k() const
2191 {
2192 return _k;
2193 }
2194 /** Multiplication factor for the width of the 1xW transposed block
2195 *
2196 * @return the multiplication factor for the width of the 1xW transposed block
2197 */
2198 int mult_transpose1xW_width() const
2199 {
2200 return _mult_transpose1xW_width;
2201 }
2202 /** Multiplication factor for the height of the 4x4 interleaved block
2203 *
2204 * @return the multiplication factor for the height of the 4x4 interleaved block
2205 */
2206 int mult_interleave4x4_height() const
2207 {
2208 return _mult_interleave4x4_height;
2209 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002210 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
2211 *
2212 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
2213 * m = depth_output_gemm3d * output_height
2214 *
2215 * @return the depth of the output tensor to be used with the GEMM3D kernel
2216 */
2217 int depth_output_gemm3d() const
2218 {
2219 return _depth_output_gemm3d;
2220 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002221 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2222 *
2223 * @return True if the input tensor has to be reinterpreted as 3D tensor
2224 */
2225 bool reinterpret_input_as_3d() const
2226 {
2227 return _reinterpret_input_as_3d;
2228 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002229 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2230 *
2231 * @return True if the shape of the bias tensor is to be broadcasted.
2232 */
2233 bool broadcast_bias() const
2234 {
2235 return _broadcast_bias;
2236 };
Gian Marco36a0a462018-01-12 10:21:40 +00002237
2238private:
SiCong Liebd8fb42020-08-18 11:03:14 +01002239 int _m;
2240 int _n;
2241 int _k;
2242 int _mult_transpose1xW_width;
2243 int _mult_interleave4x4_height;
2244 int _depth_output_gemm3d;
2245 bool _reinterpret_input_as_3d;
2246 bool _broadcast_bias;
Gian Marco36a0a462018-01-12 10:21:40 +00002247};
2248
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +01002249struct ConvolutionInfo
2250{
2251 ConvolutionInfo() = default;
2252 ConvolutionInfo(const PadStrideInfo &pad_stride_info, unsigned int depth_multiplier, const ActivationLayerInfo &act_info, const Size2D &dilation)
2253 : pad_stride_info(pad_stride_info), depth_multiplier(depth_multiplier), act_info(act_info), dilation(dilation)
2254 {
2255 }
2256 PadStrideInfo pad_stride_info{}; /**< Convolution info (Pads, strides,...) */
2257 unsigned int depth_multiplier{ 1 }; /**< Multiplier to apply to input's depth to retrieve the output depth. Defaults to 1 */
2258 ActivationLayerInfo act_info{}; /**< Fused activation to apply after convolution. */
2259 Size2D dilation{ Size2D(1, 1) }; /**< Dilation, in elements, across x and y. Defaults to (1, 1). */
2260};
2261
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002262/** GEMMLowp output stage type */
2263enum class GEMMLowpOutputStageType
2264{
Manuel Bottini959c26d2019-12-02 16:22:35 +00002265 NONE, /**< No quantization */
2266 QUANTIZE_DOWN, /**< Quantize using an integer multiplication */
2267 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize using a fixed point multiplication */
2268 QUANTIZE_DOWN_FLOAT /**< Quantize using a floating point multiplication */
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002269};
2270
2271/** GEMMLowp output stage info */
2272struct GEMMLowpOutputStageInfo
2273{
Giorgio Arena1856ff72020-02-07 13:46:45 +00002274 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
2275 int32_t gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
2276 int32_t gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
2277 int32_t gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
2278 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 */
2279 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 */
2280 std::vector<int32_t> gemmlowp_multipliers{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
2281 std::vector<int32_t> gemmlowp_shifts{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
Sheri Zhang1b14c752020-03-09 14:29:52 +00002282 float gemmlowp_real_multiplier{ 0 }; /**< GEMMLowp output stage real multiplier used for quantizing to QASYMM8 */
Giorgio Arena1856ff72020-02-07 13:46:45 +00002283 bool is_quantized_per_channel{ false }; /**< GEMMLowp quantized per-channel flag */
2284 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 +01002285};
2286
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00002287/** GEMM LHS (Left Hand Side) matrix information */
2288struct GEMMLHSMatrixInfo
2289{
morgolockaba2f912020-05-05 16:28:19 +01002290 GEMMLHSMatrixInfo() = default;
2291 GEMMLHSMatrixInfo(unsigned int m, unsigned int k, unsigned int v, bool trans, bool inter)
2292 : m0(m), k0(k), v0(v), transpose(trans), interleave(inter)
2293 {
2294 }
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00002295 unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
2296 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
2297 unsigned int v0{ 1 }; /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
2298 bool transpose{ true }; /**< True if the (m0xk0) block has to be transposed before been stored */
2299 bool interleave{ true }; /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
2300};
2301
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00002302/** GEMM RHS (Right Hand Side) matrix information */
2303struct GEMMRHSMatrixInfo
2304{
morgolockaba2f912020-05-05 16:28:19 +01002305 GEMMRHSMatrixInfo() = default;
Gian Marco Iodicee3a849a2020-06-10 17:59:30 +01002306 GEMMRHSMatrixInfo(unsigned int n, unsigned int k, unsigned int h, bool trans, bool inter, bool export_to_cl_img)
2307 : n0(n), k0(k), h0(h), transpose(trans), interleave(inter), export_to_cl_image(export_to_cl_img)
morgolockaba2f912020-05-05 16:28:19 +01002308 {
2309 }
Gian Marco Iodicedd717c32020-05-28 10:22:03 +01002310 unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
2311 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
2312 unsigned int h0{ 1 }; /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
2313 bool transpose{ true }; /**< True if the (k0xn0) block has to be transposed before been stored */
2314 bool interleave{ true }; /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
2315 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 +00002316};
2317
SiCongLi579ca842021-10-18 09:38:33 +01002318class ITensorInfo;
Gian Marco36a0a462018-01-12 10:21:40 +00002319/** GEMM information class. This class stores the necessary information to compute GEMM functions
2320 *
2321 * This object also contains the information about how matrix A and matrix B have been reshaped
2322 *
2323 */
Chunosov5124be52017-11-22 20:42:13 +07002324class GEMMInfo
2325{
2326public:
2327 /** Default constructor */
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002328 GEMMInfo() noexcept
2329 : _is_a_reshaped(false),
2330 _is_b_reshaped(false),
2331 _reshape_b_only_on_first_run(true),
2332 _depth_output_gemm3d(0),
2333 _reinterpret_input_as_3d(false),
2334 _retain_internal_weights(false),
2335 _gemmlowp_output_stage(),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002336 _fast_math(false),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002337 _fp_mixed_precision(false),
2338 _broadcast_bias(false),
Adnan AlSinanc5849582022-05-05 11:13:19 +01002339 _pretranspose_A(false),
2340 _pretranspose_B(false),
SiCongLi579ca842021-10-18 09:38:33 +01002341 _activation_info(),
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002342 _post_ops(),
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002343 _fixed_format(false),
Ramy Elgammal91780022022-07-20 14:57:37 +01002344 _weight_format(arm_compute::WeightFormat::UNSPECIFIED)
Chunosov5124be52017-11-22 20:42:13 +07002345 {
2346 }
2347 /** Constructor
2348 *
2349 * @param[in] is_a_reshaped True if the matrix A has been reshaped
2350 * @param[in] is_b_reshaped True if the matrix B has been reshaped
2351 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002352 * @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 +00002353 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002354 * @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
2355 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002356 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002357 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002358 * @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 +01002359 * @param[in] fast_math (Optional) Use a data type of shorter width to improve performance
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002360 * @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 +01002361 * @param[in] activation_info (Optional) Activation to apply after the matrix multiplication
SiCongLi579ca842021-10-18 09:38:33 +01002362 * @param[in] post_ops (Optional) A sequence of post operations that are performed after the main operation.
Ramy Elgammal91780022022-07-20 14:57:37 +01002363 * @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.
2364 * @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 +07002365 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002366 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 +01002367 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 +00002368 const ActivationLayerInfo &activation_info = ActivationLayerInfo(), const experimental::PostOpList<ITensorInfo *> &post_ops = experimental::PostOpList<ITensorInfo *>(),
Ramy Elgammal91780022022-07-20 14:57:37 +01002369 bool fixed_format = false, arm_compute::WeightFormat weight_format = arm_compute::WeightFormat::UNSPECIFIED) noexcept
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002370 : _is_a_reshaped(is_a_reshaped),
2371 _is_b_reshaped(is_b_reshaped),
2372 _reshape_b_only_on_first_run(reshape_b_only_on_first_run),
2373 _depth_output_gemm3d(depth_output_gemm3d),
2374 _reinterpret_input_as_3d(reinterpret_input_as_3d),
2375 _retain_internal_weights(retain_internal_weights),
2376 _gemmlowp_output_stage(gemmlowp_output_stage),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002377 _fast_math(fast_math),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002378 _fp_mixed_precision(fp_mixed_precision),
2379 _broadcast_bias(broadcast_bias),
Adnan AlSinanc5849582022-05-05 11:13:19 +01002380 _pretranspose_A(false),
2381 _pretranspose_B(false),
SiCongLi579ca842021-10-18 09:38:33 +01002382 _activation_info(activation_info),
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002383 _post_ops(post_ops),
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002384 _fixed_format(fixed_format),
2385 _weight_format(weight_format)
Chunosov5124be52017-11-22 20:42:13 +07002386 {
2387 }
2388 /** Flag which specifies if the matrix A has been reshaped
2389 *
2390 * @return True if the matrix A has been reshaped
2391 */
2392 bool is_a_reshaped() const
2393 {
2394 return _is_a_reshaped;
2395 };
2396 /** Flag which specifies if the matrix B has been reshaped
2397 *
2398 * @return True if the matrix B has been reshaped
2399 */
2400 bool is_b_reshaped() const
2401 {
2402 return _is_b_reshaped;
2403 };
2404 /** Flag which specifies if the reshape of matrix B should executed only for the first
2405 *
2406 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
2407 *
2408 * @return True if the reshaped of matrix B happens only for the first run
2409 */
2410 bool reshape_b_only_on_first_run() const
2411 {
2412 return _reshape_b_only_on_first_run;
2413 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002414 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002415 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002416 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002417 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002418 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00002419 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002420 return _depth_output_gemm3d;
2421 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002422 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2423 *
2424 * @return True if the input tensor has to be reinterpreted as 3D tensor
2425 */
2426 bool reinterpret_input_as_3d() const
2427 {
2428 return _reinterpret_input_as_3d;
2429 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002430 /** Flag which specifies if the weights tensor has to be retained from previous run
2431 *
2432 * @return True if the weights tensor has to be retained
2433 */
2434 bool retain_internal_weights() const
2435 {
2436 return _retain_internal_weights;
2437 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002438 /** GEMMLowp output stage
2439 *
2440 * @return the GEMMLowp output stage info
2441 */
2442 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
2443 {
2444 return _gemmlowp_output_stage;
2445 };
Georgios Pinitasdbdea0d2019-10-16 19:21:40 +01002446 /** Sets GEMMLowp output stage
2447 *
2448 * @param[in] output_stage Output stage to set
2449 */
2450 void set_gemmlowp_output_stage(GEMMLowpOutputStageInfo &output_stage)
2451 {
2452 _gemmlowp_output_stage = output_stage;
2453 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002454 /** Flag which specifies if a wider accumulator should be used.
2455 *
2456 * @return True if a wider accumulator has to be used
2457 */
2458 bool fp_mixed_precision() const
2459 {
2460 return _fp_mixed_precision;
2461 };
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002462 /** Flag which specifies if a shorter accumulator to be used.
2463 *
2464 * @return True if a shorter accumulator has to be used
2465 */
2466 bool fast_math() const
2467 {
2468 return _fast_math;
2469 };
cfRodf2c022e2021-11-05 11:29:53 +00002470 /** Set fast math flag
2471 *
2472 * @param[in] fast_math Flag to set
2473 */
2474 void set_fast_math(bool fast_math)
2475 {
2476 _fast_math = fast_math;
2477 }
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002478 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2479 *
2480 * @return True if the shape of the bias tensor is to be broadcasted.
2481 */
2482 bool broadcast_bias() const
2483 {
2484 return _broadcast_bias;
2485 };
Adnan AlSinanc5849582022-05-05 11:13:19 +01002486 /** Flag which specifies whether A should be pre-transposed if supported.
2487 *
2488 * @return True if A should be pre-transposed else false.
2489 */
2490 bool pretranspose_A() const
2491 {
2492 return _pretranspose_A;
2493 };
2494 /** Set pre-transpose A flag
2495 *
2496 * @param[in] flag Flag to set
2497 */
2498 void set_pretranspose_A(bool flag)
2499 {
2500 _pretranspose_A = flag;
2501 }
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002502 /** Flag which specifies whether b should be pre-transposed if supported.
2503 *
2504 * @return True if b should be pre-transposed else false.
2505 */
ramelg01cbbb0382021-09-17 17:36:57 +01002506 bool pretranspose_B() const
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002507 {
ramelg01cbbb0382021-09-17 17:36:57 +01002508 return _pretranspose_B;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002509 };
2510 /** Set pre-transpose b flag
2511 *
2512 * @param[in] flag Flag to set
2513 */
ramelg01cbbb0382021-09-17 17:36:57 +01002514 void set_pretranspose_B(bool flag)
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002515 {
ramelg01cbbb0382021-09-17 17:36:57 +01002516 _pretranspose_B = flag;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002517 }
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002518 /** Activation layer to apply after the matrix multiplication
2519 *
2520 * @return ActivationLayerInfo object
2521 */
2522 ActivationLayerInfo activation_info() const
2523 {
2524 return _activation_info;
2525 }
SiCongLi2e5fd632020-03-02 15:39:15 +00002526 /** Set activation layer info
2527 *
2528 * @param[in] activation_info ActivationLayerInfo object to set
2529 */
2530 void set_activation_info(const ActivationLayerInfo &activation_info)
2531 {
2532 _activation_info = activation_info;
2533 }
SiCongLi579ca842021-10-18 09:38:33 +01002534 /** Post operations to apply after the matrix multiplication
2535 *
2536 * @return experimental::PostOpList object
2537 */
2538 const experimental::PostOpList<ITensorInfo *> &post_ops() const
2539 {
2540 return _post_ops;
2541 }
2542 /** Set post ops
2543 *
2544 * @param[in] post_ops experimental::PostOpList object to set
2545 */
2546 void set_post_ops(const experimental::PostOpList<ITensorInfo *> &post_ops)
2547 {
2548 _post_ops = post_ops;
2549 }
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002550 /** Flag which specifies if the GEMM operation is running fixed-format kernels.
2551 *
2552 * @return True if the GEMM operation is running fixed-format kernel else false.
2553 */
2554 bool fixed_format() const
2555 {
2556 return _fixed_format;
2557 }
Chunosov5124be52017-11-22 20:42:13 +07002558
Milos Puzovic13b623e2022-07-27 17:53:21 +00002559 /** Set fixed-format flag
2560 *
2561 * @param[in] fixed_format sets whether or not to use fixed-format kernels
2562 */
2563 void set_fixed_format(bool fixed_format)
2564 {
2565 _fixed_format = fixed_format;
2566 }
2567
Ramy Elgammal91780022022-07-20 14:57:37 +01002568 arm_compute::WeightFormat weight_format() const
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002569 {
2570 return _weight_format;
2571 }
2572
Milos Puzovic13b623e2022-07-27 17:53:21 +00002573 /** Set weight format to be used
2574 *
2575 * @param[in] weight_format arm_compute::WeightFormat enumeration
2576 */
2577 void set_weight_format(arm_compute::WeightFormat weight_format)
2578 {
2579 _weight_format = weight_format;
2580 }
2581
Chunosov5124be52017-11-22 20:42:13 +07002582private:
SiCongLi579ca842021-10-18 09:38:33 +01002583 bool _is_a_reshaped;
2584 bool _is_b_reshaped;
2585 bool _reshape_b_only_on_first_run;
2586 int _depth_output_gemm3d;
2587 bool _reinterpret_input_as_3d;
2588 bool _retain_internal_weights;
2589 GEMMLowpOutputStageInfo _gemmlowp_output_stage;
2590 bool _fast_math;
2591 bool _fp_mixed_precision;
2592 bool _broadcast_bias;
Adnan AlSinanc5849582022-05-05 11:13:19 +01002593 bool _pretranspose_A;
SiCongLi579ca842021-10-18 09:38:33 +01002594 bool _pretranspose_B;
2595 ActivationLayerInfo _activation_info;
2596 experimental::PostOpList<ITensorInfo *> _post_ops;
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002597 bool _fixed_format;
Ramy Elgammal91780022022-07-20 14:57:37 +01002598 arm_compute::WeightFormat _weight_format;
Chunosov5124be52017-11-22 20:42:13 +07002599};
2600
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00002601/** Winograd information */
2602struct WinogradInfo
2603{
2604 /** Default constructor
2605 *
2606 * @param[in] output_tile_sz Width and height of the output tile
2607 * @param[in] kernel_sz Width and height of the kernel
2608 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
2609 * @param[in] conv_info Convolution info (Pads, strides)
2610 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
2611 */
2612 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
2613 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
2614 {
2615 }
2616
2617 Size2D output_tile_size{}; /**< Width and height of the output tile */
2618 Size2D kernel_size{}; /**< Width and height of the kernel*/
2619 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
2620 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
2621 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
2622};
2623
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002624/** IO formatting information class*/
2625struct IOFormatInfo
2626{
2627 /** Precision type used when printing floating point numbers */
2628 enum class PrecisionType
2629 {
2630 Default, /**< Default precision to the one that the current stream has */
2631 Custom, /**< Custom precision specified by the user using the precision parameter */
2632 Full /**< The maximum precision of the floating point representation */
2633 };
2634
2635 /** Specifies the area to be printed, used by Tensor objects */
2636 enum class PrintRegion
2637 {
2638 ValidRegion, /**< Prints the valid region of the Tensor object */
2639 NoPadding, /**< Prints the Tensor object without the padding */
2640 Full /**< Print the tensor object including padding */
2641 };
2642
Alex Gildayc357c472018-03-21 13:54:09 +00002643 /** Construct a set of IO formatting information.
2644 *
2645 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
2646 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
2647 * @param[in] precision Precision value for float point numbers. Default: 10.
2648 * @param[in] align_columns Whether to align columns when printed. Default: true.
2649 * @param[in] element_delim Delimeter between elements. Default: " ".
2650 * @param[in] row_delim Delimenter between rows. Default: "\n".
2651 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002652 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
2653 PrecisionType precision_type = PrecisionType::Default,
2654 unsigned int precision = 10,
2655 bool align_columns = true,
2656 std::string element_delim = " ",
2657 std::string row_delim = "\n")
2658 : print_region(print_region),
2659 precision_type(precision_type),
2660 precision(precision),
2661 element_delim(element_delim),
2662 row_delim(row_delim),
2663 align_columns(align_columns)
2664 {
2665 }
2666
Alex Gildayc357c472018-03-21 13:54:09 +00002667 /** Area to be printed by Tensor objects */
2668 PrintRegion print_region;
2669 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002670 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00002671 /** Floating point precision */
2672 unsigned int precision;
2673 /** Element delimeter */
2674 std::string element_delim;
2675 /** Row delimeter */
2676 std::string row_delim;
2677 /** Align columns */
2678 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002679};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00002680} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +00002681#endif /* ARM_COMPUTE_TYPES_H */