• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017-2020 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_VALIDATION_HELPERS_H
25 #define ARM_COMPUTE_TEST_VALIDATION_HELPERS_H
26 
27 #include "arm_compute/core/Types.h"
28 #include "arm_compute/core/Utils.h"
29 #include "support/Half.h"
30 #include "tests/Globals.h"
31 #include "tests/SimpleTensor.h"
32 
33 #include <random>
34 #include <type_traits>
35 #include <utility>
36 
37 namespace arm_compute
38 {
39 namespace test
40 {
41 namespace validation
42 {
43 template <typename T>
44 struct is_floating_point : public std::is_floating_point<T>
45 {
46 };
47 
48 template <>
49 struct is_floating_point<half> : public std::true_type
50 {
51 };
52 
53 /** Helper function to get the testing range for each activation layer.
54  *
55  * @param[in] activation Activation function to test.
56  * @param[in] data_type  Data type.
57  *
58  * @return A pair containing the lower upper testing bounds for a given function.
59  */
60 template <typename T>
61 std::pair<T, T> get_activation_layer_test_bounds(ActivationLayerInfo::ActivationFunction activation, DataType data_type)
62 {
63     std::pair<T, T> bounds;
64 
65     switch(data_type)
66     {
67         case DataType::F16:
68         {
69             using namespace half_float::literal;
70 
71             switch(activation)
72             {
73                 case ActivationLayerInfo::ActivationFunction::TANH:
74                 case ActivationLayerInfo::ActivationFunction::SQUARE:
75                 case ActivationLayerInfo::ActivationFunction::LOGISTIC:
76                 case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
77                     // Reduce range as exponent overflows
78                     bounds = std::make_pair(-2._h, 2._h);
79                     break;
80                 case ActivationLayerInfo::ActivationFunction::SQRT:
81                     // Reduce range as sqrt should take a non-negative number
82                     bounds = std::make_pair(0._h, 128._h);
83                     break;
84                 default:
85                     bounds = std::make_pair(-255._h, 255._h);
86                     break;
87             }
88             break;
89         }
90         case DataType::F32:
91             switch(activation)
92             {
93                 case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
94                     // Reduce range as exponent overflows
95                     bounds = std::make_pair(-40.f, 40.f);
96                     break;
97                 case ActivationLayerInfo::ActivationFunction::SQRT:
98                     // Reduce range as sqrt should take a non-negative number
99                     bounds = std::make_pair(0.f, 255.f);
100                     break;
101                 default:
102                     bounds = std::make_pair(-255.f, 255.f);
103                     break;
104             }
105             break;
106         default:
107             ARM_COMPUTE_ERROR("Unsupported data type");
108     }
109 
110     return bounds;
111 }
112 
113 /** Fill mask with the corresponding given pattern.
114  *
115  * @param[in,out] mask    Mask to be filled according to pattern
116  * @param[in]     cols    Columns (width) of mask
117  * @param[in]     rows    Rows (height) of mask
118  * @param[in]     pattern Pattern to fill the mask according to
119  */
120 void fill_mask_from_pattern(uint8_t *mask, int cols, int rows, MatrixPattern pattern);
121 
122 /** Calculate output tensor shape give a vector of input tensor to concatenate
123  *
124  * @param[in] input_shapes Shapes of the tensors to concatenate across depth.
125  *
126  * @return The shape of output concatenated tensor.
127  */
128 TensorShape calculate_depth_concatenate_shape(const std::vector<TensorShape> &input_shapes);
129 
130 /** Calculate output tensor shape for the concatenate operation along a given axis
131  *
132  * @param[in] input_shapes Shapes of the tensors to concatenate across width.
133  * @param[in] axis         Axis to use for the concatenate operation
134  *
135  * @return The shape of output concatenated tensor.
136  */
137 TensorShape calculate_concatenate_shape(const std::vector<TensorShape> &input_shapes, size_t axis);
138 
139 /** Parameters of Harris Corners algorithm. */
140 struct HarrisCornersParameters
141 {
142     float   threshold{ 0.f };           /**< Threshold */
143     float   sensitivity{ 0.f };         /**< Sensitivity */
144     float   min_dist{ 0.f };            /**< Minimum distance */
145     uint8_t constant_border_value{ 0 }; /**< Border value */
146 };
147 
148 /** Generate parameters for Harris Corners algorithm. */
149 HarrisCornersParameters harris_corners_parameters();
150 
151 /** Parameters of Canny edge algorithm. */
152 struct CannyEdgeParameters
153 {
154     int32_t upper_thresh{ 255 };
155     int32_t lower_thresh{ 0 };
156     uint8_t constant_border_value{ 0 };
157 };
158 
159 /** Generate parameters for Canny edge algorithm. */
160 CannyEdgeParameters canny_edge_parameters();
161 
162 /** Helper function to fill the Lut random by a ILutAccessor.
163  *
164  * @param[in,out] table Accessor at the Lut.
165  *
166  */
167 template <typename T>
168 void fill_lookuptable(T &&table)
169 {
170     std::mt19937                                          generator(library->seed());
171     std::uniform_int_distribution<typename T::value_type> distribution(std::numeric_limits<typename T::value_type>::min(), std::numeric_limits<typename T::value_type>::max());
172 
173     for(int i = std::numeric_limits<typename T::value_type>::min(); i <= std::numeric_limits<typename T::value_type>::max(); i++)
174     {
175         table[i] = distribution(generator);
176     }
177 }
178 
179 /** Convert an asymmetric quantized simple tensor into float using tensor quantization information.
180  *
181  * @param[in] src Quantized tensor.
182  *
183  * @return Float tensor.
184  */
185 template <typename T>
186 SimpleTensor<float> convert_from_asymmetric(const SimpleTensor<T> &src);
187 
188 /** Convert float simple tensor into quantized using specified quantization information.
189  *
190  * @param[in] src               Float tensor.
191  * @param[in] quantization_info Quantification information.
192  *
193  * @return Quantized tensor.
194  */
195 template <typename T>
196 SimpleTensor<T> convert_to_asymmetric(const SimpleTensor<float> &src, const QuantizationInfo &quantization_info);
197 
198 /** Convert quantized simple tensor into float using tensor quantization information.
199  *
200  * @param[in] src Quantized tensor.
201  *
202  * @return Float tensor.
203  */
204 template <typename T>
205 SimpleTensor<float> convert_from_symmetric(const SimpleTensor<T> &src);
206 
207 /** Convert float simple tensor into quantized using specified quantization information.
208  *
209  * @param[in] src               Float tensor.
210  * @param[in] quantization_info Quantification information.
211  *
212  * @return Quantized tensor.
213  */
214 template <typename T>
215 SimpleTensor<T> convert_to_symmetric(const SimpleTensor<float> &src, const QuantizationInfo &quantization_info);
216 
217 /** Matrix multiply between 2 float simple tensors
218  *
219  * @param[in]  a   Input tensor A
220  * @param[in]  b   Input tensor B
221  * @param[out] out Output tensor
222  *
223  */
224 template <typename T>
225 void matrix_multiply(const SimpleTensor<T> &a, const SimpleTensor<T> &b, SimpleTensor<T> &out);
226 
227 /** Transpose matrix
228  *
229  * @param[in]  in  Input tensor
230  * @param[out] out Output tensor
231  *
232  */
233 template <typename T>
234 void transpose_matrix(const SimpleTensor<T> &in, SimpleTensor<T> &out);
235 
236 /** Get a 2D tile from a tensor
237  *
238  * @note In case of out-of-bound reads, the tile will be filled with zeros
239  *
240  * @param[in]  in    Input tensor
241  * @param[out] tile  Tile
242  * @param[in]  coord Coordinates
243  */
244 template <typename T>
245 void get_tile(const SimpleTensor<T> &in, SimpleTensor<T> &tile, const Coordinates &coord);
246 
247 /** Fill with zeros the input tensor in the area defined by anchor and shape
248  *
249  * @param[in]  in     Input tensor to fill with zeros
250  * @param[out] anchor Starting point of the zeros area
251  * @param[in]  shape  Ending point of the zeros area
252  */
253 template <typename T>
254 void zeros(SimpleTensor<T> &in, const Coordinates &anchor, const TensorShape &shape);
255 
256 /** Helper function to compute quantized min and max bounds
257  *
258  * @param[in] quant_info Quantization info to be used for conversion
259  * @param[in] min        Floating point minimum value to be quantized
260  * @param[in] max        Floating point maximum value to be quantized
261  */
262 std::pair<int, int> get_quantized_bounds(const QuantizationInfo &quant_info, float min, float max);
263 
264 /** Helper function to compute asymmetric quantized signed min and max bounds
265  *
266  * @param[in] quant_info Quantization info to be used for conversion
267  * @param[in] min        Floating point minimum value to be quantized
268  * @param[in] max        Floating point maximum value to be quantized
269  */
270 std::pair<int, int> get_quantized_qasymm8_signed_bounds(const QuantizationInfo &quant_info, float min, float max);
271 
272 /** Helper function to compute symmetric quantized min and max bounds
273  *
274  * @param[in] quant_info Quantization info to be used for conversion
275  * @param[in] min        Floating point minimum value to be quantized
276  * @param[in] max        Floating point maximum value to be quantized
277  * @param[in] channel_id Channel id for per channel quantization info.
278  */
279 std::pair<int, int> get_symm_quantized_per_channel_bounds(const QuantizationInfo &quant_info, float min, float max, size_t channel_id = 0);
280 } // namespace validation
281 } // namespace test
282 } // namespace arm_compute
283 #endif /* ARM_COMPUTE_TEST_VALIDATION_HELPERS_H */
284