Imported Upstream version 1.18.0
[platform/core/ml/nnfw.git] / compiler / luci-interpreter / src / kernels / Mean.test.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3  * Copyright 2017 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/Mean.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 MeanTest : public ::testing::Test
32 {
33 protected:
34   void SetUp() override { _memory_manager = std::make_unique<TestMemoryManager>(); }
35
36   std::unique_ptr<IMemoryManager> _memory_manager;
37 };
38
39 TEST_F(MeanTest, FloatKeepDims)
40 {
41   std::vector<float> input_data = {1.0,  2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,
42                                    9.0,  10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
43                                    17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0};
44
45   std::vector<int32_t> axis_data{0, 2};
46   Tensor input_tensor =
47     makeInputTensor<DataType::FLOAT32>({4, 3, 2}, input_data, _memory_manager.get());
48   Tensor axis_tensor = makeInputTensor<DataType::S32>({2}, axis_data, _memory_manager.get());
49   Tensor temp_index(DataType::S32, Shape({}), {}, "");
50   Tensor resolved_axes(DataType::S32, Shape({}), {}, "");
51   Tensor temp_sum(DataType::FLOAT32, Shape({}), {}, "");
52   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
53
54   ReducerParams params{};
55   params.keep_dims = true;
56
57   Mean kernel(&input_tensor, &axis_tensor, &output_tensor, &temp_index, &resolved_axes, &temp_sum,
58               params);
59   kernel.configure();
60   _memory_manager->allocate_memory(temp_index);
61   _memory_manager->allocate_memory(resolved_axes);
62   _memory_manager->allocate_memory(temp_sum);
63   _memory_manager->allocate_memory(output_tensor);
64   kernel.execute();
65
66   std::vector<float> ref_output_data{10.5, 12.5, 14.5};
67   std::initializer_list<int32_t> ref_output_shape{1, 3, 1};
68   EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
69   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
70 }
71
72 TEST_F(MeanTest, FloatKeepDims4DMean)
73 {
74   std::vector<float> input_data = {1.0,  2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,
75                                    9.0,  10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
76                                    17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0};
77
78   std::vector<int32_t> axis_data{1, 2};
79   Tensor input_tensor =
80     makeInputTensor<DataType::FLOAT32>({2, 2, 3, 2}, input_data, _memory_manager.get());
81   Tensor axis_tensor = makeInputTensor<DataType::S32>({2}, axis_data, _memory_manager.get());
82   Tensor temp_index(DataType::S32, Shape({}), {}, "");
83   Tensor resolved_axes(DataType::S32, Shape({}), {}, "");
84   Tensor temp_sum(DataType::FLOAT32, Shape({}), {}, "");
85   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
86
87   ReducerParams params{};
88   params.keep_dims = true;
89
90   Mean kernel(&input_tensor, &axis_tensor, &output_tensor, &temp_index, &resolved_axes, &temp_sum,
91               params);
92   kernel.configure();
93   _memory_manager->allocate_memory(temp_index);
94   _memory_manager->allocate_memory(resolved_axes);
95   _memory_manager->allocate_memory(temp_sum);
96   _memory_manager->allocate_memory(output_tensor);
97   kernel.execute();
98
99   std::vector<float> ref_output_data{6, 7, 18, 19};
100   std::initializer_list<int32_t> ref_output_shape{2, 1, 1, 2};
101   EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
102   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
103 }
104
105 TEST_F(MeanTest, FloatNotKeepDims)
106 {
107   std::vector<float> input_data = {1.0,  2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,
108                                    9.0,  10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
109                                    17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0};
110
111   std::vector<int32_t> axis_data{1, 0, -3, -3};
112   Tensor input_tensor =
113     makeInputTensor<DataType::FLOAT32>({4, 3, 2}, input_data, _memory_manager.get());
114   Tensor axis_tensor = makeInputTensor<DataType::S32>({4}, axis_data, _memory_manager.get());
115   Tensor temp_index(DataType::S32, Shape({}), {}, "");
116   Tensor resolved_axes(DataType::S32, Shape({}), {}, "");
117   Tensor temp_sum(DataType::FLOAT32, Shape({}), {}, "");
118   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
119
120   ReducerParams params{};
121   params.keep_dims = false;
122
123   Mean kernel(&input_tensor, &axis_tensor, &output_tensor, &temp_index, &resolved_axes, &temp_sum,
124               params);
125   kernel.configure();
126   _memory_manager->allocate_memory(temp_index);
127   _memory_manager->allocate_memory(resolved_axes);
128   _memory_manager->allocate_memory(temp_sum);
129   _memory_manager->allocate_memory(output_tensor);
130   kernel.execute();
131
132   std::vector<float> ref_output_data{12, 13};
133   std::initializer_list<int32_t> ref_output_shape{2};
134   EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data));
135   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
136 }
137
138 TEST_F(MeanTest, Uint8KeepDims)
139 {
140   float kQuantizedTolerance = getTolerance(-1.0, 1.0, 255);
141   std::vector<float> input_data = {0.4, 0.2, 0.3, 0.4, 0.5, 0.6};
142   std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-1.0f, 1.0f);
143
144   std::vector<int32_t> axis_data{1};
145   Tensor input_tensor = makeInputTensor<DataType::U8>({3, 2}, quant_param.first, quant_param.second,
146                                                       input_data, _memory_manager.get());
147   Tensor axis_tensor = makeInputTensor<DataType::S32>({1}, axis_data, _memory_manager.get());
148   Tensor temp_index(DataType::S32, Shape({}), {}, "");
149   Tensor resolved_axes(DataType::S32, Shape({}), {}, "");
150   Tensor temp_sum(DataType::U8, Shape({}), {}, "");
151   Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
152
153   ReducerParams params{};
154   params.keep_dims = true;
155
156   Mean kernel(&input_tensor, &axis_tensor, &output_tensor, &temp_index, &resolved_axes, &temp_sum,
157               params);
158   kernel.configure();
159   _memory_manager->allocate_memory(temp_index);
160   _memory_manager->allocate_memory(resolved_axes);
161   _memory_manager->allocate_memory(temp_sum);
162   _memory_manager->allocate_memory(output_tensor);
163   kernel.execute();
164
165   std::vector<float> ref_output_data{0.3, 0.35, 0.55};
166   std::initializer_list<int32_t> ref_output_shape{3, 1};
167   EXPECT_THAT(dequantizeTensorData(output_tensor),
168               FloatArrayNear(ref_output_data, kQuantizedTolerance));
169   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
170 }
171
172 TEST_F(MeanTest, Uint8NotKeepDims)
173 {
174   float kQuantizedTolerance = getTolerance(-1.0, 1.0, 255);
175   std::vector<float> input_data = {0.4, 0.2, 0.3, 0.4, 0.5, 0.6};
176   std::pair<float, int32_t> quant_param = quantizationParams<uint8_t>(-1.0f, 1.0f);
177
178   std::vector<int32_t> axis_data{1};
179   Tensor input_tensor = makeInputTensor<DataType::U8>(
180     {1, 3, 2}, quant_param.first, quant_param.second, input_data, _memory_manager.get());
181   Tensor axis_tensor = makeInputTensor<DataType::S32>({1}, axis_data, _memory_manager.get());
182   Tensor temp_index(DataType::S32, Shape({}), {}, "");
183   Tensor resolved_axes(DataType::S32, Shape({}), {}, "");
184   Tensor temp_sum(DataType::FLOAT32, Shape({}), {}, "");
185   Tensor output_tensor = makeOutputTensor(DataType::U8, quant_param.first, quant_param.second);
186
187   ReducerParams params{};
188   params.keep_dims = false;
189
190   Mean kernel(&input_tensor, &axis_tensor, &output_tensor, &temp_index, &resolved_axes, &temp_sum,
191               params);
192   kernel.configure();
193   _memory_manager->allocate_memory(temp_index);
194   _memory_manager->allocate_memory(resolved_axes);
195   _memory_manager->allocate_memory(temp_sum);
196   _memory_manager->allocate_memory(output_tensor);
197   kernel.execute();
198
199   std::vector<float> ref_output_data{0.4, 0.4};
200   std::initializer_list<int32_t> ref_output_shape{1, 2};
201   EXPECT_THAT(dequantizeTensorData(output_tensor),
202               FloatArrayNear(ref_output_data, kQuantizedTolerance));
203   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
204 }
205
206 TEST_F(MeanTest, SInt16KeepDims4D)
207 {
208   std::vector<float> input_data = {1.0,  2.0,  3.0,  4.0,  5.0,  6.0,  7.0,  8.0,
209                                    9.0,  10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
210                                    17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0};
211   std::vector<int32_t> axes_data{1, 2};
212   std::vector<float> ref_output_data{6, 7, 18, 19};
213
214   Tensor input_tensor =
215     makeInputTensor<DataType::S16>({2, 2, 3, 2}, 0.25, 0, input_data, _memory_manager.get());
216   Tensor axes_tensor = makeInputTensor<DataType::S32>({2}, axes_data, _memory_manager.get());
217   Tensor temp_index(DataType::S32, Shape({}), {}, "");
218   Tensor resolved_axes(DataType::S32, Shape({}), {}, "");
219   Tensor temp_sum(DataType::FLOAT32, Shape({}), {}, "");
220   Tensor output_tensor = makeOutputTensor(DataType::S16, 0.2, 0);
221
222   ReducerParams params{};
223   params.keep_dims = true;
224
225   Mean kernel(&input_tensor, &axes_tensor, &output_tensor, &temp_index, &resolved_axes, &temp_sum,
226               params);
227   kernel.configure();
228   _memory_manager->allocate_memory(temp_index);
229   _memory_manager->allocate_memory(resolved_axes);
230   _memory_manager->allocate_memory(temp_sum);
231   _memory_manager->allocate_memory(output_tensor);
232   kernel.execute();
233
234   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray({2, 1, 1, 2}));
235   EXPECT_THAT(dequantizeTensorData(output_tensor), FloatArrayNear(ref_output_data));
236 }
237
238 } // namespace
239 } // namespace kernels
240 } // namespace luci_interpreter