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