Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / onert-micro / luci-interpreter / src / kernels / SVDF.test.cpp
1 /*
2  * Copyright (c) 2022 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/SVDF.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 SVDFTest : public ::testing::Test
31 {
32 protected:
33   void SetUp() override { _memory_manager = std::make_unique<TestMemoryManager>(); }
34
35   std::unique_ptr<IMemoryManager> _memory_manager;
36 };
37
38 TEST_F(SVDFTest, FullIntegerTest)
39 {
40   const int32_t batches = 2;
41   const int32_t input_size = 3;
42   const int32_t units = 4;
43   const int32_t memory_size = 10;
44   const int32_t rank = 1;
45   const int32_t num_filters = units * rank;
46
47   Shape input_shape{batches, input_size};
48   Shape weight_feature_shape{num_filters, input_size};
49   Shape weight_time_shape{num_filters, memory_size};
50   Shape bias_shape{units};
51   Shape activation_state_shape{batches, memory_size * num_filters};
52
53   std::vector<float> input_data{0.49837467, 0.19278903, 0.26584083,
54                                 0.17660543, 0.52949083, -0.77931279};
55
56   std::vector<float> weight_feature_data{-0.31930989, -0.36118156, 0.0079667,   0.37613347,
57                                          0.22197971,  0.12416199,  0.27901134,  0.27557442,
58                                          0.3905206,   -0.36137494, -0.06634006, -0.10640851};
59
60   std::vector<float> weight_time_data{
61     -0.31930989, 0.37613347,  0.27901134,  -0.36137494, -0.36118156,
62     0.22197971,  0.27557442,  -0.06634006, 0.0079667,   0.12416199,
63
64     0.3905206,   -0.10640851, -0.0976817,  0.15294972,  0.39635518,
65     -0.02702999, 0.39296314,  0.15785322,  0.21931258,  0.31053296,
66
67     -0.36916667, 0.38031587,  -0.21580373, 0.27072677,  0.23622236,
68     0.34936687,  0.18174365,  0.35907319,  -0.17493086, 0.324846,
69
70     -0.10781813, 0.27201805,  0.14324132,  -0.23681851, -0.27115166,
71     -0.01580888, -0.14943552, 0.15465137,  0.09784451,  -0.0337657};
72
73   std::vector<float> bias_data{-0.0976817, 0.15294972, 0.39635518, -0.02702999};
74
75   std::pair<float, int32_t> input_quant_param = quantizationParams<int8_t>(-1, 1);
76   std::pair<float, int32_t> weight_feature_quant_param = quantizationParams<int8_t>(-0.5, 0.5);
77   std::pair<float, int32_t> weight_time_quant_param = quantizationParams<int16_t>(-1, 1);
78   std::pair<float, int32_t> bias_quant_param = quantizationParams<int32_t>(-512, 512);
79   std::pair<float, int32_t> activation_state_quant_param = quantizationParams<int16_t>(-16, 16);
80
81   std::pair<float, int32_t> output_quant_param = quantizationParams<int8_t>(-0.5, 0.5);
82
83   Tensor input_tensor =
84     makeInputTensor<DataType::S8>(input_shape, input_quant_param.first, input_quant_param.second,
85                                   input_data, _memory_manager.get());
86   Tensor weight_feature_tensor = makeInputTensor<DataType::S8>(
87     weight_feature_shape, weight_feature_quant_param.first, weight_feature_quant_param.second,
88     weight_feature_data, _memory_manager.get());
89   Tensor weight_time_tensor = makeInputTensor<DataType::S16>(
90     weight_time_shape, weight_time_quant_param.first, weight_time_quant_param.second,
91     weight_time_data, _memory_manager.get());
92   Tensor bias_tensor = makeInputTensor<DataType::S32>(
93     bias_shape, bias_quant_param.first, bias_quant_param.second, bias_data, _memory_manager.get());
94   Tensor activation_state_tensor = makeOutputTensor(
95     DataType::S16, activation_state_quant_param.first, activation_state_quant_param.second);
96   activation_state_tensor.resize(activation_state_shape);
97   Tensor output_tensor =
98     makeOutputTensor(DataType::S8, output_quant_param.first, output_quant_param.second);
99
100   Tensor scratchpad_activation_state(DataType::S16, Shape({}), {}, "");
101   Tensor scratchpad_1(DataType::S32, Shape({}), {}, "");
102   Tensor scratchpad_2(DataType::S32, Shape({}), {}, "");
103   Tensor scratchpad_3(DataType::FLOAT32, Shape({}), {}, "");
104   Tensor scratchpad_4(DataType::FLOAT32, Shape({}), {}, "");
105   Tensor scratchpad_5(DataType::FLOAT32, Shape({}), {}, "");
106   Tensor scratchpad_6(DataType::FLOAT32, Shape({}), {}, "");
107
108   SVDFParams params{};
109   params.activation = Activation::RELU;
110   params.asymmetric_quantize_inputs = false;
111   params.svdf_rank = rank;
112
113   SVDF kernel(&input_tensor, &weight_feature_tensor, &weight_time_tensor, &bias_tensor,
114               &activation_state_tensor, &output_tensor, &scratchpad_activation_state, &scratchpad_1,
115               &scratchpad_2, &scratchpad_3, &scratchpad_4, &scratchpad_5, &scratchpad_6, params);
116   kernel.configure();
117   _memory_manager->allocate_memory(output_tensor);
118   _memory_manager->allocate_memory(scratchpad_activation_state);
119   _memory_manager->allocate_memory(scratchpad_1);
120   _memory_manager->allocate_memory(scratchpad_2);
121   _memory_manager->allocate_memory(scratchpad_3);
122   _memory_manager->allocate_memory(scratchpad_4);
123   _memory_manager->allocate_memory(scratchpad_5);
124   _memory_manager->allocate_memory(scratchpad_6);
125   kernel.execute();
126
127   std::vector<int8_t> ref_output_data{-9, 24, 31, 1, -10, 10, -3, 0};
128
129   std::vector<int32_t> ref_output_shape{batches, units};
130   EXPECT_THAT(extractTensorData<int8_t>(output_tensor), ref_output_data);
131   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
132 }
133
134 TEST_F(SVDFTest, FloatTest)
135 {
136   const int32_t batches = 2;
137   const int32_t input_size = 3;
138   const int32_t units = 4;
139   const int32_t memory_size = 10;
140   const int32_t rank = 1;
141   const int32_t num_filters = units * rank;
142
143   Shape input_shape{batches, input_size};
144   Shape weight_feature_shape{num_filters, input_size};
145   Shape weight_time_shape{num_filters, memory_size};
146   Shape activation_state_shape{batches, memory_size * num_filters};
147
148   std::vector<float> input_data{0.12609188, -0.46347019, -0.89598465,
149                                 0.35867718, 0.36897406,  0.73463392};
150
151   std::vector<float> weight_feature_data{-0.31930989, -0.36118156, 0.0079667,   0.37613347,
152                                          0.22197971,  0.12416199,  0.27901134,  0.27557442,
153                                          0.3905206,   -0.36137494, -0.06634006, -0.10640851};
154
155   std::vector<float> weight_time_data{
156     -0.31930989, 0.37613347,  0.27901134,  -0.36137494, -0.36118156,
157     0.22197971,  0.27557442,  -0.06634006, 0.0079667,   0.12416199,
158
159     0.3905206,   -0.10640851, -0.0976817,  0.15294972,  0.39635518,
160     -0.02702999, 0.39296314,  0.15785322,  0.21931258,  0.31053296,
161
162     -0.36916667, 0.38031587,  -0.21580373, 0.27072677,  0.23622236,
163     0.34936687,  0.18174365,  0.35907319,  -0.17493086, 0.324846,
164
165     -0.10781813, 0.27201805,  0.14324132,  -0.23681851, -0.27115166,
166     -0.01580888, -0.14943552, 0.15465137,  0.09784451,  -0.0337657};
167
168   Tensor input_tensor =
169     makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
170   Tensor weight_feature_tensor = makeInputTensor<DataType::FLOAT32>(
171     weight_feature_shape, weight_feature_data, _memory_manager.get());
172   Tensor weight_time_tensor =
173     makeInputTensor<DataType::FLOAT32>(weight_time_shape, weight_time_data, _memory_manager.get());
174   Tensor activation_state_tensor = makeOutputTensor(DataType::FLOAT32);
175   activation_state_tensor.resize(activation_state_shape);
176   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
177
178   Tensor scratchpad_activation_state(DataType::FLOAT32, Shape({}), {}, "");
179   Tensor scratchpad_1(DataType::FLOAT32, Shape({}), {}, "");
180   Tensor scratchpad_2(DataType::FLOAT32, Shape({}), {}, "");
181   Tensor scratchpad_3(DataType::FLOAT32, Shape({}), {}, "");
182   Tensor scratchpad_4(DataType::FLOAT32, Shape({}), {}, "");
183   Tensor scratchpad_5(DataType::FLOAT32, Shape({}), {}, "");
184   Tensor scratchpad_6(DataType::FLOAT32, Shape({}), {}, "");
185
186   SVDFParams params{};
187   params.activation = Activation::NONE;
188   params.asymmetric_quantize_inputs = false;
189   params.svdf_rank = rank;
190
191   SVDF kernel(&input_tensor, &weight_feature_tensor, &weight_time_tensor, nullptr,
192               &activation_state_tensor, &output_tensor, &scratchpad_activation_state, &scratchpad_1,
193               &scratchpad_2, &scratchpad_3, &scratchpad_4, &scratchpad_5, &scratchpad_6, params);
194   kernel.configure();
195   _memory_manager->allocate_memory(output_tensor);
196   _memory_manager->allocate_memory(scratchpad_activation_state);
197   _memory_manager->allocate_memory(scratchpad_1);
198   _memory_manager->allocate_memory(scratchpad_2);
199   _memory_manager->allocate_memory(scratchpad_3);
200   _memory_manager->allocate_memory(scratchpad_4);
201   _memory_manager->allocate_memory(scratchpad_5);
202   _memory_manager->allocate_memory(scratchpad_6);
203   kernel.execute();
204
205   std::vector<float> ref_output_data{0.014899,    -0.0517661, -0.143725, -0.00271883,
206                                      -0.03004015, 0.09565311, 0.1587342, 0.00784263};
207
208   std::vector<float> ref_output_shape{batches, units};
209   const float tolerance = 1e-5;
210   EXPECT_THAT(extractTensorData<float>(output_tensor), FloatArrayNear(ref_output_data, tolerance));
211   EXPECT_THAT(extractTensorShape(output_tensor), ::testing::ElementsAreArray(ref_output_shape));
212 }
213
214 TEST_F(SVDFTest, Unsupported_Type_Configure_NEG)
215 {
216   const int32_t batches = 2;
217   const int32_t input_size = 3;
218   const int32_t units = 4;
219   const int32_t memory_size = 10;
220   const int32_t rank = 1;
221   const int32_t num_filters = units * rank;
222
223   Shape input_shape{batches, input_size};
224   Shape weight_feature_shape{num_filters, input_size};
225   Shape weight_time_shape{num_filters, memory_size};
226   Shape activation_state_shape{batches, memory_size * num_filters};
227
228   std::vector<int32_t> input_data{0, 1, 3, 4, 4, -2};
229
230   std::vector<float> weight_feature_data{-0.31930989, -0.36118156, 0.0079667,   0.37613347,
231                                          0.22197971,  0.12416199,  0.27901134,  0.27557442,
232                                          0.3905206,   -0.36137494, -0.06634006, -0.10640851};
233
234   std::vector<float> weight_time_data{
235     -0.31930989, 0.37613347,  0.27901134,  -0.36137494, -0.36118156,
236     0.22197971,  0.27557442,  -0.06634006, 0.0079667,   0.12416199,
237
238     0.3905206,   -0.10640851, -0.0976817,  0.15294972,  0.39635518,
239     -0.02702999, 0.39296314,  0.15785322,  0.21931258,  0.31053296,
240
241     -0.36916667, 0.38031587,  -0.21580373, 0.27072677,  0.23622236,
242     0.34936687,  0.18174365,  0.35907319,  -0.17493086, 0.324846,
243
244     -0.10781813, 0.27201805,  0.14324132,  -0.23681851, -0.27115166,
245     -0.01580888, -0.14943552, 0.15465137,  0.09784451,  -0.0337657};
246
247   Tensor input_tensor =
248     makeInputTensor<DataType::S32>(input_shape, input_data, _memory_manager.get());
249   Tensor weight_feature_tensor = makeInputTensor<DataType::FLOAT32>(
250     weight_feature_shape, weight_feature_data, _memory_manager.get());
251   Tensor weight_time_tensor =
252     makeInputTensor<DataType::FLOAT32>(weight_time_shape, weight_time_data, _memory_manager.get());
253   Tensor activation_state_tensor = makeOutputTensor(DataType::FLOAT32);
254   activation_state_tensor.resize(activation_state_shape);
255   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
256
257   Tensor scratchpad_activation_state(DataType::FLOAT32, Shape({}), {}, "");
258   Tensor scratchpad_1(DataType::FLOAT32, Shape({}), {}, "");
259   Tensor scratchpad_2(DataType::FLOAT32, Shape({}), {}, "");
260   Tensor scratchpad_3(DataType::FLOAT32, Shape({}), {}, "");
261   Tensor scratchpad_4(DataType::FLOAT32, Shape({}), {}, "");
262   Tensor scratchpad_5(DataType::FLOAT32, Shape({}), {}, "");
263   Tensor scratchpad_6(DataType::FLOAT32, Shape({}), {}, "");
264
265   SVDFParams params{};
266   params.activation = Activation::NONE;
267   params.asymmetric_quantize_inputs = false;
268   params.svdf_rank = rank;
269
270   SVDF kernel(&input_tensor, &weight_feature_tensor, &weight_time_tensor, nullptr,
271               &activation_state_tensor, &output_tensor, &scratchpad_activation_state, &scratchpad_1,
272               &scratchpad_2, &scratchpad_3, &scratchpad_4, &scratchpad_5, &scratchpad_6, params);
273   EXPECT_ANY_THROW(kernel.configure());
274 }
275
276 TEST_F(SVDFTest, Invalid_Input_Shape_NEG)
277 {
278   const int32_t batches = 2;
279   const int32_t right_input_size = 3;
280   const int32_t wrong_input_size = 4;
281   const int32_t units = 4;
282   const int32_t memory_size = 10;
283   const int32_t rank = 1;
284   const int32_t num_filters = units * rank;
285
286   Shape input_shape{batches, wrong_input_size};
287   Shape weight_feature_shape{num_filters, right_input_size};
288   Shape weight_time_shape{num_filters, memory_size};
289   Shape activation_state_shape{batches, memory_size * num_filters};
290
291   std::vector<float> input_data{0, 1, 3, 2, 4, 4, -2, 1};
292
293   std::vector<float> weight_feature_data{-0.31930989, -0.36118156, 0.0079667,   0.37613347,
294                                          0.22197971,  0.12416199,  0.27901134,  0.27557442,
295                                          0.3905206,   -0.36137494, -0.06634006, -0.10640851};
296
297   std::vector<float> weight_time_data{
298     -0.31930989, 0.37613347,  0.27901134,  -0.36137494, -0.36118156,
299     0.22197971,  0.27557442,  -0.06634006, 0.0079667,   0.12416199,
300
301     0.3905206,   -0.10640851, -0.0976817,  0.15294972,  0.39635518,
302     -0.02702999, 0.39296314,  0.15785322,  0.21931258,  0.31053296,
303
304     -0.36916667, 0.38031587,  -0.21580373, 0.27072677,  0.23622236,
305     0.34936687,  0.18174365,  0.35907319,  -0.17493086, 0.324846,
306
307     -0.10781813, 0.27201805,  0.14324132,  -0.23681851, -0.27115166,
308     -0.01580888, -0.14943552, 0.15465137,  0.09784451,  -0.0337657};
309
310   Tensor input_tensor =
311     makeInputTensor<DataType::FLOAT32>(input_shape, input_data, _memory_manager.get());
312   Tensor weight_feature_tensor = makeInputTensor<DataType::FLOAT32>(
313     weight_feature_shape, weight_feature_data, _memory_manager.get());
314   Tensor weight_time_tensor =
315     makeInputTensor<DataType::FLOAT32>(weight_time_shape, weight_time_data, _memory_manager.get());
316   Tensor activation_state_tensor = makeOutputTensor(DataType::FLOAT32);
317   activation_state_tensor.resize(activation_state_shape);
318   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
319
320   Tensor scratchpad_activation_state(DataType::FLOAT32, Shape({}), {}, "");
321   Tensor scratchpad_1(DataType::FLOAT32, Shape({}), {}, "");
322   Tensor scratchpad_2(DataType::FLOAT32, Shape({}), {}, "");
323   Tensor scratchpad_3(DataType::FLOAT32, Shape({}), {}, "");
324   Tensor scratchpad_4(DataType::FLOAT32, Shape({}), {}, "");
325   Tensor scratchpad_5(DataType::FLOAT32, Shape({}), {}, "");
326   Tensor scratchpad_6(DataType::FLOAT32, Shape({}), {}, "");
327
328   SVDFParams params{};
329   params.activation = Activation::NONE;
330   params.asymmetric_quantize_inputs = false;
331   params.svdf_rank = rank;
332
333   SVDF kernel(&input_tensor, &weight_feature_tensor, &weight_time_tensor, nullptr,
334               &activation_state_tensor, &output_tensor, &scratchpad_activation_state, &scratchpad_1,
335               &scratchpad_2, &scratchpad_3, &scratchpad_4, &scratchpad_5, &scratchpad_6, params);
336   EXPECT_ANY_THROW(kernel.configure());
337 }
338
339 } // namespace
340 } // namespace kernels
341 } // namespace luci_interpreter