COMPMID-1568: Add support for QASYMM8 to CLNormalizePlanarYUV

Change-Id: Id7ea6e7f57179478e5ba0e9231274e98fa089590
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/148028
Tested-by: bsgcomp <bsgcomp@arm.com>
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
diff --git a/tests/validation/CL/NormalizePlanarYUVLayer.cpp b/tests/validation/CL/NormalizePlanarYUVLayer.cpp
index aa1a00e..31e0625 100644
--- a/tests/validation/CL/NormalizePlanarYUVLayer.cpp
+++ b/tests/validation/CL/NormalizePlanarYUVLayer.cpp
@@ -45,6 +45,7 @@
 {
 constexpr RelativeTolerance<float> tolerance_f16(0.001f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F16 */
 constexpr RelativeTolerance<float> tolerance_f32(0.001f); /**< Tolerance value for comparing reference's output against implementation's output for DataType::F32 */
+constexpr AbsoluteTolerance<float> tolerance_qasymm8(1);  /**< Tolerance value for comparing reference's output against implementation's output for quantized data types */
 } // namespace
 
 TEST_SUITE(CL)
@@ -135,6 +136,22 @@
 TEST_SUITE_END()
 TEST_SUITE_END()
 
+template <typename T>
+using CLNormalizePlanarYUVLayerQuantizedFixture = NormalizePlanarYUVLayerValidationQuantizedFixture<CLTensor, CLAccessor, CLNormalizePlanarYUVLayer, T>;
+
+TEST_SUITE(Quantized)
+TEST_SUITE(QASYMM8)
+FIXTURE_DATA_TEST_CASE(Random, CLNormalizePlanarYUVLayerQuantizedFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::RandomNormalizePlanarYUVLayerDataset(),
+                       framework::dataset::make("DataType", DataType::QASYMM8)),
+                       framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
+                       framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.1f, 128.0f) })))
+{
+    // Validate output
+    validate(CLAccessor(_target), _reference, tolerance_qasymm8, 0);
+}
+TEST_SUITE_END()
+TEST_SUITE_END()
+
 TEST_SUITE_END()
 TEST_SUITE_END()
 } // namespace validation
diff --git a/tests/validation/fixtures/NormalizePlanarYUVLayerFixture.h b/tests/validation/fixtures/NormalizePlanarYUVLayerFixture.h
index cc73e53..9d8c8fc 100644
--- a/tests/validation/fixtures/NormalizePlanarYUVLayerFixture.h
+++ b/tests/validation/fixtures/NormalizePlanarYUVLayerFixture.h
@@ -41,15 +41,15 @@
 namespace validation
 {
 template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
-class NormalizePlanarYUVLayerValidationFixture : public framework::Fixture
+class NormalizePlanarYUVLayerValidationGenericFixture : public framework::Fixture
 {
 public:
     template <typename...>
-    void setup(TensorShape shape0, TensorShape shape1, DataType dt, DataLayout data_layout)
+    void setup(TensorShape shape0, TensorShape shape1, DataType dt, DataLayout data_layout, QuantizationInfo quantization_info)
     {
         _data_type = dt;
-        _target    = compute_target(shape0, shape1, dt, data_layout);
-        _reference = compute_reference(shape0, shape1, dt);
+        _target    = compute_target(shape0, shape1, dt, data_layout, quantization_info);
+        _reference = compute_reference(shape0, shape1, dt, quantization_info);
     }
 
 protected:
@@ -67,9 +67,15 @@
             library->fill(mean_tensor, distribution, 1);
             library->fill(std_tensor, distribution_std, 2);
         }
+        else if(is_data_type_quantized_asymmetric(src_tensor.data_type()))
+        {
+            library->fill_tensor_uniform(src_tensor, 0);
+            library->fill_tensor_uniform(mean_tensor, 1);
+            library->fill_tensor_uniform(std_tensor, 2);
+        }
     }
 
