blob: c58b9a69c00f49dbe7d43baa18b5eea3877d88d9 [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#ifndef __ARM_COMPUTE_TEST_TENSOR_VISITORS_H__
25#define __ARM_COMPUTE_TEST_TENSOR_VISITORS_H__
26
27#include "Tensor.h"
28#include "TensorOperations.h"
29#include "arm_compute/core/Error.h"
Isabella Gottardib797fa22017-06-23 15:02:11 +010030#include "arm_compute/runtime/Lut.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010031
32#include "boost_wrapper.h"
33
Georgios Pinitasac4e8732017-07-05 17:02:25 +010034#include <algorithm>
Isabella Gottardib797fa22017-06-23 15:02:11 +010035#include <map>
Georgios Pinitasac4e8732017-07-05 17:02:25 +010036#include <memory>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010037#include <ostream>
Georgios Pinitasd4f8c272017-06-30 16:16:19 +010038#include <vector>
Anthony Barbier6ff3b192017-09-04 18:44:23 +010039
40namespace arm_compute
41{
42namespace test
43{
44namespace validation
45{
46namespace tensor_visitors
47{
48// Absolute Difference visitor
49struct absolute_difference_visitor : public boost::static_visitor<>
50{
51public:
52 template <typename T1, typename T2, typename T3>
53 void operator()(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out) const
54 {
55 tensor_operations::absolute_difference(in1, in2, out);
56 }
57};
58// Arithmetic Addition visitor
59struct arithmetic_addition_visitor : public boost::static_visitor<>
60{
61public:
62 explicit arithmetic_addition_visitor(ConvertPolicy convert_policy)
63 : _policy(convert_policy)
64 {
65 }
66
67 template <typename T1, typename T2, typename T3>
68 void operator()(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out) const
69 {
70 tensor_operations::arithmetic_addition(in1, in2, out, _policy);
71 }
72
73private:
74 ConvertPolicy _policy;
75};
76// Arithmetic Subtraction visitor
77struct arithmetic_subtraction_visitor : public boost::static_visitor<>
78{
79public:
80 explicit arithmetic_subtraction_visitor(ConvertPolicy convert_policy)
81 : _policy(convert_policy)
82 {
83 }
84
85 template <typename T1, typename T2, typename T3>
86 void operator()(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out) const
87 {
88 tensor_operations::arithmetic_subtraction(in1, in2, out, _policy);
89 }
90
91private:
92 ConvertPolicy _policy;
93};
94// Depth Convert visitor
95struct depth_convert_visitor : public boost::static_visitor<>
96{
97public:
98 explicit depth_convert_visitor(ConvertPolicy policy, uint32_t shift)
99 : _policy(policy), _shift(shift)
100 {
101 }
102
103 template <typename T1, typename T2>
104 void operator()(const Tensor<T1> &in, Tensor<T2> &out) const
105 {
106 tensor_operations::depth_convert(in, out, _policy, _shift);
107 }
108
109private:
110 ConvertPolicy _policy;
111 uint32_t _shift;
112};
113// GEMM visitor
114struct gemm_visitor : public boost::static_visitor<>
115{
116public:
117 explicit gemm_visitor(const TensorVariant &in1, const TensorVariant &in2, const TensorVariant &in3, float alpha, float beta)
118 : _in1(in1), _in2(in2), _in3(in3), _alpha(alpha), _beta(beta)
119 {
120 }
121
122 template <typename T>
123 void operator()(Tensor<T> &out) const
124 {
125 const Tensor<T> &in1 = boost::get<Tensor<T>>(_in1);
126 const Tensor<T> &in2 = boost::get<Tensor<T>>(_in2);
127 const Tensor<T> &in3 = boost::get<Tensor<T>>(_in3);
128 tensor_operations::gemm(in1, in2, in3, out, _alpha, _beta);
129 }
130
131private:
132 const TensorVariant &_in1, &_in2, &_in3;
133 float _alpha;
134 float _beta;
135};
136// Pixel-wise Multiplication visitor
137struct pixel_wise_multiplication_visitor : public boost::static_visitor<>
138{
139public:
140 explicit pixel_wise_multiplication_visitor(float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
141 : _scale(scale), _convert_policy(convert_policy), _rounding_policy(rounding_policy)
142 {
143 }
144
145 template <typename T1, typename T2, typename T3>
146 void operator()(const Tensor<T1> &in1, const Tensor<T2> &in2, Tensor<T3> &out) const
147 {
148 tensor_operations::pixel_wise_multiplication(in1, in2, out, _scale, _convert_policy, _rounding_policy);
149 }
150
151private:
152 float _scale;
153 ConvertPolicy _convert_policy;
154 RoundingPolicy _rounding_policy;
155};
156// Fixed Point Pixel-wise Multiplication visitor
157struct fixed_point_pixel_wise_multiplication_visitor : public boost::static_visitor<>
158{
159public:
160 explicit fixed_point_pixel_wise_multiplication_visitor(const TensorVariant &in1, const TensorVariant &in2, float scale, ConvertPolicy convert_policy, RoundingPolicy rounding_policy)
161 : _in1(in1), _in2(in2), _scale(scale), _convert_policy(convert_policy), _rounding_policy(rounding_policy)
162 {
163 }
164
165 template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
166 void operator()(Tensor<T> &out) const
167 {
168 const Tensor<T> &in1 = boost::get<Tensor<T>>(_in1);
169 const Tensor<T> &in2 = boost::get<Tensor<T>>(_in2);
170 tensor_operations::fixed_point_pixel_wise_multiplication(in1, in2, out, _scale, _convert_policy, _rounding_policy);
171 }
172 template < typename T, typename std::enable_if < !std::is_integral<T>::value, int >::type = 0 >
173 void operator()(Tensor<T> &out) const
174 {
175 ARM_COMPUTE_ERROR("NOT SUPPORTED!");
176 }
177
178private:
179 const TensorVariant &_in1;
180 const TensorVariant &_in2;
181 float _scale;
182 ConvertPolicy _convert_policy;
183 RoundingPolicy _rounding_policy;
184};
Isabella Gottardib797fa22017-06-23 15:02:11 +0100185// Table lookup operation
186template <typename T1>
187struct table_lookup : public boost::static_visitor<>
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100188{
Isabella Gottardib797fa22017-06-23 15:02:11 +0100189public:
190 explicit table_lookup(const TensorVariant &in, std::map<T1, T1> &lut)
191 : _in(in), _lut(lut)
192 {
193 }
194
195 template <typename T>
196 void operator()(Tensor<T> &out) const
197 {
198 const auto &in = boost::get<Tensor<T>>(_in);
199 tensor_operations::table_lookup(in, out, _lut);
200 }
201
202private:
203 const TensorVariant &_in;
204 std::map<T1, T1> &_lut;
205};
206template struct arm_compute::test::validation::tensor_visitors::table_lookup<uint8_t>;
207template struct arm_compute::test::validation::tensor_visitors::table_lookup<int16_t>;
208
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100209// Activation layer visitor
210struct activation_layer_visitor : public boost::static_visitor<>
211{
212public:
213 explicit activation_layer_visitor(const TensorVariant &in, ActivationLayerInfo act_info)
214 : _in(in), _act_info(act_info)
215 {
216 }
217
218 template <typename T>
219 void operator()(Tensor<T> &out) const
220 {
221 const auto &in = boost::get<Tensor<T>>(_in);
222 tensor_operations::activation_layer(in, out, _act_info);
223 }
224
225private:
226 const TensorVariant &_in;
227 const ActivationLayerInfo _act_info;
228};
229// Batch Normalization Layer visitor
230struct batch_normalization_layer_visitor : public boost::static_visitor<>
231{
232public:
233 explicit batch_normalization_layer_visitor(const TensorVariant &in, const TensorVariant &mean, const TensorVariant &var, const TensorVariant &beta, const TensorVariant &gamma, float epsilon,
234 int fixed_point_position = 0)
235 : _in(in), _mean(mean), _var(var), _beta(beta), _gamma(gamma), _epsilon(epsilon), _fixed_point_position(fixed_point_position)
236 {
237 }
238
239 template <typename T>
240 void operator()(Tensor<T> &out) const
241 {
242 const Tensor<T> &in = boost::get<Tensor<T>>(_in);
243 const Tensor<T> &mean = boost::get<Tensor<T>>(_mean);
244 const Tensor<T> &var = boost::get<Tensor<T>>(_var);
245 const Tensor<T> &beta = boost::get<Tensor<T>>(_beta);
246 const Tensor<T> &gamma = boost::get<Tensor<T>>(_gamma);
247 tensor_operations::batch_normalization_layer(in, out, mean, var, beta, gamma, _epsilon, _fixed_point_position);
248 }
249
250private:
251 const TensorVariant &_in, &_mean, &_var, &_beta, &_gamma;
252 float _epsilon;
253 int _fixed_point_position;
254};
255// Convolution Layer visitor
256struct convolution_layer_visitor : public boost::static_visitor<>
257{
258public:
259 explicit convolution_layer_visitor(const TensorVariant &in, const TensorVariant &weights, const TensorVariant &bias, PadStrideInfo conv_info)
260 : _in(in), _weights(weights), _bias(bias), _conv_info(conv_info)
261 {
262 }
263
264 template <typename T>
265 void operator()(Tensor<T> &out) const
266 {
267 const Tensor<T> &in = boost::get<Tensor<T>>(_in);
268 const Tensor<T> &weights = boost::get<Tensor<T>>(_weights);
269 const Tensor<T> &bias = boost::get<Tensor<T>>(_bias);
270 tensor_operations::convolution_layer(in, weights, bias, out, _conv_info);
271 }
272
273private:
274 const TensorVariant &_in;
275 const TensorVariant &_weights;
276 const TensorVariant &_bias;
277 PadStrideInfo _conv_info;
278};
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100279// Depth Concatenate Layer visitor
280struct depth_concatenate_layer_visitor : public boost::static_visitor<>
281{
282public:
283 explicit depth_concatenate_layer_visitor(const std::vector<TensorVariant> &srcs)
284 : _srcs(srcs)
285 {
286 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100287
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100288 template <typename T>
289 void operator()(Tensor<T> &out) const
290 {
291 std::vector<const Tensor<T> *> srcs;
292 srcs.resize(_srcs.size());
293 std::transform(_srcs.begin(), _srcs.end(), srcs.begin(), [](const TensorVariant & t)
294 {
295 return &(boost::get<Tensor<T>>(t));
296 });
297 tensor_operations::depth_concatenate_layer(srcs, out);
298 }
299
300private:
301 const std::vector<TensorVariant> &_srcs;
302};
303// Fully Connected Layer visitor
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100304struct fully_connected_layer_visitor : public boost::static_visitor<>
305{
306public:
307 explicit fully_connected_layer_visitor(const TensorVariant &in, const TensorVariant &weights, const TensorVariant &bias)
308 : _in(in), _weights(weights), _bias(bias)
309 {
310 }
311 template <typename T>
312 void operator()(Tensor<T> &out) const
313 {
314 const Tensor<T> &in = boost::get<Tensor<T>>(_in);
315 const Tensor<T> &weights = boost::get<Tensor<T>>(_weights);
316 const Tensor<T> &bias = boost::get<Tensor<T>>(_bias);
317 tensor_operations::fully_connected_layer(in, weights, bias, out);
318 }
319
320private:
321 const TensorVariant &_in;
322 const TensorVariant &_weights;
323 const TensorVariant &_bias;
324};
325
326// Normalization Layer visitor
327struct normalization_layer_visitor : public boost::static_visitor<>
328{
329public:
330 explicit normalization_layer_visitor(const TensorVariant &in, NormalizationLayerInfo norm_info)
331 : _in(in), _norm_info(norm_info)
332 {
333 }
334
335 template <typename T>
336 void operator()(Tensor<T> &out) const
337 {
338 const Tensor<T> &in = boost::get<Tensor<T>>(_in);
339 tensor_operations::normalization_layer(in, out, _norm_info);
340 }
341
342private:
343 const TensorVariant &_in;
344 NormalizationLayerInfo _norm_info;
345};
346// Pooling layer
347struct pooling_layer_visitor : public boost::static_visitor<>
348{
349public:
350 explicit pooling_layer_visitor(const TensorVariant &in, PoolingLayerInfo pool_info, int fixed_point_position = 0)
351 : _in(in), _pool_info(pool_info), _fixed_point_position(fixed_point_position)
352 {
353 }
354
355 template <typename T>
356 void operator()(Tensor<T> &out) const
357 {
358 const Tensor<T> &in = boost::get<Tensor<T>>(_in);
359 tensor_operations::pooling_layer(in, out, _pool_info, _fixed_point_position);
360 }
361
362private:
363 const TensorVariant &_in;
364 PoolingLayerInfo _pool_info;
365 int _fixed_point_position;
366};
Georgios Pinitas7b7858d2017-06-21 16:44:24 +0100367
368// ROI Pooling layer
369struct roi_pooling_layer_visitor : public boost::static_visitor<>
370{
371public:
372 explicit roi_pooling_layer_visitor(const TensorVariant &in, const std::vector<ROI> &rois, ROIPoolingLayerInfo pool_info)
373 : _in(in), _rois(rois), _pool_info(pool_info)
374 {
375 }
376
377 template <typename T>
378 void operator()(Tensor<T> &out) const
379 {
380 const Tensor<T> &in = boost::get<Tensor<T>>(_in);
381 tensor_operations::roi_pooling_layer(in, out, _rois, _pool_info);
382 }
383
384private:
385 const TensorVariant &_in;
386 const std::vector<ROI> &_rois;
387 ROIPoolingLayerInfo _pool_info;
388};
389
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100390// Softmax Layer visitor
391struct softmax_layer_visitor : public boost::static_visitor<>
392{
393public:
394 explicit softmax_layer_visitor(const TensorVariant &in)
395 : _in(in)
396 {
397 }
398
399 template <typename T>
400 void operator()(Tensor<T> &out) const
401 {
402 const auto &in = boost::get<Tensor<T>>(_in);
403 tensor_operations::softmax_layer(in, out);
404 }
405
406private:
407 const TensorVariant &_in;
408};
409// Fixed Point operations visitor
410struct fixed_point_operation_visitor : public boost::static_visitor<>
411{
412public:
413 explicit fixed_point_operation_visitor(const TensorVariant &in, FixedPointOp op)
414 : _in(in), _op(op)
415 {
416 }
417
418 template <typename T, typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
419 void operator()(Tensor<T> &out) const
420 {
421 const Tensor<T> &in = boost::get<Tensor<T>>(_in);
422 tensor_operations::fixed_point_operation(in, out, _op);
423 }
424 template < typename T, typename std::enable_if < !std::is_integral<T>::value, int >::type = 0 >
425 void operator()(Tensor<T> &out) const
426 {
427 ARM_COMPUTE_ERROR("NOT SUPPORTED!");
428 }
429
430private:
431 const TensorVariant &_in;
432 FixedPointOp _op;
433};
434// Print Tensor visitor
435struct print_visitor : public boost::static_visitor<>
436{
437public:
438 explicit print_visitor(std::ostream &out)
439 : _out(out)
440 {
441 }
442
443 template <typename T>
444 void operator()(const Tensor<T> &in) const
445 {
446 tensor_operations::print(in, _out);
447 }
448
449private:
450 std::ostream &_out;
451};
452} // namespace tensor_visitors
453} // namespace validation
454} // namespace test
455} // namespace arm_compute
456
457#endif /* __ARM_COMPUTE_TEST_TENSOR_VISITORS_H__ */