blob: 38e3751db40e77c8cc73f4aa124b4648f24637f5 [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 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +010024#include "NEON/NEAccessor.h"
25#include "TypePrinter.h"
26#include "dataset/BatchNormalizationLayerDataset.h"
Moritz Pflanzer94450f12017-06-30 12:48:43 +010027#include "tests/Globals.h"
28#include "tests/Utils.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010029#include "tests/validation/Helpers.h"
30#include "validation/Datasets.h"
31#include "validation/Reference.h"
32#include "validation/Validation.h"
33
34#include "arm_compute/runtime/NEON/functions/NEBatchNormalizationLayer.h"
35
36#include <random>
37
38using namespace arm_compute;
39using namespace arm_compute::test;
40using namespace arm_compute::test::neon;
41using namespace arm_compute::test::validation;
42
43namespace
44{
45const float tolerance_f = 1e-05; /**< Tolerance value for comparing reference's output against floating point implementation's output */
46const float tolerance_q = 3; /**< Tolerance value for comparing reference's output against quantized implementation's output */
47
48/** Compute Neon batch normalization function.
49 *
50 * @param[in] shape Shape of the input and output tensors.
51 * @param[in] dt Data type of input and output tensors.
52 * @param[in] norm_info Normalization Layer information.
53 *
54 * @return Computed output tensor.
55 */
56Tensor compute_reference_batch_normalization_layer(const TensorShape &shape0, const TensorShape &shape1, DataType dt, float epsilon, int fixed_point_position = 0)
57{
58 // Create tensors
Moritz Pflanzer94450f12017-06-30 12:48:43 +010059 Tensor src = create_tensor<Tensor>(shape0, dt, 1, fixed_point_position);
60 Tensor dst = create_tensor<Tensor>(shape0, dt, 1, fixed_point_position);
61 Tensor mean = create_tensor<Tensor>(shape1, dt, 1, fixed_point_position);
62 Tensor var = create_tensor<Tensor>(shape1, dt, 1, fixed_point_position);
63 Tensor beta = create_tensor<Tensor>(shape1, dt, 1, fixed_point_position);
64 Tensor gamma = create_tensor<Tensor>(shape1, dt, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +010065
66 // Create and configure function
67 NEBatchNormalizationLayer norm;
68 norm.configure(&src, &dst, &mean, &var, &beta, &gamma, epsilon);
69
70 // Allocate tensors
71 src.allocator()->allocate();
72 dst.allocator()->allocate();
73 mean.allocator()->allocate();
74 var.allocator()->allocate();
75 beta.allocator()->allocate();
76 gamma.allocator()->allocate();
77
78 BOOST_TEST(!src.info()->is_resizable());
79 BOOST_TEST(!dst.info()->is_resizable());
80 BOOST_TEST(!mean.info()->is_resizable());
81 BOOST_TEST(!var.info()->is_resizable());
82 BOOST_TEST(!beta.info()->is_resizable());
83 BOOST_TEST(!gamma.info()->is_resizable());
84
85 // Fill tensors
86 if(dt == DataType::F32)
87 {
88 float min_bound = 0.f;
89 float max_bound = 0.f;
90 std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<float>();
91 std::uniform_real_distribution<> distribution(min_bound, max_bound);
92 std::uniform_real_distribution<> distribution_var(0, max_bound);
93 library->fill(NEAccessor(src), distribution, 0);
94 library->fill(NEAccessor(mean), distribution, 1);
95 library->fill(NEAccessor(var), distribution_var, 0);
96 library->fill(NEAccessor(beta), distribution, 3);
97 library->fill(NEAccessor(gamma), distribution, 4);
98 }
99 else
100 {
101 int min_bound = 0;
102 int max_bound = 0;
103 std::tie(min_bound, max_bound) = get_batchnormalization_layer_test_bounds<int8_t>(fixed_point_position);
104 std::uniform_int_distribution<> distribution(min_bound, max_bound);
105 std::uniform_int_distribution<> distribution_var(0, max_bound);
106 library->fill(NEAccessor(src), distribution, 0);
107 library->fill(NEAccessor(mean), distribution, 1);
108 library->fill(NEAccessor(var), distribution_var, 0);
109 library->fill(NEAccessor(beta), distribution, 3);
110 library->fill(NEAccessor(gamma), distribution, 4);
111 }
112
113 // Compute function
114 norm.run();
115
116 return dst;
117}
118} // namespace
119
120#ifndef DOXYGEN_SKIP_THIS
121BOOST_AUTO_TEST_SUITE(NEON)
122BOOST_AUTO_TEST_SUITE(BatchNormalizationLayer)
123
124BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit") * boost::unit_test::label("nightly"))
125BOOST_DATA_TEST_CASE(Configuration, RandomBatchNormalizationLayerDataset() * (boost::unit_test::data::make(DataType::F32) + boost::unit_test::data::make(DataType::QS8)), obj, dt)
126{
127 // Set fixed point position data type allowed
128 int fixed_point_position = (arm_compute::is_data_type_fixed_point(dt)) ? 3 : 0;
129
130 // Create tensors
Moritz Pflanzer94450f12017-06-30 12:48:43 +0100131 Tensor src = create_tensor<Tensor>(obj.shape0, dt, 1, fixed_point_position);
132 Tensor dst = create_tensor<Tensor>(obj.shape0, dt, 1, fixed_point_position);
133 Tensor mean = create_tensor<Tensor>(obj.shape1, dt, 1, fixed_point_position);
134 Tensor var = create_tensor<Tensor>(obj.shape1, dt, 1, fixed_point_position);
135 Tensor beta = create_tensor<Tensor>(obj.shape1, dt, 1, fixed_point_position);
136 Tensor gamma = create_tensor<Tensor>(obj.shape1, dt, 1, fixed_point_position);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100137
138 BOOST_TEST(src.info()->is_resizable());
139 BOOST_TEST(dst.info()->is_resizable());
140 BOOST_TEST(mean.info()->is_resizable());
141 BOOST_TEST(var.info()->is_resizable());
142 BOOST_TEST(beta.info()->is_resizable());
143 BOOST_TEST(gamma.info()->is_resizable());
144
145 // Create and configure function
146 NEBatchNormalizationLayer norm;
147 norm.configure(&src, &dst, &mean, &var, &beta, &gamma, obj.epsilon);
148
149 // Validate valid region
150 const ValidRegion valid_region = shape_to_valid_region(obj.shape0);
151 const ValidRegion valid_region_vec = shape_to_valid_region(obj.shape1);
152 validate(src.info()->valid_region(), valid_region);
153 validate(dst.info()->valid_region(), valid_region);
154 validate(mean.info()->valid_region(), valid_region_vec);
155 validate(var.info()->valid_region(), valid_region_vec);
156 validate(beta.info()->valid_region(), valid_region_vec);
157 validate(gamma.info()->valid_region(), valid_region_vec);
158}
159
160BOOST_AUTO_TEST_SUITE(Float)
161BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
162BOOST_DATA_TEST_CASE(Random,
163 RandomBatchNormalizationLayerDataset() * boost::unit_test::data::make(DataType::F32),
164 obj, dt)
165{
166 // Compute function
167 Tensor dst = compute_reference_batch_normalization_layer(obj.shape0, obj.shape1, dt, obj.epsilon);
168
169 // Compute reference
170 RawTensor ref_dst = Reference::compute_reference_batch_normalization_layer(obj.shape0, obj.shape1, dt, obj.epsilon);
171
172 // Validate output
173 validate(NEAccessor(dst), ref_dst, tolerance_f, 0);
174}
175BOOST_AUTO_TEST_SUITE_END()
176
177BOOST_AUTO_TEST_SUITE(Quantized)
178BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
179BOOST_DATA_TEST_CASE(Random,
180 RandomBatchNormalizationLayerDataset() * boost::unit_test::data::make(DataType::QS8) * boost::unit_test::data::xrange(1, 6),
181 obj, dt, fixed_point_position)
182{
183 // Compute function
184 Tensor dst = compute_reference_batch_normalization_layer(obj.shape0, obj.shape1, dt, obj.epsilon, fixed_point_position);
185
186 // Compute reference
187 RawTensor ref_dst = Reference::compute_reference_batch_normalization_layer(obj.shape0, obj.shape1, dt, obj.epsilon, fixed_point_position);
188
189 // Validate output
190 validate(NEAccessor(dst), ref_dst, tolerance_q, 0);
191}
192BOOST_AUTO_TEST_SUITE_END()
193
194BOOST_AUTO_TEST_SUITE_END()
195BOOST_AUTO_TEST_SUITE_END()
Anthony Barbierac69aa12017-07-03 17:39:37 +0100196#endif /* DOXYGEN_SKIP_THIS */