-    TensorType compute_target(TensorShape shape0, const TensorShape &shape1, DataType dt, DataLayout data_layout)
+    TensorType compute_target(TensorShape shape0, const TensorShape &shape1, DataType dt, DataLayout data_layout, QuantizationInfo quantization_info)
     {
         if(data_layout == DataLayout::NHWC)
         {
@@ -77,10 +83,10 @@
         }
 
         // Create tensors
-        TensorType src  = create_tensor<TensorType>(shape0, dt, 1, QuantizationInfo(), data_layout);
-        TensorType dst  = create_tensor<TensorType>(shape0, dt, 1, QuantizationInfo(), data_layout);
-        TensorType mean = create_tensor<TensorType>(shape1, dt, 1);
-        TensorType std  = create_tensor<TensorType>(shape1, dt, 1);
+        TensorType src  = create_tensor<TensorType>(shape0, dt, 1, quantization_info, data_layout);
+        TensorType mean = create_tensor<TensorType>(shape1, dt, 1, quantization_info);
+        TensorType std  = create_tensor<TensorType>(shape1, dt, 1, quantization_info);
+        TensorType dst;
 
         // Create and configure function
         FunctionType norm;
@@ -111,12 +117,12 @@
         return dst;
     }
 
-    SimpleTensor<T> compute_reference(const TensorShape &shape0, const TensorShape &shape1, DataType dt)
+    SimpleTensor<T> compute_reference(const TensorShape &shape0, const TensorShape &shape1, DataType dt, QuantizationInfo quantization_info)
     {
         // Create reference
-        SimpleTensor<T> ref_src{ shape0, dt, 1 };
-        SimpleTensor<T> ref_mean{ shape1, dt, 1 };
-        SimpleTensor<T> ref_std{ shape1, dt, 1 };
+        SimpleTensor<T> ref_src{ shape0, dt, 1, quantization_info };
+        SimpleTensor<T> ref_mean{ shape1, dt, 1, quantization_info };
+        SimpleTensor<T> ref_std{ shape1, dt, 1, quantization_info };
 
         // Fill reference
         fill(ref_src, ref_mean, ref_std);
@@ -128,6 +134,28 @@
     SimpleTensor<T> _reference{};
     DataType        _data_type{};
 };
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class NormalizePlanarYUVLayerValidationFixture : public NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape0, TensorShape shape1, DataType dt, DataLayout data_layout)
+    {
+        NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape0, shape1, dt, data_layout, QuantizationInfo());
+    }
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class NormalizePlanarYUVLayerValidationQuantizedFixture : public NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+    template <typename...>
+    void setup(TensorShape shape0, TensorShape shape1, DataType dt, DataLayout data_layout, QuantizationInfo quantization_info)
+    {
+        NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape0, shape1, dt, data_layout, quantization_info);
+    }
+};
 } // namespace validation
 } // namespace test
 } // namespace arm_compute
diff --git a/tests/validation/reference/NormalizePlanarYUVLayer.cpp b/tests/validation/reference/NormalizePlanarYUVLayer.cpp
index cdccaf4..563e2a7 100644
--- a/tests/validation/reference/NormalizePlanarYUVLayer.cpp
+++ b/tests/validation/reference/NormalizePlanarYUVLayer.cpp
@@ -61,6 +61,17 @@
     return result;
 }
 
+template <>
+SimpleTensor<uint8_t> normalize_planar_yuv_layer<uint8_t>(const SimpleTensor<uint8_t> &src, const SimpleTensor<uint8_t> &mean, const SimpleTensor<uint8_t> &std)
+{
+    SimpleTensor<float>   src_tmp  = convert_from_asymmetric(src);
+    SimpleTensor<float>   mean_tmp = convert_from_asymmetric(mean);
+    SimpleTensor<float>   std_tmp  = convert_from_asymmetric(std);
+    SimpleTensor<float>   dst_tmp  = normalize_planar_yuv_layer<float>(src_tmp, mean_tmp, std_tmp);
+    SimpleTensor<uint8_t> dst      = convert_to_asymmetric(dst_tmp, src.quantization_info());
+    return dst;
+}
+
 template SimpleTensor<half> normalize_planar_yuv_layer(const SimpleTensor<half> &src, const SimpleTensor<half> &mean, const SimpleTensor<half> &std);
 template SimpleTensor<float> normalize_planar_yuv_layer(const SimpleTensor<float> &src, const SimpleTensor<float> &mean, const SimpleTensor<float> &std);
 } // namespace reference