2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #include "kernels/Concatenation.h"
18 #include "kernels/TestUtils.h"
19 #include "luci_interpreter/TestMemoryManager.h"
21 namespace luci_interpreter
28 using namespace testing;
30 class ConcatenationTest : public ::testing::Test
33 void SetUp() override { _memory_manager = std::make_unique<TestMemoryManager>(); }
35 std::unique_ptr<IMemoryManager> _memory_manager;
38 TEST_F(ConcatenationTest, Float)
40 std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
41 std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
42 Tensor input1_tensor =
43 makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
44 Tensor input2_tensor =
45 makeInputTensor<DataType::FLOAT32>({2, 3}, input2_data, _memory_manager.get());
46 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
47 ConcatenationParams params{};
49 // Try different 'axis' and expect different results.
52 params.activation = luci::FusedActFunc::NONE;
54 Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
56 for (auto t : kernel.getOutputTensors())
58 _memory_manager->allocate_memory(*t);
62 EXPECT_THAT(extractTensorData<float>(output_tensor),
63 FloatArrayNear({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}));
66 params.axis = -2; // Same as '0'.
67 params.activation = luci::FusedActFunc::NONE;
69 Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
71 _memory_manager->allocate_memory(output_tensor);
74 EXPECT_THAT(extractTensorData<float>(output_tensor),
75 FloatArrayNear({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}));
79 params.activation = luci::FusedActFunc::NONE;
81 Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
83 _memory_manager->allocate_memory(output_tensor);
86 EXPECT_THAT(extractTensorData<float>(output_tensor),
87 FloatArrayNear({1, 2, 3, 7, 8, 9, 4, 5, 6, 10, 11, 12}));
90 params.axis = -1; // Same as '1'.
91 params.activation = luci::FusedActFunc::NONE;
93 Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
95 _memory_manager->allocate_memory(output_tensor);
98 EXPECT_THAT(extractTensorData<float>(output_tensor),
99 FloatArrayNear({1, 2, 3, 7, 8, 9, 4, 5, 6, 10, 11, 12}));
103 TEST_F(ConcatenationTest, Input_Number_Check_NEG)
105 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
106 ConcatenationParams params{};
109 params.activation = luci::FusedActFunc::NONE;
111 Concatenation kernel({}, &output_tensor, params);
112 EXPECT_ANY_THROW(kernel.configure());
115 TEST_F(ConcatenationTest, Invalid_Axis_NEG)
117 std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
118 std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
119 Tensor input1_tensor =
120 makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
121 Tensor input2_tensor =
122 makeInputTensor<DataType::FLOAT32>({2, 3}, input2_data, _memory_manager.get());
123 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
124 ConcatenationParams params{};
127 params.activation = luci::FusedActFunc::NONE;
129 Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
130 EXPECT_ANY_THROW(kernel.configure());
133 TEST_F(ConcatenationTest, Mismatching_Input_Type_NEG)
135 std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
136 std::vector<uint8_t> input2_data{7, 8, 9, 10, 11, 12};
137 Tensor input1_tensor =
138 makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
139 Tensor input2_tensor = makeInputTensor<DataType::U8>({2, 3}, input2_data, _memory_manager.get());
140 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
141 ConcatenationParams params{};
144 params.activation = luci::FusedActFunc::NONE;
146 Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
147 EXPECT_ANY_THROW(kernel.configure());
150 TEST_F(ConcatenationTest, Mismatching_Input_Dimension_Num_NEG)
152 std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
153 std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
154 Tensor input1_tensor =
155 makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
156 Tensor input2_tensor =
157 makeInputTensor<DataType::FLOAT32>({1, 2, 3}, input2_data, _memory_manager.get());
158 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
159 ConcatenationParams params{};
162 params.activation = luci::FusedActFunc::NONE;
164 Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
165 EXPECT_ANY_THROW(kernel.configure());
168 TEST_F(ConcatenationTest, Mismatching_Input_Dimension_NEG)
170 std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
171 std::vector<float> input2_data{7, 8, 9, 10, 11, 12, 13, 14, 15};
172 Tensor input1_tensor =
173 makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
174 Tensor input2_tensor =
175 makeInputTensor<DataType::FLOAT32>({3, 3}, input2_data, _memory_manager.get());
176 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
177 ConcatenationParams params{};
180 params.activation = luci::FusedActFunc::NONE;
182 Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
183 EXPECT_ANY_THROW(kernel.configure());
186 TEST_F(ConcatenationTest, Unsupported_Configure_Type_NEG)
188 std::vector<int8_t> input1_data{1, 2, 3, 4, 5, 6};
189 std::vector<int8_t> input2_data{7, 8, 9, 10, 11, 12};
190 Tensor input1_tensor = makeInputTensor<DataType::S8>({2, 3}, input1_data, _memory_manager.get());
191 Tensor input2_tensor = makeInputTensor<DataType::S8>({2, 3}, input2_data, _memory_manager.get());
192 Tensor output_tensor = makeOutputTensor(DataType::S8);
193 ConcatenationParams params{};
196 params.activation = luci::FusedActFunc::NONE;
198 Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
199 EXPECT_ANY_THROW(kernel.configure());
202 // TODO: Remove this test when concat w/ fused_activation is supported
203 TEST_F(ConcatenationTest, With_Fused_Activation_NEG)
205 std::vector<float> input1_data{1, 2, 3, 4, 5, 6};
206 std::vector<float> input2_data{7, 8, 9, 10, 11, 12};
207 Tensor input1_tensor =
208 makeInputTensor<DataType::FLOAT32>({2, 3}, input1_data, _memory_manager.get());
209 Tensor input2_tensor =
210 makeInputTensor<DataType::FLOAT32>({2, 3}, input2_data, _memory_manager.get());
211 Tensor output_tensor = makeOutputTensor(DataType::FLOAT32);
212 ConcatenationParams params{};
215 params.activation = luci::FusedActFunc::RELU;
217 Concatenation kernel({&input1_tensor, &input2_tensor}, &output_tensor, params);
218 EXPECT_ANY_THROW(kernel.configure());
222 } // namespace kernels
223 } // namespace luci_interpreter