• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2018 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_LAPLACIAN_PYRAMID_FIXTURE
25 #define ARM_COMPUTE_TEST_LAPLACIAN_PYRAMID_FIXTURE
26 
27 #include "arm_compute/core/IPyramid.h"
28 #include "arm_compute/core/PyramidInfo.h"
29 #include "arm_compute/core/TensorShape.h"
30 #include "arm_compute/core/Types.h"
31 #include "tests/AssetsLibrary.h"
32 #include "tests/Globals.h"
33 #include "tests/IAccessor.h"
34 #include "tests/framework/Asserts.h"
35 #include "tests/framework/Fixture.h"
36 #include "tests/validation/reference/LaplacianPyramid.h"
37 
38 namespace arm_compute
39 {
40 namespace test
41 {
42 namespace validation
43 {
44 template <typename TensorType, typename AccessorType, typename FunctionType, typename T, typename U, typename PyramidType>
45 class LaplacianPyramidValidationFixture : public framework::Fixture
46 {
47 public:
48     template <typename...>
setup(TensorShape input_shape,BorderMode border_mode,size_t num_levels,Format format_in,Format format_out)49     void setup(TensorShape input_shape, BorderMode border_mode, size_t num_levels, Format format_in, Format format_out)
50     {
51         std::mt19937                     generator(library->seed());
52         std::uniform_int_distribution<T> distribution_u8(0, 255);
53         const T                          constant_border_value = distribution_u8(generator);
54 
55         _pyramid_levels = num_levels;
56         _border_mode    = border_mode;
57 
58         _target    = compute_target(input_shape, border_mode, constant_border_value, format_in, format_out);
59         _reference = compute_reference(input_shape, border_mode, constant_border_value, format_in, format_out);
60     }
61 
62 protected:
63     template <typename V>
fill(V && tensor)64     void fill(V &&tensor)
65     {
66         library->fill_tensor_uniform(tensor, 0);
67     }
68 
compute_target(const TensorShape & input_shape,BorderMode border_mode,T constant_border_value,Format format_in,Format format_out)69     PyramidType compute_target(const TensorShape &input_shape, BorderMode border_mode, T constant_border_value,
70                                Format format_in, Format format_out)
71     {
72         // Create pyramid
73         PyramidType pyramid{};
74 
75         // Create Pyramid Info
76         PyramidInfo pyramid_info(_pyramid_levels, SCALE_PYRAMID_HALF, input_shape, format_out);
77 
78         // Use conservative padding strategy to fit all subsequent kernels
79         pyramid.init_auto_padding(pyramid_info);
80 
81         // Create tensors
82         TensorType src = create_tensor<TensorType>(input_shape, format_in);
83 
84         // The first two dimensions of the output tensor must match the first
85         // two dimensions of the tensor in the last level of the pyramid
86         TensorShape dst_shape(input_shape);
87         dst_shape.set(0, pyramid.get_pyramid_level(_pyramid_levels - 1)->info()->dimension(0));
88         dst_shape.set(1, pyramid.get_pyramid_level(_pyramid_levels - 1)->info()->dimension(1));
89 
90         // The lowest resolution tensor necessary to reconstruct the input
91         // tensor from the pyramid.
92         _dst_target = create_tensor<TensorType>(dst_shape, format_out);
93 
94         // Create and configure function
95         FunctionType laplacian_pyramid;
96         laplacian_pyramid.configure(&src, &pyramid, &_dst_target, border_mode, constant_border_value);
97 
98         ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
99         ARM_COMPUTE_EXPECT(_dst_target.info()->is_resizable(), framework::LogLevel::ERRORS);
100 
101         // Allocate tensors
102         src.allocator()->allocate();
103         _dst_target.allocator()->allocate();
104 
105         ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
106         ARM_COMPUTE_EXPECT(!_dst_target.info()->is_resizable(), framework::LogLevel::ERRORS);
107 
108         pyramid.allocate();
109 
110         for(size_t i = 0; i < pyramid_info.num_levels(); ++i)
111         {
112             ARM_COMPUTE_EXPECT(!pyramid.get_pyramid_level(i)->info()->is_resizable(), framework::LogLevel::ERRORS);
113         }
114 
115         // Fill tensors
116         fill(AccessorType(src));
117 
118         // Compute function
119         laplacian_pyramid.run();
120 
121         return pyramid;
122     }
123 
compute_reference(const TensorShape & shape,BorderMode border_mode,T constant_border_value,Format format_in,Format format_out)124     std::vector<SimpleTensor<U>> compute_reference(const TensorShape &shape, BorderMode border_mode, T constant_border_value,
125                                                    Format format_in, Format format_out)
126     {
127         // Create reference
128         SimpleTensor<T> src{ shape, format_in };
129 
130         // The first two dimensions of the output tensor must match the first
131         // two dimensions of the tensor in the last level of the pyramid
132         TensorShape dst_shape(shape);
133         dst_shape.set(0, static_cast<float>(shape[0] + 1) / static_cast<float>(std::pow(2, _pyramid_levels - 1)));
134         dst_shape.set(1, static_cast<float>(shape[1] + 1) / static_cast<float>(std::pow(2, _pyramid_levels - 1)));
135 
136         _dst_reference = SimpleTensor<U>(dst_shape, format_out);
137 
138         // Fill reference
139         fill(src);
140 
141         return reference::laplacian_pyramid<T, U>(src, _dst_reference, _pyramid_levels, border_mode, constant_border_value);
142     }
143 
144     size_t                       _pyramid_levels{};
145     BorderMode                   _border_mode{};
146     SimpleTensor<U>              _dst_reference{};
147     TensorType                   _dst_target{};
148     PyramidType                  _target{};
149     std::vector<SimpleTensor<U>> _reference{};
150 };
151 } // namespace validation
152 } // namespace test
153 } // namespace arm_compute
154 #endif /* ARM_COMPUTE_TEST_LAPLACIAN_PYRAMID_FIXTURE */
155