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 ConcatBuilderTest : 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, 2};
38     std::vector<uint32_t> m_outputs{3};
39     std::vector<uint32_t> m_params{4};
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 ConcatBuilderTest::SetUp() {}
46 
TearDown()47 void ConcatBuilderTest::TearDown() {}
48 
SetAxis(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)49 void ConcatBuilderTest::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     tensor->SetBuffer(axisValue, sizeof(int64_t));
56     m_allTensors.emplace_back(tensor);
57 }
58 
59 /**
60  * @tc.name: concat_build_three_input_001
61  * @tc.desc: Verify the success of the build function
62  * @tc.type: FUNC
63  */
64 HWTEST_F(ConcatBuilderTest, concat_build_three_input_001, TestSize.Level1)
65 {
66     m_paramsIndex = m_params;
67     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
68     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
69     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
70     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
71 }
72 
73 /**
74  * @tc.name: concat_build_three_input_002
75  * @tc.desc: Verify the forbidden of the build function
76  * @tc.type: FUNC
77  */
78 HWTEST_F(ConcatBuilderTest, concat_build_three_input_002, TestSize.Level1)
79 {
80     m_paramsIndex = m_params;
81     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
82     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
83 
84     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
85     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
86     EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
87 }
88 
89 /**
90  * @tc.name: concat_build_three_input_003
91  * @tc.desc: Verify the missing input of the build function
92  * @tc.type: FUNC
93  */
94 HWTEST_F(ConcatBuilderTest, concat_build_three_input_003, TestSize.Level1)
95 {
96     m_inputs = {0};
97     m_outputs = {1};
98     m_params = {2};
99     m_paramsIndex = m_params;
100     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
101     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
102 
103     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
104     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
105 }
106 
107 /**
108  * @tc.name: concat_build_three_input_004
109  * @tc.desc: Verify the missing output of the build function
110  * @tc.type: FUNC
111  */
112 HWTEST_F(ConcatBuilderTest, concat_build_three_input_004, TestSize.Level1)
113 {
114     m_inputs = {0, 1, 2};
115     m_outputs = {};
116     m_params = {3};
117     m_paramsIndex = m_params;
118     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
119     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
120 
121     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
122     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
123 }
124 
125 /**
126  * @tc.name: concat_build_three_input_005
127  * @tc.desc: Verify the inputIndex out of bounds of the build function
128  * @tc.type: FUNC
129  */
130 HWTEST_F(ConcatBuilderTest, concat_build_three_input_005, TestSize.Level1)
131 {
132     m_outputs = {3};
133     m_params = {4};
134     m_inputs = {0, 1, 6};
135     m_paramsIndex = m_params;
136     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
137     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
138 
139     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
140     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
141 }
142 
143 /**
144  * @tc.name: concat_build_three_input_007
145  * @tc.desc: Verify the invalid axis of the build function
146  * @tc.type: FUNC
147  */
148 HWTEST_F(ConcatBuilderTest, concat_build_three_input_007, TestSize.Level1)
149 {
150     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
151     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
152 
153     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT32, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
154     m_paramsIndex = m_params;
155     int32_t* axisValue = new (std::nothrow) int32_t(0);
156     EXPECT_NE(nullptr, axisValue);
157 
158     tensor->SetBuffer(axisValue, sizeof(int32_t));
159     m_allTensors.emplace_back(tensor);
160     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
161 }
162 
163 /**
164  * @tc.name: concat_build_three_input_008
165  * @tc.desc: Verify the scalar length of the build function
166  * @tc.type: FUNC
167  */
168 HWTEST_F(ConcatBuilderTest, concat_build_three_input_008, TestSize.Level1)
169 {
170     m_paramsIndex = m_params;
171     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
172     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
173     m_param_dim = {2};
174 
175     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
176     int64_t* axisValue = new (std::nothrow) int64_t[2]{0, 0};
177     EXPECT_NE(nullptr, axisValue);
178 
179     tensor->SetBuffer(axisValue, 2 * sizeof(int64_t));
180     m_allTensors.emplace_back(tensor);
181     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
182 }
183 
184 /**
185  * @tc.name: concat_build_three_input_009
186  * @tc.desc: Verify the invalid param to concat of the build function
187  * @tc.type: FUNC
188  */
189 HWTEST_F(ConcatBuilderTest, concat_build_three_input_009, TestSize.Level1)
190 {
191     m_param_dim = {2};
192     m_paramsIndex = m_params;
193     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
194     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
195 
196     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONV2D_STRIDES);
197     int64_t* axisValue = new (std::nothrow) int64_t[2]{0, 0};
198     EXPECT_NE(nullptr, axisValue);
199 
200     tensor->SetBuffer(axisValue, 2 * sizeof(int64_t));
201     m_allTensors.emplace_back(tensor);
202     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
203 }
204 
205 /**
206  * @tc.name: concat_getprimitive_three_input_001
207  * @tc.desc: Verify the success of the GetPrimitive function
208  * @tc.type: FUNC
209  */
210 HWTEST_F(ConcatBuilderTest, concat_getprimitive_three_input_001, TestSize.Level1)
211 {
212     m_paramsIndex = m_params;
213     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
214     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
215 
216     SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
217     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
218     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
219     LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
220     EXPECT_NE(expectPrimitive, primitive);
221 
222     int64_t expectValue = mindspore::lite::MindIR_Concat_GetAxis(primitive.get());
223     EXPECT_EQ(expectValue, 0);
224 }
225 
226 /**
227  * @tc.name: concat_getprimitive_three_input_002
228  * @tc.desc: Verify the nullptr return of the GetPrimitive function
229  * @tc.type: FUNC
230  */
231 HWTEST_F(ConcatBuilderTest, concat_getprimitive_three_input_002, 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     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
239     LiteGraphTensorPtr returnPrimitive = {nullptr, DestroyLiteGraphPrimitive};
240     EXPECT_EQ(returnPrimitive, primitive);
241 }
242 } // namespace UnitTest
243 } // namespace NeuralNetworkRuntime
244 } // namespace OHOS
245