blob: 38d78971ef86bbdd53b60cc59199183e8bc37db9 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Manuel Bottinicc5171b2019-01-09 17:04:39 +00002 * Copyright (c) 2016-2019 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 */
24#ifndef __ARM_COMPUTE_TYPES_H__
25#define __ARM_COMPUTE_TYPES_H__
26
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"
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000030#include "arm_compute/core/Strides.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010031#include "arm_compute/core/TensorShape.h"
Georgios Pinitas583137c2017-08-31 18:12:42 +010032#include "support/Half.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010033
Michel Iwaniec5dfeae62017-11-29 10:48:23 +000034#include <cmath>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010035#include <cstddef>
36#include <cstdint>
Isabella Gottardia7acb3c2019-01-08 13:48:44 +000037#include <map>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010038#include <string>
39#include <utility>
40
41namespace arm_compute
42{
Georgios Pinitas583137c2017-08-31 18:12:42 +010043/** 16-bit floating point type */
44using half = half_float::half;
45
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000046/** Permutation vector */
47using PermutationVector = Strides;
Georgios Pinitas77589b52018-08-21 14:41:35 +010048/** Bidirectional strides */
49using BiStrides = Coordinates;
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000050
Anthony Barbier6ff3b192017-09-04 18:44:23 +010051/** Image colour formats */
52enum class Format
53{
Daniil Efremov02bf80d2017-11-22 00:26:51 +070054 UNKNOWN, /**< Unknown image format */
55 U8, /**< 1 channel, 1 U8 per channel */
56 S16, /**< 1 channel, 1 S16 per channel */
57 U16, /**< 1 channel, 1 U16 per channel */
58 S32, /**< 1 channel, 1 S32 per channel */
59 U32, /**< 1 channel, 1 U32 per channel */
60 F16, /**< 1 channel, 1 F16 per channel */
61 F32, /**< 1 channel, 1 F32 per channel */
62 UV88, /**< 2 channel, 1 U8 per channel */
63 RGB888, /**< 3 channels, 1 U8 per channel */
64 RGBA8888, /**< 4 channels, 1 U8 per channel */
65 YUV444, /**< A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes */
66 YUYV422, /**< A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes */
67 NV12, /**< A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling */
68 NV21, /**< A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling */
69 IYUV, /**< A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes */
70 UYVY422 /**< A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010071};
72
73/** Available data types */
74enum class DataType
75{
Georgios Pinitas8217c8e2019-11-11 18:24:22 +000076 UNKNOWN, /**< Unknown data type */
77 U8, /**< unsigned 8-bit number */
78 S8, /**< signed 8-bit number */
79 QSYMM8, /**< quantized, symmetric fixed-point 8-bit number */
80 QASYMM8, /**< quantized, asymmetric fixed-point 8-bit number unsigned */
81 QASYMM8_SIGNED, /**< quantized, asymmetric fixed-point 8-bit number signed */
82 QSYMM8_PER_CHANNEL, /**< quantized, symmetric per channel fixed-point 8-bit number */
83 U16, /**< unsigned 16-bit number */
84 S16, /**< signed 16-bit number */
85 QSYMM16, /**< quantized, symmetric fixed-point 16-bit number */
86 QASYMM16, /**< quantized, asymmetric fixed-point 16-bit number */
87 U32, /**< unsigned 32-bit number */
88 S32, /**< signed 32-bit number */
89 U64, /**< unsigned 64-bit number */
90 S64, /**< signed 64-bit number */
91 F16, /**< 16-bit floating-point number */
92 F32, /**< 32-bit floating-point number */
93 F64, /**< 64-bit floating-point number */
94 SIZET /**< size_t */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010095};
96
Daniil Efremov02bf80d2017-11-22 00:26:51 +070097/** Available Sampling Policies */
98enum class SamplingPolicy
99{
100 CENTER, /**< Samples are taken at pixel center */
101 TOP_LEFT /**< Samples are taken at pixel top left corner */
102};
103
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100104/** Constant value of the border pixels when using BorderMode::CONSTANT */
105constexpr uint8_t CONSTANT_BORDER_VALUE = 199;
106
Alex Gildayc357c472018-03-21 13:54:09 +0000107/** Constant value used to indicate a half-scale pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100108constexpr float SCALE_PYRAMID_HALF = 0.5f;
109
Alex Gildayc357c472018-03-21 13:54:09 +0000110/** Constant value used to indicate a ORB scaled pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100111constexpr float SCALE_PYRAMID_ORB = 8.408964152537146130583778358414e-01;
112
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000113/** [DataLayout enum definition] **/
114
Georgios Pinitas4074c992018-01-30 18:13:46 +0000115/** Supported tensor data layouts */
116enum class DataLayout
117{
Alex Gildayc357c472018-03-21 13:54:09 +0000118 UNKNOWN, /**< Unknown data layout */
119 NCHW, /**< Num samples, channels, height, width */
120 NHWC /**< Num samples, height, width, channels */
Georgios Pinitas4074c992018-01-30 18:13:46 +0000121};
Vidhya Sudhan Loganathand646ae12018-11-19 15:18:20 +0000122/** [DataLayout enum definition] **/
Georgios Pinitas4074c992018-01-30 18:13:46 +0000123
Isabella Gottardid17a6772018-02-27 17:41:55 +0000124/** Supported tensor data layout dimensions */
125enum class DataLayoutDimension
126{
Alex Gildayc357c472018-03-21 13:54:09 +0000127 CHANNEL, /**< channel */
128 HEIGHT, /**< height */
129 WIDTH, /**< width */
130 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{
Vidhya Sudhan Loganathan8ec0bb62019-04-23 10:40:44 +0100136 GEMM, /**< Convolution using GEMM */
137 DIRECT, /**< Direct convolution */
138 WINOGRAD, /**< Convolution using Winograd */
139 FFT /**< Convolution using FFT */
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000140};
141
Manuel Bottini05069f02019-09-26 17:18:26 +0100142/** Available DepthwiseConvolutionFunction*/
143enum class DepthwiseConvolutionFunction
144{
145 OPTIMIZED, /**< Optimized Depthwise Convolution */
146 GENERIC, /**< Generic Depthwise Convolution */
147};
148
giuros0146a49a02019-04-01 13:50:22 +0100149/** Available DeconvolutionMethod*/
150enum class DeconvolutionMethod
151{
152 GEMM, /**< Deconvolution using GEMM */
153 DIRECT, /**< Direct deconvolution */
154};
155
Manuel Bottini2732cca2019-05-28 11:44:41 +0100156/** Available FuseBatchNormalizationType*/
157enum class FuseBatchNormalizationType
158{
159 CONVOLUTION, /**< For Convolution weights */
160 DEPTHWISECONVOLUTION /**< For Depthwise Convolution weights*/
161};
162
Usama Arif89890c62019-03-19 10:57:05 +0000163/** Padding mode to use for PadLayer */
164enum class PaddingMode
165{
166 CONSTANT,
167 REFLECT,
168 SYMMETRIC
169};
170
Georgios Pinitas7900a9e2018-11-23 11:44:58 +0000171/** Supported comparison operations */
172enum class ComparisonOperation
173{
174 Equal, /**< Equal comparison ( \f$ x == y \f$ ) */
175 NotEqual, /**< NotEqual comparison ( \f$ x != y \f$ ) */
176 Greater, /**< Greater comparison ( \f$ x > y \f$ ) */
177 GreaterEqual, /**< Greater equal comparison ( \f$ x >= y \f$ ) */
178 Less, /**< Less comparison ( \f$ x < y \f$ ) */
179 LessEqual /**< Less equal comparison ( \f$ x <= y \f$ ) */
180};
181
Alex Gildayc357c472018-03-21 13:54:09 +0000182/** Container for valid region of a window */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100183struct ValidRegion
184{
Alex Gildayc357c472018-03-21 13:54:09 +0000185 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100186 ValidRegion()
187 : anchor{}, shape{}
188 {
189 }
190
Alex Gildayc357c472018-03-21 13:54:09 +0000191 /** Allow instances of this class to be copy constructed */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100192 ValidRegion(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000193 /** Allow instances of this class to be move constructed */
194 ValidRegion(ValidRegion &&) = default;
195 /** Allow instances of this class to be copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100196 ValidRegion &operator=(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000197 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100198 ValidRegion &operator=(ValidRegion &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000199 /** Default destructor */
200 ~ValidRegion() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100201
Alex Gildayc357c472018-03-21 13:54:09 +0000202 /** Constructor for a valid region with default number of dimensions
203 *
204 * @param[in] an_anchor Anchor for the start of the valid region.
205 * @param[in] a_shape Shape of the valid region.
206 *
207 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000208 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
209 : anchor{ an_anchor }, shape{ a_shape }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100210 {
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000211 anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
212 }
213
Alex Gildayc357c472018-03-21 13:54:09 +0000214 /** Constructor for a valid region with specified number of dimensions
215 *
216 * @param[in] an_anchor Anchor for the start of the valid region.
217 * @param[in] a_shape Shape of the valid region.
218 * @param[in] num_dimensions Number of dimensions (must be >= number of dimensions of anchor and shape).
219 *
220 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000221 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
222 : anchor{ an_anchor }, shape{ a_shape }
223 {
224 ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
225 anchor.set_num_dimensions(num_dimensions);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100226 }
227
228 /** Return the start of the valid region for the given dimension @p d */
229 int start(unsigned int d) const
230 {
231 return anchor[d];
232 }
233
234 /** Return the end of the valid region for the given dimension @p d */
235 int end(unsigned int d) const
236 {
237 return anchor[d] + shape[d];
238 }
239
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000240 /** Accessor to set the value of anchor and shape for one of the dimensions.
241 *
242 * @param[in] dimension Dimension for which the value is set.
243 * @param[in] start Value to be set in anchor for the dimension.
244 * @param[in] size Value to be set in shape for the dimension.
245 *
246 * @return *this.
247 */
248 ValidRegion &set(size_t dimension, int start, size_t size)
249 {
250 anchor.set(dimension, start);
251 shape.set(dimension, size);
252 return *this;
253 }
254
Alex Gildayc357c472018-03-21 13:54:09 +0000255 Coordinates anchor; /**< Anchor for the start of the valid region. */
256 TensorShape shape; /**< Shape of the valid region. */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100257};
258
259/** Methods available to handle borders */
260enum class BorderMode
261{
262 UNDEFINED, /**< Borders are left undefined */
263 CONSTANT, /**< Pixels outside the image are assumed to have a constant value */
264 REPLICATE /**< Pixels outside the image are assumed to have the same value as the closest image pixel */
265};
266
267/** Container for 2D border size */
268struct BorderSize
269{
270 /** Empty border, i.e. no border */
271 constexpr BorderSize()
272 : top{ 0 }, right{ 0 }, bottom{ 0 }, left{ 0 }
273 {
274 }
275
276 /** Border with equal size around the 2D plane */
Moritz Pflanzer7655a672017-09-23 11:57:33 +0100277 explicit constexpr BorderSize(unsigned int size)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100278 : top{ size }, right{ size }, bottom{ size }, left{ size }
279 {
280 }
281
282 /** Border with same size for top/bottom and left/right */
283 constexpr BorderSize(unsigned int top_bottom, unsigned int left_right)
284 : top{ top_bottom }, right{ left_right }, bottom{ top_bottom }, left{ left_right }
285 {
286 }
287
288 /** Border with different sizes */
289 constexpr BorderSize(unsigned int top, unsigned int right, unsigned int bottom, unsigned int left)
290 : top{ top }, right{ right }, bottom{ bottom }, left{ left }
291 {
292 }
293
294 /** Check if the entire border is zero */
295 constexpr bool empty() const
296 {
297 return top == 0 && right == 0 && bottom == 0 && left == 0;
298 }
299
300 /** Check if the border is the same size on all sides */
301 constexpr bool uniform() const
302 {
303 return top == right && top == bottom && top == left;
304 }
305
Alex Gildayc357c472018-03-21 13:54:09 +0000306 /** Scale this border size.
307 *
308 * @param[in] scale Scale to multiply border size by.
309 *
310 * @return *this.
311 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100312 BorderSize &operator*=(float scale)
313 {
314 top *= scale;
315 right *= scale;
316 bottom *= scale;
317 left *= scale;
318
319 return *this;
320 }
321
Alex Gildayc357c472018-03-21 13:54:09 +0000322 /** Scale a copy of this border size.
323 *
324 * @param[in] scale Scale to multiply border size by.
325 *
326 * @return a scaled copy of this.
327 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100328 BorderSize operator*(float scale)
329 {
330 BorderSize size = *this;
331 size *= scale;
332
333 return size;
334 }
335
Alex Gildayc357c472018-03-21 13:54:09 +0000336 /** Limit this border size.
337 *
338 * @param[in] limit Border size to limit this border size to.
339 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100340 void limit(const BorderSize &limit)
341 {
342 top = std::min(top, limit.top);
343 right = std::min(right, limit.right);
344 bottom = std::min(bottom, limit.bottom);
345 left = std::min(left, limit.left);
346 }
347
Alex Gildayc357c472018-03-21 13:54:09 +0000348 unsigned int top; /**< top of the border */
349 unsigned int right; /**< right of the border */
350 unsigned int bottom; /**< bottom of the border */
351 unsigned int left; /**< left of the border */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100352};
353
Alex Gildayc357c472018-03-21 13:54:09 +0000354/** Container for 2D padding size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100355using PaddingSize = BorderSize;
356
357/** Policy to handle overflow */
358enum class ConvertPolicy
359{
360 WRAP, /**< Wrap around */
361 SATURATE /**< Saturate */
362};
363
364/** Interpolation method */
365enum class InterpolationPolicy
366{
367 NEAREST_NEIGHBOR, /**< Output values are defined to match the source pixel whose center is nearest to the sample position */
368 BILINEAR, /**< Output values are defined by bilinear interpolation between the pixels */
369 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 */
370};
371
372/** Bilinear Interpolation method used by LKTracker */
373enum class BilinearInterpolation
374{
Alex Gildayc357c472018-03-21 13:54:09 +0000375 BILINEAR_OLD_NEW, /**< Old-new method */
376 BILINEAR_SCHARR /**< Scharr method */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100377};
378
379/** Threshold mode */
380enum class ThresholdType
381{
382 BINARY, /**< Threshold with one value */
383 RANGE /**< Threshold with two values*/
384};
385
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100386/** Termination criteria */
387enum class Termination
388{
Alex Gildayc357c472018-03-21 13:54:09 +0000389 TERM_CRITERIA_EPSILON, /**< Terminate when within epsilon of a threshold */
390 TERM_CRITERIA_ITERATIONS, /**< Terminate after a maximum number of iterations */
391 TERM_CRITERIA_BOTH /**< Terminate on whichever of the other conditions occurs first */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100392};
393
394/** Magnitude calculation type. */
395enum class MagnitudeType
396{
397 L1NORM, /**< L1 normalization type */
398 L2NORM /**< L2 normalization type */
399};
400
401/** Phase calculation type.
402 *
403 * @note When PhaseType == SIGNED, each angle is mapped to the range 0 to 255 inclusive otherwise angles between 0 and 180
404 */
405enum class PhaseType
406{
407 SIGNED, /**< Angle range: [0, 360] */
408 UNSIGNED /**< Angle range: [0, 180] */
409};
410
411/** Keypoint type */
412struct KeyPoint
413{
414 int32_t x{ 0 }; /**< X coordinates */
415 int32_t y{ 0 }; /**< Y coordinates */
416 float strength{ 0.f }; /**< Strength of the point */
417 float scale{ 0.f }; /**< Scale initialized to 0 by the corner detector */
418 float orientation{ 0.f }; /**< Orientation initialized to 0 by the corner detector */
419 int32_t tracking_status{ 0 }; /**< Status initialized to 1 by the corner detector, set to 0 when the point is lost */
420 float error{ 0.f }; /**< Tracking error initialized to 0 by the corner detector */
421};
422
Alex Gildayc357c472018-03-21 13:54:09 +0000423/** Internal key point */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100424using InternalKeypoint = std::tuple<float, float, float>; /* x,y,strength */
425
426/** Rectangle type */
427struct Rectangle
428{
429 uint16_t x; /**< Top-left x coordinate */
430 uint16_t y; /**< Top-left y coordinate */
431 uint16_t width; /**< Width of the rectangle */
432 uint16_t height; /**< Height of the rectangle */
433};
434
435/** Coordinate type */
436struct Coordinates2D
437{
438 int32_t x; /**< X coordinates */
439 int32_t y; /**< Y coordinates */
440};
441
442/** Coordinate type */
443struct Coordinates3D
444{
445 uint32_t x; /**< X coordinates */
446 uint32_t y; /**< Y coordinates */
447 uint32_t z; /**< Z coordinates */
448};
449
Giuseppe Rossinid7647d42018-07-17 18:13:13 +0100450/** Padding information as a pair of unsigned int start/end */
451using PaddingInfo = std::pair<uint32_t, uint32_t>;
452
453/** List of padding information */
454using PaddingList = std::vector<PaddingInfo>;
455
giuros013175fcf2018-11-21 09:59:17 +0000456/** Information to produce a tiled version of a Tensor */
457using Multiples = std::vector<uint32_t>;
458
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100459/** Available channels */
460enum class Channel
461{
462 UNKNOWN, /** Unknown channel format */
463 C0, /**< First channel (used by formats with unknown channel types). */
464 C1, /**< Second channel (used by formats with unknown channel types). */
465 C2, /**< Third channel (used by formats with unknown channel types). */
466 C3, /**< Fourth channel (used by formats with unknown channel types). */
467 R, /**< Red channel. */
468 G, /**< Green channel. */
469 B, /**< Blue channel. */
470 A, /**< Alpha channel. */
471 Y, /**< Luma channel. */
472 U, /**< Cb/U channel. */
473 V /**< Cr/V/Value channel. */
474};
475
476/** Available matrix patterns */
477enum class MatrixPattern
478{
479 BOX, /**< Box pattern matrix. */
480 CROSS, /**< Cross pattern matrix. */
481 DISK, /**< Disk pattern matrix. */
482 OTHER /**< Any other matrix pattern. */
483};
484
485/** Available non linear functions. */
486enum class NonLinearFilterFunction : unsigned
487{
488 MEDIAN = 0, /**< Non linear median filter. */
489 MIN = 1, /**< Non linear erode. */
490 MAX = 2, /**< Non linear dilate. */
491};
492
Georgios Pinitasd9769582017-08-03 10:19:40 +0100493/** Available reduction operations */
494enum class ReductionOperation
495{
Michalis Spyrou7930db42018-11-22 17:36:28 +0000496 ARG_IDX_MAX, /**< Index of the max value */
Manuel Bottinib412fab2018-12-10 17:40:23 +0000497 ARG_IDX_MIN, /**< Index of the min value */
498 MEAN_SUM, /**< Mean of sum */
499 PROD, /**< Product */
500 SUM_SQUARE, /**< Sum of squares */
Usama Arifa4a08ad2019-05-20 12:38:33 +0100501 SUM, /**< Sum */
502 MIN, /**< Min */
Usama Arif28f0dd92019-05-20 13:44:34 +0100503 MAX, /**< Max */
Georgios Pinitasd9769582017-08-03 10:19:40 +0100504};
505
giuros01164a2722018-11-20 18:34:46 +0000506/** Available element-wise operations */
507enum class ArithmeticOperation
508{
509 ADD, /**< (x + y) */
510 SUB, /**< (x - y) */
511 DIV, /**< (x / y) */
512 MIN, /**< Min(x, y) */
513 MAX, /**< Max(x, y) */
514 SQUARED_DIFF, /**< (x - y)^2 */
Usama Arif81e671e2019-05-13 13:33:14 +0100515 POWER, /**< x ^ y */
giuros011e6e1b82019-05-14 16:12:53 +0100516 PRELU, /**< y*x if x < 0, x otherwise */
giuros01164a2722018-11-20 18:34:46 +0000517};
518
Michalis Spyroue9362622018-11-23 17:41:37 +0000519/** Available element wise unary operations */
520enum class ElementWiseUnary
521{
522 RSQRT, /**< Reverse square root */
523 EXP, /**< Exponential */
Usama Ariff6e475c2019-05-10 12:06:28 +0100524 NEG, /**< Negate */
Usama Arifc255aa72019-05-13 16:26:29 +0100525 LOG, /**< Natural Logarithm */
Manuel Bottini6ac59922019-05-15 14:06:02 +0100526 ABS, /**< Absolute value */
Michalis Spyrou0af44182019-05-17 14:04:47 +0100527 SIN, /**< Sine */
Usama Arif0a5a57a2019-05-23 14:20:33 +0100528 ROUND, /**< Round */
Michalis Spyroue9362622018-11-23 17:41:37 +0000529};
530
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100531/** The normalization type used for the normalization layer */
532enum class NormType
533{
534 IN_MAP_1D, /**< Normalization applied within the same map in 1D region */
535 IN_MAP_2D, /**< Normalization applied within the same map in 2D region */
536 CROSS_MAP /**< Normalization applied cross maps */
537};
538
539/** Normalization type for Histogram of Oriented Gradients (HOG) */
540enum class HOGNormType
541{
542 L2_NORM = 1, /**< L2-norm */
543 L2HYS_NORM = 2, /**< L2-norm followed by clipping */
544 L1_NORM = 3 /**< L1 norm */
545};
546
547/** Detection window used for the object detection. The detection window keeps the following information:
548 *
549 * -# Geometry of the rectangular window (x/y of top-left corner and width/height)
550 * -# Index of the class used for evaluating which class the detection window belongs to
551 * -# Confidence value (score) obtained with the classifier
552 */
553struct DetectionWindow
554{
555 uint16_t x{ 0 }; /**< Top-left x coordinate */
556 uint16_t y{ 0 }; /**< Top-left y coordinate */
557 uint16_t width{ 0 }; /**< Width of the detection window */
558 uint16_t height{ 0 }; /**< Height of the detection window */
559 uint16_t idx_class{ 0 }; /**< Index of the class */
560 float score{ 0.f }; /**< Confidence value for the detection window */
561};
562
563/** Dimension rounding type when down-scaling on CNNs
564 * @note Used in pooling and convolution layer
565 */
566enum class DimensionRoundingType
567{
568 FLOOR, /**< Floor rounding */
569 CEIL /**< Ceil rounding */
570};
571
572/** Available pooling types */
573enum class PoolingType
574{
575 MAX, /**< Max Pooling */
Georgios Pinitascdf51452017-08-31 14:21:36 +0100576 AVG, /**< Average Pooling */
577 L2 /**< L2 Pooling */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100578};
579
Michalis Spyrou2709d612018-09-19 09:46:47 +0100580/** Available non maxima suppression types */
581enum class NMSType
582{
583 LINEAR, /**< Linear NMS */
584 GAUSSIAN, /**< Gaussian NMS */
585 ORIGINAL /**< Original NMS */
586};
587
588/** BoxWithNonMaximaSuppressionLimit Information class */
589class BoxNMSLimitInfo final
590{
591public:
592 /** Constructor
593 *
594 * @param[in] score_thresh (Optional) Score threshold.
595 * @param[in] nms (Optional) NMS value
596 * @param[in] detections (Optional) Number of detections
597 * @param[in] soft_nms_enabled (Optional) Enable SoftNMS
598 * @param[in] soft_nms_method (Optional) Soft NMS method
599 * @param[in] soft_nms_sigma (Optional) Soft NMS sigma value
600 * @param[in] soft_nms_min_score_thres (Optional) Soft NMS minimum score threshold
Manuel Bottini5209be52019-02-13 16:34:56 +0000601 * @param[in] suppress_size (Optional) Filter out boxes based on their size. Defaults to false
602 * @param[in] min_size (Optional) Smaller boxes than min_size will be filtered out. Defaults to 1
603 * @param[in] im_width (Optional) Boxes whose centers (on the x axis) is beyond im_width will be filtered. Defaults to 1
604 * @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 +0100605 */
606 BoxNMSLimitInfo(float score_thresh = 0.05f, float nms = 0.3f,
607 int detections = 100, bool soft_nms_enabled = false,
608 NMSType soft_nms_method = NMSType::LINEAR,
Manuel Bottini5209be52019-02-13 16:34:56 +0000609 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 +0100610 : _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 +0000611 _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 +0100612 {
613 }
614 /** Get the score threshold */
615 float score_thresh() const
616 {
617 return _score_thresh;
618 }
619 /** Get the NMS */
620 float nms() const
621 {
622 return _nms;
623 }
624 /** Get the number of detections */
625 int detections_per_im() const
626 {
627 return _detections_per_im;
628 }
629 /** Check if soft NMS is enabled */
630 bool soft_nms_enabled() const
631 {
632 return _soft_nms_enabled;
633 }
634 /** Get soft NMS method */
635 NMSType soft_nms_method() const
636 {
637 return _soft_nms_method;
638 }
639 /** Get soft NMS sigma */
640 float soft_nms_sigma() const
641 {
642 return _soft_nms_sigma;
643 }
644 /** Get soft nms min score threshold */
645 float soft_nms_min_score_thres() const
646 {
647 return _soft_nms_min_score_thres;
648 }
Manuel Bottini5209be52019-02-13 16:34:56 +0000649 /** Get if NMS will suppress boxes based on their size/position */
650 bool suppress_size() const
651 {
652 return _suppress_size;
653 }
654 /** Get size suppression threshold */
655 float min_size() const
656 {
657 return _min_size;
658 }
659 /** Get image width (NMS may suppress boxes whose center sits beyond the image width) */
660 float im_width() const
661 {
662 return _im_width;
663 }
664 /** Get image height (NMS may suppress boxes whose center sits beyond the image height) */
665 float im_height() const
666 {
667 return _im_height;
668 }
Michalis Spyrou2709d612018-09-19 09:46:47 +0100669
670private:
671 float _score_thresh;
672 float _nms;
673 int _detections_per_im;
674 bool _soft_nms_enabled;
675 NMSType _soft_nms_method;
676 float _soft_nms_sigma;
677 float _soft_nms_min_score_thres;
Manuel Bottini5209be52019-02-13 16:34:56 +0000678 bool _suppress_size;
679 float _min_size;
680 float _im_width;
681 float _im_height;
Michalis Spyrou2709d612018-09-19 09:46:47 +0100682};
683
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100684/** Padding and stride information class */
685class PadStrideInfo
686{
687public:
688 /** Constructor
689 *
690 * @param[in] stride_x (Optional) Stride, in elements, across x. Defaults to 1.
691 * @param[in] stride_y (Optional) Stride, in elements, across y. Defaults to 1.
692 * @param[in] pad_x (Optional) Padding, in elements, across x. Defaults to 0.
693 * @param[in] pad_y (Optional) Padding, in elements, across y. Defaults to 0.
694 * @param[in] round (Optional) Dimensions rounding. Defaults to @ref FLOOR.
695 */
696 PadStrideInfo(unsigned int stride_x = 1, unsigned int stride_y = 1,
697 unsigned int pad_x = 0, unsigned int pad_y = 0,
698 DimensionRoundingType round = DimensionRoundingType::FLOOR)
699 : _stride(std::make_pair(stride_x, stride_y)),
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100700 _pad_left(pad_x),
701 _pad_top(pad_y),
702 _pad_right(pad_x),
703 _pad_bottom(pad_y),
704 _round_type(round)
705 {
706 }
707 /** Constructor
708 *
709 * @param[in] stride_x Stride, in elements, across x.
710 * @param[in] stride_y Stride, in elements, across y.
711 * @param[in] pad_left Padding across x on the left, in elements.
712 * @param[in] pad_top Padding across y on the top, in elements.
713 * @param[in] pad_right Padding across x on the right, in elements.
714 * @param[in] pad_bottom Padding across y on the bottom, in elements.
715 * @param[in] round Dimensions rounding.
716 */
717 PadStrideInfo(unsigned int stride_x, unsigned int stride_y,
718 unsigned int pad_left, unsigned int pad_right,
719 unsigned int pad_top, unsigned int pad_bottom,
720 DimensionRoundingType round)
721 : _stride(std::make_pair(stride_x, stride_y)),
722 _pad_left(pad_left),
723 _pad_top(pad_top),
724 _pad_right(pad_right),
725 _pad_bottom(pad_bottom),
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100726 _round_type(round)
727 {
728 }
Alex Gildayc357c472018-03-21 13:54:09 +0000729 /** Get the stride.
730 *
731 * @return a pair: stride x, stride y.
732 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100733 std::pair<unsigned int, unsigned int> stride() const
734 {
735 return _stride;
736 }
Alex Gildayc357c472018-03-21 13:54:09 +0000737 /** Check whether the padding is symmetric.
738 *
739 * @return True if the padding is symmetric.
740 */
Anthony Barbier21f67d62018-02-16 15:17:48 +0000741 bool padding_is_symmetric() const
742 {
743 return (_pad_left == _pad_right) && (_pad_top == _pad_bottom);
744 }
Alex Gildayc357c472018-03-21 13:54:09 +0000745 /** Get the padding.
746 *
747 * @note This should only be used when the padding is symmetric.
748 *
749 * @return a pair: padding left/right, padding top/bottom
750 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100751 std::pair<unsigned int, unsigned int> pad() const
752 {
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100753 //this accessor should be used only when padding is symmetric
Anthony Barbier21f67d62018-02-16 15:17:48 +0000754 ARM_COMPUTE_ERROR_ON(!padding_is_symmetric());
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100755 return std::make_pair(_pad_left, _pad_top);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100756 }
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100757
Alex Gildayc357c472018-03-21 13:54:09 +0000758 /** Get the left padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100759 unsigned int pad_left() const
760 {
761 return _pad_left;
762 }
Alex Gildayc357c472018-03-21 13:54:09 +0000763 /** Get the right padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100764 unsigned int pad_right() const
765 {
766 return _pad_right;
767 }
Alex Gildayc357c472018-03-21 13:54:09 +0000768 /** Get the top padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100769 unsigned int pad_top() const
770 {
771 return _pad_top;
772 }
Alex Gildayc357c472018-03-21 13:54:09 +0000773 /** Get the bottom padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100774 unsigned int pad_bottom() const
775 {
776 return _pad_bottom;
777 }
778
Alex Gildayc357c472018-03-21 13:54:09 +0000779 /** Get the rounding type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100780 DimensionRoundingType round() const
781 {
782 return _round_type;
783 }
784
Alex Gildayc357c472018-03-21 13:54:09 +0000785 /** Check whether this has any padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100786 bool has_padding() const
787 {
788 return (_pad_left != 0 || _pad_top != 0 || _pad_right != 0 || _pad_bottom != 0);
789 }
790
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100791private:
792 std::pair<unsigned int, unsigned int> _stride;
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100793 unsigned int _pad_left;
794 unsigned int _pad_top;
795 unsigned int _pad_right;
796 unsigned int _pad_bottom;
797
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100798 DimensionRoundingType _round_type;
799};
800
Georgios Pinitas7d66a8e2018-07-17 12:28:42 +0100801/** Fully connected layer info */
802struct FullyConnectedLayerInfo
803{
804 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
805 bool transpose_weights{ true }; /**< Transpose weights if true. */
806 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
807 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
Georgios Pinitas44bfc3f2019-10-28 14:16:31 +0000808 bool fp_mixed_precision{ false }; /**< Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy. */
Georgios Pinitasc55cef12018-08-01 15:24:18 +0100809
810 /** Sets the weights trained data layout
811 *
812 * @param[in] layout Data layout that the weights were trained with
813 *
814 * @return Updated object
815 */
816 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
817 {
818 weights_trained_layout = layout;
819 return *this;
820 }
Georgios Pinitas195b0ba2018-08-02 17:18:51 +0100821 /** Sets the transpose weights flag
822 *
823 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
824 *
825 * @return Updated object
826 */
827 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
828 {
829 transpose_weights = should_transpose_weights;
830 return *this;
831 }
Georgios Pinitas7d66a8e2018-07-17 12:28:42 +0100832};
833
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100834/** PriorBox layer info */
835class PriorBoxLayerInfo final
836{
837public:
838 /** Default Constructor */
839 PriorBoxLayerInfo()
840 : _min_sizes(),
841 _variances(),
842 _offset(),
843 _flip(true),
844 _clip(false),
845 _max_sizes(),
846 _aspect_ratios(),
847 _img_size(),
848 _steps()
849 {
850 }
851 /** Constructor
852 *
853 * @param[in] min_sizes Min sizes vector.
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100854 * @param[in] variances Variances vector.
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100855 * @param[in] offset Offset value.
856 * @param[in] flip (Optional) Flip the aspect ratios.
857 * @param[in] clip (Optional) Clip coordinates so that they're within [0,1].
858 * @param[in] max_sizes (Optional) Max sizes vector.
859 * @param[in] aspect_ratios (Optional) Aspect ratios of the boxes.
860 * @param[in] img_size (Optional) Image size.
861 * @param[in] steps (Optional) Step values.
862 */
863 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 +0000864 const std::vector<float> &max_sizes = {}, const std::vector<float> &aspect_ratios = {},
865 const Coordinates2D &img_size = Coordinates2D{ 0, 0 }, const std::array<float, 2> &steps = { { 0.f, 0.f } })
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100866 : _min_sizes(min_sizes),
867 _variances(variances),
868 _offset(offset),
869 _flip(flip),
870 _clip(clip),
871 _max_sizes(max_sizes),
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100872 _aspect_ratios(),
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100873 _img_size(img_size),
874 _steps(steps)
875 {
876 _aspect_ratios.push_back(1.);
877 for(unsigned int i = 0; i < aspect_ratios.size(); ++i)
878 {
879 float ar = aspect_ratios[i];
880 bool already_exist = false;
881 for(auto ar_new : _aspect_ratios)
882 {
883 if(fabs(ar - ar_new) < 1e-6)
884 {
885 already_exist = true;
886 break;
887 }
888 }
889 if(!already_exist)
890 {
891 _aspect_ratios.push_back(ar);
892 if(flip)
893 {
894 _aspect_ratios.push_back(1.f / ar);
895 }
896 }
897 }
898 }
899 /** Get min sizes. */
900 std::vector<float> min_sizes() const
901 {
902 return _min_sizes;
903 }
904 /** Get min variances. */
905 std::vector<float> variances() const
906 {
907 return _variances;
908 }
909 /** Get the step coordinates */
910 std::array<float, 2> steps() const
911 {
912 return _steps;
913 }
914 /** Get the image size coordinates */
915 Coordinates2D img_size() const
916 {
917 return _img_size;
918 }
919 /** Get the offset */
920 float offset() const
921 {
922 return _offset;
923 }
924 /** Get the flip value */
925 bool flip() const
926 {
927 return _flip;
928 }
929 /** Get the clip value */
930 bool clip() const
931 {
932 return _clip;
933 }
934 /** Get max sizes. */
935 std::vector<float> max_sizes() const
936 {
937 return _max_sizes;
938 }
939 /** Get aspect ratios. */
940 std::vector<float> aspect_ratios() const
941 {
942 return _aspect_ratios;
943 }
944
945private:
946 std::vector<float> _min_sizes;
947 std::vector<float> _variances;
948 float _offset;
949 bool _flip;
950 bool _clip;
951 std::vector<float> _max_sizes;
952 std::vector<float> _aspect_ratios;
953 Coordinates2D _img_size;
954 std::array<float, 2> _steps;
955};
956
Isabella Gottardia7acb3c2019-01-08 13:48:44 +0000957// Bounding Box [xmin, ymin, xmax, ymax]
958using BBox = std::array<float, 4>;
959// LabelBBox used for map label and bounding box
960using LabelBBox = std::map<int, std::vector<BBox>>;
961
Isabella Gottardi05e56442018-11-16 11:26:52 +0000962/** Available Detection Output code types */
963enum class DetectionOutputLayerCodeType
964{
965 CORNER, /**< Use box corners */
966 CENTER_SIZE, /**< Use box centers and size */
967 CORNER_SIZE, /**< Use box centers and size */
968 TF_CENTER /**< Use box centers and size but flip x and y co-ordinates */
969};
970
971/** Detection Output layer info */
972class DetectionOutputLayerInfo final
973{
974public:
975 /** Default Constructor */
976 DetectionOutputLayerInfo()
977 : _num_classes(),
978 _share_location(),
979 _code_type(DetectionOutputLayerCodeType::CORNER),
980 _keep_top_k(),
981 _nms_threshold(),
982 _top_k(),
983 _background_label_id(),
984 _confidence_threshold(),
985 _variance_encoded_in_target(false),
986 _eta(),
987 _num_loc_classes()
988 {
989 _num_loc_classes = _share_location ? 1 : _num_classes;
990 }
991 /** Constructor
992 *
993 * @param[in] num_classes Number of classes to be predicted.
994 * @param[in] share_location If true, bounding box are shared among different classes.
995 * @param[in] code_type Type of coding method for bbox.
996 * @param[in] keep_top_k Number of total bounding boxes to be kept per image after NMS step.
997 * @param[in] nms_threshold Threshold to be used in NMS.
998 * @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.
999 * @param[in] background_label_id (Optional) Background label ID. If there is no background class, set it as -1.
1000 * @param[in] confidence_threshold (Optional) Only consider detections whose confidences are larger than a threshold. Default set to -FLT_MAX.
1001 * @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.
1002 * @param[in] eta (Optional) Eta.
1003 */
1004 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,
1005 float confidence_threshold = std::numeric_limits<float>::lowest(), bool variance_encoded_in_target = false, float eta = 1)
1006 : _num_classes(num_classes),
1007 _share_location(share_location),
1008 _code_type(code_type),
1009 _keep_top_k(keep_top_k),
1010 _nms_threshold(nms_threshold),
1011 _top_k(top_k),
1012 _background_label_id(background_label_id),
1013 _confidence_threshold(confidence_threshold),
1014 _variance_encoded_in_target(variance_encoded_in_target),
1015 _eta(eta),
1016 _num_loc_classes()
1017 {
1018 _num_loc_classes = _share_location ? 1 : _num_classes;
1019 }
1020 /** Get num classes. */
1021 int num_classes() const
1022 {
1023 return _num_classes;
1024 }
1025 /** Get share location. */
1026 bool share_location() const
1027 {
1028 return _share_location;
1029 }
1030 /** Get detection output code type. */
1031 DetectionOutputLayerCodeType code_type() const
1032 {
1033 return _code_type;
1034 }
1035 /** Get if variance encoded in target. */
1036 bool variance_encoded_in_target() const
1037 {
1038 return _variance_encoded_in_target;
1039 }
1040 /** Get the number of total bounding boxes to be kept per image. */
1041 int keep_top_k() const
1042 {
1043 return _keep_top_k;
1044 }
1045 /** Get nms threshold. */
1046 float nms_threshold() const
1047 {
1048 return _nms_threshold;
1049 }
1050 /** Get eta. */
1051 float eta() const
1052 {
1053 return _eta;
1054 }
1055 /** Get background label ID. */
1056 int background_label_id() const
1057 {
1058 return _background_label_id;
1059 }
1060 /** Get confidence threshold. */
1061 float confidence_threshold() const
1062 {
1063 return _confidence_threshold;
1064 }
1065 /** Get top K. */
1066 int top_k() const
1067 {
1068 return _top_k;
1069 }
1070 /** Get number of location classes. */
1071 int num_loc_classes() const
1072 {
1073 return _num_loc_classes;
1074 }
1075
1076private:
1077 int _num_classes;
1078 bool _share_location;
1079 DetectionOutputLayerCodeType _code_type;
1080 int _keep_top_k;
1081 float _nms_threshold;
1082 int _top_k;
1083 int _background_label_id;
1084 float _confidence_threshold;
1085 bool _variance_encoded_in_target;
1086 float _eta;
1087 int _num_loc_classes;
1088};
1089
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001090/** Detection Output layer info */
1091class DetectionPostProcessLayerInfo final
1092{
1093public:
1094 /** Default Constructor */
1095 DetectionPostProcessLayerInfo()
1096 : _max_detections(),
1097 _max_classes_per_detection(),
1098 _nms_score_threshold(),
1099 _iou_threshold(),
1100 _num_classes(),
1101 _scales_values(),
1102 _use_regular_nms(),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001103 _detection_per_class(),
1104 _dequantize_scores()
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001105 {
1106 }
1107 /** Constructor
1108 *
1109 * @param[in] max_detections Number of total detection.
1110 * @param[in] max_classes_per_detection Number of total classes to be kept after NMS step. Used in the Fast Non-Max-Suppression
1111 * @param[in] nms_score_threshold Threshold to be used in NMS
1112 * @param[in] iou_threshold Threshold to be used during the intersection over union.
1113 * @param[in] num_classes Number of classes.
1114 * @param[in] scales_values Scales values used for decode center size boxes.
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001115 * @param[in] use_regular_nms (Optional) Boolean to determinate if use regular or fast nms. Defaults to false.
1116 * @param[in] detection_per_class (Optional) Number of detection per class. Used in the Regular Non-Max-Suppression. Defaults to 100.
1117 * @param[in] dequantize_scores (Optional) If the scores need to be dequantized. Defaults to true.
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001118 */
1119 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 +01001120 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 +00001121 : _max_detections(max_detections),
1122 _max_classes_per_detection(max_classes_per_detection),
1123 _nms_score_threshold(nms_score_threshold),
1124 _iou_threshold(iou_threshold),
1125 _num_classes(num_classes),
1126 _scales_values(scales_values),
1127 _use_regular_nms(use_regular_nms),
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001128 _detection_per_class(detection_per_class),
1129 _dequantize_scores(dequantize_scores)
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001130 {
1131 }
1132 /** Get max detections. */
1133 unsigned int max_detections() const
1134 {
1135 return _max_detections;
1136 }
1137 /** Get max_classes per detection. Used in the Fast Non-Max-Suppression.*/
1138 unsigned int max_classes_per_detection() const
1139 {
1140 return _max_classes_per_detection;
1141 }
1142 /** Get detection per class. Used in the Regular Non-Max-Suppression */
1143 unsigned int detection_per_class() const
1144 {
1145 return _detection_per_class;
1146 }
1147 /** Get nms threshold. */
1148 float nms_score_threshold() const
1149 {
1150 return _nms_score_threshold;
1151 }
1152 /** Get intersection over union threshold. */
1153 float iou_threshold() const
1154 {
1155 return _iou_threshold;
1156 }
1157 /** Get num classes. */
1158 unsigned int num_classes() const
1159 {
1160 return _num_classes;
1161 }
1162 /** Get if use regular nms. */
1163 bool use_regular_nms() const
1164 {
1165 return _use_regular_nms;
1166 }
1167 /** Get y scale value. */
1168 float scale_value_y() const
1169 {
1170 // Saved as [y,x,h,w]
1171 return _scales_values[0];
1172 }
1173 /** Get x scale value. */
1174 float scale_value_x() const
1175 {
1176 // Saved as [y,x,h,w]
1177 return _scales_values[1];
1178 }
1179 /** Get h scale value. */
1180 float scale_value_h() const
1181 {
1182 // Saved as [y,x,h,w]
1183 return _scales_values[2];
1184 }
1185 /** Get w scale value. */
1186 float scale_value_w() const
1187 {
1188 // Saved as [y,x,h,w]
1189 return _scales_values[3];
1190 }
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001191 /** Get dequantize_scores value. */
1192 bool dequantize_scores() const
1193 {
1194 return _dequantize_scores;
1195 }
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001196
1197private:
1198 unsigned int _max_detections;
1199 unsigned int _max_classes_per_detection;
1200 float _nms_score_threshold;
1201 float _iou_threshold;
1202 unsigned int _num_classes;
1203 std::array<float, 4> _scales_values;
1204 bool _use_regular_nms;
1205 unsigned int _detection_per_class;
Giuseppe Rossinid9853782019-10-25 11:11:44 +01001206 bool _dequantize_scores;
Isabella Gottardia7acb3c2019-01-08 13:48:44 +00001207};
1208
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001209/** Pooling Layer Information class */
1210class PoolingLayerInfo
1211{
1212public:
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001213 /** Default Constructor */
1214 PoolingLayerInfo()
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001215 : _pool_type(PoolingType::MAX), _pool_size(Size2D()), _pad_stride_info(PadStrideInfo()), _exclude_padding(false), _is_global_pooling(false), _fp_mixed_precision(false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001216 {
1217 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001218 /** Default Constructor
1219 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001220 * @param[in] pool_type Pooling type @ref PoolingType.
1221 * @param[in] pool_size Pooling size, in elements, across x and y.
1222 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1223 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1224 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1225 * Defaults to false;
1226 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001227 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001228 explicit PoolingLayerInfo(PoolingType pool_type,
1229 unsigned int pool_size,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001230 PadStrideInfo pad_stride_info = PadStrideInfo(),
1231 bool exclude_padding = false,
1232 bool fp_mixed_precision = false)
1233 : _pool_type(pool_type), _pool_size(Size2D(pool_size, pool_size)), _pad_stride_info(pad_stride_info), _exclude_padding(exclude_padding), _is_global_pooling(false),
1234 _fp_mixed_precision(fp_mixed_precision)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001235 {
1236 }
1237 /** Default Constructor
1238 *
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001239 * @param[in] pool_type Pooling type @ref PoolingType.
1240 * @param[in] pool_size Pooling size, in elements, across x and y.
1241 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
1242 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
1243 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
1244 * Defaults to false;
1245 * @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 +00001246 */
1247 explicit PoolingLayerInfo(PoolingType pool_type,
1248 Size2D pool_size,
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001249 PadStrideInfo pad_stride_info = PadStrideInfo(),
1250 bool exclude_padding = false,
1251 bool fp_mixed_precision = false)
1252 : _pool_type(pool_type), _pool_size(pool_size), _pad_stride_info(pad_stride_info), _exclude_padding(exclude_padding), _is_global_pooling(false), _fp_mixed_precision(fp_mixed_precision)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001253 {
1254 }
1255 /** Default Constructor
1256 *
1257 * @note This constructor is used for global pooling
1258 *
1259 * @param[in] pool_type Pooling type @ref PoolingType.
1260 */
1261 explicit PoolingLayerInfo(PoolingType pool_type)
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001262 : _pool_type(pool_type), _pool_size(Size2D()), _pad_stride_info(PadStrideInfo(1, 1, 0, 0)), _exclude_padding(false), _is_global_pooling(true), _fp_mixed_precision(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001263 {
1264 }
Alex Gildayc357c472018-03-21 13:54:09 +00001265 /** Get the pooling type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001266 PoolingType pool_type() const
1267 {
1268 return _pool_type;
1269 }
Alex Gildayc357c472018-03-21 13:54:09 +00001270 /** Get the pooling size */
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001271 const Size2D &pool_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001272 {
1273 return _pool_size;
1274 }
Alex Gildayc357c472018-03-21 13:54:09 +00001275 /** Get the padding and stride */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001276 PadStrideInfo pad_stride_info() const
1277 {
1278 return _pad_stride_info;
1279 }
Alex Gildayc357c472018-03-21 13:54:09 +00001280 /** Check if padding is excluded in calculations */
Georgios Pinitasadaae7e2017-10-30 15:56:32 +00001281 bool exclude_padding() const
1282 {
1283 return _exclude_padding;
1284 }
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001285 /** Check if a wider accumulator should be used. */
1286 bool fp_mixed_precision() const
1287 {
1288 return _fp_mixed_precision;
1289 }
Alex Gildayc357c472018-03-21 13:54:09 +00001290 /** Check if is global pooling */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001291 bool is_global_pooling() const
1292 {
1293 return _is_global_pooling;
1294 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001295
1296private:
1297 PoolingType _pool_type;
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001298 Size2D _pool_size;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001299 PadStrideInfo _pad_stride_info;
Georgios Pinitasadaae7e2017-10-30 15:56:32 +00001300 bool _exclude_padding;
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001301 bool _is_global_pooling;
Sang-Hoon Park2aa7fd02019-09-18 13:39:00 +01001302 bool _fp_mixed_precision;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001303};
1304
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001305/** ROI Pooling Layer Information class */
giuros0118870812018-09-13 09:31:40 +01001306class ROIPoolingLayerInfo final
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001307{
1308public:
giuros0118870812018-09-13 09:31:40 +01001309 /** Constructor
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001310 *
giuros0118870812018-09-13 09:31:40 +01001311 * @param[in] pooled_width Pooled width of the layer.
1312 * @param[in] pooled_height Pooled height of the layer.
1313 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
1314 * @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 +01001315 */
giuros0118870812018-09-13 09:31:40 +01001316 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale, unsigned int sampling_ratio = 0)
1317 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale), _sampling_ratio(sampling_ratio)
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001318 {
1319 }
Alex Gildayc357c472018-03-21 13:54:09 +00001320 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001321 unsigned int pooled_width() const
1322 {
1323 return _pooled_width;
1324 }
Alex Gildayc357c472018-03-21 13:54:09 +00001325 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001326 unsigned int pooled_height() const
1327 {
1328 return _pooled_height;
1329 }
Alex Gildayc357c472018-03-21 13:54:09 +00001330 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001331 float spatial_scale() const
1332 {
1333 return _spatial_scale;
1334 }
giuros0118870812018-09-13 09:31:40 +01001335 /** Get sampling ratio */
1336 unsigned int sampling_ratio() const
1337 {
1338 return _sampling_ratio;
1339 }
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001340
1341private:
1342 unsigned int _pooled_width;
1343 unsigned int _pooled_height;
1344 float _spatial_scale;
giuros0118870812018-09-13 09:31:40 +01001345 unsigned int _sampling_ratio;
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001346};
1347
Manuel Bottini5209be52019-02-13 16:34:56 +00001348/** Generate Proposals Information class */
1349class GenerateProposalsInfo
1350{
1351public:
1352 /** Constructor
1353 *
1354 * @param[in] im_width Width of the original image
1355 * @param[in] im_height Height of the original image
1356 * @param[in] im_scale Scale applied to the original image
1357 * @param[in] spatial_scale (Optional)Scale applied to the feature map. Defaults to 1.0
1358 * @param[in] pre_nms_topN (Optional)Number of the best scores to be selected from the transformations. Defaults to 6000.
1359 * @param[in] post_nms_topN (Optional)Number of the best scores to be selected from the NMS operation. Defaults to 300.
1360 * @param[in] nms_thres (Optional)NMS overlap threshold. Defaults to 0.7.
1361 * @param[in] min_size (Optional)Size used to validate the anchors produced. Defaults to 16.
1362 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region of interest). Defaults to 4.
1363 */
1364 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,
1365 size_t values_per_roi = 4)
1366 : _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),
1367 _min_size(min_size), _values_per_roi(values_per_roi)
1368 {
1369 }
1370
1371 /* Get the original height */
1372 float im_height() const
1373 {
1374 return _im_height;
1375 }
1376 /* Get the original width */
1377 float im_width() const
1378 {
1379 return _im_width;
1380 }
1381 /* Get the image scale */
1382 float im_scale() const
1383 {
1384 return _im_scale;
1385 }
1386 /* Get the value of how many best scores to select (before NMS) */
1387 int pre_nms_topN() const
1388 {
1389 return _pre_nms_topN;
1390 }
1391 /* Get the value of how many best scores to select (after NMS) */
1392 int post_nms_topN() const
1393 {
1394 return _post_nms_topN;
1395 }
1396 /* Get the NMS overlap threshold */
1397 float nms_thres() const
1398 {
1399 return _nms_thres;
1400 }
1401 /* Get the minimal size */
1402 float min_size() const
1403 {
1404 return _min_size;
1405 }
1406 /* Get the spatial scale to be applied to the feature maps */
1407 float spatial_scale() const
1408 {
1409 return _spatial_scale;
1410 }
1411 /* Get the values used to represent a ROI(Region of interest)*/
1412 size_t values_per_roi() const
1413 {
1414 return _values_per_roi;
1415 }
1416
1417private:
1418 float _im_height;
1419 float _im_width;
1420 float _im_scale;
1421 float _spatial_scale;
1422 int _pre_nms_topN;
1423 int _post_nms_topN;
1424 float _nms_thres;
1425 float _min_size;
1426 size_t _values_per_roi;
1427};
1428
1429/** ComputeAnchors information class */
1430class ComputeAnchorsInfo
1431{
1432public:
1433 /** Constructor
1434 *
1435 * @param[in] feat_width Feature map width
1436 * @param[in] feat_height Feature map height
1437 * @param[in] spatial_scale Feature map scale
1438 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region Of Interest). Defaults to 4
1439 */
1440 ComputeAnchorsInfo(float feat_width, float feat_height, float spatial_scale, size_t values_per_roi = 4)
1441 : _feat_height(feat_height),
1442 _feat_width(feat_width),
1443 _spatial_scale(spatial_scale),
1444 _values_per_roi(values_per_roi)
1445 {
1446 }
1447
1448 /* Get the height of the feature map */
1449 float feat_height() const
1450 {
1451 return _feat_height;
1452 }
1453
1454 /* Get the width of the feature map */
1455 float feat_width() const
1456 {
1457 return _feat_width;
1458 }
1459
1460 /* Get the scale of the feature map */
1461 float spatial_scale() const
1462 {
1463 return _spatial_scale;
1464 }
1465
1466 /* Get the values used to represent a ROI(Region Of Interest)*/
1467 size_t values_per_roi() const
1468 {
1469 return _values_per_roi;
1470 }
1471
1472private:
1473 float _feat_height;
1474 float _feat_width;
1475 float _spatial_scale;
1476 size_t _values_per_roi;
1477};
1478
giuros01c04a0e82018-10-03 12:44:35 +01001479/** Bounding Box Transform information class */
giuros01d696cb62018-11-16 10:39:59 +00001480class BoundingBoxTransformInfo final
giuros01c04a0e82018-10-03 12:44:35 +01001481{
1482public:
1483 /** Constructor
1484 *
giuros01d696cb62018-11-16 10:39:59 +00001485 * @param[in] img_width Width of the original image
1486 * @param[in] img_height Height, of the original image
1487 * @param[in] scale Scale of the original image
1488 * @param[in] apply_scale (Optional)Re-apply scaling after transforming the boxes. Defaults to false
1489 * @param[in] weights (Optional)Weights [wx, wy, ww, wh] for the deltas. Defaults to all ones
1490 * @param[in] correct_transform_coords (Optional)Correct bounding box transform coordinates. Defaults to false
1491 * @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 +01001492 */
giuros01d696cb62018-11-16 10:39:59 +00001493 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 =
1494 false,
1495 float bbox_xform_clip =
1496 4.135166556742356f)
1497 : _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 +01001498 {
1499 }
1500
1501 std::array<float, 4> weights() const
1502 {
1503 return _weights;
1504 }
1505
1506 float bbox_xform_clip() const
1507 {
1508 return _bbox_xform_clip;
1509 }
1510
1511 float img_height() const
1512 {
1513 return _img_height;
1514 }
1515
1516 float img_width() const
1517 {
1518 return _img_width;
1519 }
1520
1521 float scale() const
1522 {
1523 return _scale;
1524 }
1525
1526 bool apply_scale() const
1527 {
1528 return _apply_scale;
1529 }
1530
giuros01d696cb62018-11-16 10:39:59 +00001531 bool correct_transform_coords() const
1532 {
1533 return _correct_transform_coords;
1534 }
1535
giuros01c04a0e82018-10-03 12:44:35 +01001536private:
1537 float _img_width;
1538 float _img_height;
1539 float _scale;
1540 bool _apply_scale;
giuros01d696cb62018-11-16 10:39:59 +00001541 bool _correct_transform_coords;
giuros01c04a0e82018-10-03 12:44:35 +01001542 std::array<float, 4> _weights;
1543 float _bbox_xform_clip;
1544};
1545
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001546/** Activation Layer Information class */
1547class ActivationLayerInfo
1548{
1549public:
1550 /** Available activation functions */
1551 enum class ActivationFunction
1552 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001553 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
1554 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
1555 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
1556 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
1557 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
Manuel Bottini581c8982019-02-07 10:31:57 +00001558 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 +01001559 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
Georgios Pinitasfb0fdcd2019-08-22 17:10:04 +01001560 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 +01001561 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
1562 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
1563 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
Usama Arif6a98a6e2019-05-10 17:07:27 +01001564 LINEAR, /**< Linear ( \f$ f(x)= ax + b \f$ ) */
1565 IDENTITY /**< Identity ( \f$ f(x)= x \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001566 };
1567
Giorgio Arena11674872018-02-07 15:38:12 +00001568 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001569 /** Default Constructor
1570 *
1571 * @param[in] f The activation function to use.
1572 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001573 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1574 * @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 +01001575 */
1576 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001577 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001578 {
1579 }
Alex Gildayc357c472018-03-21 13:54:09 +00001580 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001581 ActivationFunction activation() const
1582 {
1583 return _act;
1584 }
Alex Gildayc357c472018-03-21 13:54:09 +00001585 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001586 float a() const
1587 {
1588 return _a;
1589 }
Alex Gildayc357c472018-03-21 13:54:09 +00001590 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001591 float b() const
1592 {
1593 return _b;
1594 }
Alex Gildayc357c472018-03-21 13:54:09 +00001595 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001596 bool enabled() const
1597 {
1598 return _enabled;
1599 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001600
1601private:
Usama Arif6a98a6e2019-05-10 17:07:27 +01001602 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::IDENTITY };
Giorgio Arena11674872018-02-07 15:38:12 +00001603 float _a = {};
1604 float _b = {};
1605 bool _enabled = { false };
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001606};
1607
1608/** Normalization Layer Information class */
1609class NormalizationLayerInfo
1610{
1611public:
1612 /** Default Constructor
1613 *
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001614 * @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 +01001615 * @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 +00001616 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1617 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1618 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1619 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1620 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001621 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001622 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1623 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001624 {
1625 }
Alex Gildayc357c472018-03-21 13:54:09 +00001626 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001627 NormType type() const
1628 {
1629 return _type;
1630 }
Alex Gildayc357c472018-03-21 13:54:09 +00001631 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001632 uint32_t norm_size() const
1633 {
1634 return _norm_size;
1635 }
Alex Gildayc357c472018-03-21 13:54:09 +00001636 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001637 float alpha() const
1638 {
1639 return _alpha;
1640 }
Alex Gildayc357c472018-03-21 13:54:09 +00001641 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001642 float beta() const
1643 {
1644 return _beta;
1645 }
Alex Gildayc357c472018-03-21 13:54:09 +00001646 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001647 float kappa() const
1648 {
1649 return _kappa;
1650 }
Michele Di Giorgio9d3a8312018-11-20 12:31:24 +00001651 /** Get the is_scaled value */
1652 bool is_scaled() const
1653 {
1654 return _is_scaled;
1655 }
Alex Gildayc357c472018-03-21 13:54:09 +00001656 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001657 bool is_cross_map() const
1658 {
1659 return _type == NormType::CROSS_MAP;
1660 }
Alex Gildayc357c472018-03-21 13:54:09 +00001661 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001662 bool is_in_map() const
1663 {
1664 return !is_cross_map();
1665 }
1666 /** Return the scaling factor of the normalization function.
1667 *
1668 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1669 * 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 +01001670 *
1671 * @return The normalization scaling factor.
1672 */
1673 float scale_coeff() const
1674 {
1675 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001676 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001677 }
1678
1679private:
1680 NormType _type;
1681 uint32_t _norm_size;
1682 float _alpha;
1683 float _beta;
1684 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001685 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001686};
1687
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001688/** 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 +01001689class WeightsInfo
1690{
1691public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001692 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001693 WeightsInfo()
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001694 : _are_reshaped(false), _kernel_width(0), _kernel_height(0), _num_kernels(0), _retain_internal_weights(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001695 {
1696 }
1697 /** Constructor
1698 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001699 * @param[in] are_reshaped True if the weights have been reshaped
1700 * @param[in] kernel_width Kernel width.
1701 * @param[in] kernel_height Kernel height.
1702 * @param[in] num_kernels Number of convolution kernels.
1703 * @param[in] retain_internal_weights (Optional) True if internal reshaped weights must be retained. Used for reconfiguration purposes. Default is false.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001704 */
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001705 WeightsInfo(bool are_reshaped, unsigned int kernel_width, unsigned int kernel_height, unsigned int num_kernels, bool retain_internal_weights = false)
1706 : _are_reshaped(are_reshaped), _kernel_width(kernel_width), _kernel_height(kernel_height), _num_kernels(num_kernels), _retain_internal_weights(retain_internal_weights)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001707 {
1708 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001709 /** Flag which specifies if the weights tensor has been reshaped.
1710 *
1711 * @return True if the weights tensors has been reshaped
1712 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001713 bool are_reshaped() const
1714 {
1715 return _are_reshaped;
1716 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001717 /** Return the number of convolution kernels
1718 *
1719 * @return The number of convolution kernels
1720 */
1721 unsigned int num_kernels() const
1722 {
1723 return _num_kernels;
1724 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001725 /** Return the width and height of the kernel
1726 *
1727 * @return The width and height of the kernel
1728 */
1729 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001730 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001731 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001732 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001733 bool retain_internal_weights() const
1734 {
1735 return _retain_internal_weights;
1736 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001737
1738private:
1739 const bool _are_reshaped;
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001740 const unsigned int _kernel_width;
1741 const unsigned int _kernel_height;
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001742 const unsigned int _num_kernels;
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001743 const bool _retain_internal_weights;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001744};
1745
Gian Marco36a0a462018-01-12 10:21:40 +00001746/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
1747 *
Gian Marco Iodice5fc07aa2019-05-15 17:08:02 +01001748 * The matrix A can only be reshaped through @ref CLGEMMReshapeLHSMatrixKernel or @ref NEGEMMInterleave4x4Kernel or @ref GCGEMMInterleave4x4Kernel
1749 * Note: Optionally just for @ref 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 +00001750 *
giuros018b6b4a92018-12-18 19:01:33 +00001751 * The matrix B can only be reshaped through @ref CLGEMMReshapeRHSMatrixKernel or @ref NEGEMMTranspose1xWKernel or @ref GCGEMMTranspose1xWKernel
1752 * Note: Optionally just for @ref 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 +00001753 *
1754 */
1755class GEMMReshapeInfo final
1756{
1757public:
1758 /** Default constructor */
1759 GEMMReshapeInfo()
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001760 : _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 +00001761 {
1762 }
1763 /** Constructor
1764 *
1765 * @param[in] m Number of matrix A rows
1766 * @param[in] n Number of matrix B columns
1767 * @param[in] k Number of matrix A columns or matrix B rows
1768 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
1769 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001770 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
1771 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001772 * @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 +01001773 * to perform 1x1 convolutions with the NHWC data layout)
1774 * @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 +00001775 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001776 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 +01001777 : _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 +01001778 _reinterpret_input_as_3d(reinterpret_input_as_3d), _broadcast_bias(broadcast_bias)
Gian Marco36a0a462018-01-12 10:21:40 +00001779 {
1780 }
1781 /** Number of matrix A rows
1782 *
1783 * @return the number of matrix A rows
1784 */
1785 int m() const
1786 {
1787 return _m;
1788 }
1789 /** Number of matrix B columns
1790 *
1791 * @return the number of matrix B columns
1792 */
1793 int n() const
1794 {
1795 return _n;
1796 }
1797 /** Number of matrix A columns or matrix B rows
1798 *
1799 * @return the number of matrix A columns or matrix B rows
1800 */
1801 int k() const
1802 {
1803 return _k;
1804 }
1805 /** Multiplication factor for the width of the 1xW transposed block
1806 *
1807 * @return the multiplication factor for the width of the 1xW transposed block
1808 */
1809 int mult_transpose1xW_width() const
1810 {
1811 return _mult_transpose1xW_width;
1812 }
1813 /** Multiplication factor for the height of the 4x4 interleaved block
1814 *
1815 * @return the multiplication factor for the height of the 4x4 interleaved block
1816 */
1817 int mult_interleave4x4_height() const
1818 {
1819 return _mult_interleave4x4_height;
1820 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001821 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
1822 *
1823 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
1824 * m = depth_output_gemm3d * output_height
1825 *
1826 * @return the depth of the output tensor to be used with the GEMM3D kernel
1827 */
1828 int depth_output_gemm3d() const
1829 {
1830 return _depth_output_gemm3d;
1831 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001832 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
1833 *
1834 * @return True if the input tensor has to be reinterpreted as 3D tensor
1835 */
1836 bool reinterpret_input_as_3d() const
1837 {
1838 return _reinterpret_input_as_3d;
1839 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001840 /** Flag which specifies whether to broadcast the shape of the bias tensor.
1841 *
1842 * @return True if the shape of the bias tensor is to be broadcasted.
1843 */
1844 bool broadcast_bias() const
1845 {
1846 return _broadcast_bias;
1847 };
Gian Marco36a0a462018-01-12 10:21:40 +00001848
1849private:
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001850 const int _m;
1851 const int _n;
1852 const int _k;
1853 const int _mult_transpose1xW_width;
1854 const int _mult_interleave4x4_height;
1855 const int _depth_output_gemm3d;
1856 const bool _reinterpret_input_as_3d;
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001857 const bool _broadcast_bias;
Gian Marco36a0a462018-01-12 10:21:40 +00001858};
1859
giuros016d109962019-01-07 17:47:19 +00001860struct DepthwiseConvolutionReshapeInfo
1861{
1862 unsigned int c0{ 1 }; /**< Number of channels processed by the depth-wise convolution */
1863 bool transpose{ false }; /**< True if the block MxC0 (where M is the area of the filter i.e. KwxKh) has to be transposed */
1864};
1865
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001866/** GEMMLowp output stage type */
1867enum class GEMMLowpOutputStageType
1868{
1869 NONE, /**< No quantization to uint8 */
1870 QUANTIZE_DOWN, /**< Quantize to uint8 using an integer multiplication */
1871 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize to uint8 using a fixed point multiplication */
1872 QUANTIZE_DOWN_FLOAT /**< Quantize to uint8 using a floating point multiplication */
1873};
1874
1875/** GEMMLowp output stage info */
1876struct GEMMLowpOutputStageInfo
1877{
1878 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
1879 int gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
1880 int gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1881 int gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
1882 int gemmlowp_min_bound{ 0 }; /**< GEMMLowp min value used to saturate down the output result before converting back to QASYMM8 */
1883 int gemmlowp_max_bound{ 0 }; /**< GEMMLowp max value used to saturate down the output result before converting back to QASYMM8 */
Georgios Pinitas68adf442019-11-07 11:46:09 +00001884 std::vector<int32_t> gemmlowp_multipliers{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1885 std::vector<int32_t> gemmlowp_shifts{}; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
Vidhya Sudhan Loganathan951b8a42019-11-04 14:42:08 +00001886 bool is_quantized_per_channel{ false }; /**< GEMMLowp quantized per-channel flag */
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001887};
1888
Gian Marco Iodice5ba5e092018-12-06 17:13:09 +00001889/** GEMM LHS (Left Hand Side) matrix information */
1890struct GEMMLHSMatrixInfo
1891{
1892 unsigned int m0{ 1 }; /**< Number of rows processed by the matrix multiplication */
1893 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1894 unsigned int v0{ 1 }; /**< Number of vertical blocks of size (m0xk0) stored on the same output row */
1895 bool transpose{ true }; /**< True if the (m0xk0) block has to be transposed before been stored */
1896 bool interleave{ true }; /**< True if the v0 (m0xk0) blocks have to be interleaved in the output row */
1897};
1898
Gian Marco Iodice3b0a2652018-12-07 11:18:09 +00001899/** GEMM RHS (Right Hand Side) matrix information */
1900struct GEMMRHSMatrixInfo
1901{
1902 unsigned int n0{ 1 }; /**< Number of columns processed by the matrix multiplication */
1903 unsigned int k0{ 1 }; /**< Number of partial accumulations performed by the matrix multiplication */
1904 unsigned int h0{ 1 }; /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
1905 bool transpose{ true }; /**< True if the (k0xn0) block has to be transposed before been stored */
1906 bool interleave{ true }; /**< True if the h0 (k0xn0) blocks have to be interleaved in the output row */
1907};
1908
Gian Marco36a0a462018-01-12 10:21:40 +00001909/** GEMM information class. This class stores the necessary information to compute GEMM functions
1910 *
1911 * This object also contains the information about how matrix A and matrix B have been reshaped
1912 *
1913 */
Chunosov5124be52017-11-22 20:42:13 +07001914class GEMMInfo
1915{
1916public:
1917 /** Default constructor */
Georgios Pinitas37d080f2019-06-21 18:43:12 +01001918 GEMMInfo() noexcept
1919 : _is_a_reshaped(false),
1920 _is_b_reshaped(false),
1921 _reshape_b_only_on_first_run(true),
1922 _depth_output_gemm3d(0),
1923 _reinterpret_input_as_3d(false),
1924 _retain_internal_weights(false),
1925 _gemmlowp_output_stage(),
1926 _fp_mixed_precision(false),
1927 _broadcast_bias(false),
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01001928 _pretranpose_B(true),
1929 _activation_info()
Chunosov5124be52017-11-22 20:42:13 +07001930 {
1931 }
1932 /** Constructor
1933 *
1934 * @param[in] is_a_reshaped True if the matrix A has been reshaped
1935 * @param[in] is_b_reshaped True if the matrix B has been reshaped
1936 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001937 * @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 +00001938 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001939 * @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
1940 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01001941 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001942 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001943 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001944 * @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 +01001945 * @param[in] activation_info (Optional) Activation to apply after the matrix multiplication
Chunosov5124be52017-11-22 20:42:13 +07001946 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001947 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,
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01001948 GEMMLowpOutputStageInfo gemmlowp_output_stage = GEMMLowpOutputStageInfo(), bool fp_mixed_precision = false, bool broadcast_bias = false,
1949 const ActivationLayerInfo &activation_info = ActivationLayerInfo()) noexcept
Georgios Pinitas37d080f2019-06-21 18:43:12 +01001950 : _is_a_reshaped(is_a_reshaped),
1951 _is_b_reshaped(is_b_reshaped),
1952 _reshape_b_only_on_first_run(reshape_b_only_on_first_run),
1953 _depth_output_gemm3d(depth_output_gemm3d),
1954 _reinterpret_input_as_3d(reinterpret_input_as_3d),
1955 _retain_internal_weights(retain_internal_weights),
1956 _gemmlowp_output_stage(gemmlowp_output_stage),
1957 _fp_mixed_precision(fp_mixed_precision),
1958 _broadcast_bias(broadcast_bias),
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01001959 _pretranpose_B(reshape_b_only_on_first_run),
1960 _activation_info(activation_info)
Chunosov5124be52017-11-22 20:42:13 +07001961 {
1962 }
1963 /** Flag which specifies if the matrix A has been reshaped
1964 *
1965 * @return True if the matrix A has been reshaped
1966 */
1967 bool is_a_reshaped() const
1968 {
1969 return _is_a_reshaped;
1970 };
1971 /** Flag which specifies if the matrix B has been reshaped
1972 *
1973 * @return True if the matrix B has been reshaped
1974 */
1975 bool is_b_reshaped() const
1976 {
1977 return _is_b_reshaped;
1978 };
1979 /** Flag which specifies if the reshape of matrix B should executed only for the first
1980 *
1981 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
1982 *
1983 * @return True if the reshaped of matrix B happens only for the first run
1984 */
1985 bool reshape_b_only_on_first_run() const
1986 {
1987 return _reshape_b_only_on_first_run;
1988 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001989 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00001990 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001991 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00001992 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001993 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00001994 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001995 return _depth_output_gemm3d;
1996 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001997 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
1998 *
1999 * @return True if the input tensor has to be reinterpreted as 3D tensor
2000 */
2001 bool reinterpret_input_as_3d() const
2002 {
2003 return _reinterpret_input_as_3d;
2004 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01002005 /** Flag which specifies if the weights tensor has to be retained from previous run
2006 *
2007 * @return True if the weights tensor has to be retained
2008 */
2009 bool retain_internal_weights() const
2010 {
2011 return _retain_internal_weights;
2012 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01002013 /** GEMMLowp output stage
2014 *
2015 * @return the GEMMLowp output stage info
2016 */
2017 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
2018 {
2019 return _gemmlowp_output_stage;
2020 };
Georgios Pinitasdbdea0d2019-10-16 19:21:40 +01002021 /** Sets GEMMLowp output stage
2022 *
2023 * @param[in] output_stage Output stage to set
2024 */
2025 void set_gemmlowp_output_stage(GEMMLowpOutputStageInfo &output_stage)
2026 {
2027 _gemmlowp_output_stage = output_stage;
2028 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00002029 /** Flag which specifies if a wider accumulator should be used.
2030 *
2031 * @return True if a wider accumulator has to be used
2032 */
2033 bool fp_mixed_precision() const
2034 {
2035 return _fp_mixed_precision;
2036 };
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01002037 /** Flag which specifies whether to broadcast the shape of the bias tensor.
2038 *
2039 * @return True if the shape of the bias tensor is to be broadcasted.
2040 */
2041 bool broadcast_bias() const
2042 {
2043 return _broadcast_bias;
2044 };
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002045 /** Flag which specifies whether b should be pre-transposed if supported.
2046 *
2047 * @return True if b should be pre-transposed else false.
2048 */
2049 bool pretranpose_B() const
2050 {
2051 return _pretranpose_B;
2052 };
2053 /** Set pre-transpose b flag
2054 *
2055 * @param[in] flag Flag to set
2056 */
2057 void set_pretranpose_B(bool flag)
2058 {
2059 _pretranpose_B = flag;
2060 }
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002061 /** Activation layer to apply after the matrix multiplication
2062 *
2063 * @return ActivationLayerInfo object
2064 */
2065 ActivationLayerInfo activation_info() const
2066 {
2067 return _activation_info;
2068 }
Chunosov5124be52017-11-22 20:42:13 +07002069
2070private:
Georgios Pinitas37d080f2019-06-21 18:43:12 +01002071 bool _is_a_reshaped;
2072 bool _is_b_reshaped;
2073 bool _reshape_b_only_on_first_run;
2074 int _depth_output_gemm3d;
2075 bool _reinterpret_input_as_3d;
2076 bool _retain_internal_weights;
2077 GEMMLowpOutputStageInfo _gemmlowp_output_stage;
2078 bool _fp_mixed_precision;
2079 bool _broadcast_bias;
2080 bool _pretranpose_B;
Gian Marco Iodicef3622be2019-07-29 14:27:16 +01002081 ActivationLayerInfo _activation_info;
Chunosov5124be52017-11-22 20:42:13 +07002082};
2083
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00002084/** Winograd information */
2085struct WinogradInfo
2086{
2087 /** Default constructor
2088 *
2089 * @param[in] output_tile_sz Width and height of the output tile
2090 * @param[in] kernel_sz Width and height of the kernel
2091 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
2092 * @param[in] conv_info Convolution info (Pads, strides)
2093 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
2094 */
2095 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
2096 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
2097 {
2098 }
2099
2100 Size2D output_tile_size{}; /**< Width and height of the output tile */
2101 Size2D kernel_size{}; /**< Width and height of the kernel*/
2102 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
2103 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
2104 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
2105};
2106
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002107/** IO formatting information class*/
2108struct IOFormatInfo
2109{
2110 /** Precision type used when printing floating point numbers */
2111 enum class PrecisionType
2112 {
2113 Default, /**< Default precision to the one that the current stream has */
2114 Custom, /**< Custom precision specified by the user using the precision parameter */
2115 Full /**< The maximum precision of the floating point representation */
2116 };
2117
2118 /** Specifies the area to be printed, used by Tensor objects */
2119 enum class PrintRegion
2120 {
2121 ValidRegion, /**< Prints the valid region of the Tensor object */
2122 NoPadding, /**< Prints the Tensor object without the padding */
2123 Full /**< Print the tensor object including padding */
2124 };
2125
Alex Gildayc357c472018-03-21 13:54:09 +00002126 /** Construct a set of IO formatting information.
2127 *
2128 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
2129 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
2130 * @param[in] precision Precision value for float point numbers. Default: 10.
2131 * @param[in] align_columns Whether to align columns when printed. Default: true.
2132 * @param[in] element_delim Delimeter between elements. Default: " ".
2133 * @param[in] row_delim Delimenter between rows. Default: "\n".
2134 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002135 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
2136 PrecisionType precision_type = PrecisionType::Default,
2137 unsigned int precision = 10,
2138 bool align_columns = true,
2139 std::string element_delim = " ",
2140 std::string row_delim = "\n")
2141 : print_region(print_region),
2142 precision_type(precision_type),
2143 precision(precision),
2144 element_delim(element_delim),
2145 row_delim(row_delim),
2146 align_columns(align_columns)
2147 {
2148 }
2149
Alex Gildayc357c472018-03-21 13:54:09 +00002150 /** Area to be printed by Tensor objects */
2151 PrintRegion print_region;
2152 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002153 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00002154 /** Floating point precision */
2155 unsigned int precision;
2156 /** Element delimeter */
2157 std::string element_delim;
2158 /** Row delimeter */
2159 std::string row_delim;
2160 /** Align columns */
2161 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002162};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00002163} // namespace arm_compute
Anthony Barbier6ff3b192017-09-04 18:44:23 +01002164#endif /* __ARM_COMPUTE_TYPES_H__ */