blob: e9ddea78cb622d129568ac3c8155f77a6488a9aa [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
2 * Copyright (c) 2017 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#include "Reference.h"
25
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +010026#include "AssetsLibrary.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010027#include "Globals.h"
28#include "Helpers.h"
29#include "ReferenceCPP.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010030#include "validation/Helpers.h"
31
32#include <random>
Georgios Pinitas7b7858d2017-06-21 16:44:24 +010033#include <vector>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010034
35using namespace arm_compute::test;
36
Isabella Gottardib797fa22017-06-23 15:02:11 +010037#ifndef DOXYGEN_SKIP_THIS
Anthony Barbier6ff3b192017-09-04 18:44:23 +010038namespace arm_compute
39{
40namespace test
41{
42namespace validation
43{
Giorgio Arena50f9fd72017-06-19 17:05:30 +010044std::pair<RawTensor, RawTensor> Reference::compute_reference_sobel_3x3(const TensorShape &shape, BorderMode border_mode, uint8_t constant_border_value)
45{
46 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +010047 RawTensor ref_src(shape, Format::U8);
48 RawTensor ref_dst_x(shape, Format::S16);
49 RawTensor ref_dst_y(shape, Format::S16);
Giorgio Arena50f9fd72017-06-19 17:05:30 +010050
51 // Fill reference
52 library->fill_tensor_uniform(ref_src, 0);
53
54 // Compute reference
55 ReferenceCPP::sobel_3x3(ref_src, ref_dst_x, ref_dst_y, border_mode, constant_border_value);
56
57 return std::make_pair(ref_dst_x, ref_dst_y);
58}
59std::pair<RawTensor, RawTensor> Reference::compute_reference_sobel_5x5(const TensorShape &shape, BorderMode border_mode, uint8_t constant_border_value)
60{
61 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +010062 RawTensor ref_src(shape, Format::U8);
63 RawTensor ref_dst_x(shape, Format::S16);
64 RawTensor ref_dst_y(shape, Format::S16);
Giorgio Arena50f9fd72017-06-19 17:05:30 +010065
66 // Fill reference
67 library->fill_tensor_uniform(ref_src, 0);
68
69 // Compute reference
70 ReferenceCPP::sobel_5x5(ref_src, ref_dst_x, ref_dst_y, border_mode, constant_border_value);
71
72 return std::make_pair(ref_dst_x, ref_dst_y);
73}
Giorgio Arena935deee2017-06-14 13:40:36 +010074void Reference::compute_reference_min_max_location(const TensorShape &shape, DataType dt_in, int32_t &min, int32_t &max, IArray<Coordinates2D> &min_loc, IArray<Coordinates2D> &max_loc,
Giorgio Arena2ca209e2017-06-13 15:49:37 +010075 uint32_t &min_count, uint32_t &max_count)
76{
77 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +010078 RawTensor ref_src(shape, dt_in);
Giorgio Arena2ca209e2017-06-13 15:49:37 +010079
80 // Fill reference
81 library->fill_tensor_uniform(ref_src, 0);
82
83 // Compute reference
84 ReferenceCPP::min_max_location(ref_src, min, max, min_loc, max_loc, min_count, max_count);
85}
Giorgio Arenaf7959862017-06-13 15:19:51 +010086std::pair<float, float> Reference::compute_reference_mean_and_standard_deviation(const TensorShape &shape)
87{
88 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +010089 RawTensor ref_src(shape, DataType::U8);
Giorgio Arenaf7959862017-06-13 15:19:51 +010090
91 // Create output variables
92 float mean;
93 float std_dev;
94
95 // Fill reference
96 library->fill_tensor_uniform(ref_src, 0);
97
98 // Compute reference
99 ReferenceCPP::mean_and_standard_deviation(ref_src, mean, std_dev);
100
101 return std::make_pair(mean, std_dev);
102}
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100103RawTensor Reference::compute_reference_integral_image(const TensorShape &shape)
104{
105 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100106 RawTensor ref_src(shape, DataType::U8);
107 RawTensor ref_dst(shape, DataType::U32);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100108
109 // Fill reference
110 library->fill_tensor_uniform(ref_src, 0);
111
112 // Compute reference
113 ReferenceCPP::integral_image(ref_src, ref_dst);
114
115 return ref_dst;
116}
117RawTensor Reference::compute_reference_absolute_difference(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out)
118{
119 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100120 RawTensor ref_src1(shape, dt_in0);
121 RawTensor ref_src2(shape, dt_in1);
122 RawTensor ref_dst(shape, dt_out);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100123
124 // Fill reference
125 library->fill_tensor_uniform(ref_src1, 0);
126 library->fill_tensor_uniform(ref_src2, 1);
127
128 // Compute reference
129 ReferenceCPP::absolute_difference(ref_src1, ref_src2, ref_dst);
130
131 return ref_dst;
132}
133
134RawTensor Reference::compute_reference_accumulate(const TensorShape &shape)
135{
136 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100137 RawTensor ref_src(shape, DataType::U8);
138 RawTensor ref_dst(shape, DataType::S16);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100139
140 // Fill reference
141 library->fill_tensor_uniform(ref_src, 0);
142 library->fill_tensor_uniform(ref_dst, 1);
143
144 // Compute reference
145 ReferenceCPP::accumulate(ref_src, ref_dst);
146
147 return ref_dst;
148}
149
150RawTensor Reference::compute_reference_accumulate_squared(const TensorShape &shape, uint32_t shift)
151{
152 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100153 RawTensor ref_src(shape, DataType::U8);
154 RawTensor ref_dst(shape, DataType::S16);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100155
156 // Fill reference
157 // ref_dst tensor filled with non-negative values
158 library->fill_tensor_uniform(ref_src, 0);
159 library->fill_tensor_uniform(ref_dst, 1, static_cast<int16_t>(0), std::numeric_limits<int16_t>::max());
160
161 // Compute reference
162 ReferenceCPP::accumulate_squared(ref_src, ref_dst, shift);
163
164 return ref_dst;
165}
166
167RawTensor Reference::compute_reference_accumulate_weighted(const TensorShape &shape, float alpha)
168{
169 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100170 RawTensor ref_src(shape, DataType::U8);
171 RawTensor ref_dst(shape, DataType::U8);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100172
173 // Fill reference
174 library->fill_tensor_uniform(ref_src, 0);
175 library->fill_tensor_uniform(ref_dst, 1);
176
177 // Compute reference
178 ReferenceCPP::accumulate_weighted(ref_src, ref_dst, alpha);
179
180 return ref_dst;
181}
182
Michele Di Giorgio81f0d152017-07-11 15:00:52 +0100183RawTensor Reference::compute_reference_arithmetic_addition(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, ConvertPolicy convert_policy, int fixed_point_position)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100184{
185 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100186 RawTensor ref_src1(shape, dt_in0, 1, fixed_point_position);
187 RawTensor ref_src2(shape, dt_in1, 1, fixed_point_position);
188 RawTensor ref_dst(shape, dt_out, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100189
190 // Fill reference
191 library->fill_tensor_uniform(ref_src1, 0);
192 library->fill_tensor_uniform(ref_src2, 1);
193
194 // Compute reference
195 ReferenceCPP::arithmetic_addition(ref_src1, ref_src2, ref_dst, convert_policy);
196
197 return ref_dst;
198}
199
Michele Di Giorgio81f0d152017-07-11 15:00:52 +0100200RawTensor Reference::compute_reference_arithmetic_subtraction(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, ConvertPolicy convert_policy, int fixed_point_position)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100201{
202 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100203 RawTensor ref_src1(shape, dt_in0, 1, fixed_point_position);
204 RawTensor ref_src2(shape, dt_in1, 1, fixed_point_position);
205 RawTensor ref_dst(shape, dt_out, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100206
207 // Fill reference
208 library->fill_tensor_uniform(ref_src1, 0);
209 library->fill_tensor_uniform(ref_src2, 1);
210
211 // Compute reference
212 ReferenceCPP::arithmetic_subtraction(ref_src1, ref_src2, ref_dst, convert_policy);
213
214 return ref_dst;
215}
216
217RawTensor Reference::compute_reference_bitwise_and(const TensorShape &shape)
218{
219 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100220 RawTensor ref_src1(shape, DataType::U8);
221 RawTensor ref_src2(shape, DataType::U8);
222 RawTensor ref_dst(shape, DataType::U8);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100223
224 // Fill reference
225 library->fill_tensor_uniform(ref_src1, 0);
226 library->fill_tensor_uniform(ref_src2, 1);
227
228 // Compute reference
229 ReferenceCPP::bitwise_and(ref_src1, ref_src2, ref_dst);
230
231 return ref_dst;
232}
233
234RawTensor Reference::compute_reference_bitwise_or(const TensorShape &shape)
235{
236 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100237 RawTensor ref_src1(shape, DataType::U8);
238 RawTensor ref_src2(shape, DataType::U8);
239 RawTensor ref_dst(shape, DataType::U8);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100240
241 // Fill reference
242 library->fill_tensor_uniform(ref_src1, 0);
243 library->fill_tensor_uniform(ref_src2, 1);
244
245 // Compute reference
246 ReferenceCPP::bitwise_or(ref_src1, ref_src2, ref_dst);
247
248 return ref_dst;
249}
250
251RawTensor Reference::compute_reference_bitwise_xor(const TensorShape &shape)
252{
253 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100254 RawTensor ref_src1(shape, DataType::U8);
255 RawTensor ref_src2(shape, DataType::U8);
256 RawTensor ref_dst(shape, DataType::U8);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100257
258 // Fill reference
259 library->fill_tensor_uniform(ref_src1, 0);
260 library->fill_tensor_uniform(ref_src2, 1);
261
262 // Compute reference
263 ReferenceCPP::bitwise_xor(ref_src1, ref_src2, ref_dst);
264
265 return ref_dst;
266}
267
268RawTensor Reference::compute_reference_bitwise_not(const TensorShape &shape)
269{
270 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100271 RawTensor ref_src(shape, DataType::U8);
272 RawTensor ref_dst(shape, DataType::U8);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100273
274 // Fill reference
275 library->fill_tensor_uniform(ref_src, 0);
276
277 // Compute reference
278 ReferenceCPP::bitwise_not(ref_src, ref_dst);
279
280 return ref_dst;
281}
282
SiCong Libacaf9a2017-06-19 13:41:45 +0100283RawTensor Reference::compute_reference_box3x3(const TensorShape &shape, BorderMode border_mode, uint8_t constant_border_value)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100284{
285 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100286 RawTensor ref_src(shape, DataType::U8);
287 RawTensor ref_dst(shape, DataType::U8);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100288
289 // Fill reference
290 library->fill_tensor_uniform(ref_src, 0);
291
292 // Compute reference
SiCong Libacaf9a2017-06-19 13:41:45 +0100293 ReferenceCPP::box3x3(ref_src, ref_dst, border_mode, constant_border_value);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100294
295 return ref_dst;
296}
297
Georgios Pinitase2229412017-07-12 12:30:40 +0100298RawTensor Reference::compute_reference_depth_convert(const TensorShape &shape, DataType dt_in, DataType dt_out, ConvertPolicy policy,
299 uint32_t shift, uint32_t fixed_point_position_in, uint32_t fixed_point_position_out)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100300{
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100301 RawTensor ref_src(shape, dt_in, 1, fixed_point_position_in);
302 RawTensor ref_dst(shape, dt_out, 1, fixed_point_position_out);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100303
304 // Fill reference
305 library->fill_tensor_uniform(ref_src, 0);
306
307 // Compute reference
308 ReferenceCPP::depth_convert(ref_src, ref_dst, policy, shift);
309
310 return ref_dst;
311}
312
SiCong Li5a536642017-06-19 14:47:05 +0100313RawTensor Reference::compute_reference_gaussian3x3(const TensorShape &shape, BorderMode border_mode, uint8_t constant_border_value)
314{
315 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100316 RawTensor ref_src(shape, DataType::U8);
317 RawTensor ref_dst(shape, DataType::U8);
SiCong Li5a536642017-06-19 14:47:05 +0100318
319 // Fill reference
320 library->fill_tensor_uniform(ref_src, 0);
321
322 // Compute reference
323 ReferenceCPP::gaussian3x3(ref_src, ref_dst, border_mode, constant_border_value);
324
325 return ref_dst;
326}
327
SiCong Li3eb263e2017-06-19 15:31:43 +0100328RawTensor Reference::compute_reference_gaussian5x5(const TensorShape &shape, BorderMode border_mode, uint8_t constant_border_value)
329{
330 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100331 RawTensor ref_src(shape, DataType::U8);
332 RawTensor ref_dst(shape, DataType::U8);
SiCong Li3eb263e2017-06-19 15:31:43 +0100333
334 // Fill reference
335 library->fill_tensor_uniform(ref_src, 0);
336
337 // Compute reference
338 ReferenceCPP::gaussian5x5(ref_src, ref_dst, border_mode, constant_border_value);
339
340 return ref_dst;
341}
342
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100343RawTensor Reference::compute_reference_gemm(const TensorShape &src_shape1, const TensorShape &src_shape2, const TensorShape &src_shape3,
344 const TensorShape &dst_shape, float alpha, float beta, DataType dt, int fixed_point_position)
345{
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100346 RawTensor src1(src_shape1, dt, 1, fixed_point_position);
347 RawTensor src2(src_shape2, dt, 1, fixed_point_position);
348 RawTensor src3(src_shape3, dt, 1, fixed_point_position);
349 RawTensor dst(dst_shape, dt, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100350
351 // Fill reference
Pablo Tello221f3812017-06-28 17:27:56 +0100352 if(dt == DataType::F16 || dt == DataType::F32)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100353 {
354 std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
355 library->fill(src1, distribution, 0);
356 library->fill(src2, distribution, 1);
357 library->fill(src3, distribution, 2);
358 }
359 else
360 {
361 library->fill_tensor_uniform(src1, 0);
362 library->fill_tensor_uniform(src2, 1);
363 library->fill_tensor_uniform(src3, 2);
364 }
365
366 // Compute reference
367 ReferenceCPP::gemm(src1, src2, src3, dst, alpha, beta);
368
369 return dst;
370}
371
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +0100372RawTensor Reference::compute_reference_non_linear_filter(const TensorShape &shape, NonLinearFilterFunction function, unsigned int mask_size,
373 MatrixPattern pattern, const uint8_t *mask, BorderMode border_mode, uint8_t constant_border_value)
374{
375 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100376 RawTensor ref_src(shape, DataType::U8);
377 RawTensor ref_dst(shape, DataType::U8);
Isabella Gottardi3b77e9d2017-06-22 11:05:41 +0100378
379 // Fill reference
380 library->fill_tensor_uniform(ref_src, 0);
381
382 // Compute reference
383 ReferenceCPP::non_linear_filter(ref_src, ref_dst, function, mask_size, pattern, mask, border_mode, constant_border_value);
384
385 return ref_dst;
386}
387
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100388RawTensor Reference::compute_reference_pixel_wise_multiplication(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, float scale, ConvertPolicy convert_policy,
389 RoundingPolicy rounding_policy)
390{
391 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100392 RawTensor ref_src1(shape, dt_in0);
393 RawTensor ref_src2(shape, dt_in1);
394 RawTensor ref_dst(shape, dt_out);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100395
396 // Fill reference
397 library->fill_tensor_uniform(ref_src1, 0);
398 library->fill_tensor_uniform(ref_src2, 1);
399
400 // Compute reference
401 ReferenceCPP::pixel_wise_multiplication(ref_src1, ref_src2, ref_dst, scale, convert_policy, rounding_policy);
402
403 return ref_dst;
404}
405
406RawTensor Reference::compute_reference_fixed_point_pixel_wise_multiplication(const TensorShape &shape, DataType dt_in0, DataType dt_in1, DataType dt_out, float scale, int fixed_point_position,
407 ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
408{
409 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100410 RawTensor ref_src1(shape, dt_in0, 1, fixed_point_position);
411 RawTensor ref_src2(shape, dt_in1, 1, fixed_point_position);
412 RawTensor ref_dst(shape, dt_out, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100413
414 // Fill reference
415 library->fill_tensor_uniform(ref_src1, 0);
416 library->fill_tensor_uniform(ref_src2, 1);
417
418 // Compute reference
419 ReferenceCPP::fixed_point_pixel_wise_multiplication(ref_src1, ref_src2, ref_dst, scale, convert_policy, rounding_policy);
420
421 return ref_dst;
422}
423
Isabella Gottardib797fa22017-06-23 15:02:11 +0100424template <typename T>
425RawTensor Reference::compute_reference_table_lookup(const TensorShape &shape, DataType dt_inout, std::map<T, T> &lut)
426{
427 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100428 RawTensor ref_src(shape, dt_inout);
429 RawTensor ref_dst(shape, dt_inout);
Isabella Gottardib797fa22017-06-23 15:02:11 +0100430 // Fill reference
431 library->fill_tensor_uniform(ref_src, 0);
432
433 // Compute reference
434 ReferenceCPP::table_lookup(ref_src, ref_dst, lut);
435
436 return ref_dst;
437}
438template RawTensor arm_compute::test::validation::Reference::compute_reference_table_lookup<uint8_t>(const TensorShape &shape, DataType dt_inout, std::map<uint8_t, uint8_t> &lut);
439template RawTensor arm_compute::test::validation::Reference::compute_reference_table_lookup<int16_t>(const TensorShape &shape, DataType dt_inout, std::map<int16_t, int16_t> &lut);
440
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100441RawTensor Reference::compute_reference_threshold(const TensorShape &shape, uint8_t threshold, uint8_t false_value, uint8_t true_value, ThresholdType type, uint8_t upper)
442{
443 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100444 RawTensor ref_src(shape, DataType::U8);
445 RawTensor ref_dst(shape, DataType::U8);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100446
447 // Fill reference
Isabella Gottardib797fa22017-06-23 15:02:11 +0100448 library->fill_tensor_uniform(ref_src, 0);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100449
450 // Compute reference
Isabella Gottardib797fa22017-06-23 15:02:11 +0100451 ReferenceCPP::threshold(ref_src, ref_dst, threshold, false_value, true_value, type, upper);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100452
453 return ref_dst;
454}
455
456RawTensor Reference::compute_reference_activation_layer(const TensorShape &shape, DataType dt, ActivationLayerInfo act_info, int fixed_point_position)
457{
458 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100459 RawTensor ref_src(shape, dt, 1, fixed_point_position);
460 RawTensor ref_dst(shape, dt, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100461
Pablo Tello91654c42017-07-05 11:32:17 +0100462 // Fill tensors
463 switch(dt)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100464 {
Pablo Tello91654c42017-07-05 11:32:17 +0100465 case DataType::QS8:
Georgios Pinitas00394ae2017-06-22 18:13:55 +0100466 {
Pablo Tello91654c42017-07-05 11:32:17 +0100467 const std::pair<int8_t, int8_t> bounds = get_activation_layer_test_bounds<int8_t>(act_info.activation(), fixed_point_position);
468 std::uniform_int_distribution<> distribution(bounds.first, bounds.second);
469 library->fill(ref_src, distribution, 0);
470 break;
Georgios Pinitas00394ae2017-06-22 18:13:55 +0100471 }
Pablo Tello91654c42017-07-05 11:32:17 +0100472 case DataType::QS16:
Georgios Pinitas00394ae2017-06-22 18:13:55 +0100473 {
Pablo Tello91654c42017-07-05 11:32:17 +0100474 const std::pair<int16_t, int16_t> bounds = get_activation_layer_test_bounds<int16_t>(act_info.activation(), fixed_point_position);
475 std::uniform_int_distribution<> distribution(bounds.first, bounds.second);
476 library->fill(ref_src, distribution, 0);
477 break;
Georgios Pinitas00394ae2017-06-22 18:13:55 +0100478 }
Pablo Tello91654c42017-07-05 11:32:17 +0100479 case DataType::F16:
480 {
Moritz Pflanzere49e2662017-07-21 15:55:28 +0100481 const std::pair<half_float::half, half_float::half> bounds = get_activation_layer_test_bounds<half_float::half>(act_info.activation());
Pablo Tello91654c42017-07-05 11:32:17 +0100482 std::uniform_real_distribution<> distribution(bounds.first, bounds.second);
483 library->fill(ref_src, distribution, 0);
484 break;
485 }
Pablo Tello91654c42017-07-05 11:32:17 +0100486 case DataType::F32:
487 {
488 const std::pair<float, float> bounds = get_activation_layer_test_bounds<float>(act_info.activation());
489 std::uniform_real_distribution<> distribution(bounds.first, bounds.second);
490 library->fill(ref_src, distribution, 0);
491 break;
492 }
493 default:
494 {
495 ARM_COMPUTE_ERROR("Not supported");
496 break;
497 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100498 }
499
500 // Compute reference
501 ReferenceCPP::activation_layer(ref_src, ref_dst, act_info);
502
503 return ref_dst;
504}
505
506RawTensor Reference::compute_reference_batch_normalization_layer(const TensorShape &shape0, const TensorShape &shape1, DataType dt, float epsilon, int fixed_point_position)
507{
508 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100509 RawTensor ref_src(shape0, dt, 1, fixed_point_position);
510 RawTensor ref_dst(shape0, dt, 1, fixed_point_position);
511 RawTensor ref_mean(shape1, dt, 1, fixed_point_position);
512 RawTensor ref_var(shape1, dt, 1, fixed_point_position);
513 RawTensor ref_beta(shape1, dt, 1, fixed_point_position);
514 RawTensor ref_gamma(shape1, dt, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100515
Pablo Tello8fda1cb2017-07-05 15:20:38 +0100516 // Fill tensors
517 switch(dt)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100518 {
Pablo Tello8fda1cb2017-07-05 15:20:38 +0100519 case DataType::QS8:
Michalis Spyrou172e5702017-06-26 14:18:47 +0100520 {
Pablo Tello8fda1cb2017-07-05 15:20:38 +0100521 const std::pair<int8_t, int8_t> bounds = get_batchnormalization_layer_test_bounds<int8_t>(fixed_point_position);
522 std::uniform_int_distribution<> distribution(bounds.first, bounds.second);
523 std::uniform_int_distribution<> distribution_var(0, bounds.second);
524 fill_tensors(distribution, { 0, 1, 3, 4 }, &ref_src, &ref_mean, &ref_beta, &ref_gamma);
525 fill_tensors(distribution_var, { 0 }, &ref_var);
526 break;
Michalis Spyrou172e5702017-06-26 14:18:47 +0100527 }
Pablo Tello8fda1cb2017-07-05 15:20:38 +0100528 case DataType::QS16:
Michalis Spyrou172e5702017-06-26 14:18:47 +0100529 {
Pablo Tello8fda1cb2017-07-05 15:20:38 +0100530 const std::pair<int16_t, int16_t> bounds = get_batchnormalization_layer_test_bounds<int16_t>(fixed_point_position);
531 std::uniform_int_distribution<> distribution(bounds.first, bounds.second);
532 std::uniform_int_distribution<> distribution_var(0, bounds.second);
533 fill_tensors(distribution, { 0, 1, 3, 4 }, &ref_src, &ref_mean, &ref_beta, &ref_gamma);
534 fill_tensors(distribution_var, { 0 }, &ref_var);
535 break;
Michalis Spyrou172e5702017-06-26 14:18:47 +0100536 }
Pablo Tello8fda1cb2017-07-05 15:20:38 +0100537 case DataType::F16:
538 {
539 const std::pair<half_float::half, half_float::half> bounds = get_batchnormalization_layer_test_bounds<half_float::half>();
540 std::uniform_real_distribution<> distribution(bounds.first, bounds.second);
541 std::uniform_real_distribution<> distribution_var(0, bounds.second);
542 fill_tensors(distribution, { 0, 1, 3, 4 }, &ref_src, &ref_mean, &ref_beta, &ref_gamma);
543 fill_tensors(distribution_var, { 0 }, &ref_var);
544 break;
545 }
546 case DataType::F32:
547 {
548 const std::pair<float, float> bounds = get_batchnormalization_layer_test_bounds<float>();
549 std::uniform_real_distribution<> distribution(bounds.first, bounds.second);
550 std::uniform_real_distribution<> distribution_var(0, bounds.second);
551 fill_tensors(distribution, { 0, 1, 3, 4 }, &ref_src, &ref_mean, &ref_beta, &ref_gamma);
552 fill_tensors(distribution_var, { 0 }, &ref_var);
553 break;
554 }
555 default:
556 {
557 ARM_COMPUTE_ERROR("Not supported");
558 break;
559 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100560 }
561
562 // Compute reference
563 ReferenceCPP::batch_normalization_layer(ref_src, ref_dst, ref_mean, ref_var, ref_beta, ref_gamma, epsilon, fixed_point_position);
564
565 return ref_dst;
566}
567
568RawTensor Reference::compute_reference_convolution_layer(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape, DataType dt,
569 const PadStrideInfo &conv_info, int fixed_point_position)
570{
571 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100572 RawTensor ref_src(input_shape, dt, 1, fixed_point_position);
573 RawTensor ref_weights(weights_shape, dt, 1, fixed_point_position);
574 RawTensor ref_bias(bias_shape, dt, 1, fixed_point_position);
575 RawTensor ref_dst(output_shape, dt, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100576
577 // Fill reference
Pablo Tellodcdc85e2017-06-28 10:05:29 +0100578 switch(dt)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100579 {
Pablo Tellodcdc85e2017-06-28 10:05:29 +0100580 case DataType::F32:
581 case DataType::F16:
582 {
583 std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
584 library->fill(ref_src, distribution, 0);
585 library->fill(ref_weights, distribution, 1);
586 library->fill(ref_bias, distribution, 2);
587 break;
588 }
589 case DataType::QS16:
590 case DataType::QS8:
591 {
592 library->fill_tensor_uniform(ref_src, 0);
593 library->fill_tensor_uniform(ref_weights, 1);
594 library->fill_tensor_uniform(ref_bias, 2);
595 break;
596 }
597 default:
598 {
599 ARM_COMPUTE_ERROR("Not supported");
600 break;
601 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100602 }
603
604 // Compute reference
605 ReferenceCPP::convolution_layer(ref_src, ref_weights, ref_bias, ref_dst, conv_info);
606
607 return ref_dst;
608}
609
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100610RawTensor Reference::compute_reference_depth_concatenate_layer(const std::vector<TensorShape> &shapes, DataType dt, int fixed_point_position)
611{
612 std::vector<std::unique_ptr<RawTensor>> ref_srcs{};
613 TensorShape dst_shape = calculate_depth_concatenate_shape(shapes);
614
615 // Create tensors
Moritz Pflanzere49e2662017-07-21 15:55:28 +0100616 for(const auto &shape : shapes)
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100617 {
Moritz Pflanzere49e2662017-07-21 15:55:28 +0100618 ref_srcs.push_back(support::cpp14::make_unique<RawTensor>(shape, dt, 1, fixed_point_position));
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100619 }
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100620 RawTensor ref_dst(dst_shape, dt, 1, fixed_point_position);
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100621
622 // Fill references
623 for(unsigned int i = 0; i < ref_srcs.size(); ++i)
624 {
625 library->fill_tensor_uniform(*ref_srcs[i], i);
626 }
627
628 // Compute reference
629 ReferenceCPP::depth_concatenate_layer(ref_srcs, ref_dst);
630
631 return ref_dst;
632}
633
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100634RawTensor Reference::compute_reference_fully_connected_layer(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape,
635 DataType dt, bool transpose_weights, int fixed_point_position)
636{
637 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100638 RawTensor ref_src(input_shape, dt, 1, fixed_point_position);
639 RawTensor ref_bias(bias_shape, dt, 1, fixed_point_position);
640 RawTensor ref_dst(output_shape, dt, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100641
642 // Swap the first and second dimension of weights' shape if transpose_weights is true
643 TensorShape ws = weights_shape;
644 if(transpose_weights)
645 {
646 const size_t dimx = ws.x();
647 ws.set(0, ws.y());
648 ws.set(1, dimx);
649 }
650
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100651 RawTensor ref_weights(ws, dt, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100652
653 // Fill reference
Pablo Tellodcdc85e2017-06-28 10:05:29 +0100654 if(dt == DataType::F16 || dt == DataType::F32)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100655 {
656 std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
657 library->fill(ref_src, distribution, 0);
658 library->fill(ref_weights, distribution, 1);
659 library->fill(ref_bias, distribution, 2);
660 }
661 else
662 {
663 library->fill_tensor_uniform(ref_src, 0);
664 library->fill_tensor_uniform(ref_weights, 1);
665 library->fill_tensor_uniform(ref_bias, 2);
666 }
667
668 // Compute reference
669 ReferenceCPP::fully_connected_layer(ref_src, ref_weights, ref_bias, ref_dst);
670
671 return ref_dst;
672}
673
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100674RawTensor Reference::compute_reference_pooling_layer(const TensorShape &shape_in, const TensorShape &shape_out, DataType dt, PoolingLayerInfo pool_info, int fixed_point_position)
675{
676 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100677 RawTensor ref_src(shape_in, dt, 1, fixed_point_position);
678 RawTensor ref_dst(shape_out, dt, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100679
680 // Fill reference
681 int min = 0;
682 int max = 0;
683 switch(dt)
684 {
685 case DataType::F32:
Pablo Tello0c34fe22017-06-26 17:17:42 +0100686 case DataType::F16:
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100687 min = -1;
688 max = 1;
689 break;
690 case DataType::QS8:
691 min = -(1 << fixed_point_position);
692 max = (1 << fixed_point_position);
693 break;
694 default:
695 ARM_COMPUTE_ERROR("DataType not supported.");
696 }
697 std::uniform_real_distribution<> distribution(min, max);
698 library->fill(ref_src, distribution, 0.0);
699
700 // Compute reference
701 ReferenceCPP::pooling_layer(ref_src, ref_dst, pool_info, fixed_point_position);
702
703 return ref_dst;
704}
705
Georgios Pinitas7b7858d2017-06-21 16:44:24 +0100706RawTensor Reference::compute_reference_roi_pooling_layer(const TensorShape &shape, DataType dt, const std::vector<ROI> &rois, const ROIPoolingLayerInfo &pool_info)
707{
708 TensorShape shape_dst;
709 shape_dst.set(0, pool_info.pooled_width());
710 shape_dst.set(1, pool_info.pooled_height());
711 shape_dst.set(2, shape.z());
712 shape_dst.set(3, rois.size());
713
714 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100715 RawTensor ref_src(shape, dt);
716 RawTensor ref_dst(shape_dst, dt);
Georgios Pinitas7b7858d2017-06-21 16:44:24 +0100717
718 // Fill reference
719 std::uniform_real_distribution<> distribution(-1, 1);
720 library->fill(ref_src, distribution, 0.0);
721
722 // Compute reference
723 ReferenceCPP::roi_pooling_layer(ref_src, ref_dst, rois, pool_info);
724
725 return ref_dst;
726}
727
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100728RawTensor Reference::compute_reference_fixed_point_operation(const TensorShape &shape, DataType dt_in, DataType dt_out, FixedPointOp op, int fixed_point_position)
729{
730 // Create reference
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100731 RawTensor ref_src(shape, dt_in, 1, fixed_point_position);
732 RawTensor ref_dst(shape, dt_out, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100733
734 // Fill reference
735 int min = 0;
736 int max = 0;
737 switch(op)
738 {
739 case(FixedPointOp::INV_SQRT):
Michalis Spyrou0a8334c2017-06-14 18:00:05 +0100740 min = 1;
741 max = (dt_in == DataType::QS8) ? 0x7F : 0x7FFF;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100742 break;
743 case(FixedPointOp::LOG):
744 min = (1 << (fixed_point_position - 1));
Michalis Spyrou0a8334c2017-06-14 18:00:05 +0100745 max = (dt_in == DataType::QS8) ? 0x3F : 0x3FFF;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100746 break;
747 case(FixedPointOp::EXP):
Michalis Spyrou0a8334c2017-06-14 18:00:05 +0100748 min = -(1 << (fixed_point_position - 1));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100749 max = (1 << (fixed_point_position - 1));
750 break;
751 case(FixedPointOp::RECIPROCAL):
752 min = 15;
Michalis Spyrou0a8334c2017-06-14 18:00:05 +0100753 max = (dt_in == DataType::QS8) ? 0x7F : 0x7FFF;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100754 break;
755 default:
756 ARM_COMPUTE_ERROR("Fixed point operation not supported");
757 }
758 std::uniform_int_distribution<> distribution(min, max);
759 library->fill(ref_src, distribution, 0);
760
761 // Compute reference
762 ReferenceCPP::fixed_point_operation(ref_src, ref_dst, op);
763
764 return ref_dst;
765}
766
767} // namespace validation
768} // namespace test
769} // namespace arm_compute
Isabella Gottardib797fa22017-06-23 15:02:11 +0100770#endif /* DOXYGEN_SKIP_THIS */