blob: 38094ee56a382fa193c1922d76d46abee2391017 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Gian Marco36a0a462018-01-12 10:21:40 +00002 * Copyright (c) 2016-2018 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"
Michel Iwaniec5dfeae62017-11-29 10:48:23 +000028#include "arm_compute/core/QAsymm8.h"
29#include "arm_compute/core/Rounding.h"
Isabella Gottardi6e464c32018-01-26 12:32:45 +000030#include "arm_compute/core/Size2D.h"
Georgios Pinitas8795ffb2017-12-01 16:13:40 +000031#include "arm_compute/core/Strides.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010032#include "arm_compute/core/TensorShape.h"
Georgios Pinitas583137c2017-08-31 18:12:42 +010033#include "support/Half.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010034
Michel Iwaniec5dfeae62017-11-29 10:48:23 +000035#include <cmath>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010036#include <cstddef>
37#include <cstdint>
38#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{
Alex Gildayc357c472018-03-21 13:54:09 +000076 UNKNOWN, /**< Unknown data type */
77 U8, /**< unsigned 8-bit number */
78 S8, /**< signed 8-bit number */
Alex Gildayc357c472018-03-21 13:54:09 +000079 QASYMM8, /**< quantized, asymmetric fixed-point 8-bit number */
80 U16, /**< unsigned 16-bit number */
81 S16, /**< signed 16-bit number */
Alex Gildayc357c472018-03-21 13:54:09 +000082 U32, /**< unsigned 32-bit number */
83 S32, /**< signed 32-bit number */
Alex Gildayc357c472018-03-21 13:54:09 +000084 U64, /**< unsigned 64-bit number */
85 S64, /**< signed 64-bit number */
86 F16, /**< 16-bit floating-point number */
87 F32, /**< 32-bit floating-point number */
88 F64, /**< 64-bit floating-point number */
89 SIZET /**< size_t */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010090};
91
Daniil Efremov02bf80d2017-11-22 00:26:51 +070092/** Available Sampling Policies */
93enum class SamplingPolicy
94{
95 CENTER, /**< Samples are taken at pixel center */
96 TOP_LEFT /**< Samples are taken at pixel top left corner */
97};
98
Anthony Barbier6ff3b192017-09-04 18:44:23 +010099/** Constant value of the border pixels when using BorderMode::CONSTANT */
100constexpr uint8_t CONSTANT_BORDER_VALUE = 199;
101
Alex Gildayc357c472018-03-21 13:54:09 +0000102/** Constant value used to indicate a half-scale pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100103constexpr float SCALE_PYRAMID_HALF = 0.5f;
104
Alex Gildayc357c472018-03-21 13:54:09 +0000105/** Constant value used to indicate a ORB scaled pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100106constexpr float SCALE_PYRAMID_ORB = 8.408964152537146130583778358414e-01;
107
Georgios Pinitas4074c992018-01-30 18:13:46 +0000108/** Supported tensor data layouts */
109enum class DataLayout
110{
Alex Gildayc357c472018-03-21 13:54:09 +0000111 UNKNOWN, /**< Unknown data layout */
112 NCHW, /**< Num samples, channels, height, width */
113 NHWC /**< Num samples, height, width, channels */
Georgios Pinitas4074c992018-01-30 18:13:46 +0000114};
115
Isabella Gottardid17a6772018-02-27 17:41:55 +0000116/** Supported tensor data layout dimensions */
117enum class DataLayoutDimension
118{
Alex Gildayc357c472018-03-21 13:54:09 +0000119 CHANNEL, /**< channel */
120 HEIGHT, /**< height */
121 WIDTH, /**< width */
122 BATCHES /**< batches */
Isabella Gottardid17a6772018-02-27 17:41:55 +0000123};
124
Michel Iwaniec00633802017-10-12 14:14:15 +0100125/** Quantization settings (used for QASYMM8 data type) */
126struct QuantizationInfo
127{
Alex Gildayc357c472018-03-21 13:54:09 +0000128 /** Default constructor */
Georgios Pinitasf8d8f3a2018-06-06 17:57:04 +0100129 QuantizationInfo() noexcept
130 : scale(0.0f),
131 offset(0)
Michel Iwaniec00633802017-10-12 14:14:15 +0100132 {
133 }
134
Alex Gildayc357c472018-03-21 13:54:09 +0000135 /** Construct quantization info.
136 *
137 * @param[in] scale Scale.
138 * @param[in] offset Offset.
139 */
Michel Iwaniec00633802017-10-12 14:14:15 +0100140 QuantizationInfo(float scale, int offset)
141 : scale(scale), offset(offset)
142 {
143 }
144
Alex Gildayc357c472018-03-21 13:54:09 +0000145 /** Check whether equal to a given quantization info.
146 *
147 * @param[in] other Other quantization info.
148 *
149 * @return True if the given quantization info is the same.
150 */
Georgios Pinitas08346e92018-10-16 19:10:46 +0100151 bool operator==(const QuantizationInfo &other) const
Daniil Efremoveed841c2017-11-09 19:05:25 +0700152 {
153 return scale == other.scale && offset == other.offset;
154 }
155
Alex Gildayc357c472018-03-21 13:54:09 +0000156 /** Check whether not equal to a given quantization info.
157 *
158 * @param[in] other Other quantization info.
159 *
160 * @return True if the given quantization info is not the same.
161 */
Georgios Pinitas08346e92018-10-16 19:10:46 +0100162 bool operator!=(const QuantizationInfo &other) const
Daniil Efremoveed841c2017-11-09 19:05:25 +0700163 {
164 return !(*this == other);
165 }
166
Michel Iwaniec00633802017-10-12 14:14:15 +0100167 float scale; /**< scale */
168 int offset; /**< offset */
169
Alex Gildayc357c472018-03-21 13:54:09 +0000170 /** Quantizes a value using the scale/offset in this QuantizationInfo
171 *
172 * @param[in] value Value to quantize.
173 * @param[in] rounding_policy Policy to use when rounding.
174 *
175 * @return the quantized value.
176 */
Michel Iwaniec5dfeae62017-11-29 10:48:23 +0000177 qasymm8_t quantize(float value, RoundingPolicy rounding_policy) const
Michel Iwaniec00633802017-10-12 14:14:15 +0100178 {
179 ARM_COMPUTE_ERROR_ON_MSG(scale == 0, "QuantizationInfo::quantize: scale == 0");
Michel Iwaniec5dfeae62017-11-29 10:48:23 +0000180 return sqcvt_qasymm8_f32(value, scale, offset, rounding_policy);
Michel Iwaniec00633802017-10-12 14:14:15 +0100181 }
182
Alex Gildayc357c472018-03-21 13:54:09 +0000183 /** Dequantizes a value using the scale/offset in this QuantizationInfo
184 *
185 * @param[in] value Value to dequantize.
186 *
187 * @return the original value before quantization.
188 */
Michel Iwaniec5dfeae62017-11-29 10:48:23 +0000189 float dequantize(qasymm8_t value) const
Michel Iwaniec00633802017-10-12 14:14:15 +0100190 {
191 ARM_COMPUTE_ERROR_ON_MSG(scale == 0, "QuantizationInfo::dequantize: scale == 0");
Michel Iwaniec5dfeae62017-11-29 10:48:23 +0000192 return scvt_f32_qasymm8(value, scale, offset);
Michel Iwaniec00633802017-10-12 14:14:15 +0100193 }
194
Alex Gildayc357c472018-03-21 13:54:09 +0000195 /** Indicates whether this QuantizationInfo has valid settings or not
196 *
197 * @return True if the this has invalid settings.
198 */
Michel Iwaniec00633802017-10-12 14:14:15 +0100199 bool empty() const
200 {
201 return scale == 0;
202 }
203};
204
Alex Gildayc357c472018-03-21 13:54:09 +0000205/** Container for valid region of a window */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100206struct ValidRegion
207{
Alex Gildayc357c472018-03-21 13:54:09 +0000208 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100209 ValidRegion()
210 : anchor{}, shape{}
211 {
212 }
213
Alex Gildayc357c472018-03-21 13:54:09 +0000214 /** Allow instances of this class to be copy constructed */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100215 ValidRegion(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000216 /** Allow instances of this class to be move constructed */
217 ValidRegion(ValidRegion &&) = default;
218 /** Allow instances of this class to be copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100219 ValidRegion &operator=(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000220 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100221 ValidRegion &operator=(ValidRegion &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000222 /** Default destructor */
223 ~ValidRegion() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100224
Alex Gildayc357c472018-03-21 13:54:09 +0000225 /** Constructor for a valid region with default number of dimensions
226 *
227 * @param[in] an_anchor Anchor for the start of the valid region.
228 * @param[in] a_shape Shape of the valid region.
229 *
230 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000231 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
232 : anchor{ an_anchor }, shape{ a_shape }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100233 {
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000234 anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
235 }
236
Alex Gildayc357c472018-03-21 13:54:09 +0000237 /** Constructor for a valid region with specified number of dimensions
238 *
239 * @param[in] an_anchor Anchor for the start of the valid region.
240 * @param[in] a_shape Shape of the valid region.
241 * @param[in] num_dimensions Number of dimensions (must be >= number of dimensions of anchor and shape).
242 *
243 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000244 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
245 : anchor{ an_anchor }, shape{ a_shape }
246 {
247 ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
248 anchor.set_num_dimensions(num_dimensions);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100249 }
250
251 /** Return the start of the valid region for the given dimension @p d */
252 int start(unsigned int d) const
253 {
254 return anchor[d];
255 }
256
257 /** Return the end of the valid region for the given dimension @p d */
258 int end(unsigned int d) const
259 {
260 return anchor[d] + shape[d];
261 }
262
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000263 /** Accessor to set the value of anchor and shape for one of the dimensions.
264 *
265 * @param[in] dimension Dimension for which the value is set.
266 * @param[in] start Value to be set in anchor for the dimension.
267 * @param[in] size Value to be set in shape for the dimension.
268 *
269 * @return *this.
270 */
271 ValidRegion &set(size_t dimension, int start, size_t size)
272 {
273 anchor.set(dimension, start);
274 shape.set(dimension, size);
275 return *this;
276 }
277
Alex Gildayc357c472018-03-21 13:54:09 +0000278 Coordinates anchor; /**< Anchor for the start of the valid region. */
279 TensorShape shape; /**< Shape of the valid region. */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100280};
281
282/** Methods available to handle borders */
283enum class BorderMode
284{
285 UNDEFINED, /**< Borders are left undefined */
286 CONSTANT, /**< Pixels outside the image are assumed to have a constant value */
287 REPLICATE /**< Pixels outside the image are assumed to have the same value as the closest image pixel */
288};
289
290/** Container for 2D border size */
291struct BorderSize
292{
293 /** Empty border, i.e. no border */
294 constexpr BorderSize()
295 : top{ 0 }, right{ 0 }, bottom{ 0 }, left{ 0 }
296 {
297 }
298
299 /** Border with equal size around the 2D plane */
Moritz Pflanzer7655a672017-09-23 11:57:33 +0100300 explicit constexpr BorderSize(unsigned int size)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100301 : top{ size }, right{ size }, bottom{ size }, left{ size }
302 {
303 }
304
305 /** Border with same size for top/bottom and left/right */
306 constexpr BorderSize(unsigned int top_bottom, unsigned int left_right)
307 : top{ top_bottom }, right{ left_right }, bottom{ top_bottom }, left{ left_right }
308 {
309 }
310
311 /** Border with different sizes */
312 constexpr BorderSize(unsigned int top, unsigned int right, unsigned int bottom, unsigned int left)
313 : top{ top }, right{ right }, bottom{ bottom }, left{ left }
314 {
315 }
316
317 /** Check if the entire border is zero */
318 constexpr bool empty() const
319 {
320 return top == 0 && right == 0 && bottom == 0 && left == 0;
321 }
322
323 /** Check if the border is the same size on all sides */
324 constexpr bool uniform() const
325 {
326 return top == right && top == bottom && top == left;
327 }
328
Alex Gildayc357c472018-03-21 13:54:09 +0000329 /** Scale this border size.
330 *
331 * @param[in] scale Scale to multiply border size by.
332 *
333 * @return *this.
334 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100335 BorderSize &operator*=(float scale)
336 {
337 top *= scale;
338 right *= scale;
339 bottom *= scale;
340 left *= scale;
341
342 return *this;
343 }
344
Alex Gildayc357c472018-03-21 13:54:09 +0000345 /** Scale a copy of this border size.
346 *
347 * @param[in] scale Scale to multiply border size by.
348 *
349 * @return a scaled copy of this.
350 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100351 BorderSize operator*(float scale)
352 {
353 BorderSize size = *this;
354 size *= scale;
355
356 return size;
357 }
358
Alex Gildayc357c472018-03-21 13:54:09 +0000359 /** Limit this border size.
360 *
361 * @param[in] limit Border size to limit this border size to.
362 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100363 void limit(const BorderSize &limit)
364 {
365 top = std::min(top, limit.top);
366 right = std::min(right, limit.right);
367 bottom = std::min(bottom, limit.bottom);
368 left = std::min(left, limit.left);
369 }
370
Alex Gildayc357c472018-03-21 13:54:09 +0000371 unsigned int top; /**< top of the border */
372 unsigned int right; /**< right of the border */
373 unsigned int bottom; /**< bottom of the border */
374 unsigned int left; /**< left of the border */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100375};
376
Alex Gildayc357c472018-03-21 13:54:09 +0000377/** Container for 2D padding size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100378using PaddingSize = BorderSize;
379
380/** Policy to handle overflow */
381enum class ConvertPolicy
382{
383 WRAP, /**< Wrap around */
384 SATURATE /**< Saturate */
385};
386
387/** Interpolation method */
388enum class InterpolationPolicy
389{
390 NEAREST_NEIGHBOR, /**< Output values are defined to match the source pixel whose center is nearest to the sample position */
391 BILINEAR, /**< Output values are defined by bilinear interpolation between the pixels */
392 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 */
393};
394
395/** Bilinear Interpolation method used by LKTracker */
396enum class BilinearInterpolation
397{
Alex Gildayc357c472018-03-21 13:54:09 +0000398 BILINEAR_OLD_NEW, /**< Old-new method */
399 BILINEAR_SCHARR /**< Scharr method */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100400};
401
402/** Threshold mode */
403enum class ThresholdType
404{
405 BINARY, /**< Threshold with one value */
406 RANGE /**< Threshold with two values*/
407};
408
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100409/** Termination criteria */
410enum class Termination
411{
Alex Gildayc357c472018-03-21 13:54:09 +0000412 TERM_CRITERIA_EPSILON, /**< Terminate when within epsilon of a threshold */
413 TERM_CRITERIA_ITERATIONS, /**< Terminate after a maximum number of iterations */
414 TERM_CRITERIA_BOTH /**< Terminate on whichever of the other conditions occurs first */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100415};
416
417/** Magnitude calculation type. */
418enum class MagnitudeType
419{
420 L1NORM, /**< L1 normalization type */
421 L2NORM /**< L2 normalization type */
422};
423
424/** Phase calculation type.
425 *
426 * @note When PhaseType == SIGNED, each angle is mapped to the range 0 to 255 inclusive otherwise angles between 0 and 180
427 */
428enum class PhaseType
429{
430 SIGNED, /**< Angle range: [0, 360] */
431 UNSIGNED /**< Angle range: [0, 180] */
432};
433
434/** Keypoint type */
435struct KeyPoint
436{
437 int32_t x{ 0 }; /**< X coordinates */
438 int32_t y{ 0 }; /**< Y coordinates */
439 float strength{ 0.f }; /**< Strength of the point */
440 float scale{ 0.f }; /**< Scale initialized to 0 by the corner detector */
441 float orientation{ 0.f }; /**< Orientation initialized to 0 by the corner detector */
442 int32_t tracking_status{ 0 }; /**< Status initialized to 1 by the corner detector, set to 0 when the point is lost */
443 float error{ 0.f }; /**< Tracking error initialized to 0 by the corner detector */
444};
445
Alex Gildayc357c472018-03-21 13:54:09 +0000446/** Internal key point */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100447using InternalKeypoint = std::tuple<float, float, float>; /* x,y,strength */
448
449/** Rectangle type */
450struct Rectangle
451{
452 uint16_t x; /**< Top-left x coordinate */
453 uint16_t y; /**< Top-left y coordinate */
454 uint16_t width; /**< Width of the rectangle */
455 uint16_t height; /**< Height of the rectangle */
456};
457
458/** Coordinate type */
459struct Coordinates2D
460{
461 int32_t x; /**< X coordinates */
462 int32_t y; /**< Y coordinates */
463};
464
465/** Coordinate type */
466struct Coordinates3D
467{
468 uint32_t x; /**< X coordinates */
469 uint32_t y; /**< Y coordinates */
470 uint32_t z; /**< Z coordinates */
471};
472
Giuseppe Rossinid7647d42018-07-17 18:13:13 +0100473/** Padding information as a pair of unsigned int start/end */
474using PaddingInfo = std::pair<uint32_t, uint32_t>;
475
476/** List of padding information */
477using PaddingList = std::vector<PaddingInfo>;
478
Georgios Pinitas7b7858d2017-06-21 16:44:24 +0100479/** Region of interest */
480struct ROI
481{
482 Rectangle rect; /**< Rectangle specifying the region of interest */
483 uint16_t batch_idx; /**< The batch index of the region of interest */
484};
485
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100486/** Available channels */
487enum class Channel
488{
489 UNKNOWN, /** Unknown channel format */
490 C0, /**< First channel (used by formats with unknown channel types). */
491 C1, /**< Second channel (used by formats with unknown channel types). */
492 C2, /**< Third channel (used by formats with unknown channel types). */
493 C3, /**< Fourth channel (used by formats with unknown channel types). */
494 R, /**< Red channel. */
495 G, /**< Green channel. */
496 B, /**< Blue channel. */
497 A, /**< Alpha channel. */
498 Y, /**< Luma channel. */
499 U, /**< Cb/U channel. */
500 V /**< Cr/V/Value channel. */
501};
502
503/** Available matrix patterns */
504enum class MatrixPattern
505{
506 BOX, /**< Box pattern matrix. */
507 CROSS, /**< Cross pattern matrix. */
508 DISK, /**< Disk pattern matrix. */
509 OTHER /**< Any other matrix pattern. */
510};
511
512/** Available non linear functions. */
513enum class NonLinearFilterFunction : unsigned
514{
515 MEDIAN = 0, /**< Non linear median filter. */
516 MIN = 1, /**< Non linear erode. */
517 MAX = 2, /**< Non linear dilate. */
518};
519
Georgios Pinitasd9769582017-08-03 10:19:40 +0100520/** Available reduction operations */
521enum class ReductionOperation
522{
523 SUM_SQUARE, /**< Sum of squares */
Michalis Spyrou04f089c2017-08-08 17:42:38 +0100524 SUM, /**< Sum */
Michalis Spyrou7e9391b2018-10-05 14:49:28 +0100525 MEAN_SUM, /**< Mean of sum */
Georgios Pinitasd9769582017-08-03 10:19:40 +0100526};
527
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100528/** The normalization type used for the normalization layer */
529enum class NormType
530{
531 IN_MAP_1D, /**< Normalization applied within the same map in 1D region */
532 IN_MAP_2D, /**< Normalization applied within the same map in 2D region */
533 CROSS_MAP /**< Normalization applied cross maps */
534};
535
536/** Normalization type for Histogram of Oriented Gradients (HOG) */
537enum class HOGNormType
538{
539 L2_NORM = 1, /**< L2-norm */
540 L2HYS_NORM = 2, /**< L2-norm followed by clipping */
541 L1_NORM = 3 /**< L1 norm */
542};
543
544/** Detection window used for the object detection. The detection window keeps the following information:
545 *
546 * -# Geometry of the rectangular window (x/y of top-left corner and width/height)
547 * -# Index of the class used for evaluating which class the detection window belongs to
548 * -# Confidence value (score) obtained with the classifier
549 */
550struct DetectionWindow
551{
552 uint16_t x{ 0 }; /**< Top-left x coordinate */
553 uint16_t y{ 0 }; /**< Top-left y coordinate */
554 uint16_t width{ 0 }; /**< Width of the detection window */
555 uint16_t height{ 0 }; /**< Height of the detection window */
556 uint16_t idx_class{ 0 }; /**< Index of the class */
557 float score{ 0.f }; /**< Confidence value for the detection window */
558};
559
560/** Dimension rounding type when down-scaling on CNNs
561 * @note Used in pooling and convolution layer
562 */
563enum class DimensionRoundingType
564{
565 FLOOR, /**< Floor rounding */
566 CEIL /**< Ceil rounding */
567};
568
569/** Available pooling types */
570enum class PoolingType
571{
572 MAX, /**< Max Pooling */
Georgios Pinitascdf51452017-08-31 14:21:36 +0100573 AVG, /**< Average Pooling */
574 L2 /**< L2 Pooling */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100575};
576
Michalis Spyrou2709d612018-09-19 09:46:47 +0100577/** Available non maxima suppression types */
578enum class NMSType
579{
580 LINEAR, /**< Linear NMS */
581 GAUSSIAN, /**< Gaussian NMS */
582 ORIGINAL /**< Original NMS */
583};
584
585/** BoxWithNonMaximaSuppressionLimit Information class */
586class BoxNMSLimitInfo final
587{
588public:
589 /** Constructor
590 *
591 * @param[in] score_thresh (Optional) Score threshold.
592 * @param[in] nms (Optional) NMS value
593 * @param[in] detections (Optional) Number of detections
594 * @param[in] soft_nms_enabled (Optional) Enable SoftNMS
595 * @param[in] soft_nms_method (Optional) Soft NMS method
596 * @param[in] soft_nms_sigma (Optional) Soft NMS sigma value
597 * @param[in] soft_nms_min_score_thres (Optional) Soft NMS minimum score threshold
giuros01cd96a262018-10-03 12:44:35 +0100598 * @param[in] suppress_size (Optional) Filter out boxes based on their size. Defaults to false
599 * @param[in] min_size (Optional) Smaller boxes than min_size will be filtered out. Defaults to 1
600 * @param[in] im_width (Optional) Boxes whose centers (on the x axis) is beyond im_width will be filtered. Defaults to 1
601 * @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 +0100602 */
603 BoxNMSLimitInfo(float score_thresh = 0.05f, float nms = 0.3f,
604 int detections = 100, bool soft_nms_enabled = false,
605 NMSType soft_nms_method = NMSType::LINEAR,
giuros01cd96a262018-10-03 12:44:35 +0100606 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 +0100607 : _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),
giuros01cd96a262018-10-03 12:44:35 +0100608 _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 +0100609 {
610 }
611 /** Get the score threshold */
612 float score_thresh() const
613 {
614 return _score_thresh;
615 }
616 /** Get the NMS */
617 float nms() const
618 {
619 return _nms;
620 }
621 /** Get the number of detections */
622 int detections_per_im() const
623 {
624 return _detections_per_im;
625 }
626 /** Check if soft NMS is enabled */
627 bool soft_nms_enabled() const
628 {
629 return _soft_nms_enabled;
630 }
631 /** Get soft NMS method */
632 NMSType soft_nms_method() const
633 {
634 return _soft_nms_method;
635 }
636 /** Get soft NMS sigma */
637 float soft_nms_sigma() const
638 {
639 return _soft_nms_sigma;
640 }
641 /** Get soft nms min score threshold */
642 float soft_nms_min_score_thres() const
643 {
644 return _soft_nms_min_score_thres;
645 }
giuros01cd96a262018-10-03 12:44:35 +0100646 /** Get if NMS will suppress boxes based on their size/position */
647 bool suppress_size() const
648 {
649 return _suppress_size;
650 }
651 /** Get size suppression threshold */
652 float min_size() const
653 {
654 return _min_size;
655 }
656 /** Get image width (NMS may suppress boxes whose center sits beyond the image width) */
657 float im_width() const
658 {
659 return _im_width;
660 }
661 /** Get image height (NMS may suppress boxes whose center sits beyond the image height) */
662 float im_height() const
663 {
664 return _im_height;
665 }
Michalis Spyrou2709d612018-09-19 09:46:47 +0100666
667private:
668 float _score_thresh;
669 float _nms;
670 int _detections_per_im;
671 bool _soft_nms_enabled;
672 NMSType _soft_nms_method;
673 float _soft_nms_sigma;
674 float _soft_nms_min_score_thres;
giuros01cd96a262018-10-03 12:44:35 +0100675 bool _suppress_size;
676 float _min_size;
677 float _im_width;
678 float _im_height;
Michalis Spyrou2709d612018-09-19 09:46:47 +0100679};
680
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100681/** Padding and stride information class */
682class PadStrideInfo
683{
684public:
685 /** Constructor
686 *
687 * @param[in] stride_x (Optional) Stride, in elements, across x. Defaults to 1.
688 * @param[in] stride_y (Optional) Stride, in elements, across y. Defaults to 1.
689 * @param[in] pad_x (Optional) Padding, in elements, across x. Defaults to 0.
690 * @param[in] pad_y (Optional) Padding, in elements, across y. Defaults to 0.
691 * @param[in] round (Optional) Dimensions rounding. Defaults to @ref FLOOR.
692 */
693 PadStrideInfo(unsigned int stride_x = 1, unsigned int stride_y = 1,
694 unsigned int pad_x = 0, unsigned int pad_y = 0,
695 DimensionRoundingType round = DimensionRoundingType::FLOOR)
696 : _stride(std::make_pair(stride_x, stride_y)),
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100697 _pad_left(pad_x),
698 _pad_top(pad_y),
699 _pad_right(pad_x),
700 _pad_bottom(pad_y),
701 _round_type(round)
702 {
703 }
704 /** Constructor
705 *
706 * @param[in] stride_x Stride, in elements, across x.
707 * @param[in] stride_y Stride, in elements, across y.
708 * @param[in] pad_left Padding across x on the left, in elements.
709 * @param[in] pad_top Padding across y on the top, in elements.
710 * @param[in] pad_right Padding across x on the right, in elements.
711 * @param[in] pad_bottom Padding across y on the bottom, in elements.
712 * @param[in] round Dimensions rounding.
713 */
714 PadStrideInfo(unsigned int stride_x, unsigned int stride_y,
715 unsigned int pad_left, unsigned int pad_right,
716 unsigned int pad_top, unsigned int pad_bottom,
717 DimensionRoundingType round)
718 : _stride(std::make_pair(stride_x, stride_y)),
719 _pad_left(pad_left),
720 _pad_top(pad_top),
721 _pad_right(pad_right),
722 _pad_bottom(pad_bottom),
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100723 _round_type(round)
724 {
725 }
Alex Gildayc357c472018-03-21 13:54:09 +0000726 /** Get the stride.
727 *
728 * @return a pair: stride x, stride y.
729 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100730 std::pair<unsigned int, unsigned int> stride() const
731 {
732 return _stride;
733 }
Alex Gildayc357c472018-03-21 13:54:09 +0000734 /** Check whether the padding is symmetric.
735 *
736 * @return True if the padding is symmetric.
737 */
Anthony Barbier21f67d62018-02-16 15:17:48 +0000738 bool padding_is_symmetric() const
739 {
740 return (_pad_left == _pad_right) && (_pad_top == _pad_bottom);
741 }
Alex Gildayc357c472018-03-21 13:54:09 +0000742 /** Get the padding.
743 *
744 * @note This should only be used when the padding is symmetric.
745 *
746 * @return a pair: padding left/right, padding top/bottom
747 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100748 std::pair<unsigned int, unsigned int> pad() const
749 {
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100750 //this accessor should be used only when padding is symmetric
Anthony Barbier21f67d62018-02-16 15:17:48 +0000751 ARM_COMPUTE_ERROR_ON(!padding_is_symmetric());
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100752 return std::make_pair(_pad_left, _pad_top);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100753 }
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100754
Alex Gildayc357c472018-03-21 13:54:09 +0000755 /** Get the left padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100756 unsigned int pad_left() const
757 {
758 return _pad_left;
759 }
Alex Gildayc357c472018-03-21 13:54:09 +0000760 /** Get the right padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100761 unsigned int pad_right() const
762 {
763 return _pad_right;
764 }
Alex Gildayc357c472018-03-21 13:54:09 +0000765 /** Get the top padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100766 unsigned int pad_top() const
767 {
768 return _pad_top;
769 }
Alex Gildayc357c472018-03-21 13:54:09 +0000770 /** Get the bottom padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100771 unsigned int pad_bottom() const
772 {
773 return _pad_bottom;
774 }
775
Alex Gildayc357c472018-03-21 13:54:09 +0000776 /** Get the rounding type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100777 DimensionRoundingType round() const
778 {
779 return _round_type;
780 }
781
Alex Gildayc357c472018-03-21 13:54:09 +0000782 /** Check whether this has any padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100783 bool has_padding() const
784 {
785 return (_pad_left != 0 || _pad_top != 0 || _pad_right != 0 || _pad_bottom != 0);
786 }
787
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100788private:
789 std::pair<unsigned int, unsigned int> _stride;
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100790 unsigned int _pad_left;
791 unsigned int _pad_top;
792 unsigned int _pad_right;
793 unsigned int _pad_bottom;
794
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100795 DimensionRoundingType _round_type;
796};
797
Georgios Pinitas7d66a8e2018-07-17 12:28:42 +0100798/** Fully connected layer info */
799struct FullyConnectedLayerInfo
800{
801 DataLayout weights_trained_layout{ DataLayout::NCHW }; /**< Layout that the weights have been trained with. */
802 bool transpose_weights{ true }; /**< Transpose weights if true. */
803 bool are_weights_reshaped{ false }; /**< Reshape the weights tensor if false. */
804 bool retain_internal_weights{ false }; /**< Retain internal reshaped weights. */
Georgios Pinitasc55cef12018-08-01 15:24:18 +0100805
806 /** Sets the weights trained data layout
807 *
808 * @param[in] layout Data layout that the weights were trained with
809 *
810 * @return Updated object
811 */
812 FullyConnectedLayerInfo &set_weights_trained_layout(DataLayout layout)
813 {
814 weights_trained_layout = layout;
815 return *this;
816 }
Georgios Pinitas195b0ba2018-08-02 17:18:51 +0100817 /** Sets the transpose weights flag
818 *
819 * @param[in] should_transpose_weights Boolean flag indicating if weights should be transposed
820 *
821 * @return Updated object
822 */
823 FullyConnectedLayerInfo &set_transpose_weights(bool should_transpose_weights)
824 {
825 transpose_weights = should_transpose_weights;
826 return *this;
827 }
Georgios Pinitas7d66a8e2018-07-17 12:28:42 +0100828};
829
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100830/** PriorBox layer info */
831class PriorBoxLayerInfo final
832{
833public:
834 /** Default Constructor */
835 PriorBoxLayerInfo()
836 : _min_sizes(),
837 _variances(),
838 _offset(),
839 _flip(true),
840 _clip(false),
841 _max_sizes(),
842 _aspect_ratios(),
843 _img_size(),
844 _steps()
845 {
846 }
847 /** Constructor
848 *
849 * @param[in] min_sizes Min sizes vector.
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100850 * @param[in] variances Variances vector.
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100851 * @param[in] offset Offset value.
852 * @param[in] flip (Optional) Flip the aspect ratios.
853 * @param[in] clip (Optional) Clip coordinates so that they're within [0,1].
854 * @param[in] max_sizes (Optional) Max sizes vector.
855 * @param[in] aspect_ratios (Optional) Aspect ratios of the boxes.
856 * @param[in] img_size (Optional) Image size.
857 * @param[in] steps (Optional) Step values.
858 */
859 PriorBoxLayerInfo(const std::vector<float> &min_sizes, const std::vector<float> &variances, float offset, bool flip = true, bool clip = false,
860 const std::vector<float> &max_sizes = {}, const std::vector<float> &aspect_ratios = {}, const Coordinates2D &img_size = Coordinates2D{ 0, 0 }, const std::array<float, 2> &steps = { { 0.f, 0.f } })
861 : _min_sizes(min_sizes),
862 _variances(variances),
863 _offset(offset),
864 _flip(flip),
865 _clip(clip),
866 _max_sizes(max_sizes),
Michalis Spyrou721c4cb2018-09-04 15:27:25 +0100867 _aspect_ratios(),
Michalis Spyrou6c7c38e2018-08-29 16:28:11 +0100868 _img_size(img_size),
869 _steps(steps)
870 {
871 _aspect_ratios.push_back(1.);
872 for(unsigned int i = 0; i < aspect_ratios.size(); ++i)
873 {
874 float ar = aspect_ratios[i];
875 bool already_exist = false;
876 for(auto ar_new : _aspect_ratios)
877 {
878 if(fabs(ar - ar_new) < 1e-6)
879 {
880 already_exist = true;
881 break;
882 }
883 }
884 if(!already_exist)
885 {
886 _aspect_ratios.push_back(ar);
887 if(flip)
888 {
889 _aspect_ratios.push_back(1.f / ar);
890 }
891 }
892 }
893 }
894 /** Get min sizes. */
895 std::vector<float> min_sizes() const
896 {
897 return _min_sizes;
898 }
899 /** Get min variances. */
900 std::vector<float> variances() const
901 {
902 return _variances;
903 }
904 /** Get the step coordinates */
905 std::array<float, 2> steps() const
906 {
907 return _steps;
908 }
909 /** Get the image size coordinates */
910 Coordinates2D img_size() const
911 {
912 return _img_size;
913 }
914 /** Get the offset */
915 float offset() const
916 {
917 return _offset;
918 }
919 /** Get the flip value */
920 bool flip() const
921 {
922 return _flip;
923 }
924 /** Get the clip value */
925 bool clip() const
926 {
927 return _clip;
928 }
929 /** Get max sizes. */
930 std::vector<float> max_sizes() const
931 {
932 return _max_sizes;
933 }
934 /** Get aspect ratios. */
935 std::vector<float> aspect_ratios() const
936 {
937 return _aspect_ratios;
938 }
939
940private:
941 std::vector<float> _min_sizes;
942 std::vector<float> _variances;
943 float _offset;
944 bool _flip;
945 bool _clip;
946 std::vector<float> _max_sizes;
947 std::vector<float> _aspect_ratios;
948 Coordinates2D _img_size;
949 std::array<float, 2> _steps;
950};
951
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100952/** Pooling Layer Information class */
953class PoolingLayerInfo
954{
955public:
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000956 /** Default Constructor */
957 PoolingLayerInfo()
Isabella Gottardi6e464c32018-01-26 12:32:45 +0000958 : _pool_type(PoolingType::MAX), _pool_size(Size2D()), _pad_stride_info(PadStrideInfo()), _exclude_padding(false), _is_global_pooling(false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000959 {
960 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100961 /** Default Constructor
962 *
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000963 * @param[in] pool_type Pooling type @ref PoolingType.
964 * @param[in] pool_size Pooling size, in elements, across x and y.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100965 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
Georgios Pinitasadaae7e2017-10-30 15:56:32 +0000966 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
967 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
968 * Defaults to false;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100969 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000970 explicit PoolingLayerInfo(PoolingType pool_type,
971 unsigned int pool_size,
972 PadStrideInfo pad_stride_info = PadStrideInfo(),
973 bool exclude_padding = false)
Isabella Gottardi6e464c32018-01-26 12:32:45 +0000974 : _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)
975 {
976 }
977 /** Default Constructor
978 *
979 * @param[in] pool_type Pooling type @ref PoolingType.
980 * @param[in] pool_size Pooling size, in elements, across x and y.
981 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
982 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
983 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
984 * Defaults to false;
985 */
986 explicit PoolingLayerInfo(PoolingType pool_type,
987 Size2D pool_size,
988 PadStrideInfo pad_stride_info = PadStrideInfo(),
989 bool exclude_padding = false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000990 : _pool_type(pool_type), _pool_size(pool_size), _pad_stride_info(pad_stride_info), _exclude_padding(exclude_padding), _is_global_pooling(false)
991 {
992 }
993 /** Default Constructor
994 *
995 * @note This constructor is used for global pooling
996 *
997 * @param[in] pool_type Pooling type @ref PoolingType.
998 */
999 explicit PoolingLayerInfo(PoolingType pool_type)
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001000 : _pool_type(pool_type), _pool_size(Size2D()), _pad_stride_info(PadStrideInfo(1, 1, 0, 0)), _exclude_padding(false), _is_global_pooling(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001001 {
1002 }
Alex Gildayc357c472018-03-21 13:54:09 +00001003 /** Get the pooling type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001004 PoolingType pool_type() const
1005 {
1006 return _pool_type;
1007 }
Alex Gildayc357c472018-03-21 13:54:09 +00001008 /** Get the pooling size */
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001009 const Size2D &pool_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001010 {
1011 return _pool_size;
1012 }
Alex Gildayc357c472018-03-21 13:54:09 +00001013 /** Get the padding and stride */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001014 PadStrideInfo pad_stride_info() const
1015 {
1016 return _pad_stride_info;
1017 }
Alex Gildayc357c472018-03-21 13:54:09 +00001018 /** Check if padding is excluded in calculations */
Georgios Pinitasadaae7e2017-10-30 15:56:32 +00001019 bool exclude_padding() const
1020 {
1021 return _exclude_padding;
1022 }
Alex Gildayc357c472018-03-21 13:54:09 +00001023 /** Check if is global pooling */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001024 bool is_global_pooling() const
1025 {
1026 return _is_global_pooling;
1027 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001028
1029private:
1030 PoolingType _pool_type;
Isabella Gottardi6e464c32018-01-26 12:32:45 +00001031 Size2D _pool_size;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001032 PadStrideInfo _pad_stride_info;
Georgios Pinitasadaae7e2017-10-30 15:56:32 +00001033 bool _exclude_padding;
Georgios Pinitas4c2dd542017-11-13 12:58:41 +00001034 bool _is_global_pooling;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001035};
1036
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001037/** ROI Pooling Layer Information class */
giuros0118870812018-09-13 09:31:40 +01001038class ROIPoolingLayerInfo final
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001039{
1040public:
giuros0118870812018-09-13 09:31:40 +01001041 /** Constructor
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001042 *
giuros0118870812018-09-13 09:31:40 +01001043 * @param[in] pooled_width Pooled width of the layer.
1044 * @param[in] pooled_height Pooled height of the layer.
1045 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
1046 * @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 +01001047 */
giuros0118870812018-09-13 09:31:40 +01001048 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale, unsigned int sampling_ratio = 0)
1049 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale), _sampling_ratio(sampling_ratio)
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001050 {
1051 }
Alex Gildayc357c472018-03-21 13:54:09 +00001052 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001053 unsigned int pooled_width() const
1054 {
1055 return _pooled_width;
1056 }
Alex Gildayc357c472018-03-21 13:54:09 +00001057 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001058 unsigned int pooled_height() const
1059 {
1060 return _pooled_height;
1061 }
Alex Gildayc357c472018-03-21 13:54:09 +00001062 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001063 float spatial_scale() const
1064 {
1065 return _spatial_scale;
1066 }
giuros0118870812018-09-13 09:31:40 +01001067 /** Get sampling ratio */
1068 unsigned int sampling_ratio() const
1069 {
1070 return _sampling_ratio;
1071 }
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001072
1073private:
1074 unsigned int _pooled_width;
1075 unsigned int _pooled_height;
1076 float _spatial_scale;
giuros0118870812018-09-13 09:31:40 +01001077 unsigned int _sampling_ratio;
Georgios Pinitas7b7858d2017-06-21 16:44:24 +01001078};
1079
giuros01cd96a262018-10-03 12:44:35 +01001080/** Generate Proposals Information class */
1081class GenerateProposalsInfo
1082{
1083public:
1084 /** Constructor
1085 *
1086 * @param[in] im_width Width of the original image
1087 * @param[in] im_height Height of the original image
1088 * @param[in] im_scale Scale applied to the original image
1089 * @param[in] spatial_scale (Optional)Scale applied to the feature map. Defaults to 1.0
1090 * @param[in] pre_nms_topN (Optional)Number of the best scores to be selected from the transformations. Defaults to 6000.
1091 * @param[in] post_nms_topN (Optional)Number of the best scores to be selected from the NMS operation. Defaults to 300.
1092 * @param[in] nms_thres (Optional)NMS overlap threshold. Defaults to 0.7.
1093 * @param[in] min_size (Optional)Size used to validate the anchors produced. Defaults to 16.
1094 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region of interest). Defaults to 4.
1095 */
1096 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,
1097 size_t values_per_roi = 4)
1098 : _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),
1099 _min_size(min_size), _values_per_roi(values_per_roi)
1100 {
1101 }
1102
1103 /* Get the original height */
1104 float im_height() const
1105 {
1106 return _im_height;
1107 }
1108 /* Get the original width */
1109 float im_width() const
1110 {
1111 return _im_width;
1112 }
1113 /* Get the image scale */
1114 float im_scale() const
1115 {
1116 return _im_scale;
1117 }
1118 /* Get the value of how many best scores to select (before NMS) */
1119 int pre_nms_topN() const
1120 {
1121 return _pre_nms_topN;
1122 }
1123 /* Get the value of how many best scores to select (after NMS) */
1124 int post_nms_topN() const
1125 {
1126 return _post_nms_topN;
1127 }
1128 /* Get the NMS overlap threshold */
1129 float nms_thres() const
1130 {
1131 return _nms_thres;
1132 }
1133 /* Get the minimal size */
1134 float min_size() const
1135 {
1136 return _min_size;
1137 }
1138 /* Get the spatial scale to be applied to the feature maps */
1139 float spatial_scale() const
1140 {
1141 return _spatial_scale;
1142 }
1143 /* Get the values used to represent a ROI(Region of interest)*/
1144 size_t values_per_roi() const
1145 {
1146 return _values_per_roi;
1147 }
1148
1149private:
1150 float _im_height;
1151 float _im_width;
1152 float _im_scale;
1153 float _spatial_scale;
1154 int _pre_nms_topN;
1155 int _post_nms_topN;
1156 float _nms_thres;
1157 float _min_size;
1158 size_t _values_per_roi;
1159};
1160
1161/** ComputeAnchors information class */
1162class ComputeAnchorsInfo
1163{
1164public:
1165 /** Constructor
1166 *
1167 * @param[in] feat_width Feature map width
1168 * @param[in] feat_height Feature map height
1169 * @param[in] spatial_scale Feature map scale
1170 * @param[in] values_per_roi (Optional)Values used to represent a ROI(Region Of Interest). Defaults to 4
1171 */
1172 ComputeAnchorsInfo(float feat_width, float feat_height, float spatial_scale, size_t values_per_roi = 4)
1173 : _feat_height(feat_height),
1174 _feat_width(feat_width),
1175 _spatial_scale(spatial_scale),
1176 _values_per_roi(values_per_roi)
1177 {
1178 }
1179
1180 /* Get the height of the feature map */
1181 float feat_height() const
1182 {
1183 return _feat_height;
1184 }
1185
1186 /* Get the width of the feature map */
1187 float feat_width() const
1188 {
1189 return _feat_width;
1190 }
1191
1192 /* Get the scale of the feature map */
1193 float spatial_scale() const
1194 {
1195 return _spatial_scale;
1196 }
1197
1198 /* Get the values used to represent a ROI(Region Of Interest)*/
1199 size_t values_per_roi() const
1200 {
1201 return _values_per_roi;
1202 }
1203
1204private:
1205 float _feat_height;
1206 float _feat_width;
1207 float _spatial_scale;
1208 size_t _values_per_roi;
1209};
1210
giuros01c04a0e82018-10-03 12:44:35 +01001211/** Bounding Box Transform information class */
giuros01d696cb62018-11-16 10:39:59 +00001212class BoundingBoxTransformInfo final
giuros01c04a0e82018-10-03 12:44:35 +01001213{
1214public:
1215 /** Constructor
1216 *
giuros01d696cb62018-11-16 10:39:59 +00001217 * @param[in] img_width Width of the original image
1218 * @param[in] img_height Height, of the original image
1219 * @param[in] scale Scale of the original image
1220 * @param[in] apply_scale (Optional)Re-apply scaling after transforming the boxes. Defaults to false
1221 * @param[in] weights (Optional)Weights [wx, wy, ww, wh] for the deltas. Defaults to all ones
1222 * @param[in] correct_transform_coords (Optional)Correct bounding box transform coordinates. Defaults to false
1223 * @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 +01001224 */
giuros01d696cb62018-11-16 10:39:59 +00001225 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 =
1226 false,
1227 float bbox_xform_clip =
1228 4.135166556742356f)
1229 : _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 +01001230 {
1231 }
1232
1233 std::array<float, 4> weights() const
1234 {
1235 return _weights;
1236 }
1237
1238 float bbox_xform_clip() const
1239 {
1240 return _bbox_xform_clip;
1241 }
1242
1243 float img_height() const
1244 {
1245 return _img_height;
1246 }
1247
1248 float img_width() const
1249 {
1250 return _img_width;
1251 }
1252
1253 float scale() const
1254 {
1255 return _scale;
1256 }
1257
1258 bool apply_scale() const
1259 {
1260 return _apply_scale;
1261 }
1262
giuros01d696cb62018-11-16 10:39:59 +00001263 bool correct_transform_coords() const
1264 {
1265 return _correct_transform_coords;
1266 }
1267
giuros01c04a0e82018-10-03 12:44:35 +01001268private:
1269 float _img_width;
1270 float _img_height;
1271 float _scale;
1272 bool _apply_scale;
giuros01d696cb62018-11-16 10:39:59 +00001273 bool _correct_transform_coords;
giuros01c04a0e82018-10-03 12:44:35 +01001274 std::array<float, 4> _weights;
1275 float _bbox_xform_clip;
1276};
1277
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001278/** Activation Layer Information class */
1279class ActivationLayerInfo
1280{
1281public:
1282 /** Available activation functions */
1283 enum class ActivationFunction
1284 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001285 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
1286 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
1287 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
1288 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
1289 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
1290 LEAKY_RELU, /**< Leaky Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
1291 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
1292 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
1293 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
1294 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
1295 LINEAR /**< Linear ( \f$ f(x)= ax + b \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001296 };
1297
Giorgio Arena11674872018-02-07 15:38:12 +00001298 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001299 /** Default Constructor
1300 *
1301 * @param[in] f The activation function to use.
1302 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +01001303 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
1304 * @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 +01001305 */
1306 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +00001307 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001308 {
1309 }
Alex Gildayc357c472018-03-21 13:54:09 +00001310 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001311 ActivationFunction activation() const
1312 {
1313 return _act;
1314 }
Alex Gildayc357c472018-03-21 13:54:09 +00001315 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001316 float a() const
1317 {
1318 return _a;
1319 }
Alex Gildayc357c472018-03-21 13:54:09 +00001320 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001321 float b() const
1322 {
1323 return _b;
1324 }
Alex Gildayc357c472018-03-21 13:54:09 +00001325 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +00001326 bool enabled() const
1327 {
1328 return _enabled;
1329 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001330
1331private:
Giorgio Arena11674872018-02-07 15:38:12 +00001332 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::LOGISTIC };
1333 float _a = {};
1334 float _b = {};
1335 bool _enabled = { false };
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001336};
1337
1338/** Normalization Layer Information class */
1339class NormalizationLayerInfo
1340{
1341public:
1342 /** Default Constructor
1343 *
1344 * @param[in] type The normalization type. Can be @ref NormType::IN_MAP_1D, @ref NormType::IN_MAP_2D or @ref NORM_TYPE::CROSS_MAP
1345 * @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 +00001346 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
1347 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
1348 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
1349 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
1350 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001351 */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001352 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
1353 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001354 {
1355 }
Alex Gildayc357c472018-03-21 13:54:09 +00001356 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001357 NormType type() const
1358 {
1359 return _type;
1360 }
Alex Gildayc357c472018-03-21 13:54:09 +00001361 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001362 uint32_t norm_size() const
1363 {
1364 return _norm_size;
1365 }
Alex Gildayc357c472018-03-21 13:54:09 +00001366 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001367 float alpha() const
1368 {
1369 return _alpha;
1370 }
Alex Gildayc357c472018-03-21 13:54:09 +00001371 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001372 float beta() const
1373 {
1374 return _beta;
1375 }
Alex Gildayc357c472018-03-21 13:54:09 +00001376 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001377 float kappa() const
1378 {
1379 return _kappa;
1380 }
Alex Gildayc357c472018-03-21 13:54:09 +00001381 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001382 bool is_cross_map() const
1383 {
1384 return _type == NormType::CROSS_MAP;
1385 }
Alex Gildayc357c472018-03-21 13:54:09 +00001386 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +00001387 bool is_in_map() const
1388 {
1389 return !is_cross_map();
1390 }
1391 /** Return the scaling factor of the normalization function.
1392 *
1393 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
1394 * 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 +01001395 *
1396 * @return The normalization scaling factor.
1397 */
1398 float scale_coeff() const
1399 {
1400 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001401 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001402 }
1403
1404private:
1405 NormType _type;
1406 uint32_t _norm_size;
1407 float _alpha;
1408 float _beta;
1409 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +00001410 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001411};
1412
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001413/** 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 +01001414class WeightsInfo
1415{
1416public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001417 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001418 WeightsInfo()
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001419 : _are_reshaped(false), _kernel_width(0), _kernel_height(0), _num_kernels(0), _retain_internal_weights(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001420 {
1421 }
1422 /** Constructor
1423 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001424 * @param[in] are_reshaped True if the weights have been reshaped
1425 * @param[in] kernel_width Kernel width.
1426 * @param[in] kernel_height Kernel height.
1427 * @param[in] num_kernels Number of convolution kernels.
1428 * @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 +01001429 */
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001430 WeightsInfo(bool are_reshaped, unsigned int kernel_width, unsigned int kernel_height, unsigned int num_kernels, bool retain_internal_weights = false)
1431 : _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 +01001432 {
1433 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001434 /** Flag which specifies if the weights tensor has been reshaped.
1435 *
1436 * @return True if the weights tensors has been reshaped
1437 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001438 bool are_reshaped() const
1439 {
1440 return _are_reshaped;
1441 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001442 /** Return the number of convolution kernels
1443 *
1444 * @return The number of convolution kernels
1445 */
1446 unsigned int num_kernels() const
1447 {
1448 return _num_kernels;
1449 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001450 /** Return the width and height of the kernel
1451 *
1452 * @return The width and height of the kernel
1453 */
1454 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001455 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001456 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001457 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001458 bool retain_internal_weights() const
1459 {
1460 return _retain_internal_weights;
1461 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001462
1463private:
1464 const bool _are_reshaped;
Gian Marco Iodice4e288692017-06-27 11:41:59 +01001465 const unsigned int _kernel_width;
1466 const unsigned int _kernel_height;
Gian Marco Iodice559d7712017-08-08 08:38:09 +01001467 const unsigned int _num_kernels;
Michele Di Giorgiob62280a2018-05-31 17:31:05 +01001468 const bool _retain_internal_weights;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001469};
1470
Gian Marco36a0a462018-01-12 10:21:40 +00001471/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
1472 *
1473 * The matrix A can only be reshaped through @ref CLGEMMInterleave4x4Kernel or @ref NEGEMMInterleave4x4Kernel or @ref GCGEMMInterleave4x4Kernel
1474 * Note: Optionally just for @ref CLGEMMInterleave4x4Kernel is it possible to set mult_interleave4x4_height, the multiplication factor for the height of the 4x4 interleaved block
1475 *
1476 * The matrix B can only be reshaped through @ref CLGEMMTranspose1xWKernel or @ref NEGEMMTranspose1xWKernel or @ref GCGEMMTranspose1xWKernel
1477 * Note: Optionally just for @ref CLGEMMTranspose1xWKernel is it possible to set mult_transpose1xW_width, the multiplication factor for the width of the 1xW transposed block
1478 *
1479 */
1480class GEMMReshapeInfo final
1481{
1482public:
1483 /** Default constructor */
1484 GEMMReshapeInfo()
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001485 : _m(1), _n(1), _k(1), _mult_transpose1xW_width(1), _mult_interleave4x4_height(1), _depth_output_gemm3d(0), _reinterpret_input_as_3d(false)
Gian Marco36a0a462018-01-12 10:21:40 +00001486 {
1487 }
1488 /** Constructor
1489 *
1490 * @param[in] m Number of matrix A rows
1491 * @param[in] n Number of matrix B columns
1492 * @param[in] k Number of matrix A columns or matrix B rows
1493 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
1494 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001495 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel.
1496 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001497 * @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
1498 * to perform 1x1 convolutions with the NHWC data layout)
Gian Marco36a0a462018-01-12 10:21:40 +00001499 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001500 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)
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001501 : _m(m), _n(n), _k(k), _mult_transpose1xW_width(mult_transpose1xW_width), _mult_interleave4x4_height(mult_interleave4x4_height), _depth_output_gemm3d(depth_output_gemm3d),
1502 _reinterpret_input_as_3d(reinterpret_input_as_3d)
Gian Marco36a0a462018-01-12 10:21:40 +00001503 {
1504 }
1505 /** Number of matrix A rows
1506 *
1507 * @return the number of matrix A rows
1508 */
1509 int m() const
1510 {
1511 return _m;
1512 }
1513 /** Number of matrix B columns
1514 *
1515 * @return the number of matrix B columns
1516 */
1517 int n() const
1518 {
1519 return _n;
1520 }
1521 /** Number of matrix A columns or matrix B rows
1522 *
1523 * @return the number of matrix A columns or matrix B rows
1524 */
1525 int k() const
1526 {
1527 return _k;
1528 }
1529 /** Multiplication factor for the width of the 1xW transposed block
1530 *
1531 * @return the multiplication factor for the width of the 1xW transposed block
1532 */
1533 int mult_transpose1xW_width() const
1534 {
1535 return _mult_transpose1xW_width;
1536 }
1537 /** Multiplication factor for the height of the 4x4 interleaved block
1538 *
1539 * @return the multiplication factor for the height of the 4x4 interleaved block
1540 */
1541 int mult_interleave4x4_height() const
1542 {
1543 return _mult_interleave4x4_height;
1544 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001545 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
1546 *
1547 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
1548 * m = depth_output_gemm3d * output_height
1549 *
1550 * @return the depth of the output tensor to be used with the GEMM3D kernel
1551 */
1552 int depth_output_gemm3d() const
1553 {
1554 return _depth_output_gemm3d;
1555 }
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001556 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
1557 *
1558 * @return True if the input tensor has to be reinterpreted as 3D tensor
1559 */
1560 bool reinterpret_input_as_3d() const
1561 {
1562 return _reinterpret_input_as_3d;
1563 };
Gian Marco36a0a462018-01-12 10:21:40 +00001564
1565private:
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001566 const int _m;
1567 const int _n;
1568 const int _k;
1569 const int _mult_transpose1xW_width;
1570 const int _mult_interleave4x4_height;
1571 const int _depth_output_gemm3d;
1572 const bool _reinterpret_input_as_3d;
Gian Marco36a0a462018-01-12 10:21:40 +00001573};
1574
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001575/** GEMMLowp output stage type */
1576enum class GEMMLowpOutputStageType
1577{
1578 NONE, /**< No quantization to uint8 */
1579 QUANTIZE_DOWN, /**< Quantize to uint8 using an integer multiplication */
1580 QUANTIZE_DOWN_FIXEDPOINT, /**< Quantize to uint8 using a fixed point multiplication */
1581 QUANTIZE_DOWN_FLOAT /**< Quantize to uint8 using a floating point multiplication */
1582};
1583
1584/** GEMMLowp output stage info */
1585struct GEMMLowpOutputStageInfo
1586{
1587 GEMMLowpOutputStageType type{ GEMMLowpOutputStageType::NONE }; /**< GEMMLowp output stage type */
1588 int gemmlowp_offset{ 0 }; /**< GEMMLowp output stage offset used for quantizing to QASYMM8 */
1589 int gemmlowp_multiplier{ 0 }; /**< GEMMLowp output stage multiplier used for quantizing to QASYMM8 */
1590 int gemmlowp_shift{ 0 }; /**< GEMMLowp output stage shift used for quantizing to uint8 */
1591 int gemmlowp_min_bound{ 0 }; /**< GEMMLowp min value used to saturate down the output result before converting back to QASYMM8 */
1592 int gemmlowp_max_bound{ 0 }; /**< GEMMLowp max value used to saturate down the output result before converting back to QASYMM8 */
1593};
1594
Gian Marco36a0a462018-01-12 10:21:40 +00001595/** GEMM information class. This class stores the necessary information to compute GEMM functions
1596 *
1597 * This object also contains the information about how matrix A and matrix B have been reshaped
1598 *
1599 */
Chunosov5124be52017-11-22 20:42:13 +07001600class GEMMInfo
1601{
1602public:
1603 /** Default constructor */
1604 GEMMInfo()
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001605 : _is_a_reshaped(false), _is_b_reshaped(false), _reshape_b_only_on_first_run(false), _depth_output_gemm3d(0), _reinterpret_input_as_3d(false), _retain_internal_weights(false),
1606 _gemmlowp_output_stage(), _fp_mixed_precision(false)
Chunosov5124be52017-11-22 20:42:13 +07001607 {
1608 }
1609 /** Constructor
1610 *
1611 * @param[in] is_a_reshaped True if the matrix A has been reshaped
1612 * @param[in] is_b_reshaped True if the matrix B has been reshaped
1613 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001614 * @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 +00001615 * If 0 the output will not be reinterpreted as 3D. Default 0
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001616 * @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
1617 * to perform 1x1 convolutions with the NHWC data layout)
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01001618 * @param[in] retain_internal_weights (Optional) Retain the weights tensor from previous run
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001619 * @param[in] gemmlowp_output_stage (Optional) GEMMLowp Output stage info
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001620 * @param[in] fp_mixed_precision (Optional) Use wider accumulators (32 bit instead of 16 for FP16) to improve accuracy.
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001621 *
Chunosov5124be52017-11-22 20:42:13 +07001622 */
Gian Marco Iodice3139f032018-11-05 14:26:32 +00001623 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,
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001624 GEMMLowpOutputStageInfo gemmlowp_output_stage = GEMMLowpOutputStageInfo(), bool fp_mixed_precision = false)
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001625 : _is_a_reshaped(is_a_reshaped), _is_b_reshaped(is_b_reshaped), _reshape_b_only_on_first_run(reshape_b_only_on_first_run), _depth_output_gemm3d(depth_output_gemm3d),
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001626 _reinterpret_input_as_3d(reinterpret_input_as_3d), _retain_internal_weights(retain_internal_weights), _gemmlowp_output_stage(gemmlowp_output_stage), _fp_mixed_precision(fp_mixed_precision)
Chunosov5124be52017-11-22 20:42:13 +07001627 {
1628 }
1629 /** Flag which specifies if the matrix A has been reshaped
1630 *
1631 * @return True if the matrix A has been reshaped
1632 */
1633 bool is_a_reshaped() const
1634 {
1635 return _is_a_reshaped;
1636 };
1637 /** Flag which specifies if the matrix B has been reshaped
1638 *
1639 * @return True if the matrix B has been reshaped
1640 */
1641 bool is_b_reshaped() const
1642 {
1643 return _is_b_reshaped;
1644 };
1645 /** Flag which specifies if the reshape of matrix B should executed only for the first
1646 *
1647 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
1648 *
1649 * @return True if the reshaped of matrix B happens only for the first run
1650 */
1651 bool reshape_b_only_on_first_run() const
1652 {
1653 return _reshape_b_only_on_first_run;
1654 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001655 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00001656 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001657 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00001658 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001659 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00001660 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001661 return _depth_output_gemm3d;
1662 };
Gian Marco Iodice68a3f562018-07-26 11:44:03 +01001663 /** Flag which specifies if the input tensor has to be reinterpreted as 3D
1664 *
1665 * @return True if the input tensor has to be reinterpreted as 3D tensor
1666 */
1667 bool reinterpret_input_as_3d() const
1668 {
1669 return _reinterpret_input_as_3d;
1670 };
Michele Di Giorgioba1ffe92018-08-22 14:28:30 +01001671 /** Flag which specifies if the weights tensor has to be retained from previous run
1672 *
1673 * @return True if the weights tensor has to be retained
1674 */
1675 bool retain_internal_weights() const
1676 {
1677 return _retain_internal_weights;
1678 };
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001679 /** GEMMLowp output stage
1680 *
1681 * @return the GEMMLowp output stage info
1682 */
1683 GEMMLowpOutputStageInfo gemmlowp_output_stage() const
1684 {
1685 return _gemmlowp_output_stage;
1686 };
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001687 /** Flag which specifies if a wider accumulator should be used.
1688 *
1689 * @return True if a wider accumulator has to be used
1690 */
1691 bool fp_mixed_precision() const
1692 {
1693 return _fp_mixed_precision;
1694 };
Chunosov5124be52017-11-22 20:42:13 +07001695
1696private:
Gian Marco Iodice4b908652018-10-18 10:21:02 +01001697 const bool _is_a_reshaped;
1698 const bool _is_b_reshaped;
1699 const bool _reshape_b_only_on_first_run;
1700 const int _depth_output_gemm3d;
1701 const bool _reinterpret_input_as_3d;
1702 const bool _retain_internal_weights;
1703 const GEMMLowpOutputStageInfo _gemmlowp_output_stage;
Vidhya Sudhan Loganathana25d16c2018-11-16 11:33:12 +00001704 const bool _fp_mixed_precision;
Chunosov5124be52017-11-22 20:42:13 +07001705};
1706
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00001707/** Winograd information */
1708struct WinogradInfo
1709{
1710 /** Default constructor
1711 *
1712 * @param[in] output_tile_sz Width and height of the output tile
1713 * @param[in] kernel_sz Width and height of the kernel
1714 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
1715 * @param[in] conv_info Convolution info (Pads, strides)
1716 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
1717 */
1718 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
1719 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
1720 {
1721 }
1722
1723 Size2D output_tile_size{}; /**< Width and height of the output tile */
1724 Size2D kernel_size{}; /**< Width and height of the kernel*/
1725 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
1726 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
1727 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
1728};
1729
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001730/** IO formatting information class*/
1731struct IOFormatInfo
1732{
1733 /** Precision type used when printing floating point numbers */
1734 enum class PrecisionType
1735 {
1736 Default, /**< Default precision to the one that the current stream has */
1737 Custom, /**< Custom precision specified by the user using the precision parameter */
1738 Full /**< The maximum precision of the floating point representation */
1739 };
1740
1741 /** Specifies the area to be printed, used by Tensor objects */
1742 enum class PrintRegion
1743 {
1744 ValidRegion, /**< Prints the valid region of the Tensor object */
1745 NoPadding, /**< Prints the Tensor object without the padding */
1746 Full /**< Print the tensor object including padding */
1747 };
1748
Alex Gildayc357c472018-03-21 13:54:09 +00001749 /** Construct a set of IO formatting information.
1750 *
1751 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
1752 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
1753 * @param[in] precision Precision value for float point numbers. Default: 10.
1754 * @param[in] align_columns Whether to align columns when printed. Default: true.
1755 * @param[in] element_delim Delimeter between elements. Default: " ".
1756 * @param[in] row_delim Delimenter between rows. Default: "\n".
1757 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001758 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
1759 PrecisionType precision_type = PrecisionType::Default,
1760 unsigned int precision = 10,
1761 bool align_columns = true,
1762 std::string element_delim = " ",
1763 std::string row_delim = "\n")
1764 : print_region(print_region),
1765 precision_type(precision_type),
1766 precision(precision),
1767 element_delim(element_delim),
1768 row_delim(row_delim),
1769 align_columns(align_columns)
1770 {
1771 }
1772
Alex Gildayc357c472018-03-21 13:54:09 +00001773 /** Area to be printed by Tensor objects */
1774 PrintRegion print_region;
1775 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001776 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00001777 /** Floating point precision */
1778 unsigned int precision;
1779 /** Element delimeter */
1780 std::string element_delim;
1781 /** Row delimeter */
1782 std::string row_delim;
1783 /** Align columns */
1784 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001785};
Isabella Gottardif07d28d2018-02-06 14:52:43 +00001786
1787/** Available ConvolutionMethod*/
1788enum class ConvolutionMethod
1789{
1790 GEMM, /**< Convolution using GEMM */
1791 DIRECT, /**< Direct convolution */
1792 WINOGRAD /**< Convolution using Winograd */
1793};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00001794} // namespace arm_compute
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001795#endif /* __ARM_COMPUTE_TYPES_H__ */