ArmNN
 20.05
TypesUtils.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #include <armnn/TypesUtils.hpp>
7 
8 #include <boost/numeric/conversion/cast.hpp>
9 
10 namespace
11 {
12 /// Workaround for std:isnan() not being implemented correctly for integral types in MSVC.
13 /// https://stackoverflow.com/a/56356405
14 /// @{
15 template <typename T, typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
16 inline int IsNan(T x)
17 {
18  // The spec defines integral types to be handled as if they were casted to doubles.
19  return std::isnan(static_cast<double>(x));
20 }
21 
22 template <typename T, typename std::enable_if<!std::is_integral<T>::value, T>::type * = nullptr>
23 inline int IsNan(T x)
24 {
25  return std::isnan(x);
26 }
27 /// @}
28 } // namespace std
29 
30 template<typename QuantizedType>
31 QuantizedType armnn::Quantize(float value, float scale, int32_t offset)
32 {
33  static_assert(IsQuantizedType<QuantizedType>(), "Not an integer type.");
34  constexpr QuantizedType max = std::numeric_limits<QuantizedType>::max();
35  constexpr QuantizedType min = std::numeric_limits<QuantizedType>::lowest();
36  ARMNN_ASSERT(scale != 0.f);
37  ARMNN_ASSERT(!std::isnan(value));
38 
39  float clampedValue = std::min(std::max(static_cast<float>(round(value/scale) + offset), static_cast<float>(min)),
40  static_cast<float>(max));
41  auto quantizedBits = static_cast<QuantizedType>(clampedValue);
42 
43  return quantizedBits;
44 }
45 
46 template <typename QuantizedType>
47 float armnn::Dequantize(QuantizedType value, float scale, int32_t offset)
48 {
49  static_assert(IsQuantizedType<QuantizedType>(), "Not an integer type.");
50  ARMNN_ASSERT(scale != 0.f);
51  ARMNN_ASSERT(!IsNan(value));
52  float dequantized = boost::numeric_cast<float>(value - offset) * scale;
53  return dequantized;
54 }
55 
56 /// Explicit specialization of Quantize for int8_t
57 template
58 int8_t armnn::Quantize<int8_t>(float value, float scale, int32_t offset);
59 
60 /// Explicit specialization of Quantize for uint8_t
61 template
62 uint8_t armnn::Quantize<uint8_t>(float value, float scale, int32_t offset);
63 
64 /// Explicit specialization of Quantize for int16_t
65 template
66 int16_t armnn::Quantize<int16_t>(float value, float scale, int32_t offset);
67 
68 /// Explicit specialization of Quantize for int32_t
69 template
70 int32_t armnn::Quantize<int32_t>(float value, float scale, int32_t offset);
71 
72 /// Explicit specialization of Dequantize for int8_t
73 template
74 float armnn::Dequantize<int8_t>(int8_t value, float scale, int32_t offset);
75 
76 /// Explicit specialization of Dequantize for uint8_t
77 template
78 float armnn::Dequantize<uint8_t>(uint8_t value, float scale, int32_t offset);
79 
80 /// Explicit specialization of Dequantize for int16_t
81 template
82 float armnn::Dequantize<int16_t>(int16_t value, float scale, int32_t offset);
83 
84 /// Explicit specialization of Dequantize for int32_t
85 template
86 float armnn::Dequantize<int32_t>(int32_t value, float scale, int32_t offset);
float Dequantize(QuantizedType value, float scale, int32_t offset)
Dequantize an 8-bit data type into a floating point data type.
Definition: TypesUtils.cpp:47
#define ARMNN_ASSERT(COND)
Definition: Assert.hpp:14
QuantizedType Quantize(float value, float scale, int32_t offset)
Quantize a floating point data type into an 8-bit data type.
Definition: TypesUtils.cpp:31
std::enable_if_t< std::is_unsigned< Source >::value &&std::is_unsigned< Dest >::value, Dest > numeric_cast(Source source)
Definition: NumericCast.hpp:33