From 959c26d0457deeebf7306b9e4317863f144415b5 Mon Sep 17 00:00:00 2001 From: Manuel Bottini Date: Mon, 2 Dec 2019 16:22:35 +0000 Subject: COMPMID-2790: Add support for QASYMM8_SIGNED in CLGEMMLowpMatrixMultiplyCore Change-Id: Ifdaeb53c512ba697f174649c026075010f54f628 Signed-off-by: Manuel Bottini Reviewed-on: https://review.mlplatform.org/c/2472 Reviewed-by: Michele Di Giorgio Comments-Addressed: Arm Jenkins Reviewed-by: Sang-Hoon Park Tested-by: Arm Jenkins Reviewed-by: Giuseppe Rossini --- tests/validation/fixtures/GEMMLowpFixture.h | 59 ++++++++++++++++------------- 1 file changed, 32 insertions(+), 27 deletions(-) (limited to 'tests/validation/fixtures/GEMMLowpFixture.h') diff --git a/tests/validation/fixtures/GEMMLowpFixture.h b/tests/validation/fixtures/GEMMLowpFixture.h index b93a6447d7..1154d6c8de 100644 --- a/tests/validation/fixtures/GEMMLowpFixture.h +++ b/tests/validation/fixtures/GEMMLowpFixture.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 ARM Limited. + * Copyright (c) 2017-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -91,12 +91,15 @@ void fill(U &&tensor, int i) template TensorType compute_gemmlowp_target(const TensorShape &shape_a, const TensorShape &shape_b, const TensorShape &shape_output, int32_t a_offset, int32_t b_offset, - GEMMLowpOutputStageInfo output_stage = GEMMLowpOutputStageInfo(), DataType data_type_b = DataType::QASYMM8, QuantizationInfo b_qinfo = QuantizationInfo()) + GEMMLowpOutputStageInfo output_stage = GEMMLowpOutputStageInfo(), DataType data_type_a = DataType::QASYMM8, DataType data_type_b = DataType::QASYMM8, + QuantizationInfo b_qinfo = QuantizationInfo()) { // Create tensors - TensorType a = create_tensor(shape_a, DataType::QASYMM8, 1); + DataType data_type_output = output_stage.type == GEMMLowpOutputStageType::NONE ? DataType::S32 : data_type_a; + + TensorType a = create_tensor(shape_a, data_type_a, 1); TensorType b = create_tensor(shape_b, data_type_b, 1); // gemm output before output stage mismatch if i pass data_layout_output here. to be investigated - TensorType output = create_tensor(shape_output, output_stage.type == GEMMLowpOutputStageType::NONE ? DataType::S32 : DataType::QASYMM8, 1); + TensorType output = create_tensor(shape_output, data_type_output, 1); a.info()->set_quantization_info(QuantizationInfo(1.0f / 255, a_offset)); @@ -150,9 +153,9 @@ TensorType compute_gemmlowp_target(const TensorShape &shape_a, const TensorShape return output; } -template +template SimpleTensor compute_gemmlowp_reference(const TensorShape &shape_a, const TensorShape &shape_b, const TensorShape &shape_output, int32_t a_offset, int32_t b_offset, - DataType data_type_b = DataType::QASYMM8, QuantizationInfo b_qinfo = QuantizationInfo()) + DataType data_type_a = DataType::QASYMM8, DataType data_type_b = DataType::QASYMM8, QuantizationInfo b_qinfo = QuantizationInfo()) { TensorShape shape_a_to_use = shape_a; if(reinterpret_input_as_3d) @@ -162,13 +165,13 @@ SimpleTensor compute_gemmlowp_reference(const TensorShape &shape_a, con } // Create reference - SimpleTensor a{ shape_a_to_use, DataType::QASYMM8, 1 }; - SimpleTensor b{ shape_b, data_type_b, 1, data_type_b == DataType::QSYMM8_PER_CHANNEL ? b_qinfo : QuantizationInfo(1.0f / 255, b_offset) }; + SimpleTensor a{ shape_a_to_use, data_type_a, 1 }; + SimpleTensor b{ shape_b, data_type_b, 1, data_type_b == DataType::QSYMM8_PER_CHANNEL ? b_qinfo : QuantizationInfo(1.0f / 255, b_offset) }; // Fill reference fill(a, 0); fill(b, 1); - return reference::gemmlowp_matrix_multiply_core(a, b, shape_output, a_offset, b_offset); + return reference::gemmlowp_matrix_multiply_core(a, b, shape_output, a_offset, b_offset); } } @@ -198,7 +201,7 @@ protected: SimpleTensor _reference{}; }; -template +template class GEMMLowpMatrixMultiplyCoreFusedOffsetOutputValidationFixture : public framework::Fixture { public: @@ -206,6 +209,8 @@ public: void setup(TensorShape shape_a, TensorShape shape_b, TensorShape shape_output, int32_t a_offset, int32_t b_offset, GEMMLowpOutputStageInfo output_stage, DataType data_type_b) { ARM_COMPUTE_EXPECT(output_stage.type != GEMMLowpOutputStageType::NONE, framework::LogLevel::ERRORS); + DataType data_type_a = data_type_b == DataType::QASYMM8_SIGNED ? DataType::QASYMM8_SIGNED : DataType::QASYMM8; + if(data_type_b == DataType::QSYMM8_PER_CHANNEL) { output_stage.is_quantized_per_channel = true; @@ -220,28 +225,28 @@ public: quantization::calculate_quantized_multiplier(scales[i], &output_stage.gemmlowp_multipliers[i], &output_stage.gemmlowp_shifts[i]); } - _reference = compute_reference(shape_a, shape_b, shape_output, a_offset, 0, output_stage, data_type_b, QuantizationInfo(scales)); - _target = compute_target(shape_a, shape_b, shape_output, a_offset, 0, output_stage, data_type_b, QuantizationInfo(scales)); + _reference = compute_reference(shape_a, shape_b, shape_output, a_offset, 0, output_stage, data_type_a, data_type_b, QuantizationInfo(scales)); + _target = compute_target(shape_a, shape_b, shape_output, a_offset, 0, output_stage, data_type_a, data_type_b, QuantizationInfo(scales)); } else { - _reference = compute_reference(shape_a, shape_b, shape_output, a_offset, b_offset, output_stage, data_type_b, QuantizationInfo()); - _target = compute_target(shape_a, shape_b, shape_output, a_offset, b_offset, output_stage, data_type_b, QuantizationInfo()); + _reference = compute_reference(shape_a, shape_b, shape_output, a_offset, b_offset, output_stage, data_type_a, data_type_b, QuantizationInfo()); + _target = compute_target(shape_a, shape_b, shape_output, a_offset, b_offset, output_stage, data_type_a, data_type_b, QuantizationInfo()); } } protected: TensorType compute_target(const TensorShape &shape_a, const TensorShape &shape_b, const TensorShape &shape_output, int32_t a_offset, int32_t b_offset, GEMMLowpOutputStageInfo output_stage, - DataType data_type_b, QuantizationInfo b_qinfo) + DataType data_type_a, DataType data_type_b, QuantizationInfo b_qinfo) { return compute_gemmlowp_target(shape_a, shape_b, shape_output, a_offset, b_offset, - output_stage, data_type_b, b_qinfo); + output_stage, data_type_a, data_type_b, b_qinfo); } - SimpleTensor compute_reference(const TensorShape &shape_a, const TensorShape &shape_b, const TensorShape &shape_output, int32_t a_offset, int32_t b_offset, - GEMMLowpOutputStageInfo output_stage, DataType data_type_b, QuantizationInfo b_qinfo) + SimpleTensor compute_reference(const TensorShape &shape_a, const TensorShape &shape_b, const TensorShape &shape_output, int32_t a_offset, int32_t b_offset, + GEMMLowpOutputStageInfo output_stage, DataType data_type_a, DataType data_type_b, QuantizationInfo b_qinfo) { - SimpleTensor output = compute_gemmlowp_reference(shape_a, shape_b, shape_output, a_offset, b_offset, data_type_b, b_qinfo); + SimpleTensor output = compute_gemmlowp_reference(shape_a, shape_b, shape_output, a_offset, b_offset, data_type_a, data_type_b, b_qinfo); TensorShape bias_shape(shape_b[0]); SimpleTensor bias{ bias_shape, DataType::S32, 1 }; @@ -250,20 +255,20 @@ protected: switch(output_stage.type) { case GEMMLowpOutputStageType::QUANTIZE_DOWN: - return reference::gemmlowp_quantize_down_int32_to_uint8_scale(output, bias, - output_stage.gemmlowp_offset, output_stage.gemmlowp_multipliers, output_stage.gemmlowp_shifts, output_stage.gemmlowp_min_bound, output_stage.gemmlowp_max_bound); + return reference::gemmlowp_quantize_down_scale(output, bias, + output_stage.gemmlowp_offset, output_stage.gemmlowp_multipliers, output_stage.gemmlowp_shifts, output_stage.gemmlowp_min_bound, output_stage.gemmlowp_max_bound); break; case GEMMLowpOutputStageType::QUANTIZE_DOWN_FIXEDPOINT: - return reference::gemmlowp_quantize_down_scale_by_fixedpoint(output, bias, - output_stage.gemmlowp_multipliers, output_stage.gemmlowp_shifts, output_stage.gemmlowp_offset, output_stage.gemmlowp_min_bound, output_stage.gemmlowp_max_bound); + return reference::gemmlowp_quantize_down_scale_by_fixedpoint(output, bias, + output_stage.gemmlowp_multipliers, output_stage.gemmlowp_shifts, output_stage.gemmlowp_offset, output_stage.gemmlowp_min_bound, output_stage.gemmlowp_max_bound); break; default: ARM_COMPUTE_ERROR("Not Supported!"); } } - TensorType _target{}; - SimpleTensor _reference{}; + TensorType _target{}; + SimpleTensor _reference{}; }; template @@ -348,11 +353,11 @@ protected: // Fill bias fill(b, 1); - return reference::gemmlowp_quantize_down_int32_to_uint8_scale(a, b, result_offset, result_mult_int_vec, result_shift_vec, min, max); + return reference::gemmlowp_quantize_down_scale(a, b, result_offset, result_mult_int_vec, result_shift_vec, min, max); } else { - return reference::gemmlowp_quantize_down_int32_to_uint8_scale(a, result_offset, result_mult_int_vec, result_shift_vec, min, max); + return reference::gemmlowp_quantize_down_scale(a, result_offset, result_mult_int_vec, result_shift_vec, min, max); } } -- cgit v1.2.1