From 2232a201a9f72de483c12a7857c5f08b81cf7396 Mon Sep 17 00:00:00 2001 From: Michalis Spyrou Date: Mon, 13 Jul 2020 15:15:33 +0100 Subject: COMPMID-3589: ADD CTS test failing with data type QUANT8_ASYMM Pick the correct scales and offsets in case of broadcast. Added tests for quantized QUANT8_ASYMM. Change-Id: I04e90b8ae1f624b12bbdcf6ed9187e58b9135c85 Signed-off-by: Michalis Spyrou Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/3562 Tested-by: Arm Jenkins Reviewed-by: Michele Di Giorgio Comments-Addressed: Arm Jenkins --- src/core/NEON/kernels/NEArithmeticAdditionKernel.cpp | 13 +++++++++---- tests/validation/NEON/ArithmeticAddition.cpp | 18 ++++++++++++++++++ .../validation/fixtures/ArithmeticOperationsFixture.h | 14 ++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/core/NEON/kernels/NEArithmeticAdditionKernel.cpp b/src/core/NEON/kernels/NEArithmeticAdditionKernel.cpp index 59a454f91a..fc211f7b42 100644 --- a/src/core/NEON/kernels/NEArithmeticAdditionKernel.cpp +++ b/src/core/NEON/kernels/NEArithmeticAdditionKernel.cpp @@ -343,11 +343,7 @@ void add_QASYMM8_SIGNED_QASYMM8_SIGNED_QASYMM8_SIGNED(const ITensor *in1, const const UniformQuantizationInfo iq2_info = in2->info()->quantization_info().uniform(); const UniformQuantizationInfo oq_info = out->info()->quantization_info().uniform(); - const float32x4_t vscale1 = vdupq_n_f32(iq1_info.scale); - const float32x4_t vscale2 = vdupq_n_f32(iq2_info.scale); const float32x4_t invvscaleo = vdupq_n_f32(1.f / oq_info.scale); - const int32x4_t voffset1 = vdupq_n_s32(iq1_info.offset); - const int32x4_t voffset2 = vdupq_n_s32(iq2_info.offset); const float32x4_t voffseto = vdupq_n_f32(oq_info.offset); if(is_broadcast_across_x) @@ -360,6 +356,11 @@ void add_QASYMM8_SIGNED_QASYMM8_SIGNED_QASYMM8_SIGNED(const ITensor *in1, const const UniformQuantizationInfo broadcast_qinfo = broadcast_tensor->info()->quantization_info().uniform(); const UniformQuantizationInfo non_broadcast_qinfo = non_broadcast_tensor->info()->quantization_info().uniform(); + const float32x4_t vscale1 = is_broadcast_input_2 ? vdupq_n_f32(iq1_info.scale) : vdupq_n_f32(iq2_info.scale); + const float32x4_t vscale2 = is_broadcast_input_2 ? vdupq_n_f32(iq2_info.scale) : vdupq_n_f32(iq1_info.scale); + const int32x4_t voffset1 = is_broadcast_input_2 ? vdupq_n_s32(iq1_info.offset) : vdupq_n_s32(iq2_info.offset); + const int32x4_t voffset2 = is_broadcast_input_2 ? vdupq_n_s32(iq2_info.offset) : vdupq_n_s32(iq1_info.offset); + // Clear X Dimension on execution window as we handle manually non_broadcast_win.set(Window::DimX, Window::Dimension(0, 1, 1)); @@ -442,6 +443,10 @@ void add_QASYMM8_SIGNED_QASYMM8_SIGNED_QASYMM8_SIGNED(const ITensor *in1, const Iterator input2(in2, input2_win); Iterator output(out, win); + const float32x4_t vscale1 = vdupq_n_f32(iq1_info.scale); + const float32x4_t vscale2 = vdupq_n_f32(iq2_info.scale); + const int32x4_t voffset1 = vdupq_n_s32(iq1_info.offset); + const int32x4_t voffset2 = vdupq_n_s32(iq2_info.offset); execute_window_loop(win, [&](const Coordinates &) { const auto input1_ptr = reinterpret_cast(input1.ptr()); diff --git a/tests/validation/NEON/ArithmeticAddition.cpp b/tests/validation/NEON/ArithmeticAddition.cpp index 0d2ce6c624..7b3d4f9ac0 100644 --- a/tests/validation/NEON/ArithmeticAddition.cpp +++ b/tests/validation/NEON/ArithmeticAddition.cpp @@ -210,6 +210,9 @@ TEST_SUITE_END() // Float template using NEArithmeticAdditionQuantizedFixture = ArithmeticAdditionValidationQuantizedFixture; +template +using NEArithmeticAdditionQuantizedBroadcastFixture = ArithmeticAdditionValidationQuantizedBroadcastFixture; + TEST_SUITE(Quantized) TEST_SUITE(QASYMM8) FIXTURE_DATA_TEST_CASE(RunSmall, @@ -247,6 +250,21 @@ FIXTURE_DATA_TEST_CASE(RunSmall, validate(Accessor(_target), _reference, tolerance_quant); #endif //__aarch64__ } + +FIXTURE_DATA_TEST_CASE(RunSmallBroadcast, NEArithmeticAdditionQuantizedBroadcastFixture, framework::DatasetMode::ALL, combine(combine(combine(combine(combine( + datasets::SmallShapesBroadcast(), ArithmeticAdditionQASYMM8SIGNEDDataset), + framework::dataset::make("ConvertPolicy", { ConvertPolicy::SATURATE })), + framework::dataset::make("Src0QInfo", { QuantizationInfo(0.5f, 20) })), + framework::dataset::make("Src1QInfo", { QuantizationInfo(0.5f, 10) })), + framework::dataset::make("OutQInfo", { QuantizationInfo(0.5f, 5) }))) +{ + // Validate output +#ifdef __aarch64__ + validate(Accessor(_target), _reference); +#else //__aarch64__ + validate(Accessor(_target), _reference, tolerance_quant); +#endif //__aarch64__ +} TEST_SUITE_END() // QASYMM8_SIGNED TEST_SUITE(QSYMM16) diff --git a/tests/validation/fixtures/ArithmeticOperationsFixture.h b/tests/validation/fixtures/ArithmeticOperationsFixture.h index 6e00c46042..9ba7bd3ef7 100644 --- a/tests/validation/fixtures/ArithmeticOperationsFixture.h +++ b/tests/validation/fixtures/ArithmeticOperationsFixture.h @@ -194,6 +194,20 @@ public: } }; +template +class ArithmeticAdditionValidationQuantizedBroadcastFixture : public ArithmeticOperationGenericFixture +{ +public: + template + void setup(const TensorShape &shape0, const TensorShape &shape1, DataType data_type0, DataType data_type1, DataType output_data_type, + ConvertPolicy convert_policy, QuantizationInfo qinfo0, QuantizationInfo qinfo1, QuantizationInfo qinfo_out) + { + ArithmeticOperationGenericFixture::setup(reference::ArithmeticOperation::ADD, shape0, shape1, + data_type0, data_type1, output_data_type, convert_policy, + qinfo0, qinfo1, qinfo_out, ActivationLayerInfo(), false); + } +}; + template class ArithmeticSubtractionBroadcastValidationFixture : public ArithmeticOperationGenericFixture { -- cgit v1.2.1