blob: 814d1f5ed06ef67526cfc848e337668c365d6df2 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Giorgio Arena1f9ca1d2018-03-01 11:13:45 +00002 * Copyright (c) 2017-2018 ARM Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
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
Georgios Pinitas7b7858d2017-06-21 16:44:24 +010027#include "arm_compute/core/Types.h"
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010028#include "arm_compute/core/Utils.h"
Moritz Pflanzer6c6597c2017-09-24 12:09:41 +010029#include "support/Half.h"
John Richardson6f4d49f2017-09-07 11:21:10 +010030#include "tests/Globals.h"
Moritz Pflanzer6c6597c2017-09-24 12:09:41 +010031#include "tests/SimpleTensor.h"
Georgios Pinitas7b7858d2017-06-21 16:44:24 +010032
33#include <random>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010034#include <type_traits>
35#include <utility>
36
37namespace arm_compute
38{
39namespace test
40{
41namespace validation
42{
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010043template <typename T>
44struct is_floating_point : public std::is_floating_point<T>
Pablo Tello8fda1cb2017-07-05 15:20:38 +010045{
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010046};
47
48template <>
Georgios Pinitas583137c2017-08-31 18:12:42 +010049struct is_floating_point<half> : public std::true_type
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010050{
51};
Pablo Tello8fda1cb2017-07-05 15:20:38 +010052
Anthony Barbier6ff3b192017-09-04 18:44:23 +010053/** Helper function to get the testing range for each activation layer.
54 *
Vidhya Sudhan Loganathan014333d2018-07-02 09:13:49 +010055 * @param[in] activation Activation function to test.
56 * @param[in] data_type Data type.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010057 *
58 * @return A pair containing the lower upper testing bounds for a given function.
59 */
60template <typename T>
Vidhya Sudhan Loganathan014333d2018-07-02 09:13:49 +010061std::pair<T, T> get_activation_layer_test_bounds(ActivationLayerInfo::ActivationFunction activation, DataType data_type)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010062{
Anthony Barbier6ff3b192017-09-04 18:44:23 +010063 std::pair<T, T> bounds;
64
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010065 switch(data_type)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010066 {
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010067 case DataType::F16:
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +010068 {
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010069 using namespace half_float::literal;
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +010070
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010071 switch(activation)
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +010072 {
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010073 case ActivationLayerInfo::ActivationFunction::SQUARE:
74 case ActivationLayerInfo::ActivationFunction::LOGISTIC:
75 case ActivationLayerInfo::ActivationFunction::SOFT_RELU:
76 // Reduce range as exponent overflows
77 bounds = std::make_pair(-10._h, 10._h);
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +010078 break;
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010079 case ActivationLayerInfo::ActivationFunction::SQRT:
80 // Reduce range as sqrt should take a non-negative number
81 bounds = std::make_pair(0._h, 255._h);
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +010082 break;
83 default:
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010084 bounds = std::make_pair(-255._h, 255._h);
85 break;
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +010086 }
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010087 break;
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +010088 }
Moritz Pflanzera09de0c2017-09-01 20:41:12 +010089 case DataType::F32:
90 switch(activation)
91 {
92 case ActivationLayerInfo::ActivationFunction::LOGISTIC:
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;
Moritz Pflanzera09de0c2017-09-01 20:41:12 +0100106 default:
107 ARM_COMPUTE_ERROR("Unsupported data type");
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +0100108 }
109
Moritz Pflanzera09de0c2017-09-01 20:41:12 +0100110 return bounds;
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +0100111}
112
John Richardson6f4d49f2017-09-07 11:21:10 +0100113/** 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 */
Moritz Pflanzer6c6597c2017-09-24 12:09:41 +0100120void fill_mask_from_pattern(uint8_t *mask, int cols, int rows, MatrixPattern pattern);
John Richardson6f4d49f2017-09-07 11:21:10 +0100121
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100122/** 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 */
Moritz Pflanzera09de0c2017-09-01 20:41:12 +0100128TensorShape calculate_depth_concatenate_shape(const std::vector<TensorShape> &input_shapes);
Sanghoon Leea7a5b7b2017-09-14 12:11:03 +0100129
Michalis Spyrou55b3d122018-05-09 09:59:23 +0100130/** Calculate output tensor shape give a vector of input tensor to concatenate
131 *
132 * @param[in] input_shapes Shapes of the tensors to concatenate across width.
133 *
134 * @return The shape of output concatenated tensor.
135 */
136TensorShape calculate_width_concatenate_shape(const std::vector<TensorShape> &input_shapes);
137
Moritz Pflanzer6c6597c2017-09-24 12:09:41 +0100138/** Parameters of Harris Corners algorithm. */
139struct HarrisCornersParameters
140{
Alex Gildayc357c472018-03-21 13:54:09 +0000141 float threshold{ 0.f }; /**< Threshold */
142 float sensitivity{ 0.f }; /**< Sensitivity */
143 float min_dist{ 0.f }; /**< Minimum distance */
144 uint8_t constant_border_value{ 0 }; /**< Border value */
Moritz Pflanzer6c6597c2017-09-24 12:09:41 +0100145};
146
147/** Generate parameters for Harris Corners algorithm. */
148HarrisCornersParameters harris_corners_parameters();
149
Abe Mbise1b993382017-12-19 13:51:59 +0000150/** Parameters of Canny edge algorithm. */
151struct CannyEdgeParameters
152{
153 int32_t upper_thresh{ 255 };
154 int32_t lower_thresh{ 0 };
155 uint8_t constant_border_value{ 0 };
156};
157
158/** Generate parameters for Canny edge algorithm. */
159CannyEdgeParameters canny_edge_parameters();
160
Sanghoon Leea7a5b7b2017-09-14 12:11:03 +0100161/** Helper function to fill the Lut random by a ILutAccessor.
162 *
163 * @param[in,out] table Accessor at the Lut.
164 *
165 */
166template <typename T>
167void fill_lookuptable(T &&table)
168{
169 std::mt19937 generator(library->seed());
170 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());
171
172 for(int i = std::numeric_limits<typename T::value_type>::min(); i <= std::numeric_limits<typename T::value_type>::max(); i++)
173 {
174 table[i] = distribution(generator);
175 }
176}
Sanghoon Lee96883782017-09-15 14:10:48 +0100177
178/** Helper function to get the testing range for batch normalization layer.
179 *
Sanghoon Lee96883782017-09-15 14:10:48 +0100180 * @return A pair containing the lower upper testing bounds.
181 */
182template <typename T>
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100183std::pair<T, T> get_batchnormalization_layer_test_bounds()
Sanghoon Lee96883782017-09-15 14:10:48 +0100184{
Sanghoon Leec1294fa2017-11-17 11:47:41 +0000185 const bool is_float = std::is_floating_point<T>::value;
Sanghoon Lee96883782017-09-15 14:10:48 +0100186 std::pair<T, T> bounds;
187
188 // Set initial values
189 if(is_float)
190 {
191 bounds = std::make_pair(-1.f, 1.f);
192 }
193 else
194 {
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +0100195 bounds = std::make_pair(1, 1);
Sanghoon Lee96883782017-09-15 14:10:48 +0100196 }
197
198 return bounds;
199}
Anton Lokhmotovaf6204c2017-11-08 09:34:19 +0000200
zhenglin0fb6cf52017-12-12 15:56:09 +0800201/** Helper function to get the testing range for NormalizePlanarYUV layer.
202 *
203 * @return A pair containing the lower upper testing bounds.
204 */
205template <typename T>
206std::pair<T, T> get_normalize_planar_yuv_layer_test_bounds()
207{
208 std::pair<T, T> bounds;
209
210 bounds = std::make_pair(-1.f, 1.f);
211
212 return bounds;
213}
214
Anton Lokhmotovaf6204c2017-11-08 09:34:19 +0000215/** Convert quantized simple tensor into float using tensor quantization information.
216 *
217 * @param[in] src Quantized tensor.
218 *
219 * @return Float tensor.
Anthony Barbierf202e502017-11-23 18:02:04 +0000220 */
Anton Lokhmotovaf6204c2017-11-08 09:34:19 +0000221SimpleTensor<float> convert_from_asymmetric(const SimpleTensor<uint8_t> &src);
222
223/** Convert float simple tensor into quantized using specified quantization information.
224 *
225 * @param[in] src Float tensor.
226 * @param[in] quantization_info Quantification information.
227 *
228 * @return Quantized tensor.
Anthony Barbierf202e502017-11-23 18:02:04 +0000229 */
Anton Lokhmotovaf6204c2017-11-08 09:34:19 +0000230SimpleTensor<uint8_t> convert_to_asymmetric(const SimpleTensor<float> &src, const QuantizationInfo &quantization_info);
Giorgio Arena1f9ca1d2018-03-01 11:13:45 +0000231
232/** Matrix multiply between 2 float simple tensors
233 *
234 * @param[in] a Input tensor A
235 * @param[in] b Input tensor B
236 * @param[out] out Output tensor
237 *
238 */
239void matrix_multiply(const SimpleTensor<float> &a, const SimpleTensor<float> &b, SimpleTensor<float> &out);
240
241/** Transpose matrix
242 *
243 * @param[in] in Input tensor
244 * @param[out] out Output tensor
245 *
246 */
247void transpose_matrix(const SimpleTensor<float> &in, SimpleTensor<float> &out);
248
249/** Get a 2D tile from a tensor
250 *
251 * @note In case of out-of-bound reads, the tile will be filled with zeros
252 *
253 * @param[in] in Input tensor
254 * @param[out] tile Tile
255 * @param[in] coord Coordinates
256 */
257template <typename T>
258void get_tile(const SimpleTensor<T> &in, SimpleTensor<T> &tile, const Coordinates &coord);
Gian Marco Iodicef1c2bf02018-06-13 14:05:54 +0100259
260/** Fill with zeros the input tensor in the area defined by anchor and shape
261 *
262 * @param[in] in Input tensor to fill with zeros
263 * @param[out] anchor Starting point of the zeros area
264 * @param[in] shape Ending point of the zeros area
265 */
266template <typename T>
267void zeros(SimpleTensor<T> &in, const Coordinates &anchor, const TensorShape &shape);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100268} // namespace validation
269} // namespace test
270} // namespace arm_compute
Isabella Gottardib797fa22017-06-23 15:02:11 +0100271#endif /* __ARM_COMPUTE_TEST_VALIDATION_HELPERS_H__ */