1 /* 2 * Copyright (c) 2017-2019 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 if(is_data_type_float(_data_type)) 60 { 61 const float min_bound = -1.f; 62 const float max_bound = 1.f; 63 std::uniform_real_distribution<> distribution(min_bound, max_bound); 64 std::uniform_real_distribution<> distribution_std(0.1, max_bound); 65 library->fill(src_tensor, distribution, 0); 66 library->fill(mean_tensor, distribution, 1); 67 library->fill(std_tensor, distribution_std, 2); 68 } 69 else if(is_data_type_quantized_asymmetric(_data_type)) 70 { 71 const QuantizationInfo quant_info = src_tensor.quantization_info(); 72 std::pair<int, int> bounds = get_quantized_bounds(quant_info, -1.f, 1.0f); 73 std::uniform_int_distribution<> distribution(bounds.first, bounds.second); 74 std::uniform_int_distribution<> distribution_std(quantize_qasymm8(0.1f, quant_info.uniform()), bounds.second); 75 library->fill(src_tensor, distribution, 0); 76 library->fill(mean_tensor, distribution, 1); 77 library->fill(std_tensor, distribution_std, 2); 78 } 79 } 80 compute_target(TensorShape shape0,const TensorShape & shape1,DataType dt,DataLayout data_layout,QuantizationInfo quantization_info)81 TensorType compute_target(TensorShape shape0, const TensorShape &shape1, DataType dt, DataLayout data_layout, QuantizationInfo quantization_info) 82 { 83 if(data_layout == DataLayout::NHWC) 84 { 85 permute(shape0, PermutationVector(2U, 0U, 1U)); 86 } 87 88 // Create tensors 89 TensorType src = create_tensor<TensorType>(shape0, dt, 1, quantization_info, data_layout); 90 TensorType mean = create_tensor<TensorType>(shape1, dt, 1, quantization_info); 91 TensorType std = create_tensor<TensorType>(shape1, dt, 1, quantization_info); 92 TensorType dst; 93 94 // Create and configure function 95 FunctionType norm; 96 norm.configure(&src, &dst, &mean, &std); 97 98 ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); 99 ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS); 100 ARM_COMPUTE_EXPECT(mean.info()->is_resizable(), framework::LogLevel::ERRORS); 101 ARM_COMPUTE_EXPECT(std.info()->is_resizable(), framework::LogLevel::ERRORS); 102 103 // Allocate tensors 104 src.allocator()->allocate(); 105 dst.allocator()->allocate(); 106 mean.allocator()->allocate(); 107 std.allocator()->allocate(); 108 109 ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS); 110 ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS); 111 ARM_COMPUTE_EXPECT(!mean.info()->is_resizable(), framework::LogLevel::ERRORS); 112 ARM_COMPUTE_EXPECT(!std.info()->is_resizable(), framework::LogLevel::ERRORS); 113 114 // Fill tensors 115 fill(AccessorType(src), AccessorType(mean), AccessorType(std)); 116 117 // Compute function 118 norm.run(); 119 120 return dst; 121 } 122 compute_reference(const TensorShape & shape0,const TensorShape & shape1,DataType dt,QuantizationInfo quantization_info)123 SimpleTensor<T> compute_reference(const TensorShape &shape0, const TensorShape &shape1, DataType dt, QuantizationInfo quantization_info) 124 { 125 // Create reference 126 SimpleTensor<T> ref_src{ shape0, dt, 1, quantization_info }; 127 SimpleTensor<T> ref_mean{ shape1, dt, 1, quantization_info }; 128 SimpleTensor<T> ref_std{ shape1, dt, 1, quantization_info }; 129 130 // Fill reference 131 fill(ref_src, ref_mean, ref_std); 132 133 return reference::normalize_planar_yuv_layer(ref_src, ref_mean, ref_std); 134 } 135 136 TensorType _target{}; 137 SimpleTensor<T> _reference{}; 138 DataType _data_type{}; 139 }; 140 141 template <typename TensorType, typename AccessorType, typename FunctionType, typename T> 142 class NormalizePlanarYUVLayerValidationFixture : public NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T> 143 { 144 public: 145 template <typename...> setup(TensorShape shape0,TensorShape shape1,DataType dt,DataLayout data_layout)146 void setup(TensorShape shape0, TensorShape shape1, DataType dt, DataLayout data_layout) 147 { 148 NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape0, shape1, dt, data_layout, QuantizationInfo()); 149 } 150 }; 151 152 template <typename TensorType, typename AccessorType, typename FunctionType, typename T> 153 class NormalizePlanarYUVLayerValidationQuantizedFixture : public NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T> 154 { 155 public: 156 template <typename...> setup(TensorShape shape0,TensorShape shape1,DataType dt,DataLayout data_layout,QuantizationInfo quantization_info)157 void setup(TensorShape shape0, TensorShape shape1, DataType dt, DataLayout data_layout, QuantizationInfo quantization_info) 158 { 159 NormalizePlanarYUVLayerValidationGenericFixture<TensorType, AccessorType, FunctionType, T>::setup(shape0, shape1, dt, data_layout, quantization_info); 160 } 161 }; 162 } // namespace validation 163 } // namespace test 164 } // namespace arm_compute 165 #endif /* ARM_COMPUTE_TEST_NORMALIZE_PLANAR_YUV_LAYER_FIXTURE */ 166