1 /* 2 * Copyright (c) 2017-2021 Arm Limited. 3 * 4 * SPDX-License-Identifier: MIT 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in all 14 * copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 #ifndef ARM_COMPUTE_TEST_NORMALIZE_PLANAR_YUV_LAYER_FIXTURE 25 #define ARM_COMPUTE_TEST_NORMALIZE_PLANAR_YUV_LAYER_FIXTURE 26 27 #include "arm_compute/core/TensorShape.h" 28 #include "arm_compute/core/Types.h" 29 #include "tests/AssetsLibrary.h" 30 #include "tests/Globals.h" 31 #include "tests/IAccessor.h" 32 #include "tests/framework/Asserts.h" 33 #include "tests/framework/Fixture.h" 34 #include "tests/validation/Helpers.h" 35 #include "tests/validation/reference/NormalizePlanarYUVLayer.h" 36 37 namespace arm_compute 38 { 39 namespace test 40 { 41 namespace validation 42 { 43 template <typename TensorType, typename AccessorType, typename FunctionType, typename T> 44 class NormalizePlanarYUVLayerValidationGenericFixture : public framework::Fixture 45 { 46 public: 47 template <typename...> setup(TensorShape shape0,TensorShape shape1,DataType dt,DataLayout data_layout,QuantizationInfo quantization_info)48 void setup(TensorShape shape0, TensorShape shape1, DataType dt, DataLayout data_layout, QuantizationInfo quantization_info) 49 { 50 _data_type = dt; 51 _target = compute_target(shape0, shape1, dt, data_layout, quantization_info); 52 _reference = compute_reference(shape0, shape1, dt, quantization_info); 53 } 54 55 protected: 56 template <typename U> fill(U && src_tensor,U && mean_tensor,U && std_tensor)57 void fill(U &&src_tensor, U &&mean_tensor, U &&std_tensor) 58 { 59 using FloatDistributionType = typename std::conditional<std::is_same<T, half>::value, arm_compute::utils::uniform_real_distribution_16bit<T>, std::uniform_real_distribution<float>>::type; 60 61 if(is_data_type_float(_data_type)) 62 { 63 const T min_bound = T(-1.f); 64 const T max_bound = T(1.f); 65 FloatDistributionType distribution(min_bound, max_bound); 66 FloatDistributionType distribution_std(T(0.1f), max_bound); 67 library->fill(src_tensor, distribution, 0); 68 library->fill(mean_tensor, distribution, 1); 69 library->fill(std_tensor, distribution_std, 2); 70 } 71 else if(is_data_type_quantized_asymmetric(_data_type)) 72 { 73 const QuantizationInfo quant_info = src_tensor.quantization_info(); 74 std::pair<int, int> bounds = get_quantized_bounds(quant_info, -1.f, 1.0f); 75 std::uniform_int_distribution<> distribution(bounds.first, bounds.second); 76 std::uniform_int_distribution<> distribution_std(quantize_qasymm8(0.1f, quant_info.uniform()), bounds.second); 77 library->fill(src_tensor, distribution, 0); 78 library->fill(mean_tensor, distribution, 1); 79 library->fill(std_tensor, distribution_std, 2); 80 } 81 } 82 compute_target(TensorShape shape0,const TensorShape & shape1,DataType dt,DataLayout data_layout,QuantizationInfo quantization_info)83 TensorType compute_target(TensorShape shape0, const TensorShape &shape1, DataType dt, DataLayout data_layout, QuantizationInfo quantization_info) 84 { 85 if(data_layout == DataLayout::NHWC) 86 { 87 permute(shape0, PermutationVector(2U, 0U, 1U)); 88 } 89 90 // Create tensors 91 TensorType src = create_tensor<TensorType>(shape0, dt, 1, quantization_info, data_layout); 92 TensorType mean = create_tensor<TensorType>(shape1, dt, 1, quantization_info); 93 TensorType std = create_tensor<TensorType>(shape1, dt, 1, quantization_info); 94 TensorType dst; 95 96 // Create and configure function 97 FunctionType norm; 98 norm.configure(&src, &dst, &mean, &std); 99 100 ARM_COMPUTE_ASSERT(src.info()->is_resizable()); 101 ARM_COMPUTE_ASSERT(dst.info()->is_resizable()); 102 ARM_COMPUTE_ASSERT(mean.info()->is_resizable()); 103 ARM_COMPUTE_ASSERT(std.info()->is_resizable()); 104 105 // Allocate tensors 106 src.allocator()->allocate(); 107 dst.allocator()->allocate(); 108 mean.allocator()->allocate(); 109 std.allocator()->allocate(); 110 111 ARM_COMPUTE_ASSERT(!src.info()->is_resizable()); 112 ARM_COMPUTE_ASSERT(!dst.info()->is_resizable()); 113 ARM_COMPUTE_ASSERT(!mean.info()->is_resizable()); 114 ARM_COMPUTE_ASSERT(!std.info()->is_resizable()); 115 116 // Fill tensors 117 fill(AccessorType(src), AccessorType(mean), AccessorType(std)); 118 119 // Compute function 120 norm.run(); 121 122 return dst; 123 } 124 compute_reference(const TensorShape & shape0,const TensorShape & shape1,DataType dt,QuantizationInfo quantization_info)125 SimpleTensor<T> compute_reference(const TensorShape &shape0, const TensorShape &shape1, DataType dt, QuantizationInfo quantization_info) 126 { 127 // Create reference 128 SimpleTensor<T> ref_src{ shape0, dt, 1, quantization_info }; 129 SimpleTensor<T> ref_mean{ shape1, dt, 1, quantization_info }; 130 SimpleTensor<T> ref_std{ shape1, dt, 1, quantization_info }; 131 132 // Fill reference 133 fill(ref_src, ref_mean, ref_std); 134 135 return reference::normalize_planar_yuv_layer(ref_src, ref_mean, ref_std); 136 } 137 138 TensorType _target{}; 139 SimpleTensor<T> _reference{}; 140 DataType _data_type{}; 141 }; 142 143 template <typename TensorType, typename AccessorType, typename FunctionType, typename T> 144 class NormalizePlanarYUVLayerValidationFixture : public NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T> 145 { 146 public: 147 template <typename...> setup(TensorShape shape0,TensorShape shape1,DataType dt,DataLayout data_layout)148 void setup(TensorShape shape0, TensorShape shape1, DataType dt, DataLayout data_layout) 149 { 150 NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape0, shape1, dt, data_layout, QuantizationInfo()); 151 } 152 }; 153 154 template <typename TensorType, typename AccessorType, typename FunctionType, typename T> 155 class NormalizePlanarYUVLayerValidationQuantizedFixture : public NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T> 156 { 157 public: 158 template <typename...> setup(TensorShape shape0,TensorShape shape1,DataType dt,DataLayout data_layout,QuantizationInfo quantization_info)159 void setup(TensorShape shape0, TensorShape shape1, DataType dt, DataLayout data_layout, QuantizationInfo quantization_info) 160 { 161 NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape0, shape1, dt, data_layout, quantization_info); 162 } 163 }; 164 } // namespace validation 165 } // namespace test 166 } // namespace arm_compute 167 #endif /* ARM_COMPUTE_TEST_NORMALIZE_PLANAR_YUV_LAYER_FIXTURE */ 168