Compute Library
 20.02.1
Utils.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2020 ARM Limited.
3  *
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_UTILS_H
25 #define ARM_COMPUTE_UTILS_H
26 
27 #include "arm_compute/core/Error.h"
30 #include "arm_compute/core/Types.h"
31 
32 #include <algorithm>
33 #include <cstdint>
34 #include <cstdlib>
35 #include <iomanip>
36 #include <numeric>
37 #include <sstream>
38 #include <string>
39 #include <type_traits>
40 #include <utility>
41 #include <vector>
42 
43 namespace arm_compute
44 {
45 /** Calculate the rounded up quotient of val / m.
46  *
47  * @param[in] val Value to divide and round up.
48  * @param[in] m Value to divide by.
49  *
50  * @return the result.
51  */
52 template <typename S, typename T>
53 constexpr auto DIV_CEIL(S val, T m) -> decltype((val + m - 1) / m)
54 {
55  return (val + m - 1) / m;
56 }
57 
58 /** Computes the smallest number larger or equal to value that is a multiple of divisor.
59  *
60  * @param[in] value Lower bound value
61  * @param[in] divisor Value to compute multiple of.
62  *
63  * @return the result.
64  */
65 template <typename S, typename T>
66 inline auto ceil_to_multiple(S value, T divisor) -> decltype(((value + divisor - 1) / divisor) * divisor)
67 {
68  ARM_COMPUTE_ERROR_ON(value < 0 || divisor <= 0);
69  return DIV_CEIL(value, divisor) * divisor;
70 }
71 
72 /** Computes the largest number smaller or equal to value that is a multiple of divisor.
73  *
74  * @param[in] value Upper bound value
75  * @param[in] divisor Value to compute multiple of.
76  *
77  * @return the result.
78  */
79 template <typename S, typename T>
80 inline auto floor_to_multiple(S value, T divisor) -> decltype((value / divisor) * divisor)
81 {
82  ARM_COMPUTE_ERROR_ON(value < 0 || divisor <= 0);
83  return (value / divisor) * divisor;
84 }
85 
86 /** Returns the arm_compute library build information
87  *
88  * Contains the version number and the build options used to build the library
89  *
90  * @return The arm_compute library build information
91  */
92 std::string build_information();
93 
94 /** Load an entire file in memory
95  *
96  * @param[in] filename Name of the file to read.
97  * @param[in] binary Is it a binary file ?
98  *
99  * @return The content of the file.
100  */
101 std::string read_file(const std::string &filename, bool binary);
102 
103 /** The size in bytes of the data type
104  *
105  * @param[in] data_type Input data type
106  *
107  * @return The size in bytes of the data type
108  */
110 {
111  switch(data_type)
112  {
113  case DataType::U8:
114  case DataType::S8:
115  case DataType::QSYMM8:
116  case DataType::QASYMM8:
119  return 1;
120  case DataType::U16:
121  case DataType::S16:
122  case DataType::QSYMM16:
123  case DataType::QASYMM16:
124  case DataType::F16:
125  return 2;
126  case DataType::F32:
127  case DataType::U32:
128  case DataType::S32:
129  return 4;
130  case DataType::F64:
131  case DataType::U64:
132  case DataType::S64:
133  return 8;
134  case DataType::SIZET:
135  return sizeof(size_t);
136  default:
137  ARM_COMPUTE_ERROR("Invalid data type");
138  return 0;
139  }
140 }
141 
142 /** The size in bytes of the pixel format
143  *
144  * @param[in] format Input format
145  *
146  * @return The size in bytes of the pixel format
147  */
148 inline size_t pixel_size_from_format(Format format)
149 {
150  switch(format)
151  {
152  case Format::U8:
153  return 1;
154  case Format::U16:
155  case Format::S16:
156  case Format::F16:
157  case Format::UV88:
158  case Format::YUYV422:
159  case Format::UYVY422:
160  return 2;
161  case Format::RGB888:
162  return 3;
163  case Format::RGBA8888:
164  return 4;
165  case Format::U32:
166  case Format::S32:
167  case Format::F32:
168  return 4;
169  //Doesn't make sense for planar formats:
170  case Format::NV12:
171  case Format::NV21:
172  case Format::IYUV:
173  case Format::YUV444:
174  default:
175  ARM_COMPUTE_ERROR("Undefined pixel size for given format");
176  return 0;
177  }
178 }
179 
180 /** The size in bytes of the data type
181  *
182  * @param[in] dt Input data type
183  *
184  * @return The size in bytes of the data type
185  */
187 {
188  switch(dt)
189  {
190  case DataType::S8:
191  case DataType::U8:
192  case DataType::QSYMM8:
193  case DataType::QASYMM8:
196  return 1;
197  case DataType::U16:
198  case DataType::S16:
199  case DataType::QSYMM16:
200  case DataType::QASYMM16:
201  case DataType::F16:
202  return 2;
203  case DataType::U32:
204  case DataType::S32:
205  case DataType::F32:
206  return 4;
207  default:
208  ARM_COMPUTE_ERROR("Undefined element size for given data type");
209  return 0;
210  }
211 }
212 
213 /** Return the data type used by a given single-planar pixel format
214  *
215  * @param[in] format Input format
216  *
217  * @return The size in bytes of the pixel format
218  */
220 {
221  switch(format)
222  {
223  case Format::U8:
224  case Format::UV88:
225  case Format::RGB888:
226  case Format::RGBA8888:
227  case Format::YUYV422:
228  case Format::UYVY422:
229  return DataType::U8;
230  case Format::U16:
231  return DataType::U16;
232  case Format::S16:
233  return DataType::S16;
234  case Format::U32:
235  return DataType::U32;
236  case Format::S32:
237  return DataType::S32;
238  case Format::F16:
239  return DataType::F16;
240  case Format::F32:
241  return DataType::F32;
242  //Doesn't make sense for planar formats:
243  case Format::NV12:
244  case Format::NV21:
245  case Format::IYUV:
246  case Format::YUV444:
247  default:
248  ARM_COMPUTE_ERROR("Not supported data_type for given format");
249  return DataType::UNKNOWN;
250  }
251 }
252 
253 /** Return the plane index of a given channel given an input format.
254  *
255  * @param[in] format Input format
256  * @param[in] channel Input channel
257  *
258  * @return The plane index of the specific channel of the specific format
259  */
260 inline int plane_idx_from_channel(Format format, Channel channel)
261 {
262  switch(format)
263  {
264  // Single planar formats have a single plane
265  case Format::U8:
266  case Format::U16:
267  case Format::S16:
268  case Format::U32:
269  case Format::S32:
270  case Format::F16:
271  case Format::F32:
272  case Format::UV88:
273  case Format::RGB888:
274  case Format::RGBA8888:
275  case Format::YUYV422:
276  case Format::UYVY422:
277  return 0;
278  // Multi planar formats
279  case Format::NV12:
280  case Format::NV21:
281  {
282  // Channel U and V share the same plane of format UV88
283  switch(channel)
284  {
285  case Channel::Y:
286  return 0;
287  case Channel::U:
288  case Channel::V:
289  return 1;
290  default:
291  ARM_COMPUTE_ERROR("Not supported channel");
292  return 0;
293  }
294  }
295  case Format::IYUV:
296  case Format::YUV444:
297  {
298  switch(channel)
299  {
300  case Channel::Y:
301  return 0;
302  case Channel::U:
303  return 1;
304  case Channel::V:
305  return 2;
306  default:
307  ARM_COMPUTE_ERROR("Not supported channel");
308  return 0;
309  }
310  }
311  default:
312  ARM_COMPUTE_ERROR("Not supported format");
313  return 0;
314  }
315 }
316 
317 /** Return the channel index of a given channel given an input format.
318  *
319  * @param[in] format Input format
320  * @param[in] channel Input channel
321  *
322  * @return The channel index of the specific channel of the specific format
323  */
324 inline int channel_idx_from_format(Format format, Channel channel)
325 {
326  switch(format)
327  {
328  case Format::RGB888:
329  {
330  switch(channel)
331  {
332  case Channel::R:
333  return 0;
334  case Channel::G:
335  return 1;
336  case Channel::B:
337  return 2;
338  default:
339  ARM_COMPUTE_ERROR("Not supported channel");
340  return 0;
341  }
342  }
343  case Format::RGBA8888:
344  {
345  switch(channel)
346  {
347  case Channel::R:
348  return 0;
349  case Channel::G:
350  return 1;
351  case Channel::B:
352  return 2;
353  case Channel::A:
354  return 3;
355  default:
356  ARM_COMPUTE_ERROR("Not supported channel");
357  return 0;
358  }
359  }
360  case Format::YUYV422:
361  {
362  switch(channel)
363  {
364  case Channel::Y:
365  return 0;
366  case Channel::U:
367  return 1;
368  case Channel::V:
369  return 3;
370  default:
371  ARM_COMPUTE_ERROR("Not supported channel");
372  return 0;
373  }
374  }
375  case Format::UYVY422:
376  {
377  switch(channel)
378  {
379  case Channel::Y:
380  return 1;
381  case Channel::U:
382  return 0;
383  case Channel::V:
384  return 2;
385  default:
386  ARM_COMPUTE_ERROR("Not supported channel");
387  return 0;
388  }
389  }
390  case Format::NV12:
391  {
392  switch(channel)
393  {
394  case Channel::Y:
395  return 0;
396  case Channel::U:
397  return 0;
398  case Channel::V:
399  return 1;
400  default:
401  ARM_COMPUTE_ERROR("Not supported channel");
402  return 0;
403  }
404  }
405  case Format::NV21:
406  {
407  switch(channel)
408  {
409  case Channel::Y:
410  return 0;
411  case Channel::U:
412  return 1;
413  case Channel::V:
414  return 0;
415  default:
416  ARM_COMPUTE_ERROR("Not supported channel");
417  return 0;
418  }
419  }
420  case Format::YUV444:
421  case Format::IYUV:
422  {
423  switch(channel)
424  {
425  case Channel::Y:
426  return 0;
427  case Channel::U:
428  return 0;
429  case Channel::V:
430  return 0;
431  default:
432  ARM_COMPUTE_ERROR("Not supported channel");
433  return 0;
434  }
435  }
436  default:
437  ARM_COMPUTE_ERROR("Not supported format");
438  return 0;
439  }
440 }
441 
442 /** Return the number of planes for a given format
443  *
444  * @param[in] format Input format
445  *
446  * @return The number of planes for a given image format.
447  */
448 inline size_t num_planes_from_format(Format format)
449 {
450  switch(format)
451  {
452  case Format::U8:
453  case Format::S16:
454  case Format::U16:
455  case Format::S32:
456  case Format::U32:
457  case Format::F16:
458  case Format::F32:
459  case Format::RGB888:
460  case Format::RGBA8888:
461  case Format::YUYV422:
462  case Format::UYVY422:
463  return 1;
464  case Format::NV12:
465  case Format::NV21:
466  return 2;
467  case Format::IYUV:
468  case Format::YUV444:
469  return 3;
470  default:
471  ARM_COMPUTE_ERROR("Not supported format");
472  return 0;
473  }
474 }
475 
476 /** Return the number of channels for a given single-planar pixel format
477  *
478  * @param[in] format Input format
479  *
480  * @return The number of channels for a given image format.
481  */
482 inline size_t num_channels_from_format(Format format)
483 {
484  switch(format)
485  {
486  case Format::U8:
487  case Format::U16:
488  case Format::S16:
489  case Format::U32:
490  case Format::S32:
491  case Format::F16:
492  case Format::F32:
493  return 1;
494  // Because the U and V channels are subsampled
495  // these formats appear like having only 2 channels:
496  case Format::YUYV422:
497  case Format::UYVY422:
498  return 2;
499  case Format::UV88:
500  return 2;
501  case Format::RGB888:
502  return 3;
503  case Format::RGBA8888:
504  return 4;
505  //Doesn't make sense for planar formats:
506  case Format::NV12:
507  case Format::NV21:
508  case Format::IYUV:
509  case Format::YUV444:
510  default:
511  return 0;
512  }
513 }
514 
515 /** Return the promoted data type of a given data type.
516  *
517  * @note If promoted data type is not supported an error will be thrown
518  *
519  * @param[in] dt Data type to get the promoted type of.
520  *
521  * @return Promoted data type
522  */
524 {
525  switch(dt)
526  {
527  case DataType::U8:
528  return DataType::U16;
529  case DataType::S8:
530  return DataType::S16;
531  case DataType::U16:
532  return DataType::U32;
533  case DataType::S16:
534  return DataType::S32;
535  case DataType::QSYMM8:
536  case DataType::QASYMM8:
539  case DataType::QSYMM16:
540  case DataType::QASYMM16:
541  case DataType::F16:
542  case DataType::U32:
543  case DataType::S32:
544  case DataType::F32:
545  ARM_COMPUTE_ERROR("Unsupported data type promotions!");
546  default:
547  ARM_COMPUTE_ERROR("Undefined data type!");
548  }
549  return DataType::UNKNOWN;
550 }
551 
552 /** Compute the mininum and maximum values a data type can take
553  *
554  * @param[in] dt Data type to get the min/max bounds of
555  *
556  * @return A tuple (min,max) with the minimum and maximum values respectively wrapped in PixelValue.
557  */
558 inline std::tuple<PixelValue, PixelValue> get_min_max(DataType dt)
559 {
560  PixelValue min{};
561  PixelValue max{};
562  switch(dt)
563  {
564  case DataType::U8:
565  case DataType::QASYMM8:
566  {
567  min = PixelValue(static_cast<int32_t>(std::numeric_limits<uint8_t>::lowest()));
568  max = PixelValue(static_cast<int32_t>(std::numeric_limits<uint8_t>::max()));
569  break;
570  }
571  case DataType::S8:
572  case DataType::QSYMM8:
575  {
576  min = PixelValue(static_cast<int32_t>(std::numeric_limits<int8_t>::lowest()));
577  max = PixelValue(static_cast<int32_t>(std::numeric_limits<int8_t>::max()));
578  break;
579  }
580  case DataType::U16:
581  case DataType::QASYMM16:
582  {
583  min = PixelValue(static_cast<int32_t>(std::numeric_limits<uint16_t>::lowest()));
584  max = PixelValue(static_cast<int32_t>(std::numeric_limits<uint16_t>::max()));
585  break;
586  }
587  case DataType::S16:
588  case DataType::QSYMM16:
589  {
590  min = PixelValue(static_cast<int32_t>(std::numeric_limits<int16_t>::lowest()));
591  max = PixelValue(static_cast<int32_t>(std::numeric_limits<int16_t>::max()));
592  break;
593  }
594  case DataType::U32:
595  {
597  max = PixelValue(std::numeric_limits<uint32_t>::max());
598  break;
599  }
600  case DataType::S32:
601  {
603  max = PixelValue(std::numeric_limits<int32_t>::max());
604  break;
605  }
606  case DataType::F32:
607  {
609  max = PixelValue(std::numeric_limits<float>::max());
610  break;
611  }
612  default:
613  ARM_COMPUTE_ERROR("Undefined data type!");
614  }
615  return std::make_tuple(min, max);
616 }
617 
618 /** Return true if the given format has horizontal subsampling.
619  *
620  * @param[in] format Format to determine subsampling.
621  *
622  * @return True if the format can be subsampled horizontaly.
623  */
625 {
626  return (format == Format::YUYV422 || format == Format::UYVY422 || format == Format::NV12 || format == Format::NV21 || format == Format::IYUV || format == Format::UV88) ? true : false;
627 }
628 
629 /** Return true if the given format has vertical subsampling.
630  *
631  * @param[in] format Format to determine subsampling.
632  *
633  * @return True if the format can be subsampled verticaly.
634  */
636 {
637  return (format == Format::NV12 || format == Format::NV21 || format == Format::IYUV || format == Format::UV88) ? true : false;
638 }
639 
640 /** Separate a 2D convolution into two 1D convolutions
641  *
642  * @param[in] conv 2D convolution
643  * @param[out] conv_col 1D vertical convolution
644  * @param[out] conv_row 1D horizontal convolution
645  * @param[in] size Size of the 2D convolution
646  *
647  * @return true if the separation was successful
648  */
649 inline bool separate_matrix(const int16_t *conv, int16_t *conv_col, int16_t *conv_row, uint8_t size)
650 {
651  int32_t min_col = -1;
652  int16_t min_col_val = -1;
653 
654  for(int32_t i = 0; i < size; ++i)
655  {
656  if(conv[i] != 0 && (min_col < 0 || abs(min_col_val) > abs(conv[i])))
657  {
658  min_col = i;
659  min_col_val = conv[i];
660  }
661  }
662 
663  if(min_col < 0)
664  {
665  return false;
666  }
667 
668  for(uint32_t j = 0; j < size; ++j)
669  {
670  conv_col[j] = conv[min_col + j * size];
671  }
672 
673  for(uint32_t i = 0; i < size; i++)
674  {
675  if(static_cast<int>(i) == min_col)
676  {
677  conv_row[i] = 1;
678  }
679  else
680  {
681  int16_t coeff = conv[i] / conv[min_col];
682 
683  for(uint32_t j = 1; j < size; ++j)
684  {
685  if(conv[i + j * size] != (conv_col[j] * coeff))
686  {
687  return false;
688  }
689  }
690 
691  conv_row[i] = coeff;
692  }
693  }
694 
695  return true;
696 }
697 
698 /** Calculate the scale of the given square matrix
699  *
700  * The scale is the absolute value of the sum of all the coefficients in the matrix.
701  *
702  * @note If the coefficients add up to 0 then the scale is set to 1.
703  *
704  * @param[in] matrix Matrix coefficients
705  * @param[in] matrix_size Number of elements per side of the square matrix. (Number of coefficients = matrix_size * matrix_size).
706  *
707  * @return The absolute value of the sum of the coefficients if they don't add up to 0, otherwise 1.
708  */
709 inline uint32_t calculate_matrix_scale(const int16_t *matrix, unsigned int matrix_size)
710 {
711  const size_t size = matrix_size * matrix_size;
712 
713  return std::max(1, std::abs(std::accumulate(matrix, matrix + size, 0)));
714 }
715 
716 /** Adjust tensor shape size if width or height are odd for a given multi-planar format. No modification is done for other formats.
717  *
718  * @note Adding here a few links discussing the issue of odd size and sharing the same solution:
719  * <a href="https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/graphics/java/android/graphics/YuvImage.java">Android Source</a>
720  * <a href="https://groups.google.com/a/webmproject.org/forum/#!topic/webm-discuss/LaCKpqiDTXM">WebM</a>
721  * <a href="https://bugs.chromium.org/p/libyuv/issues/detail?id=198&amp;can=1&amp;q=odd%20width">libYUV</a>
722  * <a href="https://sourceforge.net/p/raw-yuvplayer/bugs/1/">YUVPlayer</a> *
723  *
724  * @param[in, out] shape Tensor shape of 2D size
725  * @param[in] format Format of the tensor
726  *
727  * @return The adjusted tensor shape.
728  */
730 {
731  TensorShape output{ shape };
732 
733  // Force width to be even for formats which require subsampling of the U and V channels
735  {
736  output.set(0, output.x() & ~1U);
737  }
738 
739  // Force height to be even for formats which require subsampling of the U and V channels
741  {
742  output.set(1, output.y() & ~1U);
743  }
744 
745  return output;
746 }
747 
748 /** Calculate subsampled shape for a given format and channel
749  *
750  * @param[in] shape Shape of the tensor to calculate the extracted channel.
751  * @param[in] format Format of the tensor.
752  * @param[in] channel Channel to create tensor shape to be extracted.
753  *
754  * @return The subsampled tensor shape.
755  */
757 {
758  TensorShape output{ shape };
759 
760  // Subsample shape only for U or V channel
761  if(Channel::U == channel || Channel::V == channel || Channel::UNKNOWN == channel)
762  {
763  // Subsample width for the tensor shape when channel is U or V
765  {
766  output.set(0, output.x() / 2U);
767  }
768 
769  // Subsample height for the tensor shape when channel is U or V
771  {
772  output.set(1, output.y() / 2U);
773  }
774  }
775 
776  return output;
777 }
778 
779 /** Calculate accurary required by the horizontal and vertical convolution computations
780  *
781  * @param[in] conv_col Pointer to the vertical vector of the separated convolution filter
782  * @param[in] conv_row Pointer to the horizontal vector of the convolution filter
783  * @param[in] size Number of elements per vector of the separated matrix
784  *
785  * @return The return type is a pair. The first element of the pair is the biggest data type needed for the first stage. The second
786  * element of the pair is the biggest data type needed for the second stage.
787  */
788 inline std::pair<DataType, DataType> data_type_for_convolution(const int16_t *conv_col, const int16_t *conv_row, size_t size)
789 {
790  DataType first_stage = DataType::UNKNOWN;
791  DataType second_stage = DataType::UNKNOWN;
792 
793  auto gez = [](const int16_t &v)
794  {
795  return v >= 0;
796  };
797 
798  auto accu_neg = [](const int &first, const int &second)
799  {
800  return first + (second < 0 ? second : 0);
801  };
802 
803  auto accu_pos = [](const int &first, const int &second)
804  {
805  return first + (second > 0 ? second : 0);
806  };
807 
808  const bool only_positive_coefficients = std::all_of(conv_row, conv_row + size, gez) && std::all_of(conv_col, conv_col + size, gez);
809 
810  if(only_positive_coefficients)
811  {
812  const int max_row_value = std::accumulate(conv_row, conv_row + size, 0) * UINT8_MAX;
813  const int max_value = std::accumulate(conv_col, conv_col + size, 0) * max_row_value;
814 
815  first_stage = (max_row_value <= UINT16_MAX) ? DataType::U16 : DataType::S32;
816 
817  second_stage = (max_value <= UINT16_MAX) ? DataType::U16 : DataType::S32;
818  }
819  else
820  {
821  const int min_row_value = std::accumulate(conv_row, conv_row + size, 0, accu_neg) * UINT8_MAX;
822  const int max_row_value = std::accumulate(conv_row, conv_row + size, 0, accu_pos) * UINT8_MAX;
823  const int neg_coeffs_sum = std::accumulate(conv_col, conv_col + size, 0, accu_neg);
824  const int pos_coeffs_sum = std::accumulate(conv_col, conv_col + size, 0, accu_pos);
825  const int min_value = neg_coeffs_sum * max_row_value + pos_coeffs_sum * min_row_value;
826  const int max_value = neg_coeffs_sum * min_row_value + pos_coeffs_sum * max_row_value;
827 
828  first_stage = ((INT16_MIN <= min_row_value) && (max_row_value <= INT16_MAX)) ? DataType::S16 : DataType::S32;
829 
830  second_stage = ((INT16_MIN <= min_value) && (max_value <= INT16_MAX)) ? DataType::S16 : DataType::S32;
831  }
832 
833  return std::make_pair(first_stage, second_stage);
834 }
835 
836 /** Calculate the accuracy required by the squared convolution calculation.
837  *
838  *
839  * @param[in] conv Pointer to the squared convolution matrix
840  * @param[in] size The total size of the convolution matrix
841  *
842  * @return The return is the biggest data type needed to do the convolution
843  */
844 inline DataType data_type_for_convolution_matrix(const int16_t *conv, size_t size)
845 {
846  auto gez = [](const int16_t v)
847  {
848  return v >= 0;
849  };
850 
851  const bool only_positive_coefficients = std::all_of(conv, conv + size, gez);
852 
853  if(only_positive_coefficients)
854  {
855  const int max_conv_value = std::accumulate(conv, conv + size, 0) * UINT8_MAX;
856  if(max_conv_value <= UINT16_MAX)
857  {
858  return DataType::U16;
859  }
860  else
861  {
862  return DataType::S32;
863  }
864  }
865  else
866  {
867  const int min_value = std::accumulate(conv, conv + size, 0, [](int a, int b)
868  {
869  return b < 0 ? a + b : a;
870  })
871  * UINT8_MAX;
872 
873  const int max_value = std::accumulate(conv, conv + size, 0, [](int a, int b)
874  {
875  return b > 0 ? a + b : a;
876  })
877  * UINT8_MAX;
878 
879  if((INT16_MIN <= min_value) && (INT16_MAX >= max_value))
880  {
881  return DataType::S16;
882  }
883  else
884  {
885  return DataType::S32;
886  }
887  }
888 }
889 
890 /** Permutes the given dimensions according the permutation vector
891  *
892  * @param[in,out] dimensions Dimensions to be permuted.
893  * @param[in] perm Vector describing the permutation.
894  *
895  */
896 template <typename T>
897 inline void permute_strides(Dimensions<T> &dimensions, const PermutationVector &perm)
898 {
899  const auto old_dim = utility::make_array<Dimensions<T>::num_max_dimensions>(dimensions.begin(), dimensions.end());
900  for(unsigned int i = 0; i < perm.num_dimensions(); ++i)
901  {
902  T dimension_val = old_dim[i];
903  dimensions.set(perm[i], dimension_val);
904  }
905 }
906 
907 /** Calculate padding requirements in case of SAME padding
908  *
909  * @param[in] input_shape Input shape
910  * @param[in] weights_shape Weights shape
911  * @param[in] conv_info Convolution information (containing strides)
912  * @param[in] data_layout (Optional) Data layout of the input and weights tensor
913  * @param[in] dilation (Optional) Dilation factor used in the convolution.
914  * @param[in] rounding_type (Optional) Dimension rounding type when down-scaling.
915  *
916  * @return PadStrideInfo for SAME padding
917  */
918 PadStrideInfo calculate_same_pad(TensorShape input_shape, TensorShape weights_shape, PadStrideInfo conv_info, DataLayout data_layout = DataLayout::NCHW, const Size2D &dilation = Size2D(1u, 1u),
919  const DimensionRoundingType &rounding_type = DimensionRoundingType::FLOOR);
920 
921 /** Returns expected width and height of the deconvolution's output tensor.
922  *
923  * @param[in] in_width Width of input tensor (Number of columns)
924  * @param[in] in_height Height of input tensor (Number of rows)
925  * @param[in] kernel_width Kernel width.
926  * @param[in] kernel_height Kernel height.
927  * @param[in] pad_stride_info Pad and stride information.
928  *
929  * @return A pair with the new width in the first position and the new height in the second.
930  */
931 std::pair<unsigned int, unsigned int> deconvolution_output_dimensions(unsigned int in_width, unsigned int in_height,
932  unsigned int kernel_width, unsigned int kernel_height,
933  const PadStrideInfo &pad_stride_info);
934 
935 /** Returns expected width and height of output scaled tensor depending on dimensions rounding mode.
936  *
937  * @param[in] width Width of input tensor (Number of columns)
938  * @param[in] height Height of input tensor (Number of rows)
939  * @param[in] kernel_width Kernel width.
940  * @param[in] kernel_height Kernel height.
941  * @param[in] pad_stride_info Pad and stride information.
942  * @param[in] dilation (Optional) Dilation, in elements, across x and y. Defaults to (1, 1).
943  *
944  * @return A pair with the new width in the first position and the new height in the second.
945  */
946 std::pair<unsigned int, unsigned int> scaled_dimensions(int width, int height,
947  int kernel_width, int kernel_height,
948  const PadStrideInfo &pad_stride_info,
949  const Size2D &dilation = Size2D(1U, 1U));
950 
951 /** Check if the given reduction operation should be handled in a serial way.
952  *
953  * @param[in] op Reduction operation to perform
954  * @param[in] dt Data type
955  * @param[in] axis Axis along which to reduce
956  *
957  * @return True if the given reduction operation should be handled in a serial way.
958  */
960 
961 /** Returns output quantization information for softmax layer
962  *
963  * @param[in] input_type The data type of the input tensor
964  * @param[in] is_log True for log softmax
965  *
966  * @return Quantization information for the output tensor
967  */
968 QuantizationInfo get_softmax_output_quantization_info(DataType input_type, bool is_log);
969 
970 /** Returns resize ratio between input and output with consideration of aligned corners
971  *
972  * @param[in] input_size The input size
973  * @param[in] output_size the output size
974  * @param[in] align_corners True to align corners of input and output. Defaults to false.
975  *
976  * @return The ratio between input and output (i.e., the input size divided by the output size)
977  */
978 float calculate_resize_ratio(size_t input_size, size_t output_size, bool align_corners = false);
979 
980 /** Returns a pair of minimum and maximum values for a quantized activation
981  *
982  * @param[in] act_info The information for activation
983  * @param[in] data_type The used data type
984  * @param[in] oq_info The output quantization information
985  *
986  * @return The pair with minimum and maximum values
987  */
988 std::pair<int32_t, int32_t> get_quantized_activation_min_max(ActivationLayerInfo act_info, DataType data_type, UniformQuantizationInfo oq_info);
989 
990 /** Convert a tensor format into a string.
991  *
992  * @param[in] format @ref Format to be translated to string.
993  *
994  * @return The string describing the format.
995  */
996 const std::string &string_from_format(Format format);
997 
998 /** Convert a channel identity into a string.
999  *
1000  * @param[in] channel @ref Channel to be translated to string.
1001  *
1002  * @return The string describing the channel.
1003  */
1004 const std::string &string_from_channel(Channel channel);
1005 /** Convert a data layout identity into a string.
1006  *
1007  * @param[in] dl @ref DataLayout to be translated to string.
1008  *
1009  * @return The string describing the data layout.
1010  */
1011 const std::string &string_from_data_layout(DataLayout dl);
1012 /** Convert a data type identity into a string.
1013  *
1014  * @param[in] dt @ref DataType to be translated to string.
1015  *
1016  * @return The string describing the data type.
1017  */
1018 const std::string &string_from_data_type(DataType dt);
1019 /** Convert a matrix pattern into a string.
1020  *
1021  * @param[in] pattern @ref MatrixPattern to be translated to string.
1022  *
1023  * @return The string describing the matrix pattern.
1024  */
1025 const std::string &string_from_matrix_pattern(MatrixPattern pattern);
1026 /** Translates a given activation function to a string.
1027  *
1028  * @param[in] act @ref ActivationLayerInfo::ActivationFunction to be translated to string.
1029  *
1030  * @return The string describing the activation function.
1031  */
1033 /** Translates a given non linear function to a string.
1034  *
1035  * @param[in] function @ref NonLinearFilterFunction to be translated to string.
1036  *
1037  * @return The string describing the non linear function.
1038  */
1040 /** Translates a given interpolation policy to a string.
1041  *
1042  * @param[in] policy @ref InterpolationPolicy to be translated to string.
1043  *
1044  * @return The string describing the interpolation policy.
1045  */
1047 /** Translates a given border mode policy to a string.
1048  *
1049  * @param[in] border_mode @ref BorderMode to be translated to string.
1050  *
1051  * @return The string describing the border mode.
1052  */
1053 const std::string &string_from_border_mode(BorderMode border_mode);
1054 /** Translates a given normalization type to a string.
1055  *
1056  * @param[in] type @ref NormType to be translated to string.
1057  *
1058  * @return The string describing the normalization type.
1059  */
1060 const std::string &string_from_norm_type(NormType type);
1061 /** Translates a given pooling type to a string.
1062  *
1063  * @param[in] type @ref PoolingType to be translated to string.
1064  *
1065  * @return The string describing the pooling type.
1066  */
1067 const std::string &string_from_pooling_type(PoolingType type);
1068 /** Translates a given GEMMLowp output stage to a string.
1069  *
1070  * @param[in] output_stage @ref GEMMLowpOutputStageInfo to be translated to string.
1071  *
1072  * @return The string describing the GEMMLowp output stage
1073  */
1074 const std::string &string_from_gemmlowp_output_stage(GEMMLowpOutputStageType output_stage);
1075 /** Convert a PixelValue to a string, represented through the specific data type
1076  *
1077  * @param[in] value The PixelValue to convert
1078  * @param[in] data_type The type to be used to convert the @p value
1079  *
1080  * @return String representation of the PixelValue through the given data type.
1081  */
1082 std::string string_from_pixel_value(const PixelValue &value, const DataType data_type);
1083 /** Lower a given string.
1084  *
1085  * @param[in] val Given string to lower.
1086  *
1087  * @return The lowered string
1088  */
1089 std::string lower_string(const std::string &val);
1090 
1091 /** Check if a given data type is of floating point type
1092  *
1093  * @param[in] dt Input data type.
1094  *
1095  * @return True if data type is of floating point type, else false.
1096  */
1098 {
1099  switch(dt)
1100  {
1101  case DataType::F16:
1102  case DataType::F32:
1103  return true;
1104  default:
1105  return false;
1106  }
1107 }
1108 
1109 /** Check if a given data type is of quantized type
1110  *
1111  * @note Quantized is considered a super-set of fixed-point and asymmetric data types.
1112  *
1113  * @param[in] dt Input data type.
1114  *
1115  * @return True if data type is of quantized type, else false.
1116  */
1118 {
1119  switch(dt)
1120  {
1121  case DataType::QSYMM8:
1122  case DataType::QASYMM8:
1125  case DataType::QSYMM16:
1126  case DataType::QASYMM16:
1127  return true;
1128  default:
1129  return false;
1130  }
1131 }
1132 
1133 /** Check if a given data type is of asymmetric quantized type
1134  *
1135  * @param[in] dt Input data type.
1136  *
1137  * @return True if data type is of asymmetric quantized type, else false.
1138  */
1140 {
1141  switch(dt)
1142  {
1143  case DataType::QASYMM8:
1145  case DataType::QASYMM16:
1146  return true;
1147  default:
1148  return false;
1149  }
1150 }
1151 
1152 /** Check if a given data type is of asymmetric quantized signed type
1153  *
1154  * @param[in] dt Input data type.
1155  *
1156  * @return True if data type is of asymmetric quantized signed type, else false.
1157  */
1159 {
1160  switch(dt)
1161  {
1163  return true;
1164  default:
1165  return false;
1166  }
1167 }
1168 
1169 /** Check if a given data type is of symmetric quantized type
1170  *
1171  * @param[in] dt Input data type.
1172  *
1173  * @return True if data type is of symmetric quantized type, else false.
1174  */
1176 {
1177  switch(dt)
1178  {
1179  case DataType::QSYMM8:
1181  case DataType::QSYMM16:
1182  return true;
1183  default:
1184  return false;
1185  }
1186 }
1187 
1188 /** Check if a given data type is of per channel type
1189  *
1190  * @param[in] dt Input data type.
1191  *
1192  * @return True if data type is of per channel type, else false.
1193  */
1195 {
1196  switch(dt)
1197  {
1199  return true;
1200  default:
1201  return false;
1202  }
1203 }
1204 
1205 /** Create a string with the float in full precision.
1206  *
1207  * @param val Floating point value
1208  *
1209  * @return String with the floating point value.
1210  */
1211 inline std::string float_to_string_with_full_precision(float val)
1212 {
1213  std::stringstream ss;
1214  ss.precision(std::numeric_limits<float>::max_digits10);
1215  ss << val;
1216 
1217  if(val != static_cast<int>(val))
1218  {
1219  ss << "f";
1220  }
1221 
1222  return ss.str();
1223 }
1224 
1225 /** Returns the number of elements required to go from start to end with the wanted step
1226  *
1227  * @param[in] start start value
1228  * @param[in] end end value
1229  * @param[in] step step value between each number in the wanted sequence
1230  *
1231  * @return number of elements to go from start value to end value using the wanted step
1232  */
1233 inline size_t num_of_elements_in_range(const float start, const float end, const float step)
1234 {
1235  ARM_COMPUTE_ERROR_ON_MSG(step == 0, "Range Step cannot be 0");
1236  return size_t(std::ceil((end - start) / step));
1237 }
1238 
1239 /** Returns true if the value can be represented by the given data type
1240  *
1241  * @param[in] val value to be checked
1242  * @param[in] dt data type that is checked
1243  * @param[in] qinfo (Optional) quantization info if the data type is QASYMM8
1244  *
1245  * @return true if the data type can hold the value.
1246  */
1247 template <typename T>
1249 {
1250  switch(dt)
1251  {
1252  case DataType::U8:
1253  {
1254  const auto val_u8 = static_cast<uint8_t>(val);
1255  return ((val_u8 == val) && val_u8 >= std::numeric_limits<uint8_t>::lowest() && val_u8 <= std::numeric_limits<uint8_t>::max());
1256  }
1257  case DataType::QASYMM8:
1258  {
1259  double min = static_cast<double>(dequantize_qasymm8(0, qinfo));
1260  double max = static_cast<double>(dequantize_qasymm8(std::numeric_limits<uint8_t>::max(), qinfo));
1261  return ((double)val >= min && (double)val <= max);
1262  }
1263  case DataType::S8:
1264  {
1265  const auto val_s8 = static_cast<int8_t>(val);
1266  return ((val_s8 == val) && val_s8 >= std::numeric_limits<int8_t>::lowest() && val_s8 <= std::numeric_limits<int8_t>::max());
1267  }
1268  case DataType::U16:
1269  {
1270  const auto val_u16 = static_cast<uint16_t>(val);
1271  return ((val_u16 == val) && val_u16 >= std::numeric_limits<uint16_t>::lowest() && val_u16 <= std::numeric_limits<uint16_t>::max());
1272  }
1273  case DataType::S16:
1274  {
1275  const auto val_s16 = static_cast<int16_t>(val);
1276  return ((val_s16 == val) && val_s16 >= std::numeric_limits<int16_t>::lowest() && val_s16 <= std::numeric_limits<int16_t>::max());
1277  }
1278  case DataType::U32:
1279  {
1280  const auto val_u32 = static_cast<uint32_t>(val);
1281  return ((val_u32 == val) && val_u32 >= std::numeric_limits<uint32_t>::lowest() && val_u32 <= std::numeric_limits<uint32_t>::max());
1282  }
1283  case DataType::S32:
1284  {
1285  const auto val_s32 = static_cast<int32_t>(val);
1286  return ((val_s32 == val) && val_s32 >= std::numeric_limits<int32_t>::lowest() && val_s32 <= std::numeric_limits<int32_t>::max());
1287  }
1288  case DataType::F16:
1289  return (val >= std::numeric_limits<half>::lowest() && val <= std::numeric_limits<half>::max());
1290  case DataType::F32:
1291  return (val >= std::numeric_limits<float>::lowest() && val <= std::numeric_limits<float>::max());
1292  default:
1293  ARM_COMPUTE_ERROR("Data type not supported");
1294  return false;
1295  }
1296 }
1297 
1298 #ifdef ARM_COMPUTE_ASSERTS_ENABLED
1299 /** Print consecutive elements to an output stream.
1300  *
1301  * @param[out] s Output stream to print the elements to.
1302  * @param[in] ptr Pointer to print the elements from.
1303  * @param[in] n Number of elements to print.
1304  * @param[in] stream_width (Optional) Width of the stream. If set to 0 the element's width is used. Defaults to 0.
1305  * @param[in] element_delim (Optional) Delimeter among the consecutive elements. Defaults to space delimeter
1306  */
1307 template <typename T>
1308 void print_consecutive_elements_impl(std::ostream &s, const T *ptr, unsigned int n, int stream_width = 0, const std::string &element_delim = " ")
1309 {
1310  using print_type = typename std::conditional<std::is_floating_point<T>::value, T, int>::type;
1311  std::ios stream_status(nullptr);
1312  stream_status.copyfmt(s);
1313 
1314  for(unsigned int i = 0; i < n; ++i)
1315  {
1316  // Set stream width as it is not a "sticky" stream manipulator
1317  if(stream_width != 0)
1318  {
1319  s.width(stream_width);
1320  }
1321 
1322  if(std::is_same<typename std::decay<T>::type, half>::value)
1323  {
1324  // We use T instead of print_type here is because the std::is_floating_point<half> returns false and then the print_type becomes int.
1325  s << std::right << static_cast<T>(ptr[i]) << element_delim;
1326  }
1327  else
1328  {
1329  s << std::right << static_cast<print_type>(ptr[i]) << element_delim;
1330  }
1331  }
1332 
1333  // Restore output stream flags
1334  s.copyfmt(stream_status);
1335 }
1336 
1337 /** Identify the maximum width of n consecutive elements.
1338  *
1339  * @param[in] s The output stream which will be used to print the elements. Used to extract the stream format.
1340  * @param[in] ptr Pointer to the elements.
1341  * @param[in] n Number of elements.
1342  *
1343  * @return The maximum width of the elements.
1344  */
1345 template <typename T>
1346 int max_consecutive_elements_display_width_impl(std::ostream &s, const T *ptr, unsigned int n)
1347 {
1348  using print_type = typename std::conditional<std::is_floating_point<T>::value, T, int>::type;
1349 
1350  int max_width = -1;
1351  for(unsigned int i = 0; i < n; ++i)
1352  {
1353  std::stringstream ss;
1354  ss.copyfmt(s);
1355 
1356  if(std::is_same<typename std::decay<T>::type, half>::value)
1357  {
1358  // We use T instead of print_type here is because the std::is_floating_point<half> returns false and then the print_type becomes int.
1359  ss << static_cast<T>(ptr[i]);
1360  }
1361  else
1362  {
1363  ss << static_cast<print_type>(ptr[i]);
1364  }
1365 
1366  max_width = std::max<int>(max_width, ss.str().size());
1367  }
1368  return max_width;
1369 }
1370 
1371 /** Print consecutive elements to an output stream.
1372  *
1373  * @param[out] s Output stream to print the elements to.
1374  * @param[in] dt Data type of the elements
1375  * @param[in] ptr Pointer to print the elements from.
1376  * @param[in] n Number of elements to print.
1377  * @param[in] stream_width (Optional) Width of the stream. If set to 0 the element's width is used. Defaults to 0.
1378  * @param[in] element_delim (Optional) Delimeter among the consecutive elements. Defaults to space delimeter
1379  */
1380 void print_consecutive_elements(std::ostream &s, DataType dt, const uint8_t *ptr, unsigned int n, int stream_width, const std::string &element_delim = " ");
1381 
1382 /** Identify the maximum width of n consecutive elements.
1383  *
1384  * @param[in] s Output stream to print the elements to.
1385  * @param[in] dt Data type of the elements
1386  * @param[in] ptr Pointer to print the elements from.
1387  * @param[in] n Number of elements to print.
1388  *
1389  * @return The maximum width of the elements.
1390  */
1391 int max_consecutive_elements_display_width(std::ostream &s, DataType dt, const uint8_t *ptr, unsigned int n);
1392 #endif /* ARM_COMPUTE_ASSERTS_ENABLED */
1393 }
1394 #endif /*ARM_COMPUTE_UTILS_H */
BorderMode
Methods available to handle borders.
Definition: Types.h:261
bool is_data_type_quantized(DataType dt)
Check if a given data type is of quantized type.
Definition: Utils.h:1117
bool needs_serialized_reduction(ReductionOperation op, DataType dt, unsigned int axis)
Check if the given reduction operation should be handled in a serial way.
Definition: Utils.cpp:436
Class describing the value of a pixel for any image format.
Definition: PixelValue.h:34
A single plane of 32-bit macro pixel of U0, Y0, V0, Y1 byte.
InterpolationPolicy
Interpolation method.
Definition: Types.h:366
bool has_format_vertical_subsampling(Format format)
Return true if the given format has vertical subsampling.
Definition: Utils.h:635
Shape of a tensor.
Definition: TensorShape.h:39
const DataLayout data_layout
Definition: Im2Col.cpp:146
quantized, symmetric fixed-point 16-bit number
int plane_idx_from_channel(Format format, Channel channel)
Return the plane index of a given channel given an input format.
Definition: Utils.h:260
TensorShape calculate_subsampled_shape(const TensorShape &shape, Format format, Channel channel=Channel::UNKNOWN)
Calculate subsampled shape for a given format and channel.
Definition: Utils.h:756
float dequantize_qasymm8(uint8_t value, const INFO_TYPE &qinfo)
Dequantize a value given an unsigned 8-bit asymmetric quantization scheme.
ReductionOperation
Available reduction operations.
Definition: Types.h:495
const std::string & string_from_matrix_pattern(MatrixPattern pattern)
Convert a matrix pattern into a string.
Definition: Utils.cpp:194
SimpleTensor< float > b
Definition: DFT.cpp:157
void permute_strides(Dimensions< T > &dimensions, const PermutationVector &perm)
Permutes the given dimensions according the permutation vector.
Definition: Utils.h:897
size_t num_planes_from_format(Format format)
Return the number of planes for a given format.
Definition: Utils.h:448
const std::string & string_from_channel(Channel channel)
Convert a channel identity into a string.
Definition: Utils.cpp:111
std::pair< unsigned int, unsigned int > deconvolution_output_dimensions(unsigned int in_width, unsigned int in_height, unsigned int kernel_width, unsigned int kernel_height, const PadStrideInfo &pad_stride_info)
Returns expected width and height of the deconvolution's output tensor.
Definition: Utils.cpp:382
Cr/V/Value channel.
#define ARM_COMPUTE_ERROR(msg)
Print the given message then throw an std::runtime_error.
Definition: Error.h:352
1 channel, 1 U8 per channel
size_t element_size_from_data_type(DataType dt)
The size in bytes of the data type.
Definition: Utils.h:186
half_float::half half
16-bit floating point type
Definition: Types.h:45
1 channel, 1 F32 per channel
DimensionRoundingType
Dimension rounding type when down-scaling on CNNs.
Definition: Types.h:567
std::pair< DataType, DataType > data_type_for_convolution(const int16_t *conv_col, const int16_t *conv_row, size_t size)
Calculate accurary required by the horizontal and vertical convolution computations.
Definition: Utils.h:788
std::string string_from_pixel_value(const PixelValue &value, const DataType data_type)
Convert a PixelValue to a string, represented through the specific data type.
Definition: Utils.cpp:280
#define ARM_COMPUTE_ERROR_ON(cond)
If the condition is true then an error message is printed and an exception thrown.
Definition: Error.h:466
float calculate_resize_ratio(size_t input_size, size_t output_size, bool align_corners=false)
Returns resize ratio between input and output with consideration of aligned corners.
Definition: Utils.cpp:466
size_t num_channels_from_format(Format format)
Return the number of channels for a given single-planar pixel format.
Definition: Utils.h:482
const std::string & string_from_activation_func(ActivationLayerInfo::ActivationFunction act)
Translates a given activation function to a string.
Definition: Utils.cpp:172
A 2 plane YUV format of Luma (Y) and interleaved UV data at 4:2:0 sampling.
QuantizationInfo get_softmax_output_quantization_info(DataType input_type, bool is_log)
Returns output quantization information for softmax layer.
Definition: Utils.cpp:445
quantized, asymmetric fixed-point 16-bit number
1 channel, 1 U16 per channel
const std::string & string_from_gemmlowp_output_stage(GEMMLowpOutputStageType output_stage)
Translates a given GEMMLowp output stage to a string.
Definition: Utils.cpp:267
std::string lower_string(const std::string &val)
Lower a given string.
Definition: Utils.cpp:333
bool is_data_type_quantized_symmetric(DataType dt)
Check if a given data type is of symmetric quantized type.
Definition: Utils.h:1175
void set(size_t dimension, T value)
Accessor to set the value of one of the dimensions.
Definition: Dimensions.h:74
uint32_t calculate_matrix_scale(const int16_t *matrix, unsigned int matrix_size)
Calculate the scale of the given square matrix.
Definition: Utils.h:709
auto floor_to_multiple(S value, T divisor) -> decltype((value/divisor) *divisor)
Computes the largest number smaller or equal to value that is a multiple of divisor.
Definition: Utils.h:80
A 2 plane YUV format of Luma (Y) and interleaved VU data at 4:2:0 sampling.
Copyright (c) 2017-2020 ARM Limited.
ActivationFunction
Available activation functions.
Definition: Types.h:1619
1 channel, 1 F16 per channel
constexpr auto DIV_CEIL(S val, T m) -> decltype((val+m - 1)/m)
Calculate the rounded up quotient of val / m.
Definition: Utils.h:53
std::pair< unsigned int, unsigned int > scaled_dimensions(int width, int height, int kernel_width, int kernel_height, const PadStrideInfo &pad_stride_info, const Size2D &dilation=Size2D(1U, 1U))
Returns expected width and height of output scaled tensor depending on dimensions rounding mode.
Definition: Utils.cpp:402
const std::string & string_from_norm_type(NormType type)
Translates a given normalization type to a string.
Definition: Utils.cpp:243
std::array< int16_t, 25 > conv
const std::string & string_from_border_mode(BorderMode border_mode)
Translates a given border mode policy to a string.
Definition: Utils.cpp:231
1 channel, 1 S32 per channel
signed 64-bit number
3 channels, 1 U8 per channel
Quantization information.
const std::string & string_from_data_type(DataType dt)
Convert a data type identity into a string.
Definition: Utils.cpp:144
DataType get_promoted_data_type(DataType dt)
Return the promoted data type of a given data type.
Definition: Utils.h:523
std::string read_file(const std::string &filename, bool binary)
Load an entire file in memory.
Definition: Utils.cpp:47
1 channel, 1 U32 per channel
bool is_data_type_quantized_per_channel(DataType dt)
Check if a given data type is of per channel type.
Definition: Utils.h:1194
std::string float_to_string_with_full_precision(float val)
Create a string with the float in full precision.
Definition: Utils.h:1211
bool check_value_range(T val, DataType dt, QuantizationInfo qinfo=QuantizationInfo())
Returns true if the value can be represented by the given data type.
Definition: Utils.h:1248
Channel
Available channels.
Definition: Types.h:461
Format
Image colour formats.
Definition: Types.h:53
std::pair< int32_t, int32_t > get_quantized_activation_min_max(ActivationLayerInfo act_info, DataType data_type, UniformQuantizationInfo oq_info)
Returns a pair of minimum and maximum values for a quantized activation.
Definition: Utils.cpp:478
auto ceil_to_multiple(S value, T divisor) -> decltype(((value+divisor - 1)/divisor) *divisor)
Computes the smallest number larger or equal to value that is a multiple of divisor.
Definition: Utils.h:66
quantized, asymmetric fixed-point 8-bit number unsigned
#define ARM_COMPUTE_ERROR_ON_MSG(cond, msg)
Definition: Error.h:456
const std::string & string_from_interpolation_policy(InterpolationPolicy policy)
Translates a given interpolation policy to a string.
Definition: Utils.cpp:219
bool is_data_type_quantized_asymmetric_signed(DataType dt)
Check if a given data type is of asymmetric quantized signed type.
Definition: Utils.h:1158
Dimensions with dimensionality.
Definition: Dimensions.h:41
A 3 plane of 8 bit 4:4:4 sampled Y, U, V planes.
size_t data_size_from_type(DataType data_type)
The size in bytes of the data type.
Definition: Utils.h:109
const std::string & string_from_non_linear_filter_function(NonLinearFilterFunction function)
Translates a given non linear function to a string.
Definition: Utils.cpp:207
std::array< T, num_max_dimensions >::iterator begin()
Returns a read/write iterator that points to the first element in the dimension array.
Definition: Dimensions.h:194
GEMMLowpOutputStageType
GEMMLowp output stage type.
Definition: Types.h:1935
size_t num_of_elements_in_range(const float start, const float end, const float step)
Returns the number of elements required to go from start to end with the wanted step.
Definition: Utils.h:1233
1 channel, 1 S16 per channel
quantized, symmetric fixed-point 8-bit number
Num samples, channels, height, width.
TensorShape adjust_odd_shape(const TensorShape &shape, Format format)
Adjust tensor shape size if width or height are odd for a given multi-planar format.
Definition: Utils.h:729
DataType data_type_from_format(Format format)
Return the data type used by a given single-planar pixel format.
Definition: Utils.h:219
bool is_data_type_quantized_asymmetric(DataType dt)
Check if a given data type is of asymmetric quantized type.
Definition: Utils.h:1139
Strides of an item in bytes.
Definition: Strides.h:37
quantized, symmetric per channel fixed-point 8-bit number
A 3 plane of 8-bit 4:2:0 sampled Y, U, V planes.
4 channels, 1 U8 per channel
PoolingType
Available pooling types.
Definition: Types.h:574
std::array< T, num_max_dimensions >::iterator end()
Returns a read/write iterator that points one past the last element in the dimension array.
Definition: Dimensions.h:218
const std::string & string_from_data_layout(DataLayout dl)
Convert a data layout identity into a string.
Definition: Utils.cpp:132
size_t pixel_size_from_format(Format format)
The size in bytes of the pixel format.
Definition: Utils.h:148
const QuantizationInfo qinfo
Definition: Im2Col.cpp:150
unsigned int num_dimensions() const
Returns the effective dimensionality of the tensor.
Definition: Dimensions.h:122
2 channel, 1 U8 per channel
std::string build_information()
Returns the arm_compute library build information.
bool has_format_horizontal_subsampling(Format format)
Return true if the given format has horizontal subsampling.
Definition: Utils.h:624
__kernel void accumulate(__global uchar *input_ptr, uint input_stride_x, uint input_step_x, uint input_stride_y, uint input_step_y, uint input_offset_first_element_in_bytes, __global uchar *accu_ptr, uint accu_stride_x, uint accu_step_x, uint accu_stride_y, uint accu_step_y, uint accu_offset_first_element_in_bytes)
This function accumulates an input image into output image.
Definition: accumulate.cl:41
bool separate_matrix(const int16_t *conv, int16_t *conv_col, int16_t *conv_row, uint8_t size)
Separate a 2D convolution into two 1D convolutions.
Definition: Utils.h:649
quantized, asymmetric fixed-point 8-bit number signed
64-bit floating-point number
A single plane of 32-bit macro pixel of Y0, U0, Y1, V0 bytes.
unsigned 64-bit number
DataType
Available data types.
Definition: Types.h:75
DataLayout
[DataLayout enum definition]
Definition: Types.h:117
const std::string & string_from_pooling_type(PoolingType type)
Translates a given pooling type to a string.
Definition: Utils.cpp:255
NormType
The normalization type used for the normalization layer.
Definition: Types.h:533
signed 8-bit number
MatrixPattern
Available matrix patterns.
Definition: Types.h:478
std::tuple< PixelValue, PixelValue > get_min_max(DataType dt)
Compute the mininum and maximum values a data type can take.
Definition: Utils.h:558
NonLinearFilterFunction
Available non linear functions.
Definition: Types.h:487
bool is_data_type_float(DataType dt)
Check if a given data type is of floating point type.
Definition: Utils.h:1097
int channel_idx_from_format(Format format, Channel channel)
Return the channel index of a given channel given an input format.
Definition: Utils.h:324
PadStrideInfo calculate_same_pad(TensorShape input_shape, TensorShape weights_shape, PadStrideInfo conv_info, DataLayout data_layout=DataLayout::NCHW, const Size2D &dilation=Size2D(1u, 1u), const DimensionRoundingType &rounding_type=DimensionRoundingType::FLOOR)
Calculate padding requirements in case of SAME padding.
Definition: Utils.cpp:340
DataType data_type_for_convolution_matrix(const int16_t *conv, size_t size)
Calculate the accuracy required by the squared convolution calculation.
Definition: Utils.h:844
const std::string & string_from_format(Format format)
Convert a tensor format into a string.
Definition: Utils.cpp:85