Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / onert-micro / luci-interpreter / src / kernels / MirrorPad.test.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "kernels/MirrorPad.h"
18 #include "kernels/TestUtils.h"
19 #include "luci_interpreter/TestMemoryManager.h"
20
21 namespace luci_interpreter
22 {
23 namespace kernels
24 {
25 namespace
26 {
27
28 using namespace testing;
29
30 class MirrorPadTest : public ::testing::Test
31 {
32 protected:
33   void SetUp() override { _memory_manager = std::make_unique<TestMemoryManager>(); }
34
35   void Execute(const Tensor &input, const Tensor &padding, Tensor &output, MirrorPadMode mode)
36   {
37     MirrorPadParams params{};
38     params.mode = mode;
39
40     MirrorPad kernel(&input, &padding, &output, params);
41     kernel.configure();
42     _memory_manager->allocate_memory(output);
43     kernel.execute();
44   }
45
46   std::unique_ptr<IMemoryManager> _memory_manager;
47 };
48
49 TEST_F(MirrorPadTest, FloatReflect)
50 {
51   Shape input_shape = {1, 2, 2, 1};
52   Shape padding_shape = {4, 2};
53
54   std::vector<float> input_data{1.0f, 2.0f,  //
55                                 3.0f, 4.0f}; //
56   std::vector<int> padding_data{0, 0, 2, 1, 1, 2, 0, 0};
57
58   Tensor input_tensor =
59     makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
60   Tensor padding_tensor =
61     makeInputTensor<DataType::S32>(padding_shape, padding_data, _memory_manager.get());
62
63   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
64
65   Execute(input_tensor, padding_tensor, output_tensor, MirrorPadMode::REFLECT);
66
67   std::vector<float> ref_output_data{2.0f, 1.0f, 2.0f, 1.0f, 2.0f,  //
68                                      4.0f, 3.0f, 4.0f, 3.0f, 4.0f,  //
69                                      2.0f, 1.0f, 2.0f, 1.0f, 2.0f,  //
70                                      4.0f, 3.0f, 4.0f, 3.0f, 4.0f,  //
71                                      2.0f, 1.0f, 2.0f, 1.0f, 2.0f}; //
72   std::initializer_list<int32_t> ref_output_shape{1, 5, 5, 1};
73
74   EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
75   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
76 }
77
78 TEST_F(MirrorPadTest, FloatSymmetric)
79 {
80   Shape input_shape = {1, 2, 2, 1};
81   Shape padding_shape = {4, 2};
82
83   std::vector<float> input_data{1.0f, 2.0f,  //
84                                 3.0f, 4.0f}; //
85   std::vector<int> padding_data{0, 0, 2, 1, 1, 2, 0, 0};
86
87   Tensor input_tensor =
88     makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
89   Tensor padding_tensor =
90     makeInputTensor<DataType::S32>(padding_shape, padding_data, _memory_manager.get());
91
92   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
93
94   Execute(input_tensor, padding_tensor, output_tensor, MirrorPadMode::SYMMETRIC);
95
96   std::vector<float> ref_output_data{3.0, 3.0, 4.0, 4.0, 3.0,  //
97                                      1.0, 1.0, 2.0, 2.0, 1.0,  //
98                                      1.0, 1.0, 2.0, 2.0, 1.0,  //
99                                      3.0, 3.0, 4.0, 4.0, 3.0,  //
100                                      3.0, 3.0, 4.0, 4.0, 3.0}; //
101   std::initializer_list<int32_t> ref_output_shape{1, 5, 5, 1};
102
103   EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
104   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
105 }
106
107 TEST_F(MirrorPadTest, FloatSymmetric2Dim)
108 {
109   Shape input_shape = {3, 1};
110   Shape padding_shape = {2, 2};
111
112   std::vector<float> input_data{1.0f, 2.0f, 3.0f};
113   std::vector<int> padding_data{1, 2, 0, 0};
114
115   Tensor input_tensor =
116     makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
117   Tensor padding_tensor =
118     makeInputTensor<DataType::S32>(padding_shape, padding_data, _memory_manager.get());
119
120   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
121
122   Execute(input_tensor, padding_tensor, output_tensor, MirrorPadMode::SYMMETRIC);
123
124   std::vector<float> ref_output_data{1.0, 1.0, 2.0, 3.0, 3.0, 2.0};
125   std::initializer_list<int32_t> ref_output_shape{6, 1};
126
127   EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
128   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
129 }
130
131 TEST_F(MirrorPadTest, Uint8Reflect)
132 {
133   Shape input_shape = {1, 2, 3, 1};
134   Shape padding_shape = {4, 2};
135
136   float quant_tolerance = getTolerance(0.0f, 6.0f, 255);
137   std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(0.0f, 6.0f);
138
139   std::vector<float> input_data{1.0f, 2.0f, 3.0f,  //
140                                 4.0f, 5.0f, 6.0f}; //
141   std::vector<int> padding_data{0, 0, 2, 1, 1, 3, 0, 0};
142
143   Tensor input_tensor = makeInputTensor<DataType::U8>(
144     input_shape, quant_param.first, quant_param.second, input_data, _memory_manager.get());
145
146   Tensor padding_tensor =
147     makeInputTensor<DataType::S32>(padding_shape, padding_data, _memory_manager.get());
148
149   Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
150
151   Execute(input_tensor, padding_tensor, output_tensor, MirrorPadMode::REFLECT);
152
153   std::vector<float> ref_output_data{
154     3.0f, 1.0f, 2.0f, 3.0f, 1.0f, 2.0f, 3.0f, //
155     6.0f, 4.0f, 5.0f, 6.0f, 4.0f, 5.0f, 6.0f, //
156     3.0f, 1.0f, 2.0f, 3.0f, 1.0f, 2.0f, 3.0f, //
157     6.0f, 4.0f, 5.0f, 6.0f, 4.0f, 5.0f, 6.0f, //
158     3.0f, 1.0f, 2.0f, 3.0f, 1.0f, 2.0f, 3.0f, //
159   };
160   std::initializer_list<int32_t> ref_output_shape{1, 5, 7, 1};
161
162   EXPECT_THAT(dequantizeTensorData(output_tensor),
163               FloatArrayNear(ref_output_data, quant_tolerance));
164   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
165 }
166
167 TEST_F(MirrorPadTest, Uint8Symmetric)
168 {
169   Shape input_shape = {1, 2, 3, 1};
170   Shape padding_shape = {4, 2};
171
172   float quant_tolerance = getTolerance(0.0f, 6.0f, 255);
173   std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(0.0f, 6.0f);
174
175   std::vector<float> input_data{1.0f, 2.0f, 3.0f,  //
176                                 4.0f, 5.0f, 6.0f}; //
177   std::vector<int> padding_data{0, 0, 2, 1, 1, 3, 0, 0};
178
179   Tensor input_tensor = makeInputTensor<DataType::U8>(
180     input_shape, quant_param.first, quant_param.second, input_data, _memory_manager.get());
181
182   Tensor padding_tensor =
183     makeInputTensor<DataType::S32>(padding_shape, padding_data, _memory_manager.get());
184
185   Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
186
187   Execute(input_tensor, padding_tensor, output_tensor, MirrorPadMode::SYMMETRIC);
188
189   std::vector<float> ref_output_data{
190     4.0f, 4.0f, 5.0f, 6.0f, 6.0f, 5.0f, 4.0f, //
191     1.0f, 1.0f, 2.0f, 3.0f, 3.0f, 2.0f, 1.0f, //
192     1.0f, 1.0f, 2.0f, 3.0f, 3.0f, 2.0f, 1.0f, //
193     4.0f, 4.0f, 5.0f, 6.0f, 6.0f, 5.0f, 4.0f, //
194     4.0f, 4.0f, 5.0f, 6.0f, 6.0f, 5.0f, 4.0f, //
195   };
196   std::initializer_list<int32_t> ref_output_shape{1, 5, 7, 1};
197
198   EXPECT_THAT(dequantizeTensorData(output_tensor),
199               FloatArrayNear(ref_output_data, quant_tolerance));
200   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
201 }
202
203 TEST_F(MirrorPadTest, UnsupportedDim_NEG)
204 {
205   Tensor input_tensor =
206     makeInputTensor<DataType::FLOAT32>({1, 1, 1, 1, 1}, {1.0f}, _memory_manager.get());
207   Tensor padding_tensor =
208     makeInputTensor<DataType::S32>({5, 2}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, _memory_manager.get());
209   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
210
211   EXPECT_ANY_THROW(Execute(input_tensor, padding_tensor, output_tensor, MirrorPadMode::REFLECT));
212 }
213
214 TEST_F(MirrorPadTest, InvalidInputType_NEG)
215 {
216   Tensor input_tensor = makeInputTensor<DataType::S64>({1}, {1}, _memory_manager.get());
217   Tensor padding_tensor = makeInputTensor<DataType::S32>({1, 2}, {0, 0}, _memory_manager.get());
218   Tensor output_tensor = makeOutputTensor(DataType::S64);
219
220   EXPECT_ANY_THROW(Execute(input_tensor, padding_tensor, output_tensor, MirrorPadMode::REFLECT));
221 }
222
223 } // namespace
224 } // namespace kernels
225 } // namespace luci_interpreter