Compute Library  18.03
SobelFixture.h
Go to the documentation of this file.
1 /*
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_SOBEL_FIXTURE
25 #define ARM_COMPUTE_TEST_SOBEL_FIXTURE
26 
28 #include "arm_compute/core/Types.h"
30 #include "tests/AssetsLibrary.h"
31 #include "tests/Globals.h"
32 #include "tests/IAccessor.h"
36 
37 #include <memory>
38 
39 namespace arm_compute
40 {
41 class CLSobel3x3;
42 class CLSobel5x5;
43 class CLSobel7x7;
44 class NESobel3x3;
45 class NESobel5x5;
46 class NESobel7x7;
47 
48 namespace test
49 {
50 namespace validation
51 {
52 namespace
53 {
54 template <typename Function>
55 struct info;
56 
57 template <>
58 struct info<NESobel3x3>
59 {
60  static const Format dst_format = Format::S16;
61  static const int filter_size = 3;
62 };
63 
64 template <>
65 struct info<CLSobel3x3>
66 {
67  static const Format dst_format = Format::S16;
68  static const int filter_size = 3;
69 };
70 
71 template <>
72 struct info<NESobel5x5>
73 {
74  static const Format dst_format = Format::S16;
75  static const int filter_size = 5;
76 };
77 
78 template <>
79 struct info<CLSobel5x5>
80 {
81  static const Format dst_format = Format::S16;
82  static const int filter_size = 5;
83 };
84 
85 template <>
86 struct info<NESobel7x7>
87 {
88  static const Format dst_format = Format::S32;
89  static const int filter_size = 7;
90 };
91 
92 template <>
93 struct info<CLSobel7x7>
94 {
95  static const Format dst_format = Format::S32;
96  static const int filter_size = 7;
97 };
98 } // namespace
99 
100 template <typename TensorType, typename AccessorType, typename FunctionType, typename T, typename U>
102 {
103 public:
104  template <typename...>
106  {
107  // Generate a random constant value
108  std::mt19937 gen(library->seed());
109  std::uniform_int_distribution<uint8_t> int_dist(0, 255);
110  const uint8_t constant_border_value = int_dist(gen);
111 
112  _border_mode = border_mode;
113  _target = compute_target(shape, border_mode, format, constant_border_value, gradient_dimension);
114  _reference = compute_reference(shape, info<FunctionType>::filter_size, border_mode, format, constant_border_value, gradient_dimension);
115  }
116 
117 protected:
118  template <typename V>
119  void fill(V &&tensor)
120  {
121  library->fill_tensor_uniform(tensor, 0);
122  }
123 
124  std::pair<TensorType, TensorType> compute_target(const TensorShape &shape, BorderMode border_mode, Format format, uint8_t constant_border_value, GradientDimension gradient_dimension)
125  {
126  // Create tensors
127  TensorType src = create_tensor<TensorType>(shape, data_type_from_format(format));
128  TensorType dst_x = create_tensor<TensorType>(shape, data_type_from_format(info<FunctionType>::dst_format));
129  TensorType dst_y = create_tensor<TensorType>(shape, data_type_from_format(info<FunctionType>::dst_format));
130 
131  src.info()->set_format(format);
132  dst_x.info()->set_format(info<FunctionType>::dst_format);
133  dst_y.info()->set_format(info<FunctionType>::dst_format);
134 
135  FunctionType sobel;
136 
137  switch(gradient_dimension)
138  {
139  case GradientDimension::GRAD_X:
140  sobel.configure(&src, &dst_x, nullptr, border_mode, constant_border_value);
141  break;
142  case GradientDimension::GRAD_Y:
143  sobel.configure(&src, nullptr, &dst_y, border_mode, constant_border_value);
144  break;
146  sobel.configure(&src, &dst_x, &dst_y, border_mode, constant_border_value);
147  break;
148  default:
149  ARM_COMPUTE_ERROR("Gradient dimension not supported");
150  }
151 
152  ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
153  ARM_COMPUTE_EXPECT(dst_x.info()->is_resizable(), framework::LogLevel::ERRORS);
154  ARM_COMPUTE_EXPECT(dst_y.info()->is_resizable(), framework::LogLevel::ERRORS);
155 
156  // Allocate tensors
157  src.allocator()->allocate();
158  dst_x.allocator()->allocate();
159  dst_y.allocator()->allocate();
160 
161  ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
162  ARM_COMPUTE_EXPECT(!dst_x.info()->is_resizable(), framework::LogLevel::ERRORS);
163  ARM_COMPUTE_EXPECT(!dst_y.info()->is_resizable(), framework::LogLevel::ERRORS);
164 
165  // Fill tensors
166  fill(AccessorType(src));
167 
168  // Compute function
169  sobel.run();
170 
171  return std::make_pair(std::move(dst_x), std::move(dst_y));
172  }
173 
174  std::pair<SimpleTensor<U>, SimpleTensor<U>> compute_reference(const TensorShape &shape, int filter_size, BorderMode border_mode, Format format, uint8_t constant_border_value,
175  GradientDimension gradient_dimension)
176  {
177  // Create reference
178  SimpleTensor<T> src{ shape, format };
179 
180  // Fill reference
181  fill(src);
182 
183  return reference::sobel<U>(src, filter_size, border_mode, constant_border_value, gradient_dimension);
184  }
185 
186  BorderMode _border_mode{ BorderMode::UNDEFINED };
187  std::pair<TensorType, TensorType> _target{};
188  std::pair<SimpleTensor<U>, SimpleTensor<U>> _reference{};
189 };
190 } // namespace validation
191 } // namespace test
192 } // namespace arm_compute
193 #endif /* ARM_COMPUTE_TEST_SOBEL_FIXTURE */
BorderMode
Methods available to handle borders.
Definition: Types.h:221
Shape of a tensor.
Definition: TensorShape.h:39
Cr/V/Value channel.
#define ARM_COMPUTE_ERROR(...)
Print the given message then throw an std::runtime_error.
Definition: Error.h:238
src info() -> set_format(Format::S16)
This file contains all available output stages for GEMMLowp on OpenCL.
1 channel, 1 S32 per channel
Abstract fixture class.
Definition: Fixture.h:37
void setup(TensorShape shape, BorderMode border_mode, Format format, GradientDimension gradient_dimension)
Definition: SobelFixture.h:105
std::unique_ptr< AssetsLibrary > library
Definition: main.cpp:59
Format
Image colour formats.
Definition: Types.h:50
1 channel, 1 S16 per channel
DataType data_type_from_format(Format format)
Return the data type used by a given single-planar pixel format.
Definition: Utils.h:195
x and y gradient dimension
ARM_COMPUTE_EXPECT(src.info() ->is_resizable(), framework::LogLevel::ERRORS)
Borders are left undefined.
std::pair< SimpleTensor< T >, SimpleTensor< T > > sobel(const SimpleTensor< U > &src, int filter_size, BorderMode border_mode, uint8_t constant_border_value, GradientDimension gradient_dimension)
Definition: Sobel.cpp:106
GradientDimension
Gradient dimension type.
Definition: Types.h:46
convolution configure & src