25234c5cf093481015b032c902a5f61c1d3f3d68
[platform/core/ml/nnfw.git] / onert-micro / luci-interpreter / src / kernels / Concatenation.test.cpp
1 /*
2  * Copyright (c) 2020 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 // TODO enable it
18 #if 0
19 #include "kernels/Concatenation.h"
20 #include "kernels/TestUtils.h"
21 #include "luci_interpreter/TestMemoryManager.h"
22
23 namespace luci_interpreter
24 {
25 namespace kernels
26 {
27 namespace
28 {
29
30 using namespace testing;
31
32 class ConcatenationTest : public ::testing::Test
33 {
34 protected:
35   void SetUp() override { _memory_manager = std::make_unique<TestMemoryManager>(); }
36
37   std::unique_ptr<IMemoryManager> _memory_manager;
38 };
39
40 TEST_F(ConcatenationTest, Float)
41 {
42   std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
43   std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
44   Tensor input1_tensor =
45     makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
46   Tensor input2_tensor =
47     makeInputTensor<DataType::FLOAT32>({2, 3}, input2_data, _memory_manager.get());
48   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
49   ConcatenationParams params{};
50
51   // Try different 'axis' and expect different results.
52   {
53     params.axis = 0;
54     params.activation = luci::FusedActFunc::NONE;
55
56     Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
57     kernel.configure();
58     for (auto t : kernel.getOutputTensors())
59     {
60       _memory_manager->allocate_memory(*t);
61     }
62     kernel.execute();
63
64     EXPECT_THAT(extractTensorData<float>(output_tensor),
65                 FloatArrayNear({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}));
66   }
67   {
68     params.axis = -2; // Same as '0'.
69     params.activation = luci::FusedActFunc::NONE;
70
71     Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
72     kernel.configure();
73     _memory_manager->allocate_memory(output_tensor);
74     kernel.execute();
75
76     EXPECT_THAT(extractTensorData<float>(output_tensor),
77                 FloatArrayNear({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}));
78   }
79   {
80     params.axis = 1;
81     params.activation = luci::FusedActFunc::NONE;
82
83     Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
84     kernel.configure();
85     _memory_manager->allocate_memory(output_tensor);
86     kernel.execute();
87
88     EXPECT_THAT(extractTensorData<float>(output_tensor),
89                 FloatArrayNear({1, 2, 3, 7, 8, 9, 4, 5, 6, 10, 11, 12}));
90   }
91   {
92     params.axis = -1; // Same as '1'.
93     params.activation = luci::FusedActFunc::NONE;
94
95     Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
96     kernel.configure();
97     _memory_manager->allocate_memory(output_tensor);
98     kernel.execute();
99
100     EXPECT_THAT(extractTensorData<float>(output_tensor),
101                 FloatArrayNear({1, 2, 3, 7, 8, 9, 4, 5, 6, 10, 11, 12}));
102   }
103 }
104
105 TEST_F(ConcatenationTest, Input_Number_Check_NEG)
106 {
107   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
108   ConcatenationParams params{};
109
110   params.axis = -1;
111   params.activation = luci::FusedActFunc::NONE;
112
113   Concatenation kernel({}, &output_tensor, params);
114   EXPECT_ANY_THROW(kernel.configure());
115 }
116
117 TEST_F(ConcatenationTest, Invalid_Axis_NEG)
118 {
119   std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
120   std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
121   Tensor input1_tensor =
122     makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
123   Tensor input2_tensor =
124     makeInputTensor<DataType::FLOAT32>({2, 3}, input2_data, _memory_manager.get());
125   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
126   ConcatenationParams params{};
127
128   params.axis = -3;
129   params.activation = luci::FusedActFunc::NONE;
130
131   Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
132   EXPECT_ANY_THROW(kernel.configure());
133 }
134
135 TEST_F(ConcatenationTest, Mismatching_Input_Type_NEG)
136 {
137   std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
138   std::vector<uint8_t> input2_data{7, 8, 9, 10, 11, 12};
139   Tensor input1_tensor =
140     makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
141   Tensor input2_tensor = makeInputTensor<DataType::U8>({2, 3}, input2_data, _memory_manager.get());
142   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
143   ConcatenationParams params{};
144
145   params.axis = -1;
146   params.activation = luci::FusedActFunc::NONE;
147
148   Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
149   EXPECT_ANY_THROW(kernel.configure());
150 }
151
152 TEST_F(ConcatenationTest, Mismatching_Input_Dimension_Num_NEG)
153 {
154   std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
155   std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
156   Tensor input1_tensor =
157     makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
158   Tensor input2_tensor =
159     makeInputTensor<DataType::FLOAT32>({1, 2, 3}, input2_data, _memory_manager.get());
160   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
161   ConcatenationParams params{};
162
163   params.axis = -1;
164   params.activation = luci::FusedActFunc::NONE;
165
166   Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
167   EXPECT_ANY_THROW(kernel.configure());
168 }
169
170 TEST_F(ConcatenationTest, Mismatching_Input_Dimension_NEG)
171 {
172   std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
173   std::vector<float> input2_data{7, 8, 9, 10, 11, 12, 13, 14, 15};
174   Tensor input1_tensor =
175     makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
176   Tensor input2_tensor =
177     makeInputTensor<DataType::FLOAT32>({3, 3}, input2_data, _memory_manager.get());
178   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
179   ConcatenationParams params{};
180
181   params.axis = -1;
182   params.activation = luci::FusedActFunc::NONE;
183
184   Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
185   EXPECT_ANY_THROW(kernel.configure());
186 }
187
188 TEST_F(ConcatenationTest, Int8_Mismatching_Input_Type_NEG)
189 {
190   std::vector<uint8_t> input1_data{1, 2, 3, 4};
191   std::vector<int8_t> input2_data{5, 6, 7, 8};
192   Tensor input1_tensor = makeInputTensor<DataType::U8>({2, 2}, input1_data, _memory_manager.get());
193   Tensor input2_tensor = makeInputTensor<DataType::S8>({2, 2}, input2_data, _memory_manager.get());
194   Tensor output_tensor = makeOutputTensor(DataType::S8);
195   ConcatenationParams params{};
196
197   params.axis = -1;
198   params.activation = luci::FusedActFunc::NONE;
199
200   Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
201   EXPECT_ANY_THROW(kernel.configure());
202 }
203
204 TEST_F(ConcatenationTest, Int8_Mismatching_Input_Output_Quant_Params_NEG)
205 {
206   std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
207   std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
208   int quantized_dimension = 3;
209   std::vector<float> scales{0.1, 0.2, 0.3};
210   std::vector<int32_t> zero_points{1, -1, 1};
211
212   Tensor input1_tensor = makeInputTensor<DataType::S8>(
213     {1, 1, 2, 3}, scales, zero_points, quantized_dimension, input1_data, _memory_manager.get());
214   Tensor input2_tensor = makeInputTensor<DataType::S8>(
215     {1, 1, 2, 3}, scales, zero_points, quantized_dimension, input2_data, _memory_manager.get());
216   Tensor output_tensor = makeOutputTensor(DataType::S8, scales.at(0), zero_points.at(0));
217   ConcatenationParams params{};
218
219   params.axis = -1;
220   params.activation = luci::FusedActFunc::NONE;
221
222   Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
223   EXPECT_ANY_THROW(kernel.configure());
224 }
225
226 TEST_F(ConcatenationTest, Int8_Mismatching_Zero_Point_NEG)
227 {
228   std::vector<float> input1_data{1, 2, 3, 4};
229   std::vector<float> input2_data{5, 6, 7, 8};
230   float scale = 0.1;
231   int32_t zero_point_1 = 1;
232   int32_t zero_point_2 = -1;
233
234   Tensor input1_tensor =
235     makeInputTensor<DataType::S8>({2, 2}, scale, zero_point_1, input1_data, _memory_manager.get());
236   Tensor input2_tensor =
237     makeInputTensor<DataType::S8>({2, 2}, scale, zero_point_2, input2_data, _memory_manager.get());
238
239   Tensor output_tensor = makeOutputTensor(DataType::S8, scale, zero_point_1);
240   ConcatenationParams params{};
241
242   params.axis = -1;
243   params.activation = luci::FusedActFunc::NONE;
244
245   Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
246   EXPECT_ANY_THROW(kernel.configure());
247 }
248
249 // TODO: Remove this test when concat w/ fused_activation is supported
250 TEST_F(ConcatenationTest, With_Fused_Activation_NEG)
251 {
252   std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
253   std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
254   Tensor input1_tensor =
255     makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
256   Tensor input2_tensor =
257     makeInputTensor<DataType::FLOAT32>({2, 3}, input2_data, _memory_manager.get());
258   Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
259   ConcatenationParams params{};
260
261   params.axis = 1;
262   params.activation = luci::FusedActFunc::RELU;
263
264   Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
265   EXPECT_ANY_THROW(kernel.configure());
266 }
267
268 } // namespace
269 } // namespace kernels
270 } // namespace luci_interpreter
271 #endif