From fb6aaeb3b02ad3210d57c1d945998f93c11de474 Mon Sep 17 00:00:00 2001 From: Sang-Hoon Park Date: Wed, 27 Nov 2019 15:26:44 +0000 Subject: COMPMID-2773 [NE] add support for QASYMM8_SIGNED to QuantizationLayer Change-Id: Ib692a79228fd85ee600c212d77439ca38d71f332 Signed-off-by: Sang-Hoon Park Reviewed-on: https://review.mlplatform.org/c/2377 Comments-Addressed: Arm Jenkins Tested-by: Arm Jenkins Reviewed-by: Michele Di Giorgio --- .../NEON/kernels/NEQuantizationLayerKernel.cpp | 49 +++++++++++++++------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'src/core') diff --git a/src/core/NEON/kernels/NEQuantizationLayerKernel.cpp b/src/core/NEON/kernels/NEQuantizationLayerKernel.cpp index 6a9c4ae14c..2beb730448 100644 --- a/src/core/NEON/kernels/NEQuantizationLayerKernel.cpp +++ b/src/core/NEON/kernels/NEQuantizationLayerKernel.cpp @@ -40,13 +40,15 @@ namespace arm_compute { namespace { +constexpr auto window_step = 16; + Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output) { ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, output); ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(input); ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::F16, DataType::F32); ARM_COMPUTE_RETURN_ERROR_ON(output->tensor_shape().total_size() == 0); - ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(output, 1, DataType::QASYMM8, DataType::QASYMM16); + ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(output, 1, DataType::QASYMM8, DataType::QASYMM8_SIGNED, DataType::QASYMM16); ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(input, output); return Status{}; @@ -69,6 +71,25 @@ inline const float32x4x4_t load_value(const float16_t *input_ptr) } #endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC + +template +using vector_type = wrapper::traits::neon_vector_t; + +template +vector_type vquantize_qasymm8(const float32x4x4_t &qv, const UniformQuantizationInfo &qi); + +template <> +vector_type vquantize_qasymm8(const float32x4x4_t &qv, const UniformQuantizationInfo &qi) +{ + return vquantize(qv, qi); +} + +template <> +vector_type vquantize_qasymm8(const float32x4x4_t &qv, const UniformQuantizationInfo &qi) +{ + return vquantize_signed(qv, qi); +} + } // namespace NEQuantizationLayerKernel::NEQuantizationLayerKernel() @@ -86,13 +107,15 @@ void NEQuantizationLayerKernel::configure(const ITensor *input, ITensor *output) static std::map quant_map_f32 = { - { DataType::QASYMM8, &NEQuantizationLayerKernel::run_quantize_qasymm8 }, + { DataType::QASYMM8, &NEQuantizationLayerKernel::run_quantize_qasymm8 }, + { DataType::QASYMM8_SIGNED, &NEQuantizationLayerKernel::run_quantize_qasymm8 }, { DataType::QASYMM16, &NEQuantizationLayerKernel::run_quantize_qasymm16 }, }; #ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC static std::map quant_map_f16 = { - { DataType::QASYMM8, &NEQuantizationLayerKernel::run_quantize_qasymm8 }, + { DataType::QASYMM8, &NEQuantizationLayerKernel::run_quantize_qasymm8 }, + { DataType::QASYMM8_SIGNED, &NEQuantizationLayerKernel::run_quantize_qasymm8 }, { DataType::QASYMM16, &NEQuantizationLayerKernel::run_quantize_qasymm16 }, }; #endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC*/ @@ -127,12 +150,11 @@ Status NEQuantizationLayerKernel::validate(const ITensorInfo *input, const ITens return Status{}; } -template +template void NEQuantizationLayerKernel::run_quantize_qasymm8(const Window &window) { - constexpr auto window_step = 16; - const auto window_start_x = static_cast(window.x().start()); - const auto window_end_x = static_cast(window.x().end()); + const auto window_start_x = static_cast(window.x().start()); + const auto window_end_x = static_cast(window.x().end()); const UniformQuantizationInfo uqinfo = _output->info()->quantization_info().uniform(); #ifdef __aarch64__ @@ -149,18 +171,18 @@ void NEQuantizationLayerKernel::run_quantize_qasymm8(const Window &window) Iterator output(_output, win_collapsed); execute_window_loop(win_collapsed, [&](const Coordinates &) { - auto input_ptr = reinterpret_cast(input.ptr()); - auto output_ptr = reinterpret_cast(output.ptr()); + auto input_ptr = reinterpret_cast(input.ptr()); + auto output_ptr = reinterpret_cast(output.ptr()); int x = window_start_x; for(; x <= (window_end_x - window_step); x += window_step) { - wrapper::vstore(&output_ptr[x], vquantize(load_value(&input_ptr[x]), uqinfo)); + wrapper::vstore(&output_ptr[x], vquantize_qasymm8(load_value(&input_ptr[x]), uqinfo)); } // Compute left-over elements for(; x < window_end_x; ++x) { - output_ptr[x] = quantize_qasymm8(input_ptr[x], uqinfo, rounding_policy); + output_ptr[x] = Qasymm8QuantizationHelper::quantize(input_ptr[x], uqinfo, rounding_policy); } }, input, output); @@ -169,9 +191,8 @@ void NEQuantizationLayerKernel::run_quantize_qasymm8(const Window &window) template void NEQuantizationLayerKernel::run_quantize_qasymm16(const Window &window) { - constexpr auto window_step = 16; - const auto window_start_x = static_cast(window.x().start()); - const auto window_end_x = static_cast(window.x().end()); + const auto window_start_x = static_cast(window.x().start()); + const auto window_end_x = static_cast(window.x().end()); const UniformQuantizationInfo uqinfo = _output->info()->quantization_info().uniform(); #ifdef __aarch64__ -- cgit v1.2.1