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