blob: 0ce25c55671270c8db98a007e21aa2ae598924e3 [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
26#include "Globals.h"
27#include "Helpers.h"
28#include "ReferenceCPP.h"
29#include "TensorLibrary.h"
30#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
47 RawTensor ref_src = library->get(shape, Format::U8);
48 RawTensor ref_dst_x = library->get(shape, Format::S16);
49 RawTensor ref_dst_y = library->get(shape, Format::S16);
50
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
62 RawTensor ref_src = library->get(shape, Format::U8);
63 RawTensor ref_dst_x = library->get(shape, Format::S16);
64 RawTensor ref_dst_y = library->get(shape, Format::S16);
65
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 Arena2ca209e2017-06-13 15:49:37 +010074void Reference::compute_reference_min_max_location(const TensorShape &shape, DataType dt_in, int32_t &min, int32_t &max, Coordinates2DArray &min_loc, Coordinates2DArray &max_loc,
75 uint32_t &min_count, uint32_t &max_count)
76{
77 // Create reference
78 RawTensor ref_src = library->get(shape, dt_in);
79
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
89 RawTensor ref_src = library->get(shape, DataType::U8);
90
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
106 RawTensor ref_src = library->get(shape, DataType::U8);
107 RawTensor ref_dst = library->get(shape, DataType::U32);
108
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
120 RawTensor ref_src1 = library->get(shape, dt_in0);
121 RawTensor ref_src2 = library->get(shape, dt_in1);
122 RawTensor ref_dst = library->get(shape, dt_out);
123
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
137 RawTensor ref_src = library->get(shape, DataType::U8);
138 RawTensor ref_dst = library->get(shape, DataType::S16);
139
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
153 RawTensor ref_src = library->get(shape, DataType::U8);
154 RawTensor ref_dst = library->get(shape, DataType::S16);
155
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
170 RawTensor ref_src = library->get(shape, DataType::U8);
171 RawTensor ref_dst = library->get(shape, DataType::U8);
172
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
Michele Di Giorgio81f0d152017-07-11 15:00:52 +0100186 RawTensor ref_src1 = library->get(shape, dt_in0, 1, fixed_point_position);
187 RawTensor ref_src2 = library->get(shape, dt_in1, 1, fixed_point_position);
188 RawTensor ref_dst = library->get(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
Michele Di Giorgio81f0d152017-07-11 15:00:52 +0100203 RawTensor ref_src1 = library->get(shape, dt_in0, 1, fixed_point_position);
204 RawTensor ref_src2 = library->get(shape, dt_in1, 1, fixed_point_position);
205 RawTensor ref_dst = library->get(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
220 RawTensor ref_src1 = library->get(shape, DataType::U8);
221 RawTensor ref_src2 = library->get(shape, DataType::U8);
222 RawTensor ref_dst = library->get(shape, DataType::U8);
223
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
237 RawTensor ref_src1 = library->get(shape, DataType::U8);
238 RawTensor ref_src2 = library->get(shape, DataType::U8);
239 RawTensor ref_dst = library->get(shape, DataType::U8);
240
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
254 RawTensor ref_src1 = library->get(shape, DataType::U8);
255 RawTensor ref_src2 = library->get(shape, DataType::U8);
256 RawTensor ref_dst = library->get(shape, DataType::U8);
257
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
271 RawTensor ref_src = library->get(shape, DataType::U8);
272 RawTensor ref_dst = library->get(shape, DataType::U8);
273
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
286 RawTensor ref_src = library->get(shape, DataType::U8);
287 RawTensor ref_dst = library->get(shape, DataType::U8);
288
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{
Georgios Pinitase2229412017-07-12 12:30:40 +0100301 RawTensor ref_src = library->get(shape, dt_in, 1, fixed_point_position_in);
302 RawTensor ref_dst = library->get(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
316 RawTensor ref_src = library->get(shape, DataType::U8);
317 RawTensor ref_dst = library->get(shape, DataType::U8);
318
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
331 RawTensor ref_src = library->get(shape, DataType::U8);
332 RawTensor ref_dst = library->get(shape, DataType::U8);
333
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{
346 RawTensor src1 = library->get(src_shape1, dt, 1, fixed_point_position);
347 RawTensor src2 = library->get(src_shape2, dt, 1, fixed_point_position);
348 RawTensor src3 = library->get(src_shape3, dt, 1, fixed_point_position);
349 RawTensor dst = library->get(dst_shape, dt, 1, fixed_point_position);
350
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
376 RawTensor ref_src = library->get(shape, DataType::U8);
377 RawTensor ref_dst = library->get(shape, DataType::U8);
378
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
392 RawTensor ref_src1 = library->get(shape, dt_in0);
393 RawTensor ref_src2 = library->get(shape, dt_in1);
394 RawTensor ref_dst = library->get(shape, dt_out);
395
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
410 RawTensor ref_src1 = library->get(shape, dt_in0, 1, fixed_point_position);
411 RawTensor ref_src2 = library->get(shape, dt_in1, 1, fixed_point_position);
412 RawTensor ref_dst = library->get(shape, dt_out, 1, fixed_point_position);
413
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
428 RawTensor ref_src = library->get(shape, dt_inout);
429 RawTensor ref_dst = library->get(shape, dt_inout);
430 // 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
Isabella Gottardib797fa22017-06-23 15:02:11 +0100444 RawTensor ref_src = library->get(shape, DataType::U8);
445 RawTensor ref_dst = library->get(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
459 RawTensor ref_src = library->get(shape, dt, 1, fixed_point_position);
460 RawTensor ref_dst = library->get(shape, dt, 1, fixed_point_position);
461
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#ifdef ARM_COMPUTE_ENABLE_FP16
480 case DataType::F16:
481 {
482 const std::pair<float16_t, float16_t> bounds = get_activation_layer_test_bounds<float16_t>(act_info.activation());
483 std::uniform_real_distribution<> distribution(bounds.first, bounds.second);
484 library->fill(ref_src, distribution, 0);
485 break;
486 }
487#endif /* ARM_COMPUTE_ENABLE_FP16 */
488 case DataType::F32:
489 {
490 const std::pair<float, float> bounds = get_activation_layer_test_bounds<float>(act_info.activation());
491 std::uniform_real_distribution<> distribution(bounds.first, bounds.second);
492 library->fill(ref_src, distribution, 0);
493 break;
494 }
495 default:
496 {
497 ARM_COMPUTE_ERROR("Not supported");
498 break;
499 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100500 }
501
502 // Compute reference
503 ReferenceCPP::activation_layer(ref_src, ref_dst, act_info);
504
505 return ref_dst;
506}
507
508RawTensor Reference::compute_reference_batch_normalization_layer(const TensorShape &shape0, const TensorShape &shape1, DataType dt, float epsilon, int fixed_point_position)
509{
510 // Create reference
511 RawTensor ref_src = library->get(shape0, dt, 1, fixed_point_position);
512 RawTensor ref_dst = library->get(shape0, dt, 1, fixed_point_position);
513 RawTensor ref_mean = library->get(shape1, dt, 1, fixed_point_position);
514 RawTensor ref_var = library->get(shape1, dt, 1, fixed_point_position);
515 RawTensor ref_beta = library->get(shape1, dt, 1, fixed_point_position);
516 RawTensor ref_gamma = library->get(shape1, dt, 1, fixed_point_position);
517
518 // Fill tensors with values from -1 to 1.
519 if(dt == DataType::F32)
520 {
521 float min_bound = 0.f;
522 float max_bound = 0.f;
523 std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<float>();
524 std::uniform_real_distribution<> distribution(min_bound, max_bound);
525 std::uniform_real_distribution<> distribution_var(0, max_bound);
526 library->fill(ref_src, distribution, 0);
527 library->fill(ref_mean, distribution, 1);
528 library->fill(ref_var, distribution_var, 0);
529 library->fill(ref_beta, distribution, 3);
530 library->fill(ref_gamma, distribution, 4);
531 }
532 else
533 {
534 int min_bound = 0;
535 int max_bound = 0;
Michalis Spyrou172e5702017-06-26 14:18:47 +0100536 if(dt == DataType::QS8)
537 {
538 std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<int8_t>(fixed_point_position);
539 }
540 else
541 {
542 std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<int16_t>(fixed_point_position);
543 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100544 std::uniform_int_distribution<> distribution(min_bound, max_bound);
545 std::uniform_int_distribution<> distribution_var(0, max_bound);
546 library->fill(ref_src, distribution, 0);
547 library->fill(ref_mean, distribution, 1);
548 library->fill(ref_var, distribution_var, 0);
549 library->fill(ref_beta, distribution, 3);
550 library->fill(ref_gamma, distribution, 4);
551 }
552
553 // Compute reference
554 ReferenceCPP::batch_normalization_layer(ref_src, ref_dst, ref_mean, ref_var, ref_beta, ref_gamma, epsilon, fixed_point_position);
555
556 return ref_dst;
557}
558
559RawTensor Reference::compute_reference_convolution_layer(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape, DataType dt,
560 const PadStrideInfo &conv_info, int fixed_point_position)
561{
562 // Create reference
563 RawTensor ref_src = library->get(input_shape, dt, 1, fixed_point_position);
564 RawTensor ref_weights = library->get(weights_shape, dt, 1, fixed_point_position);
565 RawTensor ref_bias = library->get(bias_shape, dt, 1, fixed_point_position);
566 RawTensor ref_dst = library->get(output_shape, dt, 1, fixed_point_position);
567
568 // Fill reference
Pablo Tellodcdc85e2017-06-28 10:05:29 +0100569 switch(dt)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100570 {
Pablo Tellodcdc85e2017-06-28 10:05:29 +0100571 case DataType::F32:
572 case DataType::F16:
573 {
574 std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
575 library->fill(ref_src, distribution, 0);
576 library->fill(ref_weights, distribution, 1);
577 library->fill(ref_bias, distribution, 2);
578 break;
579 }
580 case DataType::QS16:
581 case DataType::QS8:
582 {
583 library->fill_tensor_uniform(ref_src, 0);
584 library->fill_tensor_uniform(ref_weights, 1);
585 library->fill_tensor_uniform(ref_bias, 2);
586 break;
587 }
588 default:
589 {
590 ARM_COMPUTE_ERROR("Not supported");
591 break;
592 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100593 }
594
595 // Compute reference
596 ReferenceCPP::convolution_layer(ref_src, ref_weights, ref_bias, ref_dst, conv_info);
597
598 return ref_dst;
599}
600
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100601RawTensor Reference::compute_reference_depth_concatenate_layer(const std::vector<TensorShape> &shapes, DataType dt, int fixed_point_position)
602{
603 std::vector<std::unique_ptr<RawTensor>> ref_srcs{};
604 TensorShape dst_shape = calculate_depth_concatenate_shape(shapes);
605
606 // Create tensors
607 for(unsigned int i = 0; i < shapes.size(); ++i)
608 {
609 ref_srcs.push_back(support::cpp14::make_unique<RawTensor>(RawTensor(shapes[i], dt, 1, fixed_point_position)));
610 }
611 RawTensor ref_dst = library->get(dst_shape, dt, 1, fixed_point_position);
612
613 // Fill references
614 for(unsigned int i = 0; i < ref_srcs.size(); ++i)
615 {
616 library->fill_tensor_uniform(*ref_srcs[i], i);
617 }
618
619 // Compute reference
620 ReferenceCPP::depth_concatenate_layer(ref_srcs, ref_dst);
621
622 return ref_dst;
623}
624
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100625RawTensor Reference::compute_reference_fully_connected_layer(const TensorShape &input_shape, const TensorShape &weights_shape, const TensorShape &bias_shape, const TensorShape &output_shape,
626 DataType dt, bool transpose_weights, int fixed_point_position)
627{
628 // Create reference
629 RawTensor ref_src = library->get(input_shape, dt, 1, fixed_point_position);
630 RawTensor ref_bias = library->get(bias_shape, dt, 1, fixed_point_position);
631 RawTensor ref_dst = library->get(output_shape, dt, 1, fixed_point_position);
632
633 // Swap the first and second dimension of weights' shape if transpose_weights is true
634 TensorShape ws = weights_shape;
635 if(transpose_weights)
636 {
637 const size_t dimx = ws.x();
638 ws.set(0, ws.y());
639 ws.set(1, dimx);
640 }
641
642 RawTensor ref_weights = library->get(ws, dt, 1, fixed_point_position);
643
644 // Fill reference
Pablo Tellodcdc85e2017-06-28 10:05:29 +0100645 if(dt == DataType::F16 || dt == DataType::F32)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100646 {
647 std::uniform_real_distribution<> distribution(-1.0f, 1.0f);
648 library->fill(ref_src, distribution, 0);
649 library->fill(ref_weights, distribution, 1);
650 library->fill(ref_bias, distribution, 2);
651 }
652 else
653 {
654 library->fill_tensor_uniform(ref_src, 0);
655 library->fill_tensor_uniform(ref_weights, 1);
656 library->fill_tensor_uniform(ref_bias, 2);
657 }
658
659 // Compute reference
660 ReferenceCPP::fully_connected_layer(ref_src, ref_weights, ref_bias, ref_dst);
661
662 return ref_dst;
663}
664
665RawTensor Reference::compute_reference_normalization_layer(const TensorShape &shape, DataType dt, NormalizationLayerInfo norm_info, int fixed_point_position)
666{
667 // Create reference
668 RawTensor ref_src = library->get(shape, dt, 1, fixed_point_position);
669 RawTensor ref_dst = library->get(shape, dt, 1, fixed_point_position);
670
671 // Fill reference
672 if(dt == DataType::QS8)
673 {
674 const int8_t one_fixed_point = 1 << fixed_point_position;
675 const int8_t minus_one_fixed_point = -one_fixed_point;
676 library->fill_tensor_uniform(ref_src, 0, minus_one_fixed_point, one_fixed_point);
677 }
678 else
679 {
680 library->fill_tensor_uniform(ref_src, 0);
681 }
682
683 // Compute reference
684 ReferenceCPP::normalization_layer(ref_src, ref_dst, norm_info);
685
686 return ref_dst;
687}
688
689RawTensor Reference::compute_reference_pooling_layer(const TensorShape &shape_in, const TensorShape &shape_out, DataType dt, PoolingLayerInfo pool_info, int fixed_point_position)
690{
691 // Create reference
692 RawTensor ref_src = library->get(shape_in, dt, 1, fixed_point_position);
693 RawTensor ref_dst = library->get(shape_out, dt, 1, fixed_point_position);
694
695 // Fill reference
696 int min = 0;
697 int max = 0;
698 switch(dt)
699 {
700 case DataType::F32:
701 min = -1;
702 max = 1;
703 break;
704 case DataType::QS8:
705 min = -(1 << fixed_point_position);
706 max = (1 << fixed_point_position);
707 break;
708 default:
709 ARM_COMPUTE_ERROR("DataType not supported.");
710 }
711 std::uniform_real_distribution<> distribution(min, max);
712 library->fill(ref_src, distribution, 0.0);
713
714 // Compute reference
715 ReferenceCPP::pooling_layer(ref_src, ref_dst, pool_info, fixed_point_position);
716
717 return ref_dst;
718}
719
Georgios Pinitas7b7858d2017-06-21 16:44:24 +0100720RawTensor Reference::compute_reference_roi_pooling_layer(const TensorShape &shape, DataType dt, const std::vector<ROI> &rois, const ROIPoolingLayerInfo &pool_info)
721{
722 TensorShape shape_dst;
723 shape_dst.set(0, pool_info.pooled_width());
724 shape_dst.set(1, pool_info.pooled_height());
725 shape_dst.set(2, shape.z());
726 shape_dst.set(3, rois.size());
727
728 // Create reference
729 RawTensor ref_src = library->get(shape, dt);
730 RawTensor ref_dst = library->get(shape_dst, dt);
731
732 // Fill reference
733 std::uniform_real_distribution<> distribution(-1, 1);
734 library->fill(ref_src, distribution, 0.0);
735
736 // Compute reference
737 ReferenceCPP::roi_pooling_layer(ref_src, ref_dst, rois, pool_info);
738
739 return ref_dst;
740}
741
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100742RawTensor Reference::compute_reference_softmax_layer(const TensorShape &shape, DataType dt, int fixed_point_position)
743{
744 // Create reference
745 RawTensor ref_src = library->get(shape, dt, 1, fixed_point_position);
746 RawTensor ref_dst = library->get(shape, dt, 1, fixed_point_position);
747
748 // Fill reference
749 if(arm_compute::is_data_type_float(dt))
750 {
Georgios Pinitase5f8fd62017-06-23 18:03:44 +0100751 std::uniform_real_distribution<> distribution(-1000.f, 1000.f);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100752 library->fill(ref_src, distribution, 0);
753 }
754 else
755 {
756 int one_fixed = 1 << fixed_point_position;
757 std::uniform_int_distribution<> distribution(-one_fixed, one_fixed);
758 library->fill(ref_src, distribution, 0);
759 }
760
761 // Compute reference
762 ReferenceCPP::softmax_layer(ref_src, ref_dst);
763
764 return ref_dst;
765}
766
767RawTensor Reference::compute_reference_fixed_point_operation(const TensorShape &shape, DataType dt_in, DataType dt_out, FixedPointOp op, int fixed_point_position)
768{
769 // Create reference
770 RawTensor ref_src = library->get(shape, dt_in, 1, fixed_point_position);
771 RawTensor ref_dst = library->get(shape, dt_out, 1, fixed_point_position);
772
773 // Fill reference
774 int min = 0;
775 int max = 0;
776 switch(op)
777 {
778 case(FixedPointOp::INV_SQRT):
Michalis Spyrou0a8334c2017-06-14 18:00:05 +0100779 min = 1;
780 max = (dt_in == DataType::QS8) ? 0x7F : 0x7FFF;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100781 break;
782 case(FixedPointOp::LOG):
783 min = (1 << (fixed_point_position - 1));
Michalis Spyrou0a8334c2017-06-14 18:00:05 +0100784 max = (dt_in == DataType::QS8) ? 0x3F : 0x3FFF;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100785 break;
786 case(FixedPointOp::EXP):
Michalis Spyrou0a8334c2017-06-14 18:00:05 +0100787 min = -(1 << (fixed_point_position - 1));
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100788 max = (1 << (fixed_point_position - 1));
789 break;
790 case(FixedPointOp::RECIPROCAL):
791 min = 15;
Michalis Spyrou0a8334c2017-06-14 18:00:05 +0100792 max = (dt_in == DataType::QS8) ? 0x7F : 0x7FFF;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100793 break;
794 default:
795 ARM_COMPUTE_ERROR("Fixed point operation not supported");
796 }
797 std::uniform_int_distribution<> distribution(min, max);
798 library->fill(ref_src, distribution, 0);
799
800 // Compute reference
801 ReferenceCPP::fixed_point_operation(ref_src, ref_dst, op);
802
803 return ref_dst;
804}
805
806} // namespace validation
807} // namespace test
808} // namespace arm_compute
Isabella Gottardib797fa22017-06-23 15:02:11 +0100809#endif /* DOXYGEN_SKIP_THIS */