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/sub_builder.h"
17
18 #include <gtest/gtest.h>
19 #include "nn_tensor.h"
20 #include "ops_test.h"
21
22 using namespace testing;
23 using namespace testing::ext;
24 using namespace OHOS::NeuralNetworkRuntime::Ops;
25
26 namespace OHOS {
27 namespace NeuralNetworkRuntime {
28 namespace UnitTest {
29 class SubBuilderTest : public OpsTest {
30 protected:
31 void InitTensor(const std::vector<uint32_t>& inputsIndex,
32 const std::vector<uint32_t>& outputsIndex) override;
33 void SaveActivateTypeTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
34 const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35
36 protected:
37 SubBuilder m_builder;
38 int8_t m_expectActivationTypeValue {0};
39 };
40
SaveActivateTypeTensor(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)41 void SubBuilderTest::SaveActivateTypeTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
42 const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
43 {
44 std::shared_ptr<NNTensor> activationTypeTensor = TransToNNTensor(dataType, dim, quantParam, type);
45 int8_t* activationTypeValue = new (std::nothrow) int8_t[1]{OH_NN_FUSED_RELU6};
46 EXPECT_NE(nullptr, activationTypeValue);
47 activationTypeTensor->SetBuffer(activationTypeValue, sizeof(int8_t));
48 m_allTensors.emplace_back(activationTypeTensor);
49 m_expectActivationTypeValue = mindspore::lite::ACTIVATION_TYPE_RELU6;
50 }
51
InitTensor(const std::vector<uint32_t> & inputsIndex,const std::vector<uint32_t> & outputsIndex)52 void SubBuilderTest::InitTensor(const std::vector<uint32_t>& inputsIndex, const std::vector<uint32_t>& outputsIndex)
53 {
54 std::vector<uint32_t> paramsIndex = { 3 };
55 std::vector<int32_t> inputDim = {3};
56 std::vector<int32_t> OutputDim = {3};
57
58 m_paramsIndex = paramsIndex;
59 SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
60 SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
61 }
62
63 /**
64 * @tc.name: sub_build_001
65 * @tc.desc: Provide normal input, output, and parameters to verify the normal behavior of the Build function
66 * @tc.type: FUNC
67 */
68 HWTEST_F(SubBuilderTest, sub_build_001, TestSize.Level0)
69 {
70 std::vector<uint32_t> inputsIndex = { 0, 1 };
71 std::vector<uint32_t> outputsIndex = { 2 };
72 std::vector<int32_t> paramDim = {};
73
74 InitTensor(inputsIndex, outputsIndex);
75 SaveActivateTypeTensor(OH_NN_INT8, paramDim, nullptr, OH_NN_SUB_ACTIVATIONTYPE);
76
77 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
78 EXPECT_EQ(OH_NN_SUCCESS, ret);
79 }
80
81 /**
82 * @tc.name: sub_build_002
83 * @tc.desc: Call Build func twice to verify the abnormal behavior of the Build function
84 * @tc.type: FUNC
85 */
86 HWTEST_F(SubBuilderTest, sub_build_002, TestSize.Level0)
87 {
88 std::vector<uint32_t> inputsIndex = { 0, 1 };
89 std::vector<uint32_t> outputsIndex = { 2 };
90 std::vector<int32_t> paramDim = {};
91
92 InitTensor(inputsIndex, outputsIndex);
93 SaveActivateTypeTensor(OH_NN_INT8, paramDim, nullptr, OH_NN_SUB_ACTIVATIONTYPE);
94
95 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
96 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
97 EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, ret);
98 }
99
100 /**
101 * @tc.name: sub_build_003
102 * @tc.desc:Provide one more than normal input to verify the abnormal behavior of the Build function
103 * @tc.type: FUNC
104 */
105 HWTEST_F(SubBuilderTest, sub_build_003, TestSize.Level0)
106 {
107 std::vector<uint32_t> inputsIndex = { 0, 1, 2, 3 };
108 std::vector<uint32_t> outputsIndex = { 4 };
109 std::vector<int32_t> paramDim = {};
110
111 InitTensor(inputsIndex, outputsIndex);
112 SaveActivateTypeTensor(OH_NN_INT8, paramDim, nullptr, OH_NN_SUB_ACTIVATIONTYPE);
113
114 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
115 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
116 }
117
118 /**
119 * @tc.name: sub_build_004
120 * @tc.desc: Provide one more than normal output to verify the abnormal behavior of the Build function
121 * @tc.type: FUNC
122 */
123 HWTEST_F(SubBuilderTest, sub_build_004, TestSize.Level0)
124 {
125 std::vector<uint32_t> inputsIndex = { 0, 1 };
126 std::vector<uint32_t> outputsIndex = { 2, 3 };
127 std::vector<int32_t> paramDim = {};
128
129 InitTensor(inputsIndex, outputsIndex);
130 SaveActivateTypeTensor(OH_NN_INT8, paramDim, nullptr, OH_NN_SUB_ACTIVATIONTYPE);
131
132 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
133 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
134 }
135
136 /**
137 * @tc.name: sub_build_005
138 * @tc.desc: Provide empty input, output, and parameters to verify the abnormal behavior of the Build function
139 * @tc.type: FUNC
140 */
141 HWTEST_F(SubBuilderTest, sub_build_005, TestSize.Level0)
142 {
143 std::vector<uint32_t> inputsIndex = { 0, 1, 2 };
144 std::vector<uint32_t> outputsIndex = { 3 };
145 std::vector<uint32_t> paramsIndex = { 4 };
146
147 OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, inputsIndex, outputsIndex, m_allTensors);
148 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
149 }
150
151 /**
152 * @tc.name: sub_build_006
153 * @tc.desc: Provide empty output to verify the abnormal behavior of the Build function
154 * @tc.type: FUNC
155 */
156 HWTEST_F(SubBuilderTest, sub_build_006, TestSize.Level0)
157 {
158 std::vector<uint32_t> inputsIndex = { 0, 1, 2 };
159 std::vector<uint32_t> outputsIndex = {};
160 std::vector<int32_t> paramDim = {};
161
162 InitTensor(inputsIndex, outputsIndex);
163 SaveActivateTypeTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_SUB_ACTIVATIONTYPE);
164
165 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
166 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
167 }
168
169 /**
170 * @tc.name: sub_build_007
171 * @tc.desc: Provide param type error to verify the abnormal behavior of the Build function
172 * @tc.type: FUNC
173 */
174 HWTEST_F(SubBuilderTest, sub_build_007, TestSize.Level0)
175 {
176 std::vector<uint32_t> inputsIndex = { 0, 1 };
177 std::vector<uint32_t> outputsIndex = { 2 };
178 std::vector<int32_t> paramDim = {};
179
180 InitTensor(inputsIndex, outputsIndex);
181 SaveActivateTypeTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_SUB_ACTIVATIONTYPE);
182
183 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
184 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
185 }
186
187 /**
188 * @tc.name: sub_build_008
189 * @tc.desc:Provide param type error to verify the abnormal behavior of the Build function
190 * @tc.type: FUNC
191 */
192 HWTEST_F(SubBuilderTest, sub_build_008, TestSize.Level0)
193 {
194 std::vector<uint32_t> inputsIndex = { 0, 1 };
195 std::vector<uint32_t> outputsIndex = { 2 };
196 std::vector<int32_t> paramDim = {};
197
198 InitTensor(inputsIndex, outputsIndex);
199 SaveActivateTypeTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_SUB_ACTIVATIONTYPE);
200
201 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
202 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
203 }
204
205 /**
206 * @tc.name: sub_build_009
207 * @tc.desc: Provide activate type parameter buffer is nullptr to verify the abnormal behavior of the Build function
208 * @tc.type: FUNC
209 */
210 HWTEST_F(SubBuilderTest, sub_build_009, TestSize.Level0)
211 {
212 std::vector<uint32_t> inputsIndex = { 0, 1 };
213 std::vector<uint32_t> outputsIndex = { 2 };
214 std::vector<int32_t> paramDim = {};
215
216 InitTensor(inputsIndex, outputsIndex);
217
218 std::shared_ptr<NNTensor> activationTypeTensor = TransToNNTensor(OH_NN_INT8, paramDim, nullptr,
219 OH_NN_SUB_ACTIVATIONTYPE);
220 activationTypeTensor->SetBuffer(nullptr, 0);
221 m_allTensors.emplace_back(activationTypeTensor);
222
223 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
224 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
225 }
226
227 /**
228 * @tc.name: sub_build_010
229 * @tc.desc: Provide parameter is not scaler to verify the abnormal behavior of the Build function
230 * @tc.type: FUNC
231 */
232 HWTEST_F(SubBuilderTest, sub_build_010, TestSize.Level0)
233 {
234 std::vector<uint32_t> inputsIndex = { 0, 1 };
235 std::vector<uint32_t> outputsIndex = { 2 };
236 std::vector<int32_t> paramDim = {1, 2};
237
238 InitTensor(inputsIndex, outputsIndex);
239 SaveActivateTypeTensor(OH_NN_INT8, paramDim, nullptr, OH_NN_SUB_ACTIVATIONTYPE);
240
241 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
242 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
243 }
244
245 /**
246 * @tc.name: sub_build_011
247 * @tc.desc: Provide invalid parameter type to verify the abnormal behavior of the Build function
248 * @tc.type: FUNC
249 */
250 HWTEST_F(SubBuilderTest, sub_build_011, TestSize.Level0)
251 {
252 std::vector<uint32_t> inputsIndex = { 0, 1 };
253 std::vector<uint32_t> outputsIndex = { 2 };
254 std::vector<int32_t> paramDim = {};
255
256 InitTensor(inputsIndex, outputsIndex);
257 SaveActivateTypeTensor(OH_NN_INT8, paramDim, nullptr, OH_NN_SCALE_AXIS);
258
259 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
260 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
261 }
262
263 /**
264 * @tc.name: sub_build_012
265 * @tc.desc: Provide invalid param value to verify the abnormal behavior of the Build function
266 * @tc.type: FUNC
267 */
268 HWTEST_F(SubBuilderTest, sub_build_012, TestSize.Level0)
269 {
270 std::vector<uint32_t> inputsIndex = { 0, 1 };
271 std::vector<uint32_t> outputsIndex = { 2 };
272 std::vector<int32_t> paramDim = {};
273
274 InitTensor(inputsIndex, outputsIndex);
275
276 std::shared_ptr<NNTensor> activationTypeTensor = TransToNNTensor(OH_NN_INT8, paramDim, nullptr,
277 OH_NN_SUB_ACTIVATIONTYPE);
278 int8_t* activationTypeValue = new (std::nothrow) int8_t[1]{-1};
279 EXPECT_NE(nullptr, activationTypeValue);
280 activationTypeTensor->SetBuffer(activationTypeValue, sizeof(int8_t));
281 m_allTensors.emplace_back(activationTypeTensor);
282
283 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
284 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
285 }
286
287 /**
288 * @tc.name: sub_get_primitive_001
289 * @tc.desc: Verify the GetPrimitive function return nullptr
290 * @tc.type: FUNC
291 */
292 HWTEST_F(SubBuilderTest, sub_get_primitive_001, TestSize.Level0)
293 {
294 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
295 LiteGraphTensorPtr expectPrimitive = { nullptr, DestroyLiteGraphPrimitive };
296 EXPECT_EQ(primitive, expectPrimitive);
297 }
298
299 /**
300 * @tc.name: sub_get_primitive_002
301 * @tc.desc: Verify the normal params return behavior of the getprimitive function
302 * @tc.type: FUNC
303 */
304 HWTEST_F(SubBuilderTest, sub_get_primitive_002, TestSize.Level0)
305 {
306 std::vector<uint32_t> inputsIndex = { 0, 1 };
307 std::vector<uint32_t> outputsIndex = { 2 };
308 std::vector<int32_t> paramDim = {};
309
310 InitTensor(inputsIndex, outputsIndex);
311 SaveActivateTypeTensor(OH_NN_INT8, paramDim, nullptr, OH_NN_SUB_ACTIVATIONTYPE);
312
313 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
314 EXPECT_EQ(OH_NN_SUCCESS, ret);
315 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
316 LiteGraphTensorPtr expectPrimitive = { nullptr, DestroyLiteGraphPrimitive };
317 EXPECT_NE(primitive, expectPrimitive);
318
319 auto returnValue = mindspore::lite::MindIR_SubFusion_GetActivationType(primitive.get());
320 EXPECT_EQ(returnValue, m_expectActivationTypeValue);
321 }
322 } // namespace UnitTest
323 } // namespace NeuralNetworkRuntime
324 } // namespace OHOS
325