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/add_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 AddFusionBuilderTest : public OpsTest {
28 public:
29     void SetUp() override;
30     void TearDown() override;
31 
32     void SaveParamsTensor(const std::vector<uint32_t>& m_param, OH_NN_DataType dataType,
33         const std::vector<int32_t> &dim,  const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
34 
35 public:
36     AddBuilder 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_param{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 AddFusionBuilderTest::SetUp() {}
46 
TearDown()47 void AddFusionBuilderTest::TearDown() {}
48 
SaveParamsTensor(const std::vector<uint32_t> & m_param,OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)49 void AddFusionBuilderTest::SaveParamsTensor(const std::vector<uint32_t>& m_param, OH_NN_DataType dataType,
50     const std::vector<int32_t> &dim,  const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
51 {
52     m_paramsIndex = m_param;
53     std::shared_ptr<NNTensor> tensor = TransToNNTensor(dataType, dim, quantParam, type);
54     int8_t* activationValue = new (std::nothrow) int8_t(0);
55     EXPECT_NE(nullptr, activationValue);
56     tensor->SetBuffer(activationValue, sizeof(int8_t));
57     m_allTensors.emplace_back(tensor);
58 }
59 
60 /**
61  * @tc.name: add_build_001
62  * @tc.desc: Verify the success of the build function
63  * @tc.type: FUNC
64  */
65 HWTEST_F(AddFusionBuilderTest, add_build_001, TestSize.Level1)
66 {
67     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
68     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
69     SaveParamsTensor(m_param, OH_NN_INT8, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
70 
71     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
72 }
73 
74 /**
75  * @tc.name: add_build_002
76  * @tc.desc: Verify the forbidden of the build function
77  * @tc.type: FUNC
78  */
79 HWTEST_F(AddFusionBuilderTest, add_build_002, TestSize.Level1)
80 {
81     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
82     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
83     SaveParamsTensor(m_param, OH_NN_INT8, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
84 
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: add_build_003
91  * @tc.desc: Verify the missing input of the build function
92  * @tc.type: FUNC
93  */
94 HWTEST_F(AddFusionBuilderTest, add_build_003, TestSize.Level1)
95 {
96     m_inputs = {0};
97     m_outputs = {1};
98     m_param = {2};
99 
100     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
101     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
102     SaveParamsTensor(m_param, OH_NN_INT8, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
103 
104     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
105 }
106 
107 /**
108  * @tc.name: add_build_004
109  * @tc.desc: Verify the missing output of the build function
110  * @tc.type: FUNC
111  */
112 HWTEST_F(AddFusionBuilderTest, add_build_004, TestSize.Level1)
113 {
114     m_inputs = {0, 1};
115     m_outputs = {};
116     m_param = {2};
117 
118     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
119     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
120     SaveParamsTensor(m_param, OH_NN_INT8, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
121 
122     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
123 }
124 
125 /**
126  * @tc.name: add_build_005
127  * @tc.desc: Verify the inputIndex out of bounds of the build function
128  * @tc.type: FUNC
129  */
130 HWTEST_F(AddFusionBuilderTest, add_build_005, TestSize.Level1)
131 {
132     m_inputs = {0, 6};
133     m_outputs = {2};
134     m_param = {3};
135 
136     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
137     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
138     SaveParamsTensor(m_param, OH_NN_INT8, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
139 
140     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
141 }
142 
143 /**
144  * @tc.name: add_build_006
145  * @tc.desc: Verify the outputIndex out of bounds of the build function
146  * @tc.type: FUNC
147  */
148 HWTEST_F(AddFusionBuilderTest, add_build_006, TestSize.Level1)
149 {
150     m_inputs = {0, 1};
151     m_outputs = {6};
152     m_param = {3};
153 
154     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
155     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
156     SaveParamsTensor(m_param, OH_NN_INT8, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
157 
158     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
159 }
160 
161 /**
162  * @tc.name: add_build_007
163  * @tc.desc: Verify the param invalid type of the build function
164  * @tc.type: FUNC
165  */
166 HWTEST_F(AddFusionBuilderTest, add_build_007, TestSize.Level1)
167 {
168     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
169     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
170 
171     m_paramsIndex = m_param;
172     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT32, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
173     int32_t* activationValueTest = new (std::nothrow) int32_t(0);
174     EXPECT_NE(nullptr, activationValueTest);
175     tensor->SetBuffer(activationValueTest, sizeof(int32_t));
176     m_allTensors.emplace_back(tensor);
177 
178     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
179 }
180 
181 /**
182  * @tc.name: add_build_008
183  * @tc.desc: Verify the param invalid value of the build function
184  * @tc.type: FUNC
185  */
186 HWTEST_F(AddFusionBuilderTest, add_build_008, TestSize.Level1)
187 {
188     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
189     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
190 
191     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
192     int8_t* activationValueTest = new (std::nothrow) int8_t(40);
193     EXPECT_NE(nullptr, activationValueTest);
194     tensor->SetBuffer(activationValueTest, sizeof(int8_t));
195     m_allTensors.emplace_back(tensor);
196 
197     m_paramsIndex = m_param;
198     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
199 }
200 
201 /**
202  * @tc.name: add_build_009
203  * @tc.desc: Verify the param invalid to add of the build function
204  * @tc.type: FUNC
205  */
206 HWTEST_F(AddFusionBuilderTest, add_build_009, TestSize.Level1)
207 {
208     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
209     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
210 
211     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ARG_MAX_KEEPDIMS);
212     int8_t* activationValueTest = new (std::nothrow) int8_t(0);
213     EXPECT_NE(nullptr, activationValueTest);
214     tensor->SetBuffer(activationValueTest, sizeof(int8_t));
215     m_allTensors.emplace_back(tensor);
216 
217     m_paramsIndex = m_param;
218     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
219 }
220 
221 /**
222  * @tc.name: add_build_010
223  * @tc.desc: Verify the param invalid to add of the build function
224  * @tc.type: FUNC
225  */
226 HWTEST_F(AddFusionBuilderTest, add_build_010, TestSize.Level1)
227 {
228     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
229     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
230 
231     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
232     m_allTensors.emplace_back(tensor);
233 
234     m_paramsIndex = m_param;
235     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
236 }
237 
238 /**
239  * @tc.name: add_getprimitive_001
240  * @tc.desc: Verify the success of the GetPrimitive function
241  * @tc.type: FUNC
242  */
243 HWTEST_F(AddFusionBuilderTest, add_getprimitive_001, TestSize.Level1)
244 {
245     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
246     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
247     SaveParamsTensor(m_param, OH_NN_INT8, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
248 
249     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
250     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
251     LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
252     EXPECT_NE(expectPrimitive, primitive);
253 
254     int8_t activationValueTest = 0;
255     int8_t returnValue = mindspore::lite::MindIR_AddFusion_GetActivationType(primitive.get());
256     EXPECT_EQ(returnValue, activationValueTest);
257 }
258 
259 /**
260  * @tc.name: add_getprimitive_002
261  * @tc.desc: Verify the nullptr return of the GetPrimitive function
262  * @tc.type: FUNC
263  */
264 HWTEST_F(AddFusionBuilderTest, add_getprimitive_002, TestSize.Level1)
265 {
266     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
267     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
268     SaveParamsTensor(m_param, OH_NN_INT8, m_param_dim, nullptr, OH_NN_ADD_ACTIVATIONTYPE);
269 
270     LiteGraphTensorPtr primitive = {nullptr, DestroyLiteGraphPrimitive};
271     LiteGraphTensorPtr expectPrimitive = m_builder.GetPrimitive();
272 
273     EXPECT_EQ(primitive, expectPrimitive);
274 }
275 } // namespace UnitTest
276 } // namespace NeuralNetworkRuntime
277 } // namespace OHOS