From 6e09e1404c635d948cf20eb6b4b5747dfb6656f2 Mon Sep 17 00:00:00 2001 From: Murray Kornelsen Date: Wed, 13 Jul 2022 21:40:26 -0400 Subject: INT8 Quantized MeanStdDevNorm (LayerNorm) Implements LayerNorm for qasymm8 tensors. Uses uint8x16 loads and stores. Summation is performed in integer arithmetic (vpaddl) Normalization is performed in float32 before requantizing back to int8. Signed-off-by: Murray Kornelsen Change-Id: I2407c8b34717fb47adab98791bd76fb8a3c62f4a Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/7922 Comments-Addressed: Pablo Marquez Tello Comments-Addressed: Arm Jenkins Reviewed-by: Viet-Hoa Do Reviewed-by: Pablo Marquez Tello Tested-by: Arm Jenkins Benchmark: Arm Jenkins --- .../NEON/MeanStdDevNormalizationLayer.cpp | 19 +++++++++-- .../fixtures/MeanStdDevNormalizationLayerFixture.h | 39 +++++++++++++--------- .../reference/MeanStdDevNormalizationLayer.cpp | 11 +++++- 3 files changed, 50 insertions(+), 19 deletions(-) (limited to 'tests') diff --git a/tests/validation/NEON/MeanStdDevNormalizationLayer.cpp b/tests/validation/NEON/MeanStdDevNormalizationLayer.cpp index dee8f78da9..085f3608a0 100644 --- a/tests/validation/NEON/MeanStdDevNormalizationLayer.cpp +++ b/tests/validation/NEON/MeanStdDevNormalizationLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021 Arm Limited. + * Copyright (c) 2019-2022 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -47,7 +47,8 @@ namespace #ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC RelativeTolerance tolerance_f16(half(0.2f)); #endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */ -RelativeTolerance tolerance_f32(1e-4f); +RelativeTolerance tolerance_f32(1e-4f); +RelativeTolerance tolerance_qasymm8(1); } // namespace TEST_SUITE(NEON) @@ -114,9 +115,23 @@ FIXTURE_DATA_TEST_CASE(RunLarge, NEMeanStdDevNormalizationLayerFixture, f // Validate output validate(Accessor(_target), _reference, tolerance_f32); } + TEST_SUITE_END() // FP32 TEST_SUITE_END() // Float +TEST_SUITE(Quantized) +TEST_SUITE(QASYMM8) +FIXTURE_DATA_TEST_CASE(RunSmall, NEMeanStdDevNormalizationLayerFixture, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::Small2DShapes(), + framework::dataset::make("DataType", DataType::QASYMM8)), + framework::dataset::make("InPlace", { false, true })), + framework::dataset::make("Epsilon", { 1e-7 }))) +{ + // Validate output + validate(Accessor(_target), _reference, tolerance_qasymm8); +} +TEST_SUITE_END() // Quantized +TEST_SUITE_END() // QASYMM8 + TEST_SUITE_END() // MeanStdNormalizationLayer TEST_SUITE_END() // Neon } // namespace validation diff --git a/tests/validation/fixtures/MeanStdDevNormalizationLayerFixture.h b/tests/validation/fixtures/MeanStdDevNormalizationLayerFixture.h index 9868cd1abf..f3c108e6da 100644 --- a/tests/validation/fixtures/MeanStdDevNormalizationLayerFixture.h +++ b/tests/validation/fixtures/MeanStdDevNormalizationLayerFixture.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2021 Arm Limited. + * Copyright (c) 2019-2022 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -45,29 +45,35 @@ class MeanStdDevNormalizationLayerValidationFixture : public framework::Fixture { public: template - void setup(TensorShape shape, DataType dt, bool in_place, float epsilon = 1e-8f) + void setup(TensorShape shape, DataType dt, bool in_place, float epsilon = 1e-8) { - _data_type = dt; - _target = compute_target(shape, dt, in_place, epsilon); - _reference = compute_reference(shape, dt, epsilon); + QuantizationInfo qi = QuantizationInfo(0.5f, 10); + _data_type = dt; + _target = compute_target(shape, dt, in_place, epsilon, qi); + _reference = compute_reference(shape, dt, epsilon, qi); } protected: template - void fill(U &&src_tensor) + void fill(U &&tensor) { - static_assert(std::is_floating_point::value || std::is_same::value, "Only floating point data types supported."); - using DistributionType = typename std::conditional::value, arm_compute::utils::uniform_real_distribution_16bit, std::uniform_real_distribution>::type; - - DistributionType distribution{ T(-1.0f), T(1.0f) }; - library->fill(src_tensor, distribution, 0); + if(is_data_type_float(_data_type)) + { + std::uniform_real_distribution<> distribution{ -1.0f, 1.0f }; + library->fill(tensor, distribution, 0); + } + else + { + std::uniform_int_distribution<> distribution{ 0, 255 }; + library->fill(tensor, distribution, 0); + } } - TensorType compute_target(TensorShape shape, DataType dt, bool in_place, float epsilon) + TensorType compute_target(TensorShape shape, DataType dt, bool in_place, float epsilon, QuantizationInfo qi) { // Create tensors - TensorType src = create_tensor(shape, dt, 1); - TensorType dst; + TensorType src = create_tensor(shape, dt, 1, qi); + TensorType dst = create_tensor(shape, dt, 1, qi); TensorType *dst_ptr = in_place ? &src : &dst; @@ -104,10 +110,10 @@ protected: } } - SimpleTensor compute_reference(const TensorShape &shape, DataType dt, float epsilon) + SimpleTensor compute_reference(const TensorShape &shape, DataType dt, float epsilon, QuantizationInfo qi) { // Create reference - SimpleTensor ref_src{ shape, dt, 1 }; + SimpleTensor ref_src{ shape, dt, 1, qi }; // Fill reference fill(ref_src); @@ -119,6 +125,7 @@ protected: SimpleTensor _reference{}; DataType _data_type{}; }; + } // namespace validation } // namespace test } // namespace arm_compute diff --git a/tests/validation/reference/MeanStdDevNormalizationLayer.cpp b/tests/validation/reference/MeanStdDevNormalizationLayer.cpp index 0a23fa19bb..a7c8a784d9 100644 --- a/tests/validation/reference/MeanStdDevNormalizationLayer.cpp +++ b/tests/validation/reference/MeanStdDevNormalizationLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Arm Limited. + * Copyright (c) 2019, 2022 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -63,6 +63,15 @@ SimpleTensor mean_std_normalization_layer(const SimpleTensor &src, float e return dst; } +template <> +SimpleTensor mean_std_normalization_layer(const SimpleTensor &src, float epsilon) +{ + SimpleTensor src_tmp = convert_from_asymmetric(src); + SimpleTensor dst_tmp = mean_std_normalization_layer(src_tmp, epsilon); + SimpleTensor dst = convert_to_asymmetric(dst_tmp, src.quantization_info()); + return dst; +} + template SimpleTensor mean_std_normalization_layer(const SimpleTensor &src, float epsilon); template SimpleTensor mean_std_normalization_layer(const SimpleTensor &src, float epsilon); } // namespace reference -- cgit v1.2.1