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