Imported Upstream version 1.12.0
[platform/core/ml/nnfw.git] / tests / nnfw_api / src / one_op_tests / Concat.cc
1 /*
2  * Copyright (c) 2020 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 "GenModelTest.h"
18
19 #include <memory>
20
21 TEST_F(GenModelTest, OneOp_Concat_ShareSubTensor)
22 {
23   CircleGen cgen;
24   int lhs = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
25   int rhs = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
26   int shared_subtensor = cgen.addTensor({{1, 2, 2, 1}, circle::TensorType::TensorType_FLOAT32});
27   int concat_out = cgen.addTensor({{1, 2, 2, 2}, circle::TensorType::TensorType_FLOAT32});
28   std::vector<int32_t> padding_data{0, 0, 1, 1, 1, 1, 0, 0};
29   uint32_t padding_buf = cgen.addBuffer(padding_data);
30   int padding = cgen.addTensor({{4, 2}, circle::TensorType::TensorType_INT32, padding_buf});
31   int pad_out = cgen.addTensor({{1, 4, 4, 1}, circle::TensorType::TensorType_FLOAT32});
32   cgen.addOperatorAdd({{lhs, rhs}, {shared_subtensor}}, circle::ActivationFunctionType_NONE);
33   cgen.addOperatorConcatenation({{rhs, shared_subtensor}, {concat_out}}, 3,
34                                 circle::ActivationFunctionType_NONE);
35   cgen.addOperatorPad({{shared_subtensor, padding}, {pad_out}});
36   cgen.setInputsAndOutputs({lhs, rhs}, {pad_out, concat_out});
37
38   _context = std::make_unique<GenModelTestContext>(cgen.finish());
39   _context->addTestCase(uniformTCD<float>(
40     {{1, 3, 2, 4}, {5, 4, 7, 4}},
41     {{0, 0, 0, 0, 0, 6, 7, 0, 0, 9, 8, 0, 0, 0, 0, 0}, {5, 6, 4, 7, 7, 9, 4, 8}}));
42   _context->setBackends({"acl_cl", "acl_neon", "cpu"});
43
44   SUCCEED();
45 }
46
47 struct ConcatVariationParam
48 {
49   TestCaseData tcd;
50   circle::TensorType type = circle::TensorType::TensorType_FLOAT32;
51   float scale = 0.0f;
52   int64_t zero_point = 0;
53 };
54
55 class ConcatVariation : public GenModelTest,
56                         public ::testing::WithParamInterface<ConcatVariationParam>
57 {
58 };
59
60 // Input shape: {2, 3} / {2, 3}
61 // Output shape: {4, 3}
62 TEST_P(ConcatVariation, Test)
63 {
64   auto &param = GetParam();
65
66   CircleGen cgen;
67   int input1 = cgen.addTensor({{2, 3}, param.type}, param.scale, param.zero_point);
68   int input2 = cgen.addTensor({{2, 3}, param.type}, param.scale, param.zero_point);
69   int output = cgen.addTensor({{4, 3}, param.type}, param.scale, param.zero_point);
70   cgen.addOperatorConcatenation({{input1, input2}, {output}}, 0,
71                                 circle::ActivationFunctionType_NONE);
72   cgen.setInputsAndOutputs({input1, input2}, {output});
73
74   _context = std::make_unique<GenModelTestContext>(cgen.finish());
75   _context->addTestCase(param.tcd);
76   _context->setBackends({"acl_cl", "acl_neon", "cpu"});
77
78   SUCCEED();
79 }
80
81 INSTANTIATE_TEST_CASE_P(
82   GenModelTest, ConcatVariation,
83   ::testing::Values(
84     // Float
85     ConcatVariationParam{uniformTCD<float>({{1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12}},
86                                            {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}})},
87     // Uint8
88     ConcatVariationParam{uniformTCD<uint8_t>({{1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12}},
89                                              {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}),
90                          circle::TensorType::TensorType_UINT8, 1.0f, -2},
91     // Int8
92     ConcatVariationParam{uniformTCD<int8_t>({{1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12}},
93                                             {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}),
94                          circle::TensorType::TensorType_INT8, 1.0f, -2},
95     // Int16
96     // TODO Enable when nnfw api support int16 type
97     // ConcatVariationParam{
98     //    uniformTCD<int16_t>({{1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12}},
99     //                                  {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}),
100     //    circle::TensorType::TensorType_INT16, 1.0f, 0},
101     // Int32
102     ConcatVariationParam{uniformTCD<int32_t>({{1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12}},
103                                              {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}),
104                          circle::TensorType::TensorType_INT32},
105     // Int64
106     ConcatVariationParam{uniformTCD<int64_t>({{1, 2, 3, 4, 5, 6}, {7, 8, 9, 10, 11, 12}},
107                                              {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}),
108                          circle::TensorType::TensorType_INT64}));
109
110 TEST_F(GenModelTest, OneOp_Concat_Subtensor_4D)
111 {
112   CircleGen cgen;
113   int in1 = cgen.addTensor({{1, 1, 1, 20}, circle::TensorType::TensorType_FLOAT32});
114   int in2 = cgen.addTensor({{1, 1, 1, 10}, circle::TensorType::TensorType_FLOAT32});
115   std::vector<int32_t> axis_data{3};
116   uint32_t axis_buf = cgen.addBuffer(axis_data);
117   int axis = cgen.addTensor({{1}, circle::TensorType::TensorType_INT32, axis_buf});
118
119   int s_out1 = cgen.addTensor({{1, 1, 1, 5}, circle::TensorType::TensorType_FLOAT32});
120   int s_out2 = cgen.addTensor({{1, 1, 1, 5}, circle::TensorType::TensorType_FLOAT32});
121   int s_out3 = cgen.addTensor({{1, 1, 1, 5}, circle::TensorType::TensorType_FLOAT32});
122   int s_out4 = cgen.addTensor({{1, 1, 1, 5}, circle::TensorType::TensorType_FLOAT32});
123
124   int c_out1 = cgen.addTensor({{1, 1, 1, 10}, circle::TensorType::TensorType_FLOAT32});
125   int c_out2 = cgen.addTensor({{1, 1, 1, 10}, circle::TensorType::TensorType_FLOAT32});
126   int c_out3 = cgen.addTensor({{1, 1, 1, 10}, circle::TensorType::TensorType_FLOAT32});
127
128   int a_out1 = cgen.addTensor({{1, 1, 1, 10}, circle::TensorType::TensorType_FLOAT32});
129   int a_out2 = cgen.addTensor({{1, 1, 1, 10}, circle::TensorType::TensorType_FLOAT32});
130   int a_out3 = cgen.addTensor({{1, 1, 1, 10}, circle::TensorType::TensorType_FLOAT32});
131
132   int final_out = cgen.addTensor({{1, 1, 1, 35}, circle::TensorType::TensorType_FLOAT32});
133
134   cgen.addOperatorSplit({{axis, in1}, {s_out1, s_out2, s_out3, s_out4}}, 4);
135
136   cgen.addOperatorConcatenation({{s_out1, s_out2}, {c_out1}}, 3,
137                                 circle::ActivationFunctionType::ActivationFunctionType_NONE);
138   cgen.addOperatorConcatenation({{s_out1, s_out3}, {c_out2}}, 3,
139                                 circle::ActivationFunctionType::ActivationFunctionType_NONE);
140   cgen.addOperatorConcatenation({{s_out1, s_out4}, {c_out3}}, 3,
141                                 circle::ActivationFunctionType::ActivationFunctionType_NONE);
142
143   cgen.addOperatorAdd({{c_out1, in2}, {a_out1}},
144                       circle::ActivationFunctionType::ActivationFunctionType_NONE);
145   cgen.addOperatorAdd({{c_out2, in2}, {a_out2}},
146                       circle::ActivationFunctionType::ActivationFunctionType_NONE);
147   cgen.addOperatorAdd({{c_out3, in2}, {a_out3}},
148                       circle::ActivationFunctionType::ActivationFunctionType_NONE);
149
150   cgen.addOperatorConcatenation({{s_out1, a_out1, a_out2, a_out3}, {final_out}}, 3,
151                                 circle::ActivationFunctionType::ActivationFunctionType_NONE);
152
153   cgen.setInputsAndOutputs({in1, in2}, {s_out1, s_out2, s_out3, s_out4, c_out1, c_out2, c_out3,
154                                         a_out1, a_out2, a_out3, final_out});
155
156   _context = std::make_unique<GenModelTestContext>(cgen.finish());
157   _context->addTestCase(uniformTCD<float>(
158     {
159       // inputs
160       {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, // in1
161       {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}                                           // in2
162     },
163     {
164       // outputs
165       {1, 2, 3, 4, 5},                     // s_out1
166       {6, 7, 8, 9, 10},                    // s_out2
167       {11, 12, 13, 14, 15},                // s_out3
168       {16, 17, 18, 19, 20},                // s_out4
169       {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},     // c_out1
170       {1, 2, 3, 4, 5, 11, 12, 13, 14, 15}, // c_out2
171       {1, 2, 3, 4, 5, 16, 17, 18, 19, 20}, // c_out3
172       {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},     // a_out1
173       {1, 2, 3, 4, 5, 11, 12, 13, 14, 15}, // a_out2
174       {1, 2, 3, 4, 5, 16, 17, 18, 19, 20}, // a_out3
175       {1, 2, 3,  4,  5,  1,  2,  3, 4, 5, 6, 7, 8,  9,  10, 1,  2, 3,
176        4, 5, 11, 12, 13, 14, 15, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20} // final_out
177     }));
178   _context->setBackends({"acl_cl", "acl_neon", "cpu"});
179
180   SUCCEED();
181 }
182
183 TEST_F(GenModelTest, neg_OneOp_Concat_InvalidAxis)
184 {
185   CircleGen cgen;
186
187   int input1 = cgen.addTensor({{2, 3}, circle::TensorType::TensorType_FLOAT32});
188   int input2 = cgen.addTensor({{2, 3}, circle::TensorType::TensorType_FLOAT32});
189   int output = cgen.addTensor({{4, 3}, circle::TensorType::TensorType_FLOAT32});
190   int axis = 2;
191
192   cgen.addOperatorConcatenation({{input1, input2}, {output}}, axis,
193                                 circle::ActivationFunctionType_NONE);
194   cgen.setInputsAndOutputs({input1, input2}, {output});
195
196   _context = std::make_unique<GenModelTestContext>(cgen.finish());
197   _context->setBackends({"cpu"});
198   _context->expectFailCompile();
199
200   SUCCEED();
201 }
202
203 TEST_F(GenModelTest, neg_OneOp_Concat_InvalidRank)
204 {
205   CircleGen cgen;
206
207   int input1 = cgen.addTensor({{2, 3}, circle::TensorType::TensorType_FLOAT32});
208   int input2 = cgen.addTensor({{1, 2, 3}, circle::TensorType::TensorType_FLOAT32});
209   int output = cgen.addTensor({{1, 2, 3}, circle::TensorType::TensorType_FLOAT32});
210   int axis = 0;
211
212   cgen.addOperatorConcatenation({{input1, input2}, {output}}, axis,
213                                 circle::ActivationFunctionType_NONE);
214   cgen.setInputsAndOutputs({input1, input2}, {output});
215
216   _context = std::make_unique<GenModelTestContext>(cgen.finish());
217   _context->setBackends({"acl_cl", "acl_neon", "cpu"});
218   _context->expectFailCompile();
219
220   SUCCEED();
221 }
222
223 TEST_F(GenModelTest, neg_OneOp_Concat_InvalidDimension)
224 {
225   CircleGen cgen;
226
227   int input1 = cgen.addTensor({{2, 3}, circle::TensorType::TensorType_FLOAT32});
228   int input2 = cgen.addTensor({{3, 2}, circle::TensorType::TensorType_FLOAT32});
229   int output = cgen.addTensor({{4, 3}, circle::TensorType::TensorType_FLOAT32});
230   int axis = 0;
231
232   cgen.addOperatorConcatenation({{input1, input2}, {output}}, axis,
233                                 circle::ActivationFunctionType_NONE);
234   cgen.setInputsAndOutputs({input1, input2}, {output});
235
236   _context = std::make_unique<GenModelTestContext>(cgen.finish());
237   _context->setBackends({"acl_cl", "acl_neon", "cpu"});
238   _context->expectFailCompile();
239
240   SUCCEED();
241 }