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 "frameworks/native/ops/fullconnection_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 FullConnectionAxisBuilderTest : public OpsTest {
28 public:
29 void SetUp();
30 void TearDown();
31
32 void SetInputToAlltensor();
33 void SetActivation(OH_NN_DataType dataType,
34 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35 void SeAxis(OH_NN_DataType dataType,
36 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
37
38 public:
39 FullConnectionBuilder m_builder;
40 std::vector<uint32_t> m_inputs {0, 1, 2};
41 std::vector<uint32_t> m_outputs {3};
42 std::vector<uint32_t> m_params {4, 5};
43 std::vector<int32_t> m_output_dim {2, 2};
44 std::vector<int32_t> m_param_dim {};
45 };
46
SetUp()47 void FullConnectionAxisBuilderTest::SetUp() {}
48
TearDown()49 void FullConnectionAxisBuilderTest::TearDown() {}
50
SetInputToAlltensor()51 void FullConnectionAxisBuilderTest::SetInputToAlltensor()
52 {
53 std::vector<int32_t> m_input_dim{2, 2};
54 std::vector<int32_t> biasDim{2};
55 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_FLOAT32, m_input_dim, nullptr, OH_NN_TENSOR);
56 m_allTensors.emplace_back(tensor);
57 int32_t weightNum = 4;
58 int32_t biasNum = 2;
59 tensor = TransToNNTensor(OH_NN_FLOAT32, m_input_dim, nullptr, OH_NN_TENSOR);
60 float* valueWeight = new (std::nothrow) float[4]{1, 1, 1, 1};
61 EXPECT_NE(nullptr, valueWeight);
62 tensor->SetBuffer(valueWeight, weightNum * sizeof(float));
63 m_allTensors.emplace_back(tensor);
64
65 tensor = TransToNNTensor(OH_NN_FLOAT32, biasDim, nullptr, OH_NN_TENSOR);
66 float* valueBias = new (std::nothrow) float[2]{0, 0};
67 EXPECT_NE(nullptr, valueBias);
68 tensor->SetBuffer(valueBias, biasNum * sizeof(float));
69 m_allTensors.emplace_back(tensor);
70 }
71
SetActivation(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)72 void FullConnectionAxisBuilderTest::SetActivation(OH_NN_DataType dataType,
73 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
74 {
75 std::shared_ptr<NNTensor> tensor = TransToNNTensor(dataType, dim, quantParam, type);
76 int8_t* activationValue = new (std::nothrow) int8_t(0);
77 EXPECT_NE(nullptr, activationValue);
78
79 tensor->SetBuffer(activationValue, sizeof(int8_t));
80 m_allTensors.emplace_back(tensor);
81 }
82
SeAxis(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)83 void FullConnectionAxisBuilderTest::SeAxis(OH_NN_DataType dataType,
84 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
85 {
86 std::shared_ptr<NNTensor> tensor = TransToNNTensor(dataType, dim, quantParam, type);
87 int64_t* axisValue = new (std::nothrow) int64_t(0);
88 EXPECT_NE(nullptr, axisValue);
89
90 tensor->SetBuffer(axisValue, sizeof(int64_t));
91 m_allTensors.emplace_back(tensor);
92 }
93
94 /**
95 * @tc.name: fullconnection_build_axis_001
96 * @tc.desc: Verify the behavior of the build function
97 * @tc.type: FUNC
98 */
99 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_build_axis_001, TestSize.Level1)
100 {
101 m_inputsIndex = m_inputs;
102 m_paramsIndex = m_params;
103 SetInputToAlltensor();
104 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
105
106 SeAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
107 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
108 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
109 }
110
111 /**
112 * @tc.name: fullconnection_build_axis_002
113 * @tc.desc: Verify the behavior of the build function
114 * @tc.type: FUNC
115 */
116 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_build_axis_002, TestSize.Level1)
117 {
118 m_inputsIndex = m_inputs;
119 m_paramsIndex = m_params;
120 SetInputToAlltensor();
121 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
122
123 SeAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
124 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
125 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
126 EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
127 }
128
129 /**
130 * @tc.name: fullconnection_build_axis_003
131 * @tc.desc: Verify the missing output of the build function
132 * @tc.type: FUNC
133 */
134 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_build_axis_003, TestSize.Level1)
135 {
136 m_outputs = {};
137 m_inputsIndex = m_inputs;
138 m_paramsIndex = m_params;
139 SetInputToAlltensor();
140
141 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
142 SeAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
143 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
144 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
145 }
146
147 /**
148 * @tc.name: fullconnection_build_axis_004
149 * @tc.desc: Verify the inputIndex out of bounds of the build function
150 * @tc.type: FUNC
151 */
152 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_build_axis_004, TestSize.Level1)
153 {
154 m_inputs = {0, 1, 6};
155 m_inputsIndex = m_inputs;
156 m_paramsIndex = m_params;
157 SetInputToAlltensor();
158
159 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
160 SeAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
161 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
162 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
163 }
164
165 /**
166 * @tc.name: fullconnection_build_axis_005
167 * @tc.desc: Verify the invalid axis of the build function
168 * @tc.type: FUNC
169 */
170 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_build_axis_005, TestSize.Level1)
171 {
172 m_inputsIndex = m_inputs;
173 m_paramsIndex = m_params;
174 SetInputToAlltensor();
175
176 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
177 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT32, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
178 int32_t *axisValueTest = new (std::nothrow) int32_t(0);
179 EXPECT_NE(nullptr, axisValueTest);
180
181 tensor->SetBuffer(axisValueTest, sizeof(int32_t));
182 m_allTensors.emplace_back(tensor);
183 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
184 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
185 }
186
187 /**
188 * @tc.name: fullconnection_build_axis_006
189 * @tc.desc: Verify the behavior of the build function
190 * @tc.type: FUNC
191 */
192 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_build_axis_006, TestSize.Level1)
193 {
194 m_inputsIndex = m_inputs;
195 m_paramsIndex = m_params;
196 SetInputToAlltensor();
197
198 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
199 SeAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
200 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT32, m_param_dim, nullptr,
201 OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
202 int32_t *activationValue = new (std::nothrow) int32_t(0);
203 EXPECT_NE(nullptr, activationValue);
204
205 tensor->SetBuffer(activationValue, sizeof(int32_t));
206 m_allTensors.emplace_back(tensor);
207 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
208 }
209
210 /**
211 * @tc.name: fullconnection_build_axis_007
212 * @tc.desc: Verify the behavior of the build function
213 * @tc.type: FUNC
214 */
215 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_build_axis_007, TestSize.Level1)
216 {
217 std::vector<int32_t> paramDimTest = {2};
218 m_inputsIndex = m_inputs;
219 m_paramsIndex = m_params;
220
221 SetInputToAlltensor();
222 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
223 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT64, paramDimTest, nullptr,
224 OH_NN_FULL_CONNECTION_AXIS);
225 int64_t *axisValueTest = new (std::nothrow) int64_t[2]{0, 0};
226 EXPECT_NE(nullptr, axisValueTest);
227
228 tensor->SetBuffer(axisValueTest, 2 * sizeof(int64_t));
229 m_allTensors.emplace_back(tensor);
230 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
231 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
232 }
233
234 /**
235 * @tc.name: fullconnection_build_axis_008
236 * @tc.desc: Verify the behavior of the build function
237 * @tc.type: FUNC
238 */
239 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_build_axis_008, TestSize.Level1)
240 {
241 std::vector<int32_t> paramDimTest = {2};
242 m_inputsIndex = m_inputs;
243 m_paramsIndex = m_params;
244 SetInputToAlltensor();
245
246 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
247 SeAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
248 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, paramDimTest, nullptr,
249 OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
250 int8_t *activationValue = new (std::nothrow) int8_t[2]{0, 0};
251 EXPECT_NE(nullptr, activationValue);
252
253 tensor->SetBuffer(activationValue, 2 * sizeof(int8_t));
254 m_allTensors.emplace_back(tensor);
255 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
256 }
257
258 /**
259 * @tc.name: fullconnection_build_axis_009
260 * @tc.desc: Verify the fullconnection without set axis of the build function
261 * @tc.type: FUNC
262 */
263 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_build_axis_009, TestSize.Level1)
264 {
265 m_inputsIndex = m_inputs;
266 m_paramsIndex = m_params;
267 SetInputToAlltensor();
268
269 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
270 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT64, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
271 m_allTensors.emplace_back(tensor);
272 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
273 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
274 }
275
276 /**
277 * @tc.name: fullconnection_build_axis_010
278 * @tc.desc: Verify the fullconnection without set activation of the build function
279 * @tc.type: FUNC
280 */
281 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_build_axis_010, TestSize.Level1)
282 {
283 m_inputsIndex = m_inputs;
284 m_paramsIndex = m_params;
285 SetInputToAlltensor();
286
287 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
288 SeAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
289 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr,
290 OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
291 m_allTensors.emplace_back(tensor);
292 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
293 }
294
295 /**
296 * @tc.name: fullconnection_getprimitive_axis_001
297 * @tc.desc: Verify the behavior of the GetPrimitive function
298 * @tc.type: FUNC
299 */
300 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_getprimitive_axis_001, TestSize.Level1)
301 {
302 m_inputsIndex = m_inputs;
303 m_paramsIndex = m_params;
304 SetInputToAlltensor();
305 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
306 SeAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
307 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
308 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
309
310 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
311 LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
312 EXPECT_NE(expectPrimitive, primitive);
313
314 int returnValue = mindspore::lite::MindIR_FullConnection_GetAxis(primitive.get());
315 EXPECT_EQ(returnValue, 0);
316 bool activationReturn = mindspore::lite::MindIR_FullConnection_GetActivationType(primitive.get());
317 EXPECT_EQ(activationReturn, 0);
318 }
319
320 /**
321 * @tc.name: fullconnection_getprimitive_axis_002
322 * @tc.desc: Verify the behavior of the GetPrimitive function
323 * @tc.type: FUNC
324 */
325 HWTEST_F(FullConnectionAxisBuilderTest, fullconnection_getprimitive_axis_002, TestSize.Level1)
326 {
327 m_inputsIndex = m_inputs;
328 m_paramsIndex = m_params;
329 SetInputToAlltensor();
330
331 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
332 SeAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_AXIS);
333 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
334
335 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
336 LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
337 EXPECT_EQ(expectPrimitive, primitive);
338 }
339 } // namespace UnitTest
340 } // namespace NeuralNetworkRuntime
341 } // namespace OHOS