1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
//
// Copyright © 2017 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//
#pragma once
#include <armnn/utility/IgnoreUnused.hpp>
#include <armnn/utility/NumericCast.hpp>
#include <armnn/TypesUtils.hpp>
#include <BFloat16.hpp>
#include <Half.hpp>
#include <initializer_list>
#include <iterator>
#include <vector>
namespace armnnUtils
{
template<typename T, bool DoQuantize=true>
struct SelectiveQuantizer
{
static T Quantize(float value, float scale, int32_t offset)
{
return armnn::Quantize<T>(value, scale, offset);
}
static float Dequantize(T value, float scale, int32_t offset)
{
return armnn::Dequantize(value, scale, offset);
}
};
template<typename T>
struct SelectiveQuantizer<T, false>
{
static T Quantize(float value, float scale, int32_t offset)
{
armnn::IgnoreUnused(scale, offset);
return value;
}
static float Dequantize(T value, float scale, int32_t offset)
{
armnn::IgnoreUnused(scale, offset);
return value;
}
};
template<>
struct SelectiveQuantizer<armnn::Half, false>
{
static armnn::Half Quantize(float value, float scale, int32_t offset)
{
armnn::IgnoreUnused(scale, offset);
return armnn::Half(value);
}
static float Dequantize(armnn::Half value, float scale, int32_t offset)
{
armnn::IgnoreUnused(scale, offset);
return value;
}
};
template<>
struct SelectiveQuantizer<armnn::BFloat16, false>
{
static armnn::BFloat16 Quantize(float value, float scale, int32_t offset)
{
armnn::IgnoreUnused(scale, offset);
return armnn::BFloat16(value);
}
static float Dequantize(armnn::BFloat16 value, float scale, int32_t offset)
{
armnn::IgnoreUnused(scale, offset);
return value;
}
};
template<typename T>
T SelectiveQuantize(float value, float scale, int32_t offset)
{
return SelectiveQuantizer<T, armnn::IsQuantizedType<T>()>::Quantize(value, scale, offset);
};
template<typename T>
float SelectiveDequantize(T value, float scale, int32_t offset)
{
return SelectiveQuantizer<T, armnn::IsQuantizedType<T>()>::Dequantize(value, scale, offset);
};
template<typename ItType>
struct IsFloatingPointIterator
{
static constexpr bool value=std::is_floating_point<typename std::iterator_traits<ItType>::value_type>::value;
};
template <typename T, typename FloatIt,
typename std::enable_if<IsFloatingPointIterator<FloatIt>::value, int>::type=0 // Makes sure fp iterator is valid.
>
std::vector<T> QuantizedVector(FloatIt first, FloatIt last, float qScale, int32_t qOffset)
{
std::vector<T> quantized;
quantized.reserve(armnn::numeric_cast<size_t>(std::distance(first, last)));
for (auto it = first; it != last; ++it)
{
auto f = *it;
T q = SelectiveQuantize<T>(f, qScale, qOffset);
quantized.push_back(q);
}
return quantized;
}
template<typename T>
std::vector<T> QuantizedVector(const std::vector<float>& array, float qScale = 1.f, int32_t qOffset = 0)
{
return QuantizedVector<T>(array.begin(), array.end(), qScale, qOffset);
}
template<typename T>
std::vector<T> QuantizedVector(std::initializer_list<float> array, float qScale = 1.f, int32_t qOffset = 0)
{
return QuantizedVector<T>(array.begin(), array.end(), qScale, qOffset);
}
} // namespace armnnUtils
|