From 07263980e66059a91ce57612e4ca8f4b2a2a206a Mon Sep 17 00:00:00 2001 From: Manuel Bottini Date: Thu, 17 Oct 2019 18:37:26 +0100 Subject: COMPMID-2501: Support multiplier > 1 during QASYMM8 requantization for Quantized LSTM Change-Id: I7eddbdf77881f313b707b9e59428245f1330a2cf Signed-off-by: Manuel Bottini Reviewed-on: https://review.mlplatform.org/c/2119 Comments-Addressed: Arm Jenkins Tested-by: Arm Jenkins Reviewed-by: Pablo Marquez --- tests/validation/CL/GEMMLowp.cpp | 30 ++++++ tests/validation/CL/LSTMLayerQuantized.cpp | 152 ++++++++++++++++++++++++++- tests/validation/NEON/GEMMLowp.cpp | 34 +++++- tests/validation/NEON/LSTMLayerQuantized.cpp | 151 +++++++++++++++++++++++++- tests/validation/reference/GEMMLowp.cpp | 9 +- 5 files changed, 363 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/tests/validation/CL/GEMMLowp.cpp b/tests/validation/CL/GEMMLowp.cpp index b8dfc030a2..f5bd871f90 100644 --- a/tests/validation/CL/GEMMLowp.cpp +++ b/tests/validation/CL/GEMMLowp.cpp @@ -305,6 +305,14 @@ const auto quantize_down_int32_to_int16_scale_by_fixedpoint_relu_cases = framewo 2) * framework::dataset::make("min", -2, 0) * framework::dataset::make("max", 1, 3) * framework::dataset::make("addBias", { false, true }); +const auto quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_cases = framework::dataset::make("result_fixedpoint_multiplier", 1073741823, 1073741825) * framework::dataset::make("result_shift", -3, + -2) + * framework::dataset::make("min", 0) * framework::dataset::make("max", 0) * framework::dataset::make("addBias", { false, true }); + +const auto quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_relu_cases = framework::dataset::make("result_fixedpoint_multiplier", 254601600, 254601602) * framework::dataset::make("result_shift", -3, + -1) + * framework::dataset::make("min", -2, 0) * framework::dataset::make("max", 1, 3) * framework::dataset::make("addBias", { false, true }); + using CLGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture = GEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointValidationFixture; @@ -344,19 +352,41 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip( } // clang-format on // *INDENT-ON* +TEST_SUITE(NoRelu) +TEST_SUITE(MultSmallerEq1) FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), quantize_down_int32_to_int16_scale_by_fixedpoint_cases)) { // Validate output validate(CLAccessor(_target), _reference); } +TEST_SUITE_END() // MultSmallerEq1 +TEST_SUITE(MultGreater1) +FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), + quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_cases)) +{ + // Validate output + validate(CLAccessor(_target), _reference); +} +TEST_SUITE_END() // MultGreater1 +TEST_SUITE_END() // NoRelu TEST_SUITE(BoundedReLu) +TEST_SUITE(MultSmallerEq1) FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), quantize_down_int32_to_int16_scale_by_fixedpoint_relu_cases)) { // Validate output validate(CLAccessor(_target), _reference); } +TEST_SUITE_END() // MultSmallerEq1 +TEST_SUITE(MultGreater1) +FIXTURE_DATA_TEST_CASE(RunSmall, CLGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), + quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_relu_cases)) +{ + // Validate output + validate(CLAccessor(_target), _reference); +} +TEST_SUITE_END() // MultGreater1 TEST_SUITE_END() // BoundedReLu TEST_SUITE_END() // QuantizeDownInt32ToInt16ScaleByFixedPoint TEST_SUITE_END() // OutputStage diff --git a/tests/validation/CL/LSTMLayerQuantized.cpp b/tests/validation/CL/LSTMLayerQuantized.cpp index 1fc0af1ecb..686d6bcef8 100644 --- a/tests/validation/CL/LSTMLayerQuantized.cpp +++ b/tests/validation/CL/LSTMLayerQuantized.cpp @@ -72,13 +72,14 @@ TEST_SUITE(LSTMLayerQuantized) // *INDENT-OFF* // clang-format off -TEST_CASE(IntegrationTestCaseSmall, framework::DatasetMode::PRECOMMIT) +TEST_SUITE(IntegrationTestCase) +TEST_SUITE(MultSmallerEq1) +TEST_CASE(RunSmall, framework::DatasetMode::PRECOMMIT) { const int batch_size = 2; const int input_size = 2; const int output_size = 4; - QuantizationInfo qasymm(1.f / 128.f, 128); QuantizationInfo qweights(1.f / 128.f, 128); QuantizationInfo qsymm_3(8.f / 32768.f, 0); @@ -211,7 +212,7 @@ TEST_CASE(IntegrationTestCaseSmall, framework::DatasetMode::PRECOMMIT) validate(CLAccessor(output_state), expected_output); } -TEST_CASE(IntegrationTestCaseLarge, framework::DatasetMode::PRECOMMIT) +TEST_CASE(RunLarge, framework::DatasetMode::PRECOMMIT) { const int batch_size = 16; const int input_size = 8; @@ -448,11 +449,154 @@ TEST_CASE(IntegrationTestCaseLarge, framework::DatasetMode::PRECOMMIT) lstmq.run(); validate(CLAccessor(output_state), expected_output); } +TEST_SUITE_END() // MultSmallerEq1 + +TEST_SUITE(MultGreater1) +TEST_CASE(RunSmall, framework::DatasetMode::PRECOMMIT) +{ + //Input sequence length is 1 + const int batch_size = 2; + const int input_size = 2; + const int output_size = 4; + + QuantizationInfo qasymm(1.f / 128.f, 128); + QuantizationInfo qweights(1.f / 16.f, 16); + QuantizationInfo qsymm_3(8.f / 32768.f, 0); + QuantizationInfo qsymm_4(16.f / 32768.f, 0); + + TensorShape input_shape{ input_size, batch_size }; + TensorShape input_weights_shape{ input_size, output_size }; + TensorShape recurrent_weights_shape{ output_size, output_size }; + TensorShape output_shape{ output_size, batch_size}; + TensorShape bias_shape{ output_size }; + + auto input_to_input_weights = create_tensor(input_weights_shape, DataType::QASYMM8, 1, qweights); + auto input_to_forget_weights = create_tensor(input_weights_shape, DataType::QASYMM8, 1, qweights); + auto input_to_cell_weights = create_tensor(input_weights_shape, DataType::QASYMM8, 1, qweights); + auto input_to_output_weights = create_tensor(input_weights_shape, DataType::QASYMM8, 1, qweights); + auto recurrent_to_input_weights = create_tensor(recurrent_weights_shape, DataType::QASYMM8, 1, qweights); + auto recurrent_to_forget_weights = create_tensor(recurrent_weights_shape, DataType::QASYMM8, 1, qweights); + auto recurrent_to_cell_weights = create_tensor(recurrent_weights_shape, DataType::QASYMM8, 1, qweights); + auto recurrent_to_output_weights = create_tensor(recurrent_weights_shape, DataType::QASYMM8, 1, qweights); + auto input_gate_bias = create_tensor(bias_shape, DataType::S32); + auto forget_gate_bias = create_tensor(bias_shape, DataType::S32); + auto cell_gate_bias = create_tensor(bias_shape, DataType::S32); + auto output_gate_bias = create_tensor(bias_shape, DataType::S32); + + // LSTM input + auto input = create_tensor(input_shape, DataType::QASYMM8, 1, qasymm); + + // LSTM output state + auto output_state = create_tensor(output_shape, DataType::QASYMM8, 1, qasymm); + + // LSTM cell state + auto cell_state = create_tensor(output_shape, DataType::QSYMM16, 1, qsymm_4); + + CLLSTMLayerQuantized lstmq; + + lstmq.configure(&input, &input_to_input_weights, &input_to_forget_weights, &input_to_cell_weights, &input_to_output_weights, + &recurrent_to_input_weights, &recurrent_to_forget_weights, &recurrent_to_cell_weights, &recurrent_to_output_weights, + &input_gate_bias, &forget_gate_bias, &cell_gate_bias, &output_gate_bias, &cell_state, &output_state, &cell_state, &output_state); + + input.allocator()->allocate(); + input_to_input_weights.allocator()->allocate(); + input_to_forget_weights.allocator()->allocate(); + input_to_cell_weights.allocator()->allocate(); + input_to_output_weights.allocator()->allocate(); + recurrent_to_input_weights.allocator()->allocate(); + recurrent_to_forget_weights.allocator()->allocate(); + recurrent_to_cell_weights.allocator()->allocate(); + recurrent_to_output_weights.allocator()->allocate(); + input_gate_bias.allocator()->allocate(); + forget_gate_bias.allocator()->allocate(); + cell_gate_bias.allocator()->allocate(); + output_gate_bias.allocator()->allocate(); + cell_state.allocator()->allocate(); + output_state.allocator()->allocate(); + + // Fill weights and biases + fill_tensor(input_to_input_weights, std::vector{ 122, 130, + 124, 134, + 120, 122, + 134, 134 }); + + fill_tensor(input_to_forget_weights, std::vector { 204, 193, + 148, 59, + 113, 17, + 66, 197 }); + + fill_tensor(input_to_cell_weights, std::vector { 172, 101, + 184, 209, + 165, 82, + 108, 209 }); + + fill_tensor(input_to_output_weights, std::vector { 203, 244, + 219, 114, + 130, 16, + 163, 222 }); + + fill_tensor(recurrent_to_input_weights, std::vector { 162, 168, 7, 95, + 91, 155, 108, 216, + 255, 100, 48, 188, + 58, 37, 186, 147 }); + + fill_tensor(recurrent_to_forget_weights, std::vector { 46, 58, 47, 170, + 246, 96, 12, 99, + 68, 23, 186, 161, + 237, 164, 89, 6 }); + + fill_tensor(recurrent_to_cell_weights, std::vector { 234, 99, 71, 206, + 205, 159, 64, 253, + 191, 148, 116, 8, + 209, 136, 59, 138 }); + + fill_tensor(recurrent_to_output_weights, std::vector { 23, 241, 137, 36, + 206, 5, 227, 56, + 254, 176, 231, 47, + 18, 201, 161, 11 }); + + fill_tensor(input_gate_bias, std::vector {-103038, 30525, 115255, -38154 }); + fill_tensor(forget_gate_bias, std::vector { -23428, 126970, 116806, 46307 }); + fill_tensor(cell_gate_bias, std::vector { 128006, 69949, -42808, 42568 }); + fill_tensor(output_gate_bias, std::vector { -67066, -53607, 47233, 7300 }); + + SimpleTensor expected_output(output_shape, DataType::QASYMM8, 1, qasymm); + + // Initialize state + fill_tensor(output_state, std::vector { 128, 128, 128, 128, + 128, 128, 128, 128 }); + fill_tensor(cell_state, std::vector { 0, 0, 0, 0, + 0, 0, 0, 0 }); + + // First input + fill_tensor(input, std::vector { 106, 193, + 155, 150 }); + + fill_tensor(expected_output, std::vector { 128, 128, 31, 128, + 128, 128, 31, 128 }); + + lstmq.run(); + validate(CLAccessor(output_state), expected_output); + + // Second input + fill_tensor(expected_output, std::vector { 128, 128, 5, 128, + 128, 128, 5, 128 }); + lstmq.run(); + validate(CLAccessor(output_state), expected_output); + + // Third input + fill_tensor(expected_output, std::vector { 128, 128, 1, 128, + 128, 128, 1, 128, }); + lstmq.run(); + validate(CLAccessor(output_state), expected_output); +} +TEST_SUITE_END() // MultGreater1 +TEST_SUITE_END() // IntegrationTestCase // clang-format on // *INDENT-ON* TEST_SUITE_END() // LSTMLayerQuantized -TEST_SUITE_END() // NEON +TEST_SUITE_END() // CL } // namespace validation } // namespace test } // namespace arm_compute diff --git a/tests/validation/NEON/GEMMLowp.cpp b/tests/validation/NEON/GEMMLowp.cpp index 2f604c95ea..d79374efa7 100644 --- a/tests/validation/NEON/GEMMLowp.cpp +++ b/tests/validation/NEON/GEMMLowp.cpp @@ -417,6 +417,13 @@ const auto quantize_down_int32_to_int16_scale_by_fixedpoint_cases = framework::d const auto quantize_down_int32_to_int16_scale_by_fixedpoint_relu_cases = framework::dataset::make("result_fixedpoint_multiplier", 254601600, 254601602) * framework::dataset::make("result_shift", 1, 2) * framework::dataset::make("min", -2, 0) * framework::dataset::make("max", 1, 3) * framework::dataset::make("addBias", { false, true }); +const auto quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_cases = framework::dataset::make("result_fixedpoint_multiplier", 1073741823, 1073741825) * framework::dataset::make("result_shift", -3, + -2) + * framework::dataset::make("min", 0) * framework::dataset::make("max", 0) * framework::dataset::make("addBias", { false, true }); + +const auto quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_relu_cases = framework::dataset::make("result_fixedpoint_multiplier", 254601600, 254601602) * framework::dataset::make("result_shift", -3, + -1) + * framework::dataset::make("min", -2, 0) * framework::dataset::make("max", 1, 3) * framework::dataset::make("addBias", { false, true }); using NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture = GEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointValidationFixture; @@ -499,27 +506,44 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(datasets::Sma validate(bias.info()->padding(), padding); } } - +TEST_SUITE(NoRelu) +TEST_SUITE(MultSmallerEq1) FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), quantize_down_int32_to_int16_scale_by_fixedpoint_cases)) { // Validate output validate(Accessor(_target), _reference); } - +TEST_SUITE_END() // MultSmallerEq1 +TEST_SUITE(MultGreater1) +FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), + quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_cases)) +{ + // Validate output + validate(Accessor(_target), _reference); +} +TEST_SUITE_END() // MultGreater1 +TEST_SUITE_END() // NoRelu TEST_SUITE(BoundedReLu) +TEST_SUITE(MultSmallerEq1) FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), quantize_down_int32_to_int16_scale_by_fixedpoint_relu_cases)) { // Validate output validate(Accessor(_target), _reference); } +TEST_SUITE_END() // MultSmallerEq1 +TEST_SUITE(MultGreater1) +FIXTURE_DATA_TEST_CASE(RunSmall, NEGEMMLowpQuantizeDownInt32ToInt16ScaleByFixedPointFixture, framework::DatasetMode::ALL, combine(datasets::SmallShapes(), + quantize_down_int32_to_int16_scale_by_fixedpoint_multgreat1_relu_cases)) +{ + // Validate output + validate(Accessor(_target), _reference); +} +TEST_SUITE_END() // MultGreater1 TEST_SUITE_END() // BoundedReLu - TEST_SUITE_END() // QuantizeDownInt32ToInt16ScaleByFixedPoint - TEST_SUITE_END() // OutputStage - TEST_SUITE_END() // GEMMLowp TEST_SUITE_END() // NEON } // namespace validation diff --git a/tests/validation/NEON/LSTMLayerQuantized.cpp b/tests/validation/NEON/LSTMLayerQuantized.cpp index 0935165564..b57a8f7d26 100644 --- a/tests/validation/NEON/LSTMLayerQuantized.cpp +++ b/tests/validation/NEON/LSTMLayerQuantized.cpp @@ -77,7 +77,9 @@ TEST_SUITE(LSTMLayerQuantized) // *INDENT-OFF* // clang-format off -TEST_CASE(IntegrationTestCaseSmall, framework::DatasetMode::PRECOMMIT) +TEST_SUITE(IntegrationTestCase) +TEST_SUITE(MultSmallerEq1) +TEST_CASE(RunSmall, framework::DatasetMode::PRECOMMIT) { const int batch_size = 2; const int input_size = 2; @@ -216,7 +218,7 @@ TEST_CASE(IntegrationTestCaseSmall, framework::DatasetMode::PRECOMMIT) validate(Accessor(output_state), expected_output, tolerance_qsymm16); } -TEST_CASE(IntegrationTestCaseLarge, framework::DatasetMode::PRECOMMIT) +TEST_CASE(RunLarge, framework::DatasetMode::PRECOMMIT) { const int batch_size = 16; const int input_size = 8; @@ -453,11 +455,154 @@ TEST_CASE(IntegrationTestCaseLarge, framework::DatasetMode::PRECOMMIT) lstmq.run(); validate(Accessor(output_state), expected_output, tolerance_qsymm16); } +TEST_SUITE_END() // MultSmallerEq1 + +TEST_SUITE(MultGreater1) +TEST_CASE(RunSmall, framework::DatasetMode::PRECOMMIT) +{ + //Input sequence length is 1 + const int batch_size = 2; + const int input_size = 2; + const int output_size = 4; + + QuantizationInfo qasymm(1.f / 128.f, 128); + QuantizationInfo qweights(1.f / 16.f, 16); + QuantizationInfo qsymm_3(8.f / 32768.f, 0); + QuantizationInfo qsymm_4(16.f / 32768.f, 0); + + TensorShape input_shape{ input_size, batch_size }; + TensorShape input_weights_shape{ input_size, output_size }; + TensorShape recurrent_weights_shape{ output_size, output_size }; + TensorShape output_shape{ output_size, batch_size}; + TensorShape bias_shape{ output_size }; + + auto input_to_input_weights = create_tensor(input_weights_shape, DataType::QASYMM8, 1, qweights); + auto input_to_forget_weights = create_tensor(input_weights_shape, DataType::QASYMM8, 1, qweights); + auto input_to_cell_weights = create_tensor(input_weights_shape, DataType::QASYMM8, 1, qweights); + auto input_to_output_weights = create_tensor(input_weights_shape, DataType::QASYMM8, 1, qweights); + auto recurrent_to_input_weights = create_tensor(recurrent_weights_shape, DataType::QASYMM8, 1, qweights); + auto recurrent_to_forget_weights = create_tensor(recurrent_weights_shape, DataType::QASYMM8, 1, qweights); + auto recurrent_to_cell_weights = create_tensor(recurrent_weights_shape, DataType::QASYMM8, 1, qweights); + auto recurrent_to_output_weights = create_tensor(recurrent_weights_shape, DataType::QASYMM8, 1, qweights); + auto input_gate_bias = create_tensor(bias_shape, DataType::S32); + auto forget_gate_bias = create_tensor(bias_shape, DataType::S32); + auto cell_gate_bias = create_tensor(bias_shape, DataType::S32); + auto output_gate_bias = create_tensor(bias_shape, DataType::S32); + + // LSTM input + auto input = create_tensor(input_shape, DataType::QASYMM8, 1, qasymm); + + // LSTM output state + auto output_state = create_tensor(output_shape, DataType::QASYMM8, 1, qasymm); + + // LSTM cell state + auto cell_state = create_tensor(output_shape, DataType::QSYMM16, 1, qsymm_4); + + NELSTMLayerQuantized lstmq; + + lstmq.configure(&input, &input_to_input_weights, &input_to_forget_weights, &input_to_cell_weights, &input_to_output_weights, + &recurrent_to_input_weights, &recurrent_to_forget_weights, &recurrent_to_cell_weights, &recurrent_to_output_weights, + &input_gate_bias, &forget_gate_bias, &cell_gate_bias, &output_gate_bias, &cell_state, &output_state, &cell_state, &output_state); + + input.allocator()->allocate(); + input_to_input_weights.allocator()->allocate(); + input_to_forget_weights.allocator()->allocate(); + input_to_cell_weights.allocator()->allocate(); + input_to_output_weights.allocator()->allocate(); + recurrent_to_input_weights.allocator()->allocate(); + recurrent_to_forget_weights.allocator()->allocate(); + recurrent_to_cell_weights.allocator()->allocate(); + recurrent_to_output_weights.allocator()->allocate(); + input_gate_bias.allocator()->allocate(); + forget_gate_bias.allocator()->allocate(); + cell_gate_bias.allocator()->allocate(); + output_gate_bias.allocator()->allocate(); + cell_state.allocator()->allocate(); + output_state.allocator()->allocate(); + + // Fill weights and biases + fill_tensor(input_to_input_weights, std::vector{ 122, 130, + 124, 134, + 120, 122, + 134, 134 }); + + fill_tensor(input_to_forget_weights, std::vector { 204, 193, + 148, 59, + 113, 17, + 66, 197 }); + + fill_tensor(input_to_cell_weights, std::vector { 172, 101, + 184, 209, + 165, 82, + 108, 209 }); + + fill_tensor(input_to_output_weights, std::vector { 203, 244, + 219, 114, + 130, 16, + 163, 222 }); + + fill_tensor(recurrent_to_input_weights, std::vector { 162, 168, 7, 95, + 91, 155, 108, 216, + 255, 100, 48, 188, + 58, 37, 186, 147 }); + + fill_tensor(recurrent_to_forget_weights, std::vector { 46, 58, 47, 170, + 246, 96, 12, 99, + 68, 23, 186, 161, + 237, 164, 89, 6 }); + + fill_tensor(recurrent_to_cell_weights, std::vector { 234, 99, 71, 206, + 205, 159, 64, 253, + 191, 148, 116, 8, + 209, 136, 59, 138 }); + + fill_tensor(recurrent_to_output_weights, std::vector { 23, 241, 137, 36, + 206, 5, 227, 56, + 254, 176, 231, 47, + 18, 201, 161, 11 }); + + fill_tensor(input_gate_bias, std::vector {-103038, 30525, 115255, -38154 }); + fill_tensor(forget_gate_bias, std::vector { -23428, 126970, 116806, 46307 }); + fill_tensor(cell_gate_bias, std::vector { 128006, 69949, -42808, 42568 }); + fill_tensor(output_gate_bias, std::vector { -67066, -53607, 47233, 7300 }); + + SimpleTensor expected_output(output_shape, DataType::QASYMM8, 1, qasymm); + + // Initialize state + fill_tensor(output_state, std::vector { 128, 128, 128, 128, + 128, 128, 128, 128 }); + fill_tensor(cell_state, std::vector { 0, 0, 0, 0, + 0, 0, 0, 0 }); + + // First input + fill_tensor(input, std::vector { 106, 193, + 155, 150 }); + + fill_tensor(expected_output, std::vector { 128, 128, 31, 128, + 128, 128, 31, 128 }); + + lstmq.run(); + validate(Accessor(output_state), expected_output); + + // Second input + fill_tensor(expected_output, std::vector { 128, 128, 5, 128, + 128, 128, 5, 128 }); + lstmq.run(); + validate(Accessor(output_state), expected_output); + + // Third input + fill_tensor(expected_output, std::vector { 128, 128, 1, 128, + 128, 128, 1, 128, }); + lstmq.run(); + validate(Accessor(output_state), expected_output); +} +TEST_SUITE_END() // MultGreater1 +TEST_SUITE_END() // IntegrationTestCase // clang-format on // *INDENT-ON* TEST_SUITE_END() // LSTMLayerQuantized -TEST_SUITE_END() // CL +TEST_SUITE_END() // NEON } // namespace validation } // namespace test } // namespace arm_compute diff --git a/tests/validation/reference/GEMMLowp.cpp b/tests/validation/reference/GEMMLowp.cpp index 97d05327e7..4283cb5bac 100644 --- a/tests/validation/reference/GEMMLowp.cpp +++ b/tests/validation/reference/GEMMLowp.cpp @@ -112,7 +112,14 @@ void quantize_down_int32_to_int16_scale_by_fixedpoint(const SimpleTensor *in, } // Fixed point multiplication - result = asymm_rounding_divide_by_pow2(asymm_int_mult(result, result_fixedpoint_multiplier), result_shift); + if(result_shift < 0) + { + result = asymm_int_mult(result * (1 << (-result_shift)), result_fixedpoint_multiplier); + } + else + { + result = asymm_rounding_divide_by_pow2(asymm_int_mult(result, result_fixedpoint_multiplier), result_shift); + } // Bounded ReLu if(min != max) -- cgit v1.2.1