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
25 namespace OHOS {
26 namespace NeuralNetworkRuntime {
27 namespace UnitTest {
28 class FullConnectionBuilderTest : public OpsTest {
29 public:
30 void SetUp() override;
31 void TearDown() override;
32
33 void SetInputToAlltensor();
34 void SetActivation(OH_NN_DataType dataType,
35 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
36
37 public:
38 FullConnectionBuilder m_builder;
39 std::vector<uint32_t> m_inputs {0, 1, 2};
40 std::vector<uint32_t> m_outputs {3};
41 std::vector<uint32_t> m_params {4};
42 std::vector<int32_t> m_output_dim {2, 2};
43 std::vector<int32_t> m_param_dim {};
44 };
45
SetUp()46 void FullConnectionBuilderTest::SetUp() {}
47
TearDown()48 void FullConnectionBuilderTest::TearDown() {}
49
SetInputToAlltensor()50 void FullConnectionBuilderTest::SetInputToAlltensor()
51 {
52 std::vector<int32_t> m_input_dim{2, 2};
53 std::vector<int32_t> biasDim = {2};
54 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_FLOAT32, m_input_dim, nullptr, OH_NN_TENSOR);
55 m_allTensors.emplace_back(tensor);
56
57 int32_t numWeight = 4;
58 int32_t numBias = 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
63 tensor->SetBuffer(valueWeight, numWeight * sizeof(float));
64 m_allTensors.emplace_back(tensor);
65
66 tensor = TransToNNTensor(OH_NN_FLOAT32, biasDim, nullptr, OH_NN_TENSOR);
67 float* valueBias = new (std::nothrow) float[2]{0, 0};
68 EXPECT_NE(nullptr, valueBias);
69 tensor->SetBuffer(valueBias, numBias * sizeof(float));
70 m_allTensors.emplace_back(tensor);
71 }
72
SetActivation(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)73 void FullConnectionBuilderTest::SetActivation(OH_NN_DataType dataType,
74 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
75 {
76 std::shared_ptr<NNTensor> tensor = TransToNNTensor(dataType, dim, quantParam, type);
77 int8_t* activationValue = new (std::nothrow) int8_t(0);
78 EXPECT_NE(nullptr, activationValue);
79
80 tensor->SetBuffer(activationValue, sizeof(int8_t));
81 m_allTensors.emplace_back(tensor);
82 }
83
84 /**
85 * @tc.name: fullconnection_build_001
86 * @tc.desc: Verify the success of the build function
87 * @tc.type: FUNC
88 */
89 HWTEST_F(FullConnectionBuilderTest, fullconnection_build_001, TestSize.Level1)
90 {
91 m_inputsIndex = m_inputs;
92 m_paramsIndex = m_params;
93 SetInputToAlltensor();
94
95 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
96 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
97 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
98 }
99
100 /**
101 * @tc.name: fullconnection_build_002
102 * @tc.desc: Verify the forbidden of the build function
103 * @tc.type: FUNC
104 */
105 HWTEST_F(FullConnectionBuilderTest, fullconnection_build_002, TestSize.Level1)
106 {
107 m_inputsIndex = m_inputs;
108 m_paramsIndex = m_params;
109 SetInputToAlltensor();
110
111 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
112 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
113 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
114 EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
115 }
116
117 /**
118 * @tc.name: fullconnection_build_003
119 * @tc.desc: Verify the missing output of the build function
120 * @tc.type: FUNC
121 */
122 HWTEST_F(FullConnectionBuilderTest, fullconnection_build_003, TestSize.Level1)
123 {
124 m_outputs = {};
125 m_params = {3};
126 m_inputsIndex = m_inputs;
127 m_paramsIndex = m_params;
128 SetInputToAlltensor();
129
130 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
131 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
132 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
133 }
134
135 /**
136 * @tc.name: fullconnection_build_004
137 * @tc.desc: Verify the inputIndex out of bounds of the build function
138 * @tc.type: FUNC
139 */
140 HWTEST_F(FullConnectionBuilderTest, fullconnection_build_004, TestSize.Level1)
141 {
142 m_inputs = {0, 1, 6};
143 m_outputs = {3};
144 m_params = {4};
145
146 m_inputsIndex = m_inputs;
147 m_paramsIndex = m_params;
148 SetInputToAlltensor();
149
150 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
151 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
152 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
153 }
154
155 /**
156 * @tc.name: fullconnection_build_005
157 * @tc.desc: Verify the behavior of the build function
158 * @tc.type: FUNC
159 */
160
161 HWTEST_F(FullConnectionBuilderTest, fullconnection_build_005, TestSize.Level1)
162 {
163 m_inputsIndex = m_inputs;
164 m_paramsIndex = m_params;
165 SetInputToAlltensor();
166
167 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
168 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT32, m_param_dim, nullptr,
169 OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
170 int32_t *activationValue = new (std::nothrow) int32_t(0);
171 EXPECT_NE(nullptr, activationValue);
172
173 tensor->SetBuffer(activationValue, sizeof(int32_t));
174 m_allTensors.emplace_back(tensor);
175 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
176 }
177
178 /**
179 * @tc.name: fullconnection_build_006
180 * @tc.desc: Verify the behavior of the build function
181 * @tc.type: FUNC
182 */
183
184 HWTEST_F(FullConnectionBuilderTest, fullconnection_build_006, TestSize.Level1)
185 {
186 m_param_dim = {2};
187 m_inputsIndex = m_inputs;
188 m_paramsIndex = m_params;
189 SetInputToAlltensor();
190
191 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
192 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr,
193 OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
194 int8_t *activationValue = new (std::nothrow) int8_t[2]{0, 0};
195 EXPECT_NE(nullptr, activationValue);
196
197 tensor->SetBuffer(activationValue, 2 * sizeof(int8_t));
198 m_allTensors.emplace_back(tensor);
199 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
200 }
201
202 /**
203 * @tc.name: fullconnection_build_007
204 * @tc.desc: Verify the invalid avtivation value of the build function
205 * @tc.type: FUNC
206 */
207
208 HWTEST_F(FullConnectionBuilderTest, fullconnection_build_007, TestSize.Level1)
209 {
210 m_inputsIndex = m_inputs;
211 m_paramsIndex = m_params;
212 SetInputToAlltensor();
213
214 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
215 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr,
216 OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
217 int8_t *activationValue = new (std::nothrow) int8_t(10);
218 EXPECT_NE(nullptr, activationValue);
219
220 tensor->SetBuffer(activationValue, sizeof(int8_t));
221 m_allTensors.emplace_back(tensor);
222 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
223 }
224
225 /**
226 * @tc.name: fullconnection_build_008
227 * @tc.desc: Verify the invalid param to fullconnection of the build function
228 * @tc.type: FUNC
229 */
230
231 HWTEST_F(FullConnectionBuilderTest, fullconnection_build_008, TestSize.Level1)
232 {
233 m_inputsIndex = m_inputs;
234 m_paramsIndex = m_params;
235 SetInputToAlltensor();
236
237 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
238 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr,
239 OH_NN_DIV_ACTIVATIONTYPE);
240 int8_t *activationValue = new (std::nothrow) int8_t(0);
241 EXPECT_NE(nullptr, activationValue);
242 tensor->SetBuffer(activationValue, sizeof(int8_t));
243
244 m_allTensors.emplace_back(tensor);
245 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
246 }
247
248 /**
249 * @tc.name: fullconnection_getprimitive_001
250 * @tc.desc: Verify the success of the GetPrimitive function
251 * @tc.type: FUNC
252 */
253 HWTEST_F(FullConnectionBuilderTest, fullconnection_getprimitive_001, TestSize.Level1)
254 {
255 m_inputsIndex = m_inputs;
256 m_paramsIndex = m_params;
257 SetInputToAlltensor();
258
259 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
260 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
261 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
262 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
263 LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
264 EXPECT_NE(expectPrimitive, primitive);
265
266 int8_t activationReturn = mindspore::lite::MindIR_FullConnection_GetActivationType(primitive.get());
267 EXPECT_EQ(activationReturn, 0);
268 }
269
270 /**
271 * @tc.name: fullconnection_getprimitive_002
272 * @tc.desc: Verify the nullptr return of the GetPrimitive function
273 * @tc.type: FUNC
274 */
275 HWTEST_F(FullConnectionBuilderTest, fullconnection_getprimitive_002, TestSize.Level1)
276 {
277 m_inputsIndex = m_inputs;
278 m_paramsIndex = m_params;
279 SetInputToAlltensor();
280
281 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
282 SetActivation(OH_NN_INT8, m_param_dim, nullptr, OH_NN_FULL_CONNECTION_ACTIVATIONTYPE);
283 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
284 LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
285 EXPECT_EQ(expectPrimitive, primitive);
286 }
287 } // namespace UnitTest
288 } // namespace NeuralNetworkRuntime
289 } // namespace OHOS