blob: 1dc4f03e997a77cec107a74641bc5f3709775d71 [file] [log] [blame]
Michalis Spyroue9362622018-11-23 17:41:37 +00001/*
Ramy Elgammal14d7b532023-01-30 04:56:47 +00002 * Copyright (c) 2018-2021, 2023 Arm Limited.
Michalis Spyroue9362622018-11-23 17:41:37 +00003 *
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_ELEMENTWISE_UNARY_FIXTURE
25#define ARM_COMPUTE_TEST_ELEMENTWISE_UNARY_FIXTURE
26
27#include "arm_compute/core/TensorShape.h"
28#include "arm_compute/core/Types.h"
29#include "tests/AssetsLibrary.h"
30#include "tests/Globals.h"
31#include "tests/IAccessor.h"
32#include "tests/framework/Asserts.h"
33#include "tests/framework/Fixture.h"
Jakub Sujakee301b32021-06-04 09:46:08 +010034#include "tests/validation/reference/ElementwiseUnary.h"
Michalis Spyroue9362622018-11-23 17:41:37 +000035
36namespace arm_compute
37{
38namespace test
39{
40namespace validation
41{
42template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
43class ElementWiseUnaryValidationFixture : public framework::Fixture
44{
45public:
46 template <typename...>
Ramy Elgammal14d7b532023-01-30 04:56:47 +000047 void setup(TensorShape input_shape, DataType input_data_type, bool in_place, ElementWiseUnary op,
48 bool use_dynamic_shape = false, QuantizationInfo qinfo = QuantizationInfo(), QuantizationInfo qinfo_out = QuantizationInfo())
Michalis Spyroue9362622018-11-23 17:41:37 +000049 {
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +000050 _op = op;
Ramy Elgammal14d7b532023-01-30 04:56:47 +000051 _target = compute_target(input_shape, input_data_type, in_place, qinfo, qinfo_out);
52 _reference = compute_reference(input_shape, input_data_type, qinfo, qinfo_out);
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +000053 _use_dynamic_shape = use_dynamic_shape;
Michalis Spyroue9362622018-11-23 17:41:37 +000054 }
55
56protected:
57 template <typename U>
Usama Ariff6e475c2019-05-10 12:06:28 +010058 void fill(U &&tensor, int i, DataType data_type)
Michalis Spyroue9362622018-11-23 17:41:37 +000059 {
Giorgio Arena4bdd1772020-12-17 16:47:07 +000060 using FloatType = typename std::conditional < std::is_same<T, half>::value || std::is_floating_point<T>::value, T, float >::type;
Giorgio Arena33b103b2021-01-08 10:37:15 +000061 using FloatDistributionType = typename std::conditional<std::is_same<T, half>::value, arm_compute::utils::uniform_real_distribution_16bit<T>, std::uniform_real_distribution<FloatType>>::type;
Giorgio Arena4bdd1772020-12-17 16:47:07 +000062
Michalis Spyroue9362622018-11-23 17:41:37 +000063 switch(_op)
64 {
65 case ElementWiseUnary::EXP:
66 {
Giorgio Arena4bdd1772020-12-17 16:47:07 +000067 FloatDistributionType distribution{ FloatType(-1.0f), FloatType(1.0f) };
Michalis Spyroue9362622018-11-23 17:41:37 +000068 library->fill(tensor, distribution, i);
69 break;
70 }
71 case ElementWiseUnary::RSQRT:
72 {
Ramy Elgammal14d7b532023-01-30 04:56:47 +000073 if(data_type == DataType::F32 || data_type == DataType::F16)
74 {
75 FloatDistributionType distribution{ FloatType(1.0f), FloatType(2.0f) };
76 library->fill(tensor, distribution, i);
77 }
78 else
79 {
80 library->fill_tensor_uniform(tensor, i);
81 }
Michalis Spyroue9362622018-11-23 17:41:37 +000082 break;
83 }
Manuel Bottini6ac59922019-05-15 14:06:02 +010084 case ElementWiseUnary::ABS:
Usama Ariff6e475c2019-05-10 12:06:28 +010085 case ElementWiseUnary::NEG:
86 {
87 switch(data_type)
88 {
Usama Ariff6e475c2019-05-10 12:06:28 +010089 case DataType::F16:
90 {
Giorgio Arenaa8e2aeb2021-01-06 11:34:57 +000091 arm_compute::utils::uniform_real_distribution_16bit<half> distribution{ -2.0f, 2.0f };
Giorgio Arena6aeb2172020-12-15 15:45:43 +000092 library->fill(tensor, distribution, i);
93 break;
94 }
95 case DataType::F32:
96 {
Giorgio Arena4bdd1772020-12-17 16:47:07 +000097 FloatDistributionType distribution{ FloatType(-2.0f), FloatType(2.0f) };
Usama Ariff6e475c2019-05-10 12:06:28 +010098 library->fill(tensor, distribution, i);
99 break;
100 }
101 case DataType::S32:
102 {
103 std::uniform_int_distribution<int32_t> distribution(-100, 100);
104 library->fill(tensor, distribution, i);
105 break;
106 }
107 default:
108 ARM_COMPUTE_ERROR("DataType for Elementwise Negation Not implemented");
109 }
110 break;
111 }
Usama Arifc255aa72019-05-13 16:26:29 +0100112 case ElementWiseUnary::LOG:
113 {
Giorgio Arena4bdd1772020-12-17 16:47:07 +0000114 FloatDistributionType distribution{ FloatType(0.0000001f), FloatType(100.0f) };
Usama Arifc255aa72019-05-13 16:26:29 +0100115 library->fill(tensor, distribution, i);
116 break;
117 }
Michalis Spyrou0af44182019-05-17 14:04:47 +0100118 case ElementWiseUnary::SIN:
119 {
Giorgio Arena4bdd1772020-12-17 16:47:07 +0000120 FloatDistributionType distribution{ FloatType(-100.00f), FloatType(100.00f) };
Michalis Spyrou0af44182019-05-17 14:04:47 +0100121 library->fill(tensor, distribution, i);
122 break;
123 }
Usama Arif0a5a57a2019-05-23 14:20:33 +0100124 case ElementWiseUnary::ROUND:
125 {
Giorgio Arena4bdd1772020-12-17 16:47:07 +0000126 FloatDistributionType distribution{ FloatType(100.0f), FloatType(-100.0f) };
Usama Arif0a5a57a2019-05-23 14:20:33 +0100127 library->fill(tensor, distribution, i);
128 break;
129 }
Michalis Spyroue9362622018-11-23 17:41:37 +0000130 default:
131 ARM_COMPUTE_ERROR("Not implemented");
132 }
133 }
134
Ramy Elgammal14d7b532023-01-30 04:56:47 +0000135 TensorType compute_target(const TensorShape &shape, DataType data_type, bool in_place, QuantizationInfo qinfo, QuantizationInfo qinfo_out)
Michalis Spyroue9362622018-11-23 17:41:37 +0000136 {
137 // Create tensors
Ramy Elgammal14d7b532023-01-30 04:56:47 +0000138 TensorType src = create_tensor<TensorType>(shape, data_type, 1, qinfo);
139 TensorType dst = create_tensor<TensorType>(shape, data_type, 1, qinfo_out);
Manuel Bottini80feed52020-06-03 13:20:41 +0100140 TensorType *actual_dst = in_place ? &src : &dst;
141
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000142 // if _use_dynamic_shape is true, this fixture will test scenario for dynamic shapes.
143 // - At configure time, all input tensors are marked as dynamic using set_tensor_dynamic()
144 // - After configure, tensors are marked as static for run using set_tensor_static()
145 // - The tensors with static shape are given to run()
146 if(_use_dynamic_shape)
147 {
148 set_tensor_dynamic(src);
149 }
150
Michalis Spyroue9362622018-11-23 17:41:37 +0000151 // Create and configure function
152 FunctionType elwiseunary_layer;
Manuel Bottini80feed52020-06-03 13:20:41 +0100153 elwiseunary_layer.configure(&src, actual_dst);
Michalis Spyroue9362622018-11-23 17:41:37 +0000154
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000155 if(_use_dynamic_shape)
156 {
157 set_tensor_static(src);
158 }
159
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100160 ARM_COMPUTE_ASSERT(src.info()->is_resizable());
Michalis Spyroue9362622018-11-23 17:41:37 +0000161 src.allocator()->allocate();
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100162 ARM_COMPUTE_ASSERT(!src.info()->is_resizable());
Manuel Bottini80feed52020-06-03 13:20:41 +0100163 if(!in_place)
164 {
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100165 ARM_COMPUTE_ASSERT(dst.info()->is_resizable());
Manuel Bottini80feed52020-06-03 13:20:41 +0100166 dst.allocator()->allocate();
Michele Di Giorgio4fc10b32021-04-30 18:30:41 +0100167 ARM_COMPUTE_ASSERT(!dst.info()->is_resizable());
Manuel Bottini80feed52020-06-03 13:20:41 +0100168 }
Michalis Spyroue9362622018-11-23 17:41:37 +0000169
170 // Fill tensors
Usama Ariff6e475c2019-05-10 12:06:28 +0100171 fill(AccessorType(src), 0, data_type);
Michalis Spyroue9362622018-11-23 17:41:37 +0000172
173 // Compute function
174 elwiseunary_layer.run();
175
Manuel Bottini80feed52020-06-03 13:20:41 +0100176 if(in_place)
177 {
178 return src;
179 }
180 else
181 {
182 return dst;
183 }
Michalis Spyroue9362622018-11-23 17:41:37 +0000184 }
185
Ramy Elgammal14d7b532023-01-30 04:56:47 +0000186 SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type, QuantizationInfo qinfo, QuantizationInfo qinfo_out)
Michalis Spyroue9362622018-11-23 17:41:37 +0000187 {
188 // Create reference
Ramy Elgammal14d7b532023-01-30 04:56:47 +0000189 SimpleTensor<T> src{ shape, data_type, 1, qinfo };
190 SimpleTensor<T> dst{ shape, data_type, 1, qinfo_out };
Michalis Spyroue9362622018-11-23 17:41:37 +0000191
192 // Fill reference
Usama Ariff6e475c2019-05-10 12:06:28 +0100193 fill(src, 0, data_type);
Michalis Spyroue9362622018-11-23 17:41:37 +0000194
Ramy Elgammal14d7b532023-01-30 04:56:47 +0000195 return reference::elementwise_unary<T>(src, dst, _op);
Michalis Spyroue9362622018-11-23 17:41:37 +0000196 }
197
198 TensorType _target{};
199 SimpleTensor<T> _reference{};
200 ElementWiseUnary _op{};
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000201 bool _use_dynamic_shape{ false };
Michalis Spyroue9362622018-11-23 17:41:37 +0000202};
Ramy Elgammal14d7b532023-01-30 04:56:47 +0000203template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
204class RsqrtQuantizedValidationFixture : public ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>
205{
206public:
207 template <typename...>
208 void setup(const TensorShape &shape, DataType data_type, QuantizationInfo qinfo, QuantizationInfo qinfo_out)
209 {
210 ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, false, ElementWiseUnary::RSQRT, false, qinfo, qinfo_out);
211 }
212};
Michalis Spyroue9362622018-11-23 17:41:37 +0000213
214template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
215class RsqrtValidationFixture : public ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>
216{
217public:
218 template <typename...>
219 void setup(const TensorShape &shape, DataType data_type)
220 {
Manuel Bottini80feed52020-06-03 13:20:41 +0100221 ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, false, ElementWiseUnary::RSQRT);
Michalis Spyroue9362622018-11-23 17:41:37 +0000222 }
223};
224
225template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
Sang-Hoon Park668ccdc2021-02-03 10:32:59 +0000226class RsqrtDynamicShapeValidationFixture : public ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>
227{
228public:
229 template <typename...>
230 void setup(const TensorShape &shape, DataType data_type)
231 {
232 ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, false, ElementWiseUnary::RSQRT, true);
233 }
234};
235
236template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
Michalis Spyroue9362622018-11-23 17:41:37 +0000237class ExpValidationFixture : public ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>
238{
239public:
240 template <typename...>
241 void setup(const TensorShape &shape, DataType data_type)
242 {
Manuel Bottini80feed52020-06-03 13:20:41 +0100243 ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, false, ElementWiseUnary::EXP);
Michalis Spyroue9362622018-11-23 17:41:37 +0000244 }
245};
Usama Ariff6e475c2019-05-10 12:06:28 +0100246
247template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
248class NegValidationFixture : public ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>
249{
250public:
251 template <typename...>
252 void setup(const TensorShape &shape, DataType data_type)
253 {
Manuel Bottini80feed52020-06-03 13:20:41 +0100254 ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, false, ElementWiseUnary::NEG);
255 }
256};
257
258template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
259class NegValidationInPlaceFixture : public ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>
260{
261public:
262 template <typename...>
263 void setup(const TensorShape &shape, DataType data_type, bool in_place)
264 {
265 ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, in_place, ElementWiseUnary::NEG);
Usama Ariff6e475c2019-05-10 12:06:28 +0100266 }
267};
Usama Arifc255aa72019-05-13 16:26:29 +0100268
269template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
270class LogValidationFixture : public ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>
271{
272public:
273 template <typename...>
274 void setup(const TensorShape &shape, DataType data_type)
275 {
Manuel Bottini80feed52020-06-03 13:20:41 +0100276 ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, false, ElementWiseUnary::LOG);
Usama Arifc255aa72019-05-13 16:26:29 +0100277 }
278};
Manuel Bottini6ac59922019-05-15 14:06:02 +0100279
280template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
281class AbsValidationFixture : public ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>
282{
283public:
284 template <typename...>
285 void setup(const TensorShape &shape, DataType data_type)
286 {
Manuel Bottini80feed52020-06-03 13:20:41 +0100287 ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, false, ElementWiseUnary::ABS);
Manuel Bottini6ac59922019-05-15 14:06:02 +0100288 }
289};
Michalis Spyrou0af44182019-05-17 14:04:47 +0100290
291template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
292class SinValidationFixture : public ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>
293{
294public:
295 template <typename...>
296 void setup(const TensorShape &shape, DataType data_type)
297 {
Manuel Bottini80feed52020-06-03 13:20:41 +0100298 ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, false, ElementWiseUnary::SIN);
Michalis Spyrou0af44182019-05-17 14:04:47 +0100299 }
300};
Usama Arif0a5a57a2019-05-23 14:20:33 +0100301
302template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
303class RoundValidationFixture : public ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>
304{
305public:
306 template <typename...>
307 void setup(const TensorShape &shape, DataType data_type)
308 {
Manuel Bottini80feed52020-06-03 13:20:41 +0100309 ElementWiseUnaryValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, false, ElementWiseUnary::ROUND);
Usama Arif0a5a57a2019-05-23 14:20:33 +0100310 }
311};
Michalis Spyroue9362622018-11-23 17:41:37 +0000312} // namespace validation
313} // namespace test
314} // namespace arm_compute
315#endif /* ARM_COMPUTE_TEST_ELEMENTWISE_UNARY_FIXTURE */