blob: da28e131deba60fc5f2bc500f4bc33ec8e27f75e [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;
48
Anthony Barbier6ff3b192017-09-04 18:44:23 +010049/** Image colour formats */
50enum class Format
51{
Daniil Efremov02bf80d2017-11-22 00:26:51 +070052 UNKNOWN, /**< Unknown image format */
53 U8, /**< 1 channel, 1 U8 per channel */
54 S16, /**< 1 channel, 1 S16 per channel */
55 U16, /**< 1 channel, 1 U16 per channel */
56 S32, /**< 1 channel, 1 S32 per channel */
57 U32, /**< 1 channel, 1 U32 per channel */
58 F16, /**< 1 channel, 1 F16 per channel */
59 F32, /**< 1 channel, 1 F32 per channel */
60 UV88, /**< 2 channel, 1 U8 per channel */
61 RGB888, /**< 3 channels, 1 U8 per channel */
62 RGBA8888, /**< 4 channels, 1 U8 per channel */
63 YUV444, /**< A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes */
64 YUYV422, /**< A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes */
65 NV12, /**< A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling */
66 NV21, /**< A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling */
67 IYUV, /**< A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes */
68 UYVY422 /**< A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010069};
70
71/** Available data types */
72enum class DataType
73{
Alex Gildayc357c472018-03-21 13:54:09 +000074 UNKNOWN, /**< Unknown data type */
75 U8, /**< unsigned 8-bit number */
76 S8, /**< signed 8-bit number */
77 QS8, /**< quantized, symmetric fixed-point 8-bit number */
78 QASYMM8, /**< quantized, asymmetric fixed-point 8-bit number */
79 U16, /**< unsigned 16-bit number */
80 S16, /**< signed 16-bit number */
81 QS16, /**< quantized, symmetric fixed-point 16-bit number */
82 U32, /**< unsigned 32-bit number */
83 S32, /**< signed 32-bit number */
84 QS32, /**< quantized, symmetric fixed-point 32-bit number */
85 U64, /**< unsigned 64-bit number */
86 S64, /**< signed 64-bit number */
87 F16, /**< 16-bit floating-point number */
88 F32, /**< 32-bit floating-point number */
89 F64, /**< 64-bit floating-point number */
90 SIZET /**< size_t */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010091};
92
Daniil Efremov02bf80d2017-11-22 00:26:51 +070093/** Available Sampling Policies */
94enum class SamplingPolicy
95{
96 CENTER, /**< Samples are taken at pixel center */
97 TOP_LEFT /**< Samples are taken at pixel top left corner */
98};
99
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100100/** Constant value of the border pixels when using BorderMode::CONSTANT */
101constexpr uint8_t CONSTANT_BORDER_VALUE = 199;
102
Alex Gildayc357c472018-03-21 13:54:09 +0000103/** Constant value used to indicate a half-scale pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100104constexpr float SCALE_PYRAMID_HALF = 0.5f;
105
Alex Gildayc357c472018-03-21 13:54:09 +0000106/** Constant value used to indicate a ORB scaled pyramid */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100107constexpr float SCALE_PYRAMID_ORB = 8.408964152537146130583778358414e-01;
108
Georgios Pinitas4074c992018-01-30 18:13:46 +0000109/** Supported tensor data layouts */
110enum class DataLayout
111{
Alex Gildayc357c472018-03-21 13:54:09 +0000112 UNKNOWN, /**< Unknown data layout */
113 NCHW, /**< Num samples, channels, height, width */
114 NHWC /**< Num samples, height, width, channels */
Georgios Pinitas4074c992018-01-30 18:13:46 +0000115};
116
Isabella Gottardid17a6772018-02-27 17:41:55 +0000117/** Supported tensor data layout dimensions */
118enum class DataLayoutDimension
119{
Alex Gildayc357c472018-03-21 13:54:09 +0000120 CHANNEL, /**< channel */
121 HEIGHT, /**< height */
122 WIDTH, /**< width */
123 BATCHES /**< batches */
Isabella Gottardid17a6772018-02-27 17:41:55 +0000124};
125
Michel Iwaniec00633802017-10-12 14:14:15 +0100126/** Quantization settings (used for QASYMM8 data type) */
127struct QuantizationInfo
128{
Alex Gildayc357c472018-03-21 13:54:09 +0000129 /** Default constructor */
Georgios Pinitasf8d8f3a2018-06-06 17:57:04 +0100130 QuantizationInfo() noexcept
131 : scale(0.0f),
132 offset(0)
Michel Iwaniec00633802017-10-12 14:14:15 +0100133 {
134 }
135
Alex Gildayc357c472018-03-21 13:54:09 +0000136 /** Construct quantization info.
137 *
138 * @param[in] scale Scale.
139 * @param[in] offset Offset.
140 */
Michel Iwaniec00633802017-10-12 14:14:15 +0100141 QuantizationInfo(float scale, int offset)
142 : scale(scale), offset(offset)
143 {
144 }
145
Alex Gildayc357c472018-03-21 13:54:09 +0000146 /** Check whether equal to a given quantization info.
147 *
148 * @param[in] other Other quantization info.
149 *
150 * @return True if the given quantization info is the same.
151 */
Daniil Efremoveed841c2017-11-09 19:05:25 +0700152 bool operator==(const QuantizationInfo &other)
153 {
154 return scale == other.scale && offset == other.offset;
155 }
156
Alex Gildayc357c472018-03-21 13:54:09 +0000157 /** Check whether not equal to a given quantization info.
158 *
159 * @param[in] other Other quantization info.
160 *
161 * @return True if the given quantization info is not the same.
162 */
Daniil Efremoveed841c2017-11-09 19:05:25 +0700163 bool operator!=(const QuantizationInfo &other)
164 {
165 return !(*this == other);
166 }
167
Michel Iwaniec00633802017-10-12 14:14:15 +0100168 float scale; /**< scale */
169 int offset; /**< offset */
170
Alex Gildayc357c472018-03-21 13:54:09 +0000171 /** Quantizes a value using the scale/offset in this QuantizationInfo
172 *
173 * @param[in] value Value to quantize.
174 * @param[in] rounding_policy Policy to use when rounding.
175 *
176 * @return the quantized value.
177 */
Michel Iwaniec5dfeae62017-11-29 10:48:23 +0000178 qasymm8_t quantize(float value, RoundingPolicy rounding_policy) const
Michel Iwaniec00633802017-10-12 14:14:15 +0100179 {
180 ARM_COMPUTE_ERROR_ON_MSG(scale == 0, "QuantizationInfo::quantize: scale == 0");
Michel Iwaniec5dfeae62017-11-29 10:48:23 +0000181 return sqcvt_qasymm8_f32(value, scale, offset, rounding_policy);
Michel Iwaniec00633802017-10-12 14:14:15 +0100182 }
183
Alex Gildayc357c472018-03-21 13:54:09 +0000184 /** Dequantizes a value using the scale/offset in this QuantizationInfo
185 *
186 * @param[in] value Value to dequantize.
187 *
188 * @return the original value before quantization.
189 */
Michel Iwaniec5dfeae62017-11-29 10:48:23 +0000190 float dequantize(qasymm8_t value) const
Michel Iwaniec00633802017-10-12 14:14:15 +0100191 {
192 ARM_COMPUTE_ERROR_ON_MSG(scale == 0, "QuantizationInfo::dequantize: scale == 0");
Michel Iwaniec5dfeae62017-11-29 10:48:23 +0000193 return scvt_f32_qasymm8(value, scale, offset);
Michel Iwaniec00633802017-10-12 14:14:15 +0100194 }
195
Alex Gildayc357c472018-03-21 13:54:09 +0000196 /** Indicates whether this QuantizationInfo has valid settings or not
197 *
198 * @return True if the this has invalid settings.
199 */
Michel Iwaniec00633802017-10-12 14:14:15 +0100200 bool empty() const
201 {
202 return scale == 0;
203 }
204};
205
Alex Gildayc357c472018-03-21 13:54:09 +0000206/** Container for valid region of a window */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100207struct ValidRegion
208{
Alex Gildayc357c472018-03-21 13:54:09 +0000209 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100210 ValidRegion()
211 : anchor{}, shape{}
212 {
213 }
214
Alex Gildayc357c472018-03-21 13:54:09 +0000215 /** Allow instances of this class to be copy constructed */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100216 ValidRegion(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000217 /** Allow instances of this class to be move constructed */
218 ValidRegion(ValidRegion &&) = default;
219 /** Allow instances of this class to be copied */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100220 ValidRegion &operator=(const ValidRegion &) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000221 /** Allow instances of this class to be moved */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100222 ValidRegion &operator=(ValidRegion &&) = default;
Alex Gildayc357c472018-03-21 13:54:09 +0000223 /** Default destructor */
224 ~ValidRegion() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100225
Alex Gildayc357c472018-03-21 13:54:09 +0000226 /** Constructor for a valid region with default number of dimensions
227 *
228 * @param[in] an_anchor Anchor for the start of the valid region.
229 * @param[in] a_shape Shape of the valid region.
230 *
231 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000232 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape)
233 : anchor{ an_anchor }, shape{ a_shape }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100234 {
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000235 anchor.set_num_dimensions(std::max(anchor.num_dimensions(), shape.num_dimensions()));
236 }
237
Alex Gildayc357c472018-03-21 13:54:09 +0000238 /** Constructor for a valid region with specified number of dimensions
239 *
240 * @param[in] an_anchor Anchor for the start of the valid region.
241 * @param[in] a_shape Shape of the valid region.
242 * @param[in] num_dimensions Number of dimensions (must be >= number of dimensions of anchor and shape).
243 *
244 */
Diego Lopez Recasbcbc9702017-12-18 11:28:27 +0000245 ValidRegion(const Coordinates &an_anchor, const TensorShape &a_shape, size_t num_dimensions)
246 : anchor{ an_anchor }, shape{ a_shape }
247 {
248 ARM_COMPUTE_ERROR_ON(num_dimensions < std::max(anchor.num_dimensions(), shape.num_dimensions()));
249 anchor.set_num_dimensions(num_dimensions);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100250 }
251
252 /** Return the start of the valid region for the given dimension @p d */
253 int start(unsigned int d) const
254 {
255 return anchor[d];
256 }
257
258 /** Return the end of the valid region for the given dimension @p d */
259 int end(unsigned int d) const
260 {
261 return anchor[d] + shape[d];
262 }
263
Diego Lopez Recas35ceeb22017-12-04 18:56:10 +0000264 /** Accessor to set the value of anchor and shape for one of the dimensions.
265 *
266 * @param[in] dimension Dimension for which the value is set.
267 * @param[in] start Value to be set in anchor for the dimension.
268 * @param[in] size Value to be set in shape for the dimension.
269 *
270 * @return *this.
271 */
272 ValidRegion &set(size_t dimension, int start, size_t size)
273 {
274 anchor.set(dimension, start);
275 shape.set(dimension, size);
276 return *this;
277 }
278
Alex Gildayc357c472018-03-21 13:54:09 +0000279 Coordinates anchor; /**< Anchor for the start of the valid region. */
280 TensorShape shape; /**< Shape of the valid region. */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100281};
282
283/** Methods available to handle borders */
284enum class BorderMode
285{
286 UNDEFINED, /**< Borders are left undefined */
287 CONSTANT, /**< Pixels outside the image are assumed to have a constant value */
288 REPLICATE /**< Pixels outside the image are assumed to have the same value as the closest image pixel */
289};
290
291/** Container for 2D border size */
292struct BorderSize
293{
294 /** Empty border, i.e. no border */
295 constexpr BorderSize()
296 : top{ 0 }, right{ 0 }, bottom{ 0 }, left{ 0 }
297 {
298 }
299
300 /** Border with equal size around the 2D plane */
Moritz Pflanzer7655a672017-09-23 11:57:33 +0100301 explicit constexpr BorderSize(unsigned int size)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100302 : top{ size }, right{ size }, bottom{ size }, left{ size }
303 {
304 }
305
306 /** Border with same size for top/bottom and left/right */
307 constexpr BorderSize(unsigned int top_bottom, unsigned int left_right)
308 : top{ top_bottom }, right{ left_right }, bottom{ top_bottom }, left{ left_right }
309 {
310 }
311
312 /** Border with different sizes */
313 constexpr BorderSize(unsigned int top, unsigned int right, unsigned int bottom, unsigned int left)
314 : top{ top }, right{ right }, bottom{ bottom }, left{ left }
315 {
316 }
317
318 /** Check if the entire border is zero */
319 constexpr bool empty() const
320 {
321 return top == 0 && right == 0 && bottom == 0 && left == 0;
322 }
323
324 /** Check if the border is the same size on all sides */
325 constexpr bool uniform() const
326 {
327 return top == right && top == bottom && top == left;
328 }
329
Alex Gildayc357c472018-03-21 13:54:09 +0000330 /** Scale this border size.
331 *
332 * @param[in] scale Scale to multiply border size by.
333 *
334 * @return *this.
335 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100336 BorderSize &operator*=(float scale)
337 {
338 top *= scale;
339 right *= scale;
340 bottom *= scale;
341 left *= scale;
342
343 return *this;
344 }
345
Alex Gildayc357c472018-03-21 13:54:09 +0000346 /** Scale a copy of this border size.
347 *
348 * @param[in] scale Scale to multiply border size by.
349 *
350 * @return a scaled copy of this.
351 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100352 BorderSize operator*(float scale)
353 {
354 BorderSize size = *this;
355 size *= scale;
356
357 return size;
358 }
359
Alex Gildayc357c472018-03-21 13:54:09 +0000360 /** Limit this border size.
361 *
362 * @param[in] limit Border size to limit this border size to.
363 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100364 void limit(const BorderSize &limit)
365 {
366 top = std::min(top, limit.top);
367 right = std::min(right, limit.right);
368 bottom = std::min(bottom, limit.bottom);
369 left = std::min(left, limit.left);
370 }
371
Alex Gildayc357c472018-03-21 13:54:09 +0000372 unsigned int top; /**< top of the border */
373 unsigned int right; /**< right of the border */
374 unsigned int bottom; /**< bottom of the border */
375 unsigned int left; /**< left of the border */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100376};
377
Alex Gildayc357c472018-03-21 13:54:09 +0000378/** Container for 2D padding size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100379using PaddingSize = BorderSize;
380
381/** Policy to handle overflow */
382enum class ConvertPolicy
383{
384 WRAP, /**< Wrap around */
385 SATURATE /**< Saturate */
386};
387
388/** Interpolation method */
389enum class InterpolationPolicy
390{
391 NEAREST_NEIGHBOR, /**< Output values are defined to match the source pixel whose center is nearest to the sample position */
392 BILINEAR, /**< Output values are defined by bilinear interpolation between the pixels */
393 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 */
394};
395
396/** Bilinear Interpolation method used by LKTracker */
397enum class BilinearInterpolation
398{
Alex Gildayc357c472018-03-21 13:54:09 +0000399 BILINEAR_OLD_NEW, /**< Old-new method */
400 BILINEAR_SCHARR /**< Scharr method */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100401};
402
403/** Threshold mode */
404enum class ThresholdType
405{
406 BINARY, /**< Threshold with one value */
407 RANGE /**< Threshold with two values*/
408};
409
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100410/** Termination criteria */
411enum class Termination
412{
Alex Gildayc357c472018-03-21 13:54:09 +0000413 TERM_CRITERIA_EPSILON, /**< Terminate when within epsilon of a threshold */
414 TERM_CRITERIA_ITERATIONS, /**< Terminate after a maximum number of iterations */
415 TERM_CRITERIA_BOTH /**< Terminate on whichever of the other conditions occurs first */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100416};
417
418/** Magnitude calculation type. */
419enum class MagnitudeType
420{
421 L1NORM, /**< L1 normalization type */
422 L2NORM /**< L2 normalization type */
423};
424
425/** Phase calculation type.
426 *
427 * @note When PhaseType == SIGNED, each angle is mapped to the range 0 to 255 inclusive otherwise angles between 0 and 180
428 */
429enum class PhaseType
430{
431 SIGNED, /**< Angle range: [0, 360] */
432 UNSIGNED /**< Angle range: [0, 180] */
433};
434
435/** Keypoint type */
436struct KeyPoint
437{
438 int32_t x{ 0 }; /**< X coordinates */
439 int32_t y{ 0 }; /**< Y coordinates */
440 float strength{ 0.f }; /**< Strength of the point */
441 float scale{ 0.f }; /**< Scale initialized to 0 by the corner detector */
442 float orientation{ 0.f }; /**< Orientation initialized to 0 by the corner detector */
443 int32_t tracking_status{ 0 }; /**< Status initialized to 1 by the corner detector, set to 0 when the point is lost */
444 float error{ 0.f }; /**< Tracking error initialized to 0 by the corner detector */
445};
446
Alex Gildayc357c472018-03-21 13:54:09 +0000447/** Internal key point */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100448using InternalKeypoint = std::tuple<float, float, float>; /* x,y,strength */
449
450/** Rectangle type */
451struct Rectangle
452{
453 uint16_t x; /**< Top-left x coordinate */
454 uint16_t y; /**< Top-left y coordinate */
455 uint16_t width; /**< Width of the rectangle */
456 uint16_t height; /**< Height of the rectangle */
457};
458
459/** Coordinate type */
460struct Coordinates2D
461{
462 int32_t x; /**< X coordinates */
463 int32_t y; /**< Y coordinates */
464};
465
466/** Coordinate type */
467struct Coordinates3D
468{
469 uint32_t x; /**< X coordinates */
470 uint32_t y; /**< Y coordinates */
471 uint32_t z; /**< Z coordinates */
472};
473
Georgios Pinitas7b7858d2017-06-21 16:44:24 +0100474/** Region of interest */
475struct ROI
476{
477 Rectangle rect; /**< Rectangle specifying the region of interest */
478 uint16_t batch_idx; /**< The batch index of the region of interest */
479};
480
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100481/** Available channels */
482enum class Channel
483{
484 UNKNOWN, /** Unknown channel format */
485 C0, /**< First channel (used by formats with unknown channel types). */
486 C1, /**< Second channel (used by formats with unknown channel types). */
487 C2, /**< Third channel (used by formats with unknown channel types). */
488 C3, /**< Fourth channel (used by formats with unknown channel types). */
489 R, /**< Red channel. */
490 G, /**< Green channel. */
491 B, /**< Blue channel. */
492 A, /**< Alpha channel. */
493 Y, /**< Luma channel. */
494 U, /**< Cb/U channel. */
495 V /**< Cr/V/Value channel. */
496};
497
498/** Available matrix patterns */
499enum class MatrixPattern
500{
501 BOX, /**< Box pattern matrix. */
502 CROSS, /**< Cross pattern matrix. */
503 DISK, /**< Disk pattern matrix. */
504 OTHER /**< Any other matrix pattern. */
505};
506
507/** Available non linear functions. */
508enum class NonLinearFilterFunction : unsigned
509{
510 MEDIAN = 0, /**< Non linear median filter. */
511 MIN = 1, /**< Non linear erode. */
512 MAX = 2, /**< Non linear dilate. */
513};
514
Georgios Pinitasd9769582017-08-03 10:19:40 +0100515/** Available reduction operations */
516enum class ReductionOperation
517{
518 SUM_SQUARE, /**< Sum of squares */
Michalis Spyrou04f089c2017-08-08 17:42:38 +0100519 SUM, /**< Sum */
Georgios Pinitasd9769582017-08-03 10:19:40 +0100520};
521
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100522/** The normalization type used for the normalization layer */
523enum class NormType
524{
525 IN_MAP_1D, /**< Normalization applied within the same map in 1D region */
526 IN_MAP_2D, /**< Normalization applied within the same map in 2D region */
527 CROSS_MAP /**< Normalization applied cross maps */
528};
529
530/** Normalization type for Histogram of Oriented Gradients (HOG) */
531enum class HOGNormType
532{
533 L2_NORM = 1, /**< L2-norm */
534 L2HYS_NORM = 2, /**< L2-norm followed by clipping */
535 L1_NORM = 3 /**< L1 norm */
536};
537
538/** Detection window used for the object detection. The detection window keeps the following information:
539 *
540 * -# Geometry of the rectangular window (x/y of top-left corner and width/height)
541 * -# Index of the class used for evaluating which class the detection window belongs to
542 * -# Confidence value (score) obtained with the classifier
543 */
544struct DetectionWindow
545{
546 uint16_t x{ 0 }; /**< Top-left x coordinate */
547 uint16_t y{ 0 }; /**< Top-left y coordinate */
548 uint16_t width{ 0 }; /**< Width of the detection window */
549 uint16_t height{ 0 }; /**< Height of the detection window */
550 uint16_t idx_class{ 0 }; /**< Index of the class */
551 float score{ 0.f }; /**< Confidence value for the detection window */
552};
553
554/** Dimension rounding type when down-scaling on CNNs
555 * @note Used in pooling and convolution layer
556 */
557enum class DimensionRoundingType
558{
559 FLOOR, /**< Floor rounding */
560 CEIL /**< Ceil rounding */
561};
562
563/** Available pooling types */
564enum class PoolingType
565{
566 MAX, /**< Max Pooling */
Georgios Pinitascdf51452017-08-31 14:21:36 +0100567 AVG, /**< Average Pooling */
568 L2 /**< L2 Pooling */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100569};
570
571/** Padding and stride information class */
572class PadStrideInfo
573{
574public:
575 /** Constructor
576 *
577 * @param[in] stride_x (Optional) Stride, in elements, across x. Defaults to 1.
578 * @param[in] stride_y (Optional) Stride, in elements, across y. Defaults to 1.
579 * @param[in] pad_x (Optional) Padding, in elements, across x. Defaults to 0.
580 * @param[in] pad_y (Optional) Padding, in elements, across y. Defaults to 0.
581 * @param[in] round (Optional) Dimensions rounding. Defaults to @ref FLOOR.
582 */
583 PadStrideInfo(unsigned int stride_x = 1, unsigned int stride_y = 1,
584 unsigned int pad_x = 0, unsigned int pad_y = 0,
585 DimensionRoundingType round = DimensionRoundingType::FLOOR)
586 : _stride(std::make_pair(stride_x, stride_y)),
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100587 _pad_left(pad_x),
588 _pad_top(pad_y),
589 _pad_right(pad_x),
590 _pad_bottom(pad_y),
591 _round_type(round)
592 {
593 }
594 /** Constructor
595 *
596 * @param[in] stride_x Stride, in elements, across x.
597 * @param[in] stride_y Stride, in elements, across y.
598 * @param[in] pad_left Padding across x on the left, in elements.
599 * @param[in] pad_top Padding across y on the top, in elements.
600 * @param[in] pad_right Padding across x on the right, in elements.
601 * @param[in] pad_bottom Padding across y on the bottom, in elements.
602 * @param[in] round Dimensions rounding.
603 */
604 PadStrideInfo(unsigned int stride_x, unsigned int stride_y,
605 unsigned int pad_left, unsigned int pad_right,
606 unsigned int pad_top, unsigned int pad_bottom,
607 DimensionRoundingType round)
608 : _stride(std::make_pair(stride_x, stride_y)),
609 _pad_left(pad_left),
610 _pad_top(pad_top),
611 _pad_right(pad_right),
612 _pad_bottom(pad_bottom),
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100613 _round_type(round)
614 {
615 }
Alex Gildayc357c472018-03-21 13:54:09 +0000616 /** Get the stride.
617 *
618 * @return a pair: stride x, stride y.
619 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100620 std::pair<unsigned int, unsigned int> stride() const
621 {
622 return _stride;
623 }
Alex Gildayc357c472018-03-21 13:54:09 +0000624 /** Check whether the padding is symmetric.
625 *
626 * @return True if the padding is symmetric.
627 */
Anthony Barbier21f67d62018-02-16 15:17:48 +0000628 bool padding_is_symmetric() const
629 {
630 return (_pad_left == _pad_right) && (_pad_top == _pad_bottom);
631 }
Alex Gildayc357c472018-03-21 13:54:09 +0000632 /** Get the padding.
633 *
634 * @note This should only be used when the padding is symmetric.
635 *
636 * @return a pair: padding left/right, padding top/bottom
637 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100638 std::pair<unsigned int, unsigned int> pad() const
639 {
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100640 //this accessor should be used only when padding is symmetric
Anthony Barbier21f67d62018-02-16 15:17:48 +0000641 ARM_COMPUTE_ERROR_ON(!padding_is_symmetric());
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100642 return std::make_pair(_pad_left, _pad_top);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100643 }
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100644
Alex Gildayc357c472018-03-21 13:54:09 +0000645 /** Get the left padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100646 unsigned int pad_left() const
647 {
648 return _pad_left;
649 }
Alex Gildayc357c472018-03-21 13:54:09 +0000650 /** Get the right padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100651 unsigned int pad_right() const
652 {
653 return _pad_right;
654 }
Alex Gildayc357c472018-03-21 13:54:09 +0000655 /** Get the top padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100656 unsigned int pad_top() const
657 {
658 return _pad_top;
659 }
Alex Gildayc357c472018-03-21 13:54:09 +0000660 /** Get the bottom padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100661 unsigned int pad_bottom() const
662 {
663 return _pad_bottom;
664 }
665
Alex Gildayc357c472018-03-21 13:54:09 +0000666 /** Get the rounding type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100667 DimensionRoundingType round() const
668 {
669 return _round_type;
670 }
671
Alex Gildayc357c472018-03-21 13:54:09 +0000672 /** Check whether this has any padding */
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100673 bool has_padding() const
674 {
675 return (_pad_left != 0 || _pad_top != 0 || _pad_right != 0 || _pad_bottom != 0);
676 }
677
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100678private:
679 std::pair<unsigned int, unsigned int> _stride;
Jaroslaw Rzepeckia1ed41f2017-10-13 11:13:58 +0100680 unsigned int _pad_left;
681 unsigned int _pad_top;
682 unsigned int _pad_right;
683 unsigned int _pad_bottom;
684
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100685 DimensionRoundingType _round_type;
686};
687
688/** Pooling Layer Information class */
689class PoolingLayerInfo
690{
691public:
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000692 /** Default Constructor */
693 PoolingLayerInfo()
Isabella Gottardi6e464c32018-01-26 12:32:45 +0000694 : _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 +0000695 {
696 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100697 /** Default Constructor
698 *
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000699 * @param[in] pool_type Pooling type @ref PoolingType.
700 * @param[in] pool_size Pooling size, in elements, across x and y.
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100701 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
Georgios Pinitasadaae7e2017-10-30 15:56:32 +0000702 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
703 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
704 * Defaults to false;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100705 */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000706 explicit PoolingLayerInfo(PoolingType pool_type,
707 unsigned int pool_size,
708 PadStrideInfo pad_stride_info = PadStrideInfo(),
709 bool exclude_padding = false)
Isabella Gottardi6e464c32018-01-26 12:32:45 +0000710 : _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)
711 {
712 }
713 /** Default Constructor
714 *
715 * @param[in] pool_type Pooling type @ref PoolingType.
716 * @param[in] pool_size Pooling size, in elements, across x and y.
717 * @param[in] pad_stride_info (Optional) Padding and stride information @ref PadStrideInfo
718 * @param[in] exclude_padding (Optional) Strategy when accounting padding in calculations.
719 * True will exclude padding while false will not (Used in AVG/L2 pooling to determine the pooling area).
720 * Defaults to false;
721 */
722 explicit PoolingLayerInfo(PoolingType pool_type,
723 Size2D pool_size,
724 PadStrideInfo pad_stride_info = PadStrideInfo(),
725 bool exclude_padding = false)
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000726 : _pool_type(pool_type), _pool_size(pool_size), _pad_stride_info(pad_stride_info), _exclude_padding(exclude_padding), _is_global_pooling(false)
727 {
728 }
729 /** Default Constructor
730 *
731 * @note This constructor is used for global pooling
732 *
733 * @param[in] pool_type Pooling type @ref PoolingType.
734 */
735 explicit PoolingLayerInfo(PoolingType pool_type)
Isabella Gottardi6e464c32018-01-26 12:32:45 +0000736 : _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 +0100737 {
738 }
Alex Gildayc357c472018-03-21 13:54:09 +0000739 /** Get the pooling type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100740 PoolingType pool_type() const
741 {
742 return _pool_type;
743 }
Alex Gildayc357c472018-03-21 13:54:09 +0000744 /** Get the pooling size */
Isabella Gottardi6e464c32018-01-26 12:32:45 +0000745 const Size2D &pool_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100746 {
747 return _pool_size;
748 }
Alex Gildayc357c472018-03-21 13:54:09 +0000749 /** Get the padding and stride */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100750 PadStrideInfo pad_stride_info() const
751 {
752 return _pad_stride_info;
753 }
Alex Gildayc357c472018-03-21 13:54:09 +0000754 /** Check if padding is excluded in calculations */
Georgios Pinitasadaae7e2017-10-30 15:56:32 +0000755 bool exclude_padding() const
756 {
757 return _exclude_padding;
758 }
Alex Gildayc357c472018-03-21 13:54:09 +0000759 /** Check if is global pooling */
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000760 bool is_global_pooling() const
761 {
762 return _is_global_pooling;
763 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100764
765private:
766 PoolingType _pool_type;
Isabella Gottardi6e464c32018-01-26 12:32:45 +0000767 Size2D _pool_size;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100768 PadStrideInfo _pad_stride_info;
Georgios Pinitasadaae7e2017-10-30 15:56:32 +0000769 bool _exclude_padding;
Georgios Pinitas4c2dd542017-11-13 12:58:41 +0000770 bool _is_global_pooling;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100771};
772
Georgios Pinitas7b7858d2017-06-21 16:44:24 +0100773/** ROI Pooling Layer Information class */
774class ROIPoolingLayerInfo
775{
776public:
777 /** Default Constructor
778 *
779 * @param[in] pooled_width Pooled width of the layer.
780 * @param[in] pooled_height Pooled height of the layer.
781 * @param[in] spatial_scale Spatial scale to be applied to the ROI coordinates and dimensions.
782 */
783 ROIPoolingLayerInfo(unsigned int pooled_width, unsigned int pooled_height, float spatial_scale)
784 : _pooled_width(pooled_width), _pooled_height(pooled_height), _spatial_scale(spatial_scale)
785 {
786 }
Alex Gildayc357c472018-03-21 13:54:09 +0000787 /** Get the pooled width of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +0100788 unsigned int pooled_width() const
789 {
790 return _pooled_width;
791 }
Alex Gildayc357c472018-03-21 13:54:09 +0000792 /** Get the pooled height of the layer */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +0100793 unsigned int pooled_height() const
794 {
795 return _pooled_height;
796 }
Alex Gildayc357c472018-03-21 13:54:09 +0000797 /** Get the spatial scale */
Georgios Pinitas7b7858d2017-06-21 16:44:24 +0100798 float spatial_scale() const
799 {
800 return _spatial_scale;
801 }
802
803private:
804 unsigned int _pooled_width;
805 unsigned int _pooled_height;
806 float _spatial_scale;
807};
808
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100809/** Activation Layer Information class */
810class ActivationLayerInfo
811{
812public:
813 /** Available activation functions */
814 enum class ActivationFunction
815 {
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +0100816 LOGISTIC, /**< Logistic ( \f$ f(x) = \frac{1}{1 + e^{-x}} \f$ ) */
817 TANH, /**< Hyperbolic tangent ( \f$ f(x) = a \cdot tanh(b \cdot x) \f$ ) */
818 RELU, /**< Rectifier ( \f$ f(x) = max(0,x) \f$ ) */
819 BOUNDED_RELU, /**< Upper Bounded Rectifier ( \f$ f(x) = min(a, max(0,x)) \f$ ) */
820 LU_BOUNDED_RELU, /**< Lower and Upper Bounded Rectifier ( \f$ f(x) = min(a, max(b,x)) \f$ ) */
821 LEAKY_RELU, /**< Leaky Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
822 SOFT_RELU, /**< Soft Rectifier ( \f$ f(x)= log(1+e^x) \f$ ) */
823 ABS, /**< Absolute ( \f$ f(x)= |x| \f$ ) */
824 SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/
825 SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/
826 LINEAR /**< Linear ( \f$ f(x)= ax + b \f$ ) */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100827 };
828
Giorgio Arena11674872018-02-07 15:38:12 +0000829 ActivationLayerInfo() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100830 /** Default Constructor
831 *
832 * @param[in] f The activation function to use.
833 * @param[in] a (Optional) The alpha parameter used by some activation functions
Georgios Pinitas64ebe5b2017-09-01 17:44:24 +0100834 * (@ref ActivationFunction::BOUNDED_RELU, @ref ActivationFunction::LU_BOUNDED_RELU, @ref ActivationFunction::LINEAR, @ref ActivationFunction::TANH).
835 * @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 +0100836 */
837 ActivationLayerInfo(ActivationFunction f, float a = 0.0f, float b = 0.0f)
Giorgio Arena11674872018-02-07 15:38:12 +0000838 : _act(f), _a(a), _b(b), _enabled(true)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100839 {
840 }
Alex Gildayc357c472018-03-21 13:54:09 +0000841 /** Get the type of activation function */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100842 ActivationFunction activation() const
843 {
844 return _act;
845 }
Alex Gildayc357c472018-03-21 13:54:09 +0000846 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100847 float a() const
848 {
849 return _a;
850 }
Alex Gildayc357c472018-03-21 13:54:09 +0000851 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100852 float b() const
853 {
854 return _b;
855 }
Alex Gildayc357c472018-03-21 13:54:09 +0000856 /** Check if initialised */
Giorgio Arena11674872018-02-07 15:38:12 +0000857 bool enabled() const
858 {
859 return _enabled;
860 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100861
862private:
Giorgio Arena11674872018-02-07 15:38:12 +0000863 ActivationFunction _act = { ActivationLayerInfo::ActivationFunction::LOGISTIC };
864 float _a = {};
865 float _b = {};
866 bool _enabled = { false };
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100867};
868
869/** Normalization Layer Information class */
870class NormalizationLayerInfo
871{
872public:
873 /** Default Constructor
874 *
875 * @param[in] type The normalization type. Can be @ref NormType::IN_MAP_1D, @ref NormType::IN_MAP_2D or @ref NORM_TYPE::CROSS_MAP
876 * @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 +0000877 * @param[in] alpha (Optional) Alpha parameter used by normalization equation. Defaults to 0.0001.
878 * @param[in] beta (Optional) Beta parameter used by normalization equation. Defaults to 0.5.
879 * @param[in] kappa (Optional) Kappa parameter used by [Krichevksy 2012] Across Channel Local Brightness Normalization equation.
880 * @param[in] is_scaled (Optional) Boolean that specifies if alpha will be scaled by the normalization size or not.
881 * Should be false to follow [Krichevksy 2012].
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100882 */
Georgios Pinitas41caa622017-11-16 14:37:08 +0000883 NormalizationLayerInfo(NormType type, uint32_t norm_size = 5, float alpha = 0.0001f, float beta = 0.5f, float kappa = 1.f, bool is_scaled = true)
884 : _type(type), _norm_size(norm_size), _alpha(alpha), _beta(beta), _kappa(kappa), _is_scaled(is_scaled)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100885 {
886 }
Alex Gildayc357c472018-03-21 13:54:09 +0000887 /** Get the normalization type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100888 NormType type() const
889 {
890 return _type;
891 }
Alex Gildayc357c472018-03-21 13:54:09 +0000892 /** Get the normalization size */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100893 uint32_t norm_size() const
894 {
895 return _norm_size;
896 }
Alex Gildayc357c472018-03-21 13:54:09 +0000897 /** Get the alpha value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100898 float alpha() const
899 {
900 return _alpha;
901 }
Alex Gildayc357c472018-03-21 13:54:09 +0000902 /** Get the beta value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100903 float beta() const
904 {
905 return _beta;
906 }
Alex Gildayc357c472018-03-21 13:54:09 +0000907 /** Get the kappa value */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100908 float kappa() const
909 {
910 return _kappa;
911 }
Alex Gildayc357c472018-03-21 13:54:09 +0000912 /** Check if normalization is cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +0000913 bool is_cross_map() const
914 {
915 return _type == NormType::CROSS_MAP;
916 }
Alex Gildayc357c472018-03-21 13:54:09 +0000917 /** Check if normalization is not cross map */
Georgios Pinitas41caa622017-11-16 14:37:08 +0000918 bool is_in_map() const
919 {
920 return !is_cross_map();
921 }
922 /** Return the scaling factor of the normalization function.
923 *
924 * If is_scaled is set to false then [Krichevksy 2012] normalization scaling is performed,
925 * 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 +0100926 *
927 * @return The normalization scaling factor.
928 */
929 float scale_coeff() const
930 {
931 const uint32_t size = (_type == NormType::IN_MAP_2D) ? _norm_size * _norm_size : _norm_size;
Georgios Pinitas41caa622017-11-16 14:37:08 +0000932 return (_is_scaled) ? (_alpha / size) : _alpha;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100933 }
934
935private:
936 NormType _type;
937 uint32_t _norm_size;
938 float _alpha;
939 float _beta;
940 float _kappa;
Georgios Pinitas41caa622017-11-16 14:37:08 +0000941 bool _is_scaled;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100942};
943
Gian Marco Iodice559d7712017-08-08 08:38:09 +0100944/** 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 +0100945class WeightsInfo
946{
947public:
Gian Marco Iodice4e288692017-06-27 11:41:59 +0100948 /** Default constructor */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100949 WeightsInfo()
Michele Di Giorgiob62280a2018-05-31 17:31:05 +0100950 : _are_reshaped(false), _kernel_width(0), _kernel_height(0), _num_kernels(0), _retain_internal_weights(false)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100951 {
952 }
953 /** Constructor
954 *
Michele Di Giorgiob62280a2018-05-31 17:31:05 +0100955 * @param[in] are_reshaped True if the weights have been reshaped
956 * @param[in] kernel_width Kernel width.
957 * @param[in] kernel_height Kernel height.
958 * @param[in] num_kernels Number of convolution kernels.
959 * @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 +0100960 */
Michele Di Giorgiob62280a2018-05-31 17:31:05 +0100961 WeightsInfo(bool are_reshaped, unsigned int kernel_width, unsigned int kernel_height, unsigned int num_kernels, bool retain_internal_weights = false)
962 : _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 +0100963 {
964 }
Gian Marco Iodice4e288692017-06-27 11:41:59 +0100965 /** Flag which specifies if the weights tensor has been reshaped.
966 *
967 * @return True if the weights tensors has been reshaped
968 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100969 bool are_reshaped() const
970 {
971 return _are_reshaped;
972 };
Gian Marco Iodice559d7712017-08-08 08:38:09 +0100973 /** Return the number of convolution kernels
974 *
975 * @return The number of convolution kernels
976 */
977 unsigned int num_kernels() const
978 {
979 return _num_kernels;
980 };
Gian Marco Iodice4e288692017-06-27 11:41:59 +0100981 /** Return the width and height of the kernel
982 *
983 * @return The width and height of the kernel
984 */
985 std::pair<unsigned int, unsigned int> kernel_size() const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100986 {
Gian Marco Iodice4e288692017-06-27 11:41:59 +0100987 return std::make_pair(_kernel_width, _kernel_height);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100988 }
Michele Di Giorgiob62280a2018-05-31 17:31:05 +0100989 bool retain_internal_weights() const
990 {
991 return _retain_internal_weights;
992 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100993
994private:
995 const bool _are_reshaped;
Gian Marco Iodice4e288692017-06-27 11:41:59 +0100996 const unsigned int _kernel_width;
997 const unsigned int _kernel_height;
Gian Marco Iodice559d7712017-08-08 08:38:09 +0100998 const unsigned int _num_kernels;
Michele Di Giorgiob62280a2018-05-31 17:31:05 +0100999 const bool _retain_internal_weights;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001000};
1001
Gian Marco36a0a462018-01-12 10:21:40 +00001002/** GEMM reshape information class. This class stores the necessary information about matrix A and matrix B reshape.
1003 *
1004 * The matrix A can only be reshaped through @ref CLGEMMInterleave4x4Kernel or @ref NEGEMMInterleave4x4Kernel or @ref GCGEMMInterleave4x4Kernel
1005 * 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
1006 *
1007 * The matrix B can only be reshaped through @ref CLGEMMTranspose1xWKernel or @ref NEGEMMTranspose1xWKernel or @ref GCGEMMTranspose1xWKernel
1008 * 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
1009 *
1010 */
1011class GEMMReshapeInfo final
1012{
1013public:
1014 /** Default constructor */
1015 GEMMReshapeInfo()
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001016 : _m(1), _n(1), _k(1), _mult_transpose1xW_width(1), _mult_interleave4x4_height(1), _depth_output_gemm3d(1)
Gian Marco36a0a462018-01-12 10:21:40 +00001017 {
1018 }
1019 /** Constructor
1020 *
1021 * @param[in] m Number of matrix A rows
1022 * @param[in] n Number of matrix B columns
1023 * @param[in] k Number of matrix A columns or matrix B rows
1024 * @param[in] mult_transpose1xW_width (Optional) Multiplication factor for the width of the 1xW transposed block
1025 * @param[in] mult_interleave4x4_height (Optional) Multiplication factor for the height of the 4x4 interleaved block
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001026 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
Gian Marco36a0a462018-01-12 10:21:40 +00001027 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001028 GEMMReshapeInfo(int m, int n, int k, int mult_transpose1xW_width = 1, int mult_interleave4x4_height = 1, int depth_output_gemm3d = 1)
1029 : _m(m), _n(n), _k(k), _mult_transpose1xW_width(mult_transpose1xW_width), _mult_interleave4x4_height(mult_interleave4x4_height), _depth_output_gemm3d(depth_output_gemm3d)
Gian Marco36a0a462018-01-12 10:21:40 +00001030 {
1031 }
1032 /** Number of matrix A rows
1033 *
1034 * @return the number of matrix A rows
1035 */
1036 int m() const
1037 {
1038 return _m;
1039 }
1040 /** Number of matrix B columns
1041 *
1042 * @return the number of matrix B columns
1043 */
1044 int n() const
1045 {
1046 return _n;
1047 }
1048 /** Number of matrix A columns or matrix B rows
1049 *
1050 * @return the number of matrix A columns or matrix B rows
1051 */
1052 int k() const
1053 {
1054 return _k;
1055 }
1056 /** Multiplication factor for the width of the 1xW transposed block
1057 *
1058 * @return the multiplication factor for the width of the 1xW transposed block
1059 */
1060 int mult_transpose1xW_width() const
1061 {
1062 return _mult_transpose1xW_width;
1063 }
1064 /** Multiplication factor for the height of the 4x4 interleaved block
1065 *
1066 * @return the multiplication factor for the height of the 4x4 interleaved block
1067 */
1068 int mult_interleave4x4_height() const
1069 {
1070 return _mult_interleave4x4_height;
1071 }
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001072 /** Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
1073 *
1074 * @note GEMM3D kernel is used when the output has to be reinterpret as 3D tensor. In that case:
1075 * m = depth_output_gemm3d * output_height
1076 *
1077 * @return the depth of the output tensor to be used with the GEMM3D kernel
1078 */
1079 int depth_output_gemm3d() const
1080 {
1081 return _depth_output_gemm3d;
1082 }
Gian Marco36a0a462018-01-12 10:21:40 +00001083
1084private:
1085 const int _m;
1086 const int _n;
1087 const int _k;
1088 const int _mult_transpose1xW_width;
1089 const int _mult_interleave4x4_height;
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001090 const int _depth_output_gemm3d;
Gian Marco36a0a462018-01-12 10:21:40 +00001091};
1092
1093/** GEMM information class. This class stores the necessary information to compute GEMM functions
1094 *
1095 * This object also contains the information about how matrix A and matrix B have been reshaped
1096 *
1097 */
Chunosov5124be52017-11-22 20:42:13 +07001098class GEMMInfo
1099{
1100public:
1101 /** Default constructor */
1102 GEMMInfo()
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001103 : _is_a_reshaped(false), _is_b_reshaped(false), _reshape_b_only_on_first_run(false), _depth_output_gemm3d(1)
Chunosov5124be52017-11-22 20:42:13 +07001104 {
1105 }
1106 /** Constructor
1107 *
1108 * @param[in] is_a_reshaped True if the matrix A has been reshaped
1109 * @param[in] is_b_reshaped True if the matrix B has been reshaped
1110 * @param[in] reshape_b_only_on_first_run Reshape matrix B only for the first run
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001111 * @param[in] depth_output_gemm3d (Optional) Depth (third dimension) of the output tensor to be used with the GEMM3D kernel
1112 *
Chunosov5124be52017-11-22 20:42:13 +07001113 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001114 GEMMInfo(bool is_a_reshaped, bool is_b_reshaped, bool reshape_b_only_on_first_run, int depth_output_gemm3d = 1)
1115 : _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)
Chunosov5124be52017-11-22 20:42:13 +07001116 {
1117 }
1118 /** Flag which specifies if the matrix A has been reshaped
1119 *
1120 * @return True if the matrix A has been reshaped
1121 */
1122 bool is_a_reshaped() const
1123 {
1124 return _is_a_reshaped;
1125 };
1126 /** Flag which specifies if the matrix B has been reshaped
1127 *
1128 * @return True if the matrix B has been reshaped
1129 */
1130 bool is_b_reshaped() const
1131 {
1132 return _is_b_reshaped;
1133 };
1134 /** Flag which specifies if the reshape of matrix B should executed only for the first
1135 *
1136 * @note This flag could be set to TRUE when GEMM is used to accelerate convolution layer
1137 *
1138 * @return True if the reshaped of matrix B happens only for the first run
1139 */
1140 bool reshape_b_only_on_first_run() const
1141 {
1142 return _reshape_b_only_on_first_run;
1143 };
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001144 /** Depth of the output when GEMM output is reinterpreted as 3D tensor
Gian Marco36a0a462018-01-12 10:21:40 +00001145 *
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001146 * @return the depth of the output tensor
Gian Marco36a0a462018-01-12 10:21:40 +00001147 */
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001148 int depth_output_gemm3d() const
Gian Marco36a0a462018-01-12 10:21:40 +00001149 {
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001150 return _depth_output_gemm3d;
1151 };
Chunosov5124be52017-11-22 20:42:13 +07001152
1153private:
Isabella Gottardi8e74f442018-03-01 16:42:00 +00001154 const bool _is_a_reshaped;
1155 const bool _is_b_reshaped;
1156 const bool _reshape_b_only_on_first_run;
1157 const int _depth_output_gemm3d;
Chunosov5124be52017-11-22 20:42:13 +07001158};
1159
Gian Marco Iodice247f52c2018-03-22 11:24:56 +00001160/** Winograd information */
1161struct WinogradInfo
1162{
1163 /** Default constructor
1164 *
1165 * @param[in] output_tile_sz Width and height of the output tile
1166 * @param[in] kernel_sz Width and height of the kernel
1167 * @param[in] input_dims Width and height of the input tensor before the convolution is applied
1168 * @param[in] conv_info Convolution info (Pads, strides)
1169 * @param[in] data_layout Data layout to use for the output tensor once the convolution has been applied
1170 */
1171 WinogradInfo(Size2D output_tile_sz, Size2D kernel_sz, Size2D input_dims, PadStrideInfo conv_info, DataLayout data_layout)
1172 : output_tile_size(output_tile_sz), kernel_size(kernel_sz), input_dimensions(input_dims), convolution_info(conv_info), output_data_layout(data_layout)
1173 {
1174 }
1175
1176 Size2D output_tile_size{}; /**< Width and height of the output tile */
1177 Size2D kernel_size{}; /**< Width and height of the kernel*/
1178 Size2D input_dimensions{}; /**< Width and height of the input tensor before the convolution is applied */
1179 PadStrideInfo convolution_info{}; /**< Convolution info (Pads, strides,...) */
1180 DataLayout output_data_layout{ DataLayout::NCHW }; /**< Data layout to use for the output tensor once the convolution has been applied (NCHW or NHWC) */
1181};
1182
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001183/** IO formatting information class*/
1184struct IOFormatInfo
1185{
1186 /** Precision type used when printing floating point numbers */
1187 enum class PrecisionType
1188 {
1189 Default, /**< Default precision to the one that the current stream has */
1190 Custom, /**< Custom precision specified by the user using the precision parameter */
1191 Full /**< The maximum precision of the floating point representation */
1192 };
1193
1194 /** Specifies the area to be printed, used by Tensor objects */
1195 enum class PrintRegion
1196 {
1197 ValidRegion, /**< Prints the valid region of the Tensor object */
1198 NoPadding, /**< Prints the Tensor object without the padding */
1199 Full /**< Print the tensor object including padding */
1200 };
1201
Alex Gildayc357c472018-03-21 13:54:09 +00001202 /** Construct a set of IO formatting information.
1203 *
1204 * @param[in] print_region Area to be printed. Used by Tensor objects. Default: ValidRegion.
1205 * @param[in] precision_type Precision type for floating point numbers. Default: stream default.
1206 * @param[in] precision Precision value for float point numbers. Default: 10.
1207 * @param[in] align_columns Whether to align columns when printed. Default: true.
1208 * @param[in] element_delim Delimeter between elements. Default: " ".
1209 * @param[in] row_delim Delimenter between rows. Default: "\n".
1210 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001211 IOFormatInfo(PrintRegion print_region = PrintRegion::ValidRegion,
1212 PrecisionType precision_type = PrecisionType::Default,
1213 unsigned int precision = 10,
1214 bool align_columns = true,
1215 std::string element_delim = " ",
1216 std::string row_delim = "\n")
1217 : print_region(print_region),
1218 precision_type(precision_type),
1219 precision(precision),
1220 element_delim(element_delim),
1221 row_delim(row_delim),
1222 align_columns(align_columns)
1223 {
1224 }
1225
Alex Gildayc357c472018-03-21 13:54:09 +00001226 /** Area to be printed by Tensor objects */
1227 PrintRegion print_region;
1228 /** Floating point precision type */
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001229 PrecisionType precision_type;
Alex Gildayc357c472018-03-21 13:54:09 +00001230 /** Floating point precision */
1231 unsigned int precision;
1232 /** Element delimeter */
1233 std::string element_delim;
1234 /** Row delimeter */
1235 std::string row_delim;
1236 /** Align columns */
1237 bool align_columns;
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001238};
Isabella Gottardif07d28d2018-02-06 14:52:43 +00001239
1240/** Available ConvolutionMethod*/
1241enum class ConvolutionMethod
1242{
1243 GEMM, /**< Convolution using GEMM */
1244 DIRECT, /**< Direct convolution */
1245 WINOGRAD /**< Convolution using Winograd */
1246};
Georgios Pinitasd8734b52017-12-22 15:27:52 +00001247} // namespace arm_compute
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001248#endif /* __ARM_COMPUTE_TYPES_H__ */