blob: 9fdc674b1c3f9c1212321d5124c6dc58f156861f [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$ ) */
1644 HARD_SWISH /**< Hard-swish ( \f$ f(x) = (x * relu6(x+3))/6 \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001645 };
1646
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001647 /** Lookup table */
1648 using LookupTable256 = std::array<qasymm8_t, 256>;
1649
Giorgio Arena11674872018-02-07 15:38:12 +00001650 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001651 /** Default Constructor
1652 *
1653 * @param[in] f The activation function to use.
1654 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001655 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1656 * @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 +01001657 */
1658 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001659 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001660 {
1661 }
Alex Gildayc357c472018-03-21 13:54:09 +00001662 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001663 ActivationFunction activation() const
1664 {
1665 return _act;
1666 }
Alex Gildayc357c472018-03-21 13:54:09 +00001667 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001668 float a() const
1669 {
1670 return _a;
1671 }
Alex Gildayc357c472018-03-21 13:54:09 +00001672 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001673 float b() const
1674 {
1675 return _b;
1676 }
Alex Gildayc357c472018-03-21 13:54:09 +00001677 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001678 bool enabled() const
1679 {
1680 return _enabled;
1681 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001682
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001683#ifdef __aarch64__
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001684 const LookupTable256 &lut() const
1685 {
1686 return _lut;
1687 }
1688
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001689 void init_lut(DataType data_type, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001690 {
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001691 if(_act == ActivationFunction::HARD_SWISH)
1692 {
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001693 if(data_type == DataType::QASYMM8)
1694 {
1695 qasymm8_hard_swish_populate_table(_lut, qi_in, qi_out);
1696 }
1697 else
1698 {
1699 qasymm8_signed_hard_swish_populate_table(_lut, qi_in, qi_out);
1700 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001701 }
1702 else if(_act == ActivationFunction::LEAKY_RELU)
1703 {
1704 qasymm8_leaky_relu_populate_table(_lut, qi_in, qi_out, _a);
1705 }
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001706 else if(_act == ActivationFunction::LOGISTIC)
1707 {
1708 if(data_type == DataType::QASYMM8)
1709 {
1710 qasymm8_logistic_populate_table(_lut, qi_in, qi_out);
1711 }
1712 else
1713 {
1714 qasymm8_signed_logistic_populate_table(_lut, qi_in, qi_out);
1715 }
1716 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001717 }
1718#endif // __aarch64__
1719
1720 static inline bool is_lut_supported(ActivationFunction act_func, DataType data_type)
1721 {
1722#ifdef __aarch64__
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001723 switch(act_func)
1724 {
1725 case ActivationFunction::HARD_SWISH:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001726 return data_type == DataType::QASYMM8 || data_type == DataType::QASYMM8_SIGNED;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001727 case ActivationFunction::LEAKY_RELU:
1728 return data_type == DataType::QASYMM8;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001729 case ActivationFunction::LOGISTIC:
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001730 return data_type == DataType::QASYMM8 || data_type == DataType::QASYMM8_SIGNED;
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001731 default:
1732 return false;
1733 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001734#else // __aarch64__
1735 ARM_COMPUTE_UNUSED(act_func);
1736 ARM_COMPUTE_UNUSED(data_type);
1737 return false;
1738#endif // __aarch64__
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001739 }
1740
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001741private:
Usama Arif6a98a6e2019-05-10 17:07:27 +01001742 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::IDENTITY };
Giorgio Arena11674872018-02-07 15:38:12 +00001743 float _a = {};
1744 float _b = {};
1745 bool _enabled = { false };
Pablo Marquez Tellod75cd8a2022-05-26 14:19:39 +01001746
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001747#ifdef __aarch64__
1748 LookupTable256 _lut = {};
1749
1750 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 +01001751 {
1752 for(size_t i = 0; i < lut.size(); ++i)
1753 {
1754 lut[i] = qasymm8_hard_swish(i, qi_in, qi_out);
1755 }
1756 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001757
Pablo Marquez Tello16789a12022-07-25 14:41:26 +01001758 static inline void qasymm8_signed_hard_swish_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1759 {
1760 for(size_t i = 0; i < lut.size(); ++i)
1761 {
1762 lut[i] = qasymm8_signed_hard_swish(i, qi_in, qi_out);
1763 }
1764 }
1765
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001766 static inline void qasymm8_leaky_relu_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out, float alpha)
1767 {
1768 for(size_t i = 0; i < lut.size(); ++i)
1769 {
1770 lut[i] = qasymm8_leaky_relu(i, qi_in, qi_out, alpha);
1771 }
1772 }
Viet-Hoa Do29db3d22022-08-10 11:56:49 +01001773
1774 static inline void qasymm8_logistic_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1775 {
1776 for(size_t i = 0; i < lut.size(); ++i)
1777 {
1778 lut[i] = qasymm8_logistic(i, qi_in, qi_out);
1779 }
1780 }
1781
1782 static inline void qasymm8_signed_logistic_populate_table(LookupTable256 &lut, const UniformQuantizationInfo &qi_in, const UniformQuantizationInfo &qi_out)
1783 {
1784 for(size_t i = 0; i < lut.size(); ++i)
1785 {
1786 lut[i] = qasymm8_signed_logistic(static_cast<int8_t>(i), qi_in, qi_out);
1787 }
1788 }
Viet-Hoa Dob042e392022-06-21 15:56:15 +01001789#endif // __aarch64__
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001790};
1791
Giorgio Arena1856ff72020-02-07 13:46:45 +00001792/** Fully connected layer info */
1793struct FullyConnectedLayerInfo
1794{
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001795 /* Fused-activation parameters */
1796 ActivationLayerInfo activation_info{}; /**< Fused activation to apply after the matrix multiplication. */
1797 /* Information about weights */
1798 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
1799 bool transpose_weights{ true }; /**< Transpose weights if true. */
1800 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
1801 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
cfRodf2c022e2021-11-05 11:29:53 +00001802 bool enable_fast_math{ false }; /**< Enable fast math computation. */
Michele Di Giorgioc3f459d2021-05-05 15:42:20 +01001803 /* Other parameters */
1804 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 +00001805
1806 /** Sets the weights trained data layout
1807 *
1808 * @param[in] layout Data layout that the weights were trained with
1809 *
1810 * @return Updated object
1811 */
1812 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
1813 {
1814 weights_trained_layout = layout;
1815 return *this;
1816 }
1817 /** Sets the transpose weights flag
1818 *
1819 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
1820 *
1821 * @return Updated object
1822 */
1823 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
1824 {
1825 transpose_weights = should_transpose_weights;
1826 return *this;
1827 }
1828};
1829
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001830/** Normalization Layer Information class */
1831class NormalizationLayerInfo
1832{
1833public:
1834 /** Default Constructor
1835 *
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001836 * @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 +01001837 * @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 +00001838 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1839 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1840 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1841 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1842 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001843 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001844 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1845 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001846 {
1847 }
Alex Gildayc357c472018-03-21 13:54:09 +00001848 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001849 NormType type() const
1850 {
1851 return _type;
1852 }
Alex Gildayc357c472018-03-21 13:54:09 +00001853 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001854 uint32_t norm_size() const
1855 {
1856 return _norm_size;
1857 }
Alex Gildayc357c472018-03-21 13:54:09 +00001858 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001859 float alpha() const
1860 {
1861 return _alpha;
1862 }
Alex Gildayc357c472018-03-21 13:54:09 +00001863 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001864 float beta() const
1865 {
1866 return _beta;
1867 }
Alex Gildayc357c472018-03-21 13:54:09 +00001868 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001869 float kappa() const
1870 {
1871 return _kappa;
1872 }
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001873 /** Get the is_scaled value */
1874 bool is_scaled() const
1875 {
1876 return _is_scaled;
1877 }
Alex Gildayc357c472018-03-21 13:54:09 +00001878 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001879 bool is_cross_map() const
1880 {
1881 return _type == NormType::CROSS_MAP;
1882 }
Alex Gildayc357c472018-03-21 13:54:09 +00001883 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001884 bool is_in_map() const
1885 {
1886 return !is_cross_map();
1887 }
1888 /** Return the scaling factor of the normalization function.
1889 *
1890 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1891 * 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 +01001892 *
1893 * @return The normalization scaling factor.
1894 */
1895 float scale_coeff() const
1896 {
1897 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001898 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001899 }
1900
1901private:
1902 NormType _type;
1903 uint32_t _norm_size;
1904 float _alpha;
1905 float _beta;
1906 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001907 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001908};
1909
thecha012bfadd92020-08-12 17:25:51 +01001910class StridedSliceLayerInfo
1911{
1912public:
1913 /** Default Constructor
1914 *
1915 * @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.
1916 * @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.
1917 * @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.
1918 */
1919 StridedSliceLayerInfo(int32_t begin_mask = 0, int32_t end_mask = 0, int32_t shrink_axis_mask = 0)
1920 : _begin_mask(begin_mask), _end_mask(end_mask), _shrink_axis_mask(shrink_axis_mask)
1921 {
1922 }
1923
1924 /* Get the begin mask value */
1925 int32_t begin_mask() const
1926 {
1927 return _begin_mask;
1928 }
1929
1930 /* Get the end mask value */
1931 int32_t end_mask() const
1932 {
1933 return _end_mask;
1934 }
1935
1936 /* Get the shrink axis mask value */
1937 int32_t shrink_axis_mask() const
1938 {
1939 return _shrink_axis_mask;
1940 }
1941
1942private:
1943 int32_t _begin_mask;
1944 int32_t _end_mask;
1945 int32_t _shrink_axis_mask;
1946};
1947
Ramy Elgammal91780022022-07-20 14:57:37 +01001948/** Memory layouts for the weights tensor.
1949 *
1950 * * UNSPECIFIED is used to select kernels that do not run in
1951 * variable weights mode.
1952 *
1953 * * ANY is used to query the kernel database to retrieve any of the
1954 * kernels that runs in variable weights mode. Once a kernel is
1955 * found, the specific format expected by the kernel can be
1956 * retrieved by the user for reordering the weights tensor
1957 * accordingly.
1958 *
1959 * The other values OHWIo{interleave_by}i{block_by} describe the
1960 * memory layout of a 4D tensor with layout OHWI that has been
1961 * transformed into a 4D tensor with dimensions O'HWI' where:
1962 *
1963 * O' = first multiple of {interleave_by} s.t. O<=O'
1964 * I' = first multiple of {block_by} s.t. I<=I'
1965 *
1966 * The total size of the dst tensor is O' x H x W x I'
1967 *
1968 * The access function of the tensor with layout
1969 * OHWIo{interleave_by}i{block_by} and size O'HWI' is a 6-parameter
1970 * access function, where the 6 parameters are computed as follows:
1971 *
1972 * x5 = floor(o/{interleave_by}) RANGE [0, O'/{interleave_by} -1] SIZE: O'/{interleave_by}
1973 *
1974 * x4 = h RANGE [0, H-1] SIZE: H
1975 * x3 = w RANGE [0, W-1] SIZE: W
1976 * x2 = floor(i/{block_by}) RANGE [0, I'/{block_by} -1] SIZE: I'/{block_by}
1977 * x1 = o%{interleave_by} RANGE [0, {interleave_by} -1] SIZE: {interleave_by}
1978 * x0 = i%{block_by} RANGE [0, {block_by} -1] SIZE: {block_by}
1979 * TOTAL SIZE: O' * H * W * I'
1980 *
1981 * 4D 6D
1982 * ----------------- -----------------------------------
1983 * value(o, h, w, i) = x5 * H * W * I' * {interleave_by}
1984 * + x4 * W * I' * {interleave_by}
1985 * + x3 * I' * {interleave_by}
1986 * + x2 * {interleave_by} * {block_by}
1987 * + x1 * {block_by}
1988 * + x0
1989 *
1990 * Notice that in arm_gemm the 4D tensor of dimension O'HWI' created
1991 * for the OHWIo{interleave_by}i{block_by} format is in reality seen
1992 * as a 2D tensor, where the number of rows is O'/{interleave_by}
1993 * and the number of columns is {interleave_by} * H * W * I'.
1994 *
1995 * The postfix *_bf16 is for the memory layout needed for the
1996 * fast-mode kernels, in which the weights are passed in bfloat16
1997 * format.
1998 */
1999enum class WeightFormat
2000{
2001 UNSPECIFIED = 0x1,
2002 ANY = 0x2,
2003 OHWI = 0x100100,
2004 OHWIo2 = 0x100200,
2005 OHWIo4 = 0x100400,
2006 OHWIo8 = 0x100800,
2007 OHWIo16 = 0x101000,
2008 OHWIo32 = 0x102000,
2009 OHWIo64 = 0x104000,
2010 OHWIo128 = 0x108000,
2011 OHWIo4i2 = 0x200400,
2012 OHWIo4i2_bf16 = 0x200410,
2013 OHWIo8i2 = 0x200800,
2014 OHWIo8i2_bf16 = 0x200810,
2015 OHWIo16i2 = 0x201000,
2016 OHWIo16i2_bf16 = 0x201010,
2017 OHWIo32i2 = 0x202000,
2018 OHWIo32i2_bf16 = 0x202010,
2019 OHWIo64i2 = 0x204000,
2020 OHWIo64i2_bf16 = 0x204010,
2021 OHWIo4i4 = 0x400400,
2022 OHWIo4i4_bf16 = 0x400410,
2023 OHWIo8i4 = 0x400800,
2024 OHWIo8i4_bf16 = 0x400810,
2025 OHWIo16i4 = 0x401000,
2026 OHWIo16i4_bf16 = 0x401010,
2027 OHWIo32i4 = 0x402000,
2028 OHWIo32i4_bf16 = 0x402010,
2029 OHWIo64i4 = 0x404000,
2030 OHWIo64i4_bf16 = 0x404010,
2031 OHWIo2i8 = 0x800200,
2032 OHWIo4i8 = 0x800400,
2033 OHWIo8i8 = 0x800800,
2034 OHWIo16i8 = 0x801000,
2035 OHWIo32i8 = 0x802000,
2036 OHWIo64i8 = 0x804000
2037};
2038// OHWIo<interleave_by>i<block_by>
2039inline int interleave_by(const WeightFormat wf)
2040{
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002041 return (static_cast<int>(wf) >> 8) & 0xFFF;
Ramy Elgammal91780022022-07-20 14:57:37 +01002042}
2043inline int block_by(const WeightFormat wf)
2044{
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002045 return (static_cast<int>(wf) >> 20) & 0xF;
Ramy Elgammal91780022022-07-20 14:57:37 +01002046}
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002047inline bool is_fixed_format(const WeightFormat &wf)
Ramy Elgammal91780022022-07-20 14:57:37 +01002048{
2049 return wf != WeightFormat::UNSPECIFIED && wf != WeightFormat::ANY;
2050}
Pablo Marquez Tello93581a52022-07-21 13:55:27 +01002051inline bool is_fixed_format_fast_math(const WeightFormat &wf)
2052{
2053 return (static_cast<int>(wf) >> 4) & 0x1;
2054}
Ramy Elgammal91780022022-07-20 14:57:37 +01002055
Gian Marco Iodice559d7712017-08-08 08:38:09 +01002056/** 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 +01002057class WeightsInfo
2058{
2059public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002060 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002061 WeightsInfo()
Ramy Elgammal91780022022-07-20 14:57:37 +01002062 : _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 +01002063 {
2064 }
2065 /** Constructor
2066 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01002067 * @param[in] are_reshaped True if the weights have been reshaped
2068 * @param[in] kernel_width Kernel width.
2069 * @param[in] kernel_height Kernel height.
2070 * @param[in] num_kernels Number of convolution kernels.
2071 * @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 +01002072 * @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 +01002073 */
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002074 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 +01002075 arm_compute::WeightFormat weight_format = arm_compute::WeightFormat::UNSPECIFIED)
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002076 : _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 +01002077 {
2078 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002079 /** Flag which specifies if the weights tensor has been reshaped.
2080 *
2081 * @return True if the weights tensors has been reshaped
2082 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002083 bool are_reshaped() const
2084 {
2085 return _are_reshaped;
2086 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01002087 /** Return the number of convolution kernels
2088 *
2089 * @return The number of convolution kernels
2090 */
2091 unsigned int num_kernels() const
2092 {
2093 return _num_kernels;
2094 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002095 /** Return the width and height of the kernel
2096 *
2097 * @return The width and height of the kernel
2098 */
2099 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002100 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01002101 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002102 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01002103 bool retain_internal_weights() const
2104 {
2105 return _retain_internal_weights;
2106 }
Ramy Elgammal91780022022-07-20 14:57:37 +01002107 arm_compute::WeightFormat weight_format() const
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002108 {
2109 return _weight_format;
2110 }
Milos Puzovic13b623e2022-07-27 17:53:21 +00002111 void set_weight_format(arm_compute::WeightFormat weight_format)
2112 {
2113 _weight_format = weight_format;
2114 }
2115
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002116 unsigned int kernel_width() const
2117 {
2118 return _kernel_width;
2119 }
2120 unsigned int kernel_height() const
2121 {
2122 return _kernel_height;
2123 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002124
2125private:
Ramy Elgammal91780022022-07-20 14:57:37 +01002126 bool _are_reshaped;
2127 unsigned int _kernel_width;
2128 unsigned int _kernel_height;
2129 unsigned int _num_kernels;
2130 bool _retain_internal_weights;
2131 arm_compute::WeightFormat _weight_format;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002132};
2133
Gian Marco36a0a462018-01-12 10:21:40 +00002134/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
2135 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01002136 * The matrix A can only be reshaped through @ref opencl::kernels::ClGemmReshapeLhsMatrixKernel or @ref cpu::kernels::CpuGemmInterleave4x4Kernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01002137 * 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 +00002138 *
Michele Di Giorgio93b75e02021-06-21 12:00:43 +01002139 * The matrix B can only be reshaped through @ref opencl::kernels::ClGemmReshapeRhsMatrixKernel or @ref cpu::kernels::CpuGemmTranspose1xWKernel
Georgios Pinitas856f66e2021-04-22 21:13:21 +01002140 * 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 +00002141 *
2142 */
2143class GEMMReshapeInfo final
2144{
2145public:
2146 /** Default constructor */
2147 GEMMReshapeInfo()
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002148 : _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 +00002149 {
2150 }
2151 /** Constructor
2152 *
2153 * @param[in] m Number of matrix A rows
2154 * @param[in] n Number of matrix B columns
2155 * @param[in] k Number of matrix A columns or matrix B rows
2156 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
2157 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002158 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
2159 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002160 * @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 +01002161 * to perform 1x1 convolutions with the NHWC data layout)
2162 * @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 +00002163 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002164 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 +01002165 : _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 +01002166 _reinterpret_input_as_3d(reinterpret_input_as_3d), _broadcast_bias(broadcast_bias)
Gian Marco36a0a462018-01-12 10:21:40 +00002167 {
2168 }
2169 /** Number of matrix A rows
2170 *
2171 * @return the number of matrix A rows
2172 */
2173 int m() const
2174 {
2175 return _m;
2176 }
2177 /** Number of matrix B columns
2178 *
2179 * @return the number of matrix B columns
2180 */
2181 int n() const
2182 {
2183 return _n;
2184 }
2185 /** Number of matrix A columns or matrix B rows
2186 *
2187 * @return the number of matrix A columns or matrix B rows
2188 */
2189 int k() const
2190 {
2191 return _k;
2192 }
2193 /** Multiplication factor for the width of the 1xW transposed block
2194 *
2195 * @return the multiplication factor for the width of the 1xW transposed block
2196 */
2197 int mult_transpose1xW_width() const
2198 {
2199 return _mult_transpose1xW_width;
2200 }
2201 /** Multiplication factor for the height of the 4x4 interleaved block
2202 *
2203 * @return the multiplication factor for the height of the 4x4 interleaved block
2204 */
2205 int mult_interleave4x4_height() const
2206 {
2207 return _mult_interleave4x4_height;
2208 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002209 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
2210 *
2211 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
2212 * m = depth_output_gemm3d * output_height
2213 *
2214 * @return the depth of the output tensor to be used with the GEMM3D kernel
2215 */
2216 int depth_output_gemm3d() const
2217 {
2218 return _depth_output_gemm3d;
2219 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002220 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2221 *
2222 * @return True if the input tensor has to be reinterpreted as 3D tensor
2223 */
2224 bool reinterpret_input_as_3d() const
2225 {
2226 return _reinterpret_input_as_3d;
2227 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002228 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2229 *
2230 * @return True if the shape of the bias tensor is to be broadcasted.
2231 */
2232 bool broadcast_bias() const
2233 {
2234 return _broadcast_bias;
2235 };
Gian Marco36a0a462018-01-12 10:21:40 +00002236
2237private:
SiCong Liebd8fb42020-08-18 11:03:14 +01002238 int _m;
2239 int _n;
2240 int _k;
2241 int _mult_transpose1xW_width;
2242 int _mult_interleave4x4_height;
2243 int _depth_output_gemm3d;
2244 bool _reinterpret_input_as_3d;
2245 bool _broadcast_bias;
Gian Marco36a0a462018-01-12 10:21:40 +00002246};
2247
Michalis Spyrou60c3b0e2021-04-08 12:02:58 +01002248struct ConvolutionInfo
2249{
2250 ConvolutionInfo() = default;
2251 ConvolutionInfo(const PadStrideInfo &pad_stride_info, unsigned int depth_multiplier, const ActivationLayerInfo &act_info, const Size2D &dilation)
2252 : pad_stride_info(pad_stride_info), depth_multiplier(depth_multiplier), act_info(act_info), dilation(dilation)
2253 {
2254 }
2255 PadStrideInfo pad_stride_info{}; /**< Convolution info (Pads, strides,...) */
2256 unsigned int depth_multiplier{ 1 }; /**< Multiplier to apply to input's depth to retrieve the output depth. Defaults to 1 */
2257 ActivationLayerInfo act_info{}; /**< Fused activation to apply after convolution. */
2258 Size2D dilation{ Size2D(1, 1) }; /**< Dilation, in elements, across x and y. Defaults to (1, 1). */
2259};
2260
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002261/** GEMMLowp output stage type */
2262enum class GEMMLowpOutputStageType
2263{
Manuel Bottini959c26d2019-12-02 16:22:35 +00002264 NONE, /**< No quantization */
2265 QUANTIZE_DOWN, /**< Quantize using an integer multiplication */
2266 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize using a fixed point multiplication */
2267 QUANTIZE_DOWN_FLOAT /**< Quantize using a floating point multiplication */
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002268};
2269
2270/** GEMMLowp output stage info */
2271struct GEMMLowpOutputStageInfo
2272{
Giorgio Arena1856ff72020-02-07 13:46:45 +00002273 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
2274 int32_t gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
2275 int32_t gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
2276 int32_t gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
2277 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 */
2278 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 */
2279 std::vector<int32_t> gemmlowp_multipliers{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
2280 std::vector<int32_t> gemmlowp_shifts{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
Sheri Zhang1b14c752020-03-09 14:29:52 +00002281 float gemmlowp_real_multiplier{ 0 }; /**< GEMMLowp output stage real multiplier used for quantizing to QASYMM8 */
Giorgio Arena1856ff72020-02-07 13:46:45 +00002282 bool is_quantized_per_channel{ false }; /**< GEMMLowp quantized per-channel flag */
2283 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 +01002284};
2285
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00002286/** GEMM LHS (Left Hand Side) matrix information */
2287struct GEMMLHSMatrixInfo
2288{
morgolockaba2f912020-05-05 16:28:19 +01002289 GEMMLHSMatrixInfo() = default;
2290 GEMMLHSMatrixInfo(unsigned int m, unsigned int k, unsigned int v, bool trans, bool inter)
2291 : m0(m), k0(k), v0(v), transpose(trans), interleave(inter)
2292 {
2293 }
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00002294 unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
2295 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
2296 unsigned int v0{ 1 }; /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
2297 bool transpose{ true }; /**< True if the (m0xk0) block has to be transposed before been stored */
2298 bool interleave{ true }; /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
2299};
2300
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00002301/** GEMM RHS (Right Hand Side) matrix information */
2302struct GEMMRHSMatrixInfo
2303{
morgolockaba2f912020-05-05 16:28:19 +01002304 GEMMRHSMatrixInfo() = default;
Gian Marco Iodicee3a849a2020-06-10 17:59:30 +01002305 GEMMRHSMatrixInfo(unsigned int n, unsigned int k, unsigned int h, bool trans, bool inter, bool export_to_cl_img)
2306 : n0(n), k0(k), h0(h), transpose(trans), interleave(inter), export_to_cl_image(export_to_cl_img)
morgolockaba2f912020-05-05 16:28:19 +01002307 {
2308 }
Gian Marco Iodicedd717c32020-05-28 10:22:03 +01002309 unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
2310 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
2311 unsigned int h0{ 1 }; /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
2312 bool transpose{ true }; /**< True if the (k0xn0) block has to be transposed before been stored */
2313 bool interleave{ true }; /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
2314 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 +00002315};
2316
SiCongLi579ca842021-10-18 09:38:33 +01002317class ITensorInfo;
Gian Marco36a0a462018-01-12 10:21:40 +00002318/** GEMM information class. This class stores the necessary information to compute GEMM functions
2319 *
2320 * This object also contains the information about how matrix A and matrix B have been reshaped
2321 *
2322 */
Chunosov5124be52017-11-22 20:42:13 +07002323class GEMMInfo
2324{
2325public:
2326 /** Default constructor */
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002327 GEMMInfo() noexcept
2328 : _is_a_reshaped(false),
2329 _is_b_reshaped(false),
2330 _reshape_b_only_on_first_run(true),
2331 _depth_output_gemm3d(0),
2332 _reinterpret_input_as_3d(false),
2333 _retain_internal_weights(false),
2334 _gemmlowp_output_stage(),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002335 _fast_math(false),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002336 _fp_mixed_precision(false),
2337 _broadcast_bias(false),
Adnan AlSinanc5849582022-05-05 11:13:19 +01002338 _pretranspose_A(false),
2339 _pretranspose_B(false),
SiCongLi579ca842021-10-18 09:38:33 +01002340 _activation_info(),
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002341 _post_ops(),
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002342 _fixed_format(false),
Ramy Elgammal91780022022-07-20 14:57:37 +01002343 _weight_format(arm_compute::WeightFormat::UNSPECIFIED)
Chunosov5124be52017-11-22 20:42:13 +07002344 {
2345 }
2346 /** Constructor
2347 *
2348 * @param[in] is_a_reshaped True if the matrix A has been reshaped
2349 * @param[in] is_b_reshaped True if the matrix B has been reshaped
2350 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002351 * @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 +00002352 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002353 * @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
2354 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002355 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002356 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002357 * @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 +01002358 * @param[in] fast_math (Optional) Use a data type of shorter width to improve performance
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002359 * @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 +01002360 * @param[in] activation_info (Optional) Activation to apply after the matrix multiplication
SiCongLi579ca842021-10-18 09:38:33 +01002361 * @param[in] post_ops (Optional) A sequence of post operations that are performed after the main operation.
Ramy Elgammal91780022022-07-20 14:57:37 +01002362 * @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.
2363 * @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 +07002364 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00002365 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 +01002366 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 +00002367 const ActivationLayerInfo &activation_info = ActivationLayerInfo(), const experimental::PostOpList<ITensorInfo *> &post_ops = experimental::PostOpList<ITensorInfo *>(),
Ramy Elgammal91780022022-07-20 14:57:37 +01002368 bool fixed_format = false, arm_compute::WeightFormat weight_format = arm_compute::WeightFormat::UNSPECIFIED) noexcept
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002369 : _is_a_reshaped(is_a_reshaped),
2370 _is_b_reshaped(is_b_reshaped),
2371 _reshape_b_only_on_first_run(reshape_b_only_on_first_run),
2372 _depth_output_gemm3d(depth_output_gemm3d),
2373 _reinterpret_input_as_3d(reinterpret_input_as_3d),
2374 _retain_internal_weights(retain_internal_weights),
2375 _gemmlowp_output_stage(gemmlowp_output_stage),
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002376 _fast_math(fast_math),
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002377 _fp_mixed_precision(fp_mixed_precision),
2378 _broadcast_bias(broadcast_bias),
Adnan AlSinanc5849582022-05-05 11:13:19 +01002379 _pretranspose_A(false),
2380 _pretranspose_B(false),
SiCongLi579ca842021-10-18 09:38:33 +01002381 _activation_info(activation_info),
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002382 _post_ops(post_ops),
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002383 _fixed_format(fixed_format),
2384 _weight_format(weight_format)
Chunosov5124be52017-11-22 20:42:13 +07002385 {
2386 }
2387 /** Flag which specifies if the matrix A has been reshaped
2388 *
2389 * @return True if the matrix A has been reshaped
2390 */
2391 bool is_a_reshaped() const
2392 {
2393 return _is_a_reshaped;
2394 };
2395 /** Flag which specifies if the matrix B has been reshaped
2396 *
2397 * @return True if the matrix B has been reshaped
2398 */
2399 bool is_b_reshaped() const
2400 {
2401 return _is_b_reshaped;
2402 };
2403 /** Flag which specifies if the reshape of matrix B should executed only for the first
2404 *
2405 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
2406 *
2407 * @return True if the reshaped of matrix B happens only for the first run
2408 */
2409 bool reshape_b_only_on_first_run() const
2410 {
2411 return _reshape_b_only_on_first_run;
2412 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002413 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002414 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002415 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00002416 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002417 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00002418 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00002419 return _depth_output_gemm3d;
2420 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01002421 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
2422 *
2423 * @return True if the input tensor has to be reinterpreted as 3D tensor
2424 */
2425 bool reinterpret_input_as_3d() const
2426 {
2427 return _reinterpret_input_as_3d;
2428 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002429 /** Flag which specifies if the weights tensor has to be retained from previous run
2430 *
2431 * @return True if the weights tensor has to be retained
2432 */
2433 bool retain_internal_weights() const
2434 {
2435 return _retain_internal_weights;
2436 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002437 /** GEMMLowp output stage
2438 *
2439 * @return the GEMMLowp output stage info
2440 */
2441 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
2442 {
2443 return _gemmlowp_output_stage;
2444 };
Georgios Pinitasdbdea0d2019-10-16 19:21:40 +01002445 /** Sets GEMMLowp output stage
2446 *
2447 * @param[in] output_stage Output stage to set
2448 */
2449 void set_gemmlowp_output_stage(GEMMLowpOutputStageInfo &output_stage)
2450 {
2451 _gemmlowp_output_stage = output_stage;
2452 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002453 /** Flag which specifies if a wider accumulator should be used.
2454 *
2455 * @return True if a wider accumulator has to be used
2456 */
2457 bool fp_mixed_precision() const
2458 {
2459 return _fp_mixed_precision;
2460 };
Georgios Pinitas4ee8b152021-07-16 16:16:43 +01002461 /** Flag which specifies if a shorter accumulator to be used.
2462 *
2463 * @return True if a shorter accumulator has to be used
2464 */
2465 bool fast_math() const
2466 {
2467 return _fast_math;
2468 };
cfRodf2c022e2021-11-05 11:29:53 +00002469 /** Set fast math flag
2470 *
2471 * @param[in] fast_math Flag to set
2472 */
2473 void set_fast_math(bool fast_math)
2474 {
2475 _fast_math = fast_math;
2476 }
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002477 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2478 *
2479 * @return True if the shape of the bias tensor is to be broadcasted.
2480 */
2481 bool broadcast_bias() const
2482 {
2483 return _broadcast_bias;
2484 };
Adnan AlSinanc5849582022-05-05 11:13:19 +01002485 /** Flag which specifies whether A should be pre-transposed if supported.
2486 *
2487 * @return True if A should be pre-transposed else false.
2488 */
2489 bool pretranspose_A() const
2490 {
2491 return _pretranspose_A;
2492 };
2493 /** Set pre-transpose A flag
2494 *
2495 * @param[in] flag Flag to set
2496 */
2497 void set_pretranspose_A(bool flag)
2498 {
2499 _pretranspose_A = flag;
2500 }
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002501 /** Flag which specifies whether b should be pre-transposed if supported.
2502 *
2503 * @return True if b should be pre-transposed else false.
2504 */
ramelg01cbbb0382021-09-17 17:36:57 +01002505 bool pretranspose_B() const
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002506 {
ramelg01cbbb0382021-09-17 17:36:57 +01002507 return _pretranspose_B;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002508 };
2509 /** Set pre-transpose b flag
2510 *
2511 * @param[in] flag Flag to set
2512 */
ramelg01cbbb0382021-09-17 17:36:57 +01002513 void set_pretranspose_B(bool flag)
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002514 {
ramelg01cbbb0382021-09-17 17:36:57 +01002515 _pretranspose_B = flag;
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002516 }
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002517 /** Activation layer to apply after the matrix multiplication
2518 *
2519 * @return ActivationLayerInfo object
2520 */
2521 ActivationLayerInfo activation_info() const
2522 {
2523 return _activation_info;
2524 }
SiCongLi2e5fd632020-03-02 15:39:15 +00002525 /** Set activation layer info
2526 *
2527 * @param[in] activation_info ActivationLayerInfo object to set
2528 */
2529 void set_activation_info(const ActivationLayerInfo &activation_info)
2530 {
2531 _activation_info = activation_info;
2532 }
SiCongLi579ca842021-10-18 09:38:33 +01002533 /** Post operations to apply after the matrix multiplication
2534 *
2535 * @return experimental::PostOpList object
2536 */
2537 const experimental::PostOpList<ITensorInfo *> &post_ops() const
2538 {
2539 return _post_ops;
2540 }
2541 /** Set post ops
2542 *
2543 * @param[in] post_ops experimental::PostOpList object to set
2544 */
2545 void set_post_ops(const experimental::PostOpList<ITensorInfo *> &post_ops)
2546 {
2547 _post_ops = post_ops;
2548 }
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002549 /** Flag which specifies if the GEMM operation is running fixed-format kernels.
2550 *
2551 * @return True if the GEMM operation is running fixed-format kernel else false.
2552 */
2553 bool fixed_format() const
2554 {
2555 return _fixed_format;
2556 }
Chunosov5124be52017-11-22 20:42:13 +07002557
Milos Puzovic13b623e2022-07-27 17:53:21 +00002558 /** Set fixed-format flag
2559 *
2560 * @param[in] fixed_format sets whether or not to use fixed-format kernels
2561 */
2562 void set_fixed_format(bool fixed_format)
2563 {
2564 _fixed_format = fixed_format;
2565 }
2566
Ramy Elgammal91780022022-07-20 14:57:37 +01002567 arm_compute::WeightFormat weight_format() const
Francesco Petrogalli553f6952022-06-30 10:22:01 +00002568 {
2569 return _weight_format;
2570 }
2571
Milos Puzovic13b623e2022-07-27 17:53:21 +00002572 /** Set weight format to be used
2573 *
2574 * @param[in] weight_format arm_compute::WeightFormat enumeration
2575 */
2576 void set_weight_format(arm_compute::WeightFormat weight_format)
2577 {
2578 _weight_format = weight_format;
2579 }
2580
Chunosov5124be52017-11-22 20:42:13 +07002581private:
SiCongLi579ca842021-10-18 09:38:33 +01002582 bool _is_a_reshaped;
2583 bool _is_b_reshaped;
2584 bool _reshape_b_only_on_first_run;
2585 int _depth_output_gemm3d;
2586 bool _reinterpret_input_as_3d;
2587 bool _retain_internal_weights;
2588 GEMMLowpOutputStageInfo _gemmlowp_output_stage;
2589 bool _fast_math;
2590 bool _fp_mixed_precision;
2591 bool _broadcast_bias;
Adnan AlSinanc5849582022-05-05 11:13:19 +01002592 bool _pretranspose_A;
SiCongLi579ca842021-10-18 09:38:33 +01002593 bool _pretranspose_B;
2594 ActivationLayerInfo _activation_info;
2595 experimental::PostOpList<ITensorInfo *> _post_ops;
Francesco.Petrogalli@arm.com5fcf22d2022-04-05 10:31:08 +00002596 bool _fixed_format;
Ramy Elgammal91780022022-07-20 14:57:37 +01002597 arm_compute::WeightFormat _weight_format;
Chunosov5124be52017-11-22 20:42:13 +07002598};
2599
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00002600/** Winograd information */
2601struct WinogradInfo
2602{
2603 /** Default constructor
2604 *
2605 * @param[in] output_tile_sz Width and height of the output tile
2606 * @param[in] kernel_sz Width and height of the kernel
2607 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
2608 * @param[in] conv_info Convolution info (Pads, strides)
2609 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
2610 */
2611 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
2612 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
2613 {
2614 }
2615
2616 Size2D output_tile_size{}; /**< Width and height of the output tile */
2617 Size2D kernel_size{}; /**< Width and height of the kernel*/
2618 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
2619 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
2620 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
2621};
2622
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002623/** IO formatting information class*/
2624struct IOFormatInfo
2625{
2626 /** Precision type used when printing floating point numbers */
2627 enum class PrecisionType
2628 {
2629 Default, /**< Default precision to the one that the current stream has */
2630 Custom, /**< Custom precision specified by the user using the precision parameter */
2631 Full /**< The maximum precision of the floating point representation */
2632 };
2633
2634 /** Specifies the area to be printed, used by Tensor objects */
2635 enum class PrintRegion
2636 {
2637 ValidRegion, /**< Prints the valid region of the Tensor object */
2638 NoPadding, /**< Prints the Tensor object without the padding */
2639 Full /**< Print the tensor object including padding */
2640 };
2641
Alex Gildayc357c472018-03-21 13:54:09 +00002642 /** Construct a set of IO formatting information.
2643 *
2644 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
2645 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
2646 * @param[in] precision Precision value for float point numbers. Default: 10.
2647 * @param[in] align_columns Whether to align columns when printed. Default: true.
2648 * @param[in] element_delim Delimeter between elements. Default: " ".
2649 * @param[in] row_delim Delimenter between rows. Default: "\n".
2650 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002651 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
2652 PrecisionType precision_type = PrecisionType::Default,
2653 unsigned int precision = 10,
2654 bool align_columns = true,
2655 std::string element_delim = " ",
2656 std::string row_delim = "\n")
2657 : print_region(print_region),
2658 precision_type(precision_type),
2659 precision(precision),
2660 element_delim(element_delim),
2661 row_delim(row_delim),
2662 align_columns(align_columns)
2663 {
2664 }
2665
Alex Gildayc357c472018-03-21 13:54:09 +00002666 /** Area to be printed by Tensor objects */
2667 PrintRegion print_region;
2668 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002669 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00002670 /** Floating point precision */
2671 unsigned int precision;
2672 /** Element delimeter */
2673 std::string element_delim;
2674 /** Row delimeter */
2675 std::string row_delim;
2676 /** Align columns */
2677 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002678};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00002679} // namespace arm_compute
Michalis Spyrouf4643372019-11-29 16:17:13 +00002680#endif /* ARM_COMPUTE_TYPES_H */