1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ops/concat_builder.h"
17 
18 #include "ops_test.h"
19 
20 using namespace testing;
21 using namespace testing::ext;
22 using namespace OHOS::NeuralNetworkRuntime::Ops;
23 
24 namespace OHOS {
25 namespace NeuralNetworkRuntime {
26 namespace UnitTest {
27 class ConcatTwoInputBuilderTest : public OpsTest {
28 public:
29     void SetUp() override;
30     void TearDown() override;
31 
32     void SetAxis(OH_NN_DataType dataType,
33         const std::vector<int32_t> &dim,  const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
34 
35 public:
36     ConcatBuilder m_builder;
37     std::vector<uint32_t> m_inputs{0, 1};
38     std::vector<uint32_t> m_outputs{2};
39     std::vector<uint32_t> m_params{3};
40     std::vector<int32_t> m_input_dim{3, 3};
41     std::vector<int32_t> m_output_dim{3, 3};
42     std::vector<int32_t> m_param_dim{};
43 };
44 
SetUp()45 void ConcatTwoInputBuilderTest::SetUp() {}
46 
TearDown()47 void ConcatTwoInputBuilderTest::TearDown() {}
48 
SetAxis(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)49 void ConcatTwoInputBuilderTest::SetAxis(OH_NN_DataType dataType,
50     const std::vector<int32_t> &dim,  const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
51 {
52     std::shared_ptr<NNTensor> tensor = TransToNNTensor(dataType, dim, quantParam, type);
53     int64_t* axisValue = new (std::nothrow) int64_t(0);
54     EXPECT_NE(nullptr, axisValue);
55 
56     tensor->SetBuffer(axisValue, sizeof(int64_t));
57     m_allTensors.emplace_back(tensor);
58 }
59 
60 /**
61  * @tc.name: concat_build_two_input_001
62  * @tc.desc: Verify the success of the build function
63  * @tc.type: FUNC
64  */
65 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_001, TestSize.Level1)
66 {
67     m_paramsIndex = m_params;
68     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
69     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
70 
71     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
72     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
73 }
74 
75 /**
76  * @tc.name: concat_build_two_input_002
77  * @tc.desc: Verify the forbidden of the build function
78  * @tc.type: FUNC
79  */
80 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_002, TestSize.Level1)
81 {
82     m_paramsIndex = m_params;
83     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
84     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
85 
86     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
87     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
88     EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
89 }
90 
91 /**
92  * @tc.name: concat_build_two_input_003
93  * @tc.desc: Verify the missing input of the build function
94  * @tc.type: FUNC
95  */
96 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_003, TestSize.Level1)
97 {
98     m_inputs = {0};
99     m_outputs = {2};
100     m_params = {3};
101     m_paramsIndex = m_params;
102 
103     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
104     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
105 
106     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
107     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
108 }
109 
110 /**
111  * @tc.name: concat_build_two_input_004
112  * @tc.desc: Verify the missing output of the build function
113  * @tc.type: FUNC
114  */
115 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_004, TestSize.Level1)
116 {
117     m_inputs = {0, 1};
118     m_outputs = {};
119     m_params = {3};
120     m_paramsIndex = m_params;
121 
122     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
123     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
124 
125     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
126     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
127 }
128 
129 /**
130  * @tc.name: concat_build_two_input_005
131  * @tc.desc: Verify the inputIndex out of bounds of the build function
132  * @tc.type: FUNC
133  */
134 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_005, TestSize.Level1)
135 {
136     m_inputs = {0, 1, 6};
137     m_outputs = {3};
138     m_params = {4};
139     m_paramsIndex = m_params;
140 
141     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
142     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
143 
144     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
145     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
146 }
147 
148 /**
149  * @tc.name: concat_build_two_input_006
150  * @tc.desc: Verify the outputIndex out of bounds of the build function
151  * @tc.type: FUNC
152  */
153 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_006, TestSize.Level1)
154 {
155     m_inputs = {0, 1};
156     m_outputs = {6};
157     m_params = {3};
158     m_paramsIndex = m_params;
159 
160     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
161     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
162 
163     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
164     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
165 }
166 
167 /**
168  * @tc.name: concat_build_two_input_007
169  * @tc.desc: Verify the invalid axis of the build function
170  * @tc.type: FUNC
171  */
172 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_007, TestSize.Level1)
173 {
174     m_paramsIndex = m_params;
175     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
176     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
177 
178     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT32, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
179     int32_t* axisValue = new (std::nothrow) int32_t(0);
180     EXPECT_NE(nullptr, axisValue);
181 
182     tensor->SetBuffer(axisValue, sizeof(int32_t));
183     m_allTensors.emplace_back(tensor);
184     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
185 }
186 
187 /**
188  * @tc.name: concat_build_two_input_008
189  * @tc.desc: Verify the scalar length of the build function
190  * @tc.type: FUNC
191  */
192 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_008, TestSize.Level1)
193 {
194     m_param_dim = {2};
195     m_paramsIndex = m_params;
196 
197     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
198     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
199 
200     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
201     int64_t* axisValue = new (std::nothrow) int64_t[2]{0, 0};
202     EXPECT_NE(nullptr, axisValue);
203 
204     tensor->SetBuffer(axisValue, 2 * sizeof(int64_t));
205     m_allTensors.emplace_back(tensor);
206     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
207 }
208 
209 /**
210  * @tc.name: concat_build_two_input_009
211  * @tc.desc: This is OH_NN_INVALID_PARAMETER case, course the value of axis is nullptr.
212  * @tc.type: FUNC
213  */
214 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_010, TestSize.Level1)
215 {
216     m_paramsIndex = m_params;
217     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
218     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
219 
220     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
221     m_allTensors.emplace_back(tensor);
222 
223     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
224 }
225 
226 /**
227  * @tc.name: concat_getprimitive_two_input_001
228  * @tc.desc: Verify the success of the GetPrimitive function
229  * @tc.type: FUNC
230  */
231 HWTEST_F(ConcatTwoInputBuilderTest, concat_getprimitive_two_input_001, TestSize.Level1)
232 {
233     m_paramsIndex = m_params;
234     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
235     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
236 
237     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
238     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
239     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
240     LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
241     EXPECT_NE(expectPrimitive, primitive);
242 
243     int64_t returnValue = mindspore::lite::MindIR_Concat_GetAxis(primitive.get());
244     EXPECT_EQ(returnValue, 0);
245 }
246 
247 /**
248  * @tc.name: concat_getprimitive_two_input_001
249  * @tc.desc: Verify the nullptr return of the GetPrimitive function
250  * @tc.type: FUNC
251  */
252 HWTEST_F(ConcatTwoInputBuilderTest, concat_getprimitive_two_input_002, TestSize.Level1)
253 {
254     m_paramsIndex = m_params;
255     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
256     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
257 
258     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
259     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
260     LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
261     EXPECT_EQ(expectPrimitive, primitive);
262 }
263 } // namespace UnitTest
264 } // namespace NeuralNetworkRuntime
265 } // namespace OHOS