From ae6ef7cb55af14dc25f85c6957edbba31d778d1f Mon Sep 17 00:00:00 2001 From: Sang-Hoon Park Date: Wed, 13 Nov 2019 16:51:45 +0000 Subject: COMPMID-2763 convert functions and helpers for QASYMM8_SIGNED Helpers and functions are modified to add capabilities to convert from/to QASYMM8_SIGNED. Change-Id: Iadd94f9a8469da77421d6987ce67738cf16a1c52 Signed-off-by: Sang-Hoon Park Reviewed-on: https://review.mlplatform.org/c/2288 Comments-Addressed: Arm Jenkins Tested-by: Arm Jenkins Reviewed-by: Michele Di Giorgio Reviewed-by: Georgios Pinitas --- arm_compute/core/QuantizationInfo.h | 104 ++++++++++++++++++++++++++++-------- 1 file changed, 83 insertions(+), 21 deletions(-) (limited to 'arm_compute/core/QuantizationInfo.h') diff --git a/arm_compute/core/QuantizationInfo.h b/arm_compute/core/QuantizationInfo.h index ebd9b677da..7a6fe42098 100644 --- a/arm_compute/core/QuantizationInfo.h +++ b/arm_compute/core/QuantizationInfo.h @@ -21,13 +21,14 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef __ARM_COMPUTE_QUANTIZATION_INFO_H__ -#define __ARM_COMPUTE_QUANTIZATION_INFO_H__ +#ifndef ARM_COMPUTE_QUANTIZATION_INFO_H +#define ARM_COMPUTE_QUANTIZATION_INFO_H #include "arm_compute/core/Rounding.h" #include "utils/misc/Utility.h" #include +#include #include namespace arm_compute @@ -204,8 +205,71 @@ inline bool operator!=(const UniformQuantizationInfo &lhs, const UniformQuantiza { return !(operator==(lhs, rhs)); } +template +struct Qasymm8QuantizationHelper +{ + static_assert(std::is_same::value + || std::is_same::value, + "quantized type should be either uint8_t or int8_t."); + + /** Quantize a value given a 8-bit asymmetric quantization scheme + * + * @param[in] value Value to quantize + * @param[in] qinfo Quantization information to use for quantizing + * @param[in] rounding_policy (Optional) Rounding policy to use. Default: nearest up + * + * @return Quantized value + */ + static inline QUANTIZED_TYPE quantize(float value, const UniformQuantizationInfo &qinfo, RoundingPolicy rounding_policy = RoundingPolicy::TO_NEAREST_UP) + { + ARM_COMPUTE_ERROR_ON(qinfo.scale == 0); + const int quantized = arm_compute::round(value / qinfo.scale, rounding_policy) + qinfo.offset; + return static_cast(arm_compute::utility::clamp(quantized)); + } + + /** Quantize a value given a 8-bit asymmetric quantization scheme + * + * @param[in] value Value to quantize + * @param[in] qinfo Quantization information to use for quantizing + * @param[in] rounding_policy (Optional) Rounding policy to use. Default: nearest up + * + * @return Quantized value + */ + static inline QUANTIZED_TYPE quantize(float value, const QuantizationInfo &qinfo, RoundingPolicy rounding_policy = RoundingPolicy::TO_NEAREST_UP) + { + const UniformQuantizationInfo uqinfo = qinfo.uniform(); + ARM_COMPUTE_ERROR_ON(uqinfo.scale == 0); + const int quantized = arm_compute::round(value / uqinfo.scale, rounding_policy) + uqinfo.offset; + return static_cast(arm_compute::utility::clamp(quantized)); + } + + /** Dequantize a value given a 8-bit asymmetric quantization scheme + * + * @param[in] value Value to dequantize + * @param[in] qinfo Quantization information to use for dequantizing + * + * @return Dequantized value + */ + static inline float dequantize(QUANTIZED_TYPE value, const UniformQuantizationInfo &qinfo) + { + return (static_cast(value) - qinfo.offset) * qinfo.scale; + } -/** Quantize a value given a 8-bit asymmetric quantization scheme + /** Dequantize a value given a 8-bit asymmetric quantization scheme + * + * @param[in] value Value to dequantize + * @param[in] qinfo Quantization information to use for dequantizing + * + * @return Dequantized value + */ + static inline float dequantize(QUANTIZED_TYPE value, const QuantizationInfo &qinfo) + { + const UniformQuantizationInfo uqinfo = qinfo.uniform(); + return (static_cast(value) - uqinfo.offset) * uqinfo.scale; + } +}; + +/** Quantize a value given an unsigned 8-bit asymmetric quantization scheme * * @param[in] value Value to quantize * @param[in] qinfo Quantization information to use for quantizing @@ -213,14 +277,13 @@ inline bool operator!=(const UniformQuantizationInfo &lhs, const UniformQuantiza * * @return Quantized value */ -inline uint8_t quantize_qasymm8(float value, const UniformQuantizationInfo &qinfo, RoundingPolicy rounding_policy = RoundingPolicy::TO_NEAREST_UP) +template +inline uint8_t quantize_qasymm8(float value, const INFO_TYPE &qinfo, RoundingPolicy rounding_policy = RoundingPolicy::TO_NEAREST_UP) { - int quantized = arm_compute::round(value / qinfo.scale, rounding_policy) + qinfo.offset; - quantized = std::max(0, std::min(quantized, 255)); - return quantized; + return Qasymm8QuantizationHelper::quantize(value, qinfo, rounding_policy); } -/** Quantize a value given a 8-bit asymmetric quantization scheme +/** Quantize a value given a signed 8-bit asymmetric quantization scheme * * @param[in] value Value to quantize * @param[in] qinfo Quantization information to use for quantizing @@ -228,12 +291,10 @@ inline uint8_t quantize_qasymm8(float value, const UniformQuantizationInfo &qinf * * @return Quantized value */ -inline uint8_t quantize_qasymm8(float value, const QuantizationInfo &qinfo, RoundingPolicy rounding_policy = RoundingPolicy::TO_NEAREST_UP) +template +inline int8_t quantize_qasymm8_signed(float value, const INFO_TYPE &qinfo, RoundingPolicy rounding_policy = RoundingPolicy::TO_NEAREST_UP) { - UniformQuantizationInfo uqinfo = qinfo.uniform(); - int quantized = arm_compute::round(value / uqinfo.scale, rounding_policy) + uqinfo.offset; - quantized = std::max(0, std::min(quantized, 255)); - return quantized; + return Qasymm8QuantizationHelper::quantize(value, qinfo, rounding_policy); } /** Quantize a value given a 8-bit symmetric quantization scheme @@ -265,29 +326,30 @@ inline int8_t quantize_qsymm8_per_channel(float value, const QuantizationInfo &q return quantized; } -/** Dequantize a value given a 8-bit asymmetric quantization scheme +/** Dequantize a value given an unsigned 8-bit asymmetric quantization scheme * * @param[in] value Value to dequantize * @param[in] qinfo Quantization information to use for dequantizing * * @return Dequantized value */ -inline float dequantize_qasymm8(uint8_t value, const UniformQuantizationInfo &qinfo) +template +inline float dequantize_qasymm8(uint8_t value, const INFO_TYPE &qinfo) { - return (static_cast(value) - qinfo.offset) * qinfo.scale; + return Qasymm8QuantizationHelper::dequantize(value, qinfo); } -/** Dequantize a value given a 8-bit asymmetric quantization scheme +/** Dequantize a value given a signed 8-bit asymmetric quantization scheme * * @param[in] value Value to dequantize * @param[in] qinfo Quantization information to use for dequantizing * * @return Dequantized value */ -inline float dequantize_qasymm8(uint8_t value, const QuantizationInfo &qinfo) +template +inline float dequantize_qasymm8_signed(int8_t value, const INFO_TYPE &qinfo) { - UniformQuantizationInfo uqinfo = qinfo.uniform(); - return (static_cast(value) - uqinfo.offset) * uqinfo.scale; + return Qasymm8QuantizationHelper::dequantize(value, qinfo); } /** Dequantize a value given an 8-bit asymmetric quantization scheme @@ -454,4 +516,4 @@ inline float dequantize_qasymm16(uint16_t value, const QuantizationInfo &qinfo) return dequantize_qasymm16(value, qinfo.uniform()); } } // namespace arm_compute -#endif /*__ARM_COMPUTE_QUANTIZATION_INFO_H__ */ +#endif /* ARM_COMPUTE_QUANTIZATION_INFO_H */ -- cgit v1.2.1