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/scale_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 ScaleBuilderTest : public OpsTest {
28 public:
29 void SetUp() override;
30 void TearDown() override;
31
32 protected:
33 void SaveAxisTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
34 const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35 void SaveActivationTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
36 const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
37
38 protected:
39 ScaleBuilder 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_dim {1, 4, 1, 1};
44 std::vector<int32_t> m_paramDim {};
45 };
46
SetUp()47 void ScaleBuilderTest::SetUp() {}
48
TearDown()49 void ScaleBuilderTest::TearDown() {}
50
SaveAxisTensor(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)51 void ScaleBuilderTest::SaveAxisTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
52 const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
53 {
54 std::shared_ptr<NNTensor> axisTensor = TransToNNTensor(dataType, dim, quantParam, type);
55 int64_t *axisValue = new (std::nothrow) int64_t(1);
56 EXPECT_NE(nullptr, axisValue);
57 axisTensor->SetBuffer(axisValue, sizeof(int64_t));
58 m_allTensors.emplace_back(axisTensor);
59 }
60
SaveActivationTensor(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)61 void ScaleBuilderTest::SaveActivationTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
62 const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
63 {
64 std::shared_ptr<NNTensor> activationTensor = TransToNNTensor(dataType, dim, quantParam, type);
65 int8_t *activationValue = new (std::nothrow) int8_t(0);
66 EXPECT_NE(nullptr, activationValue);
67 activationTensor->SetBuffer(activationValue, sizeof(int64_t));
68 m_allTensors.emplace_back(activationTensor);
69 }
70
71 /**
72 * @tc.name: scale_build_001
73 * @tc.desc: Provide normal input, output, and parameters to verify the normal behavior of the Build function
74 * @tc.type: FUNC
75 */
76 HWTEST_F(ScaleBuilderTest, scale_build_001, TestSize.Level0)
77 {
78 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
79 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
80 SaveAxisTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
81 SaveActivationTensor(OH_NN_INT8, m_paramDim, nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
82
83 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
84 EXPECT_EQ(OH_NN_SUCCESS, ret);
85 }
86
87 /**
88 * @tc.name: scale_build_002
89 * @tc.desc: Call Build func twice to verify the abnormal behavior of the Build function
90 * @tc.type: FUNC
91 */
92 HWTEST_F(ScaleBuilderTest, scale_build_002, TestSize.Level0)
93 {
94 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
95 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
96 SaveAxisTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
97 SaveActivationTensor(OH_NN_INT8, m_paramDim, nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
98
99 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
100 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
101 EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, ret);
102 }
103
104 /**
105 * @tc.name: scale_build_003
106 * @tc.desc: Provide one more than normal input to verify the abnormal behavior of the Build function
107 * @tc.type: FUNC
108 */
109 HWTEST_F(ScaleBuilderTest, scale_build_003, TestSize.Level0)
110 {
111 m_inputs = {0, 1, 2, 3};
112 m_outputs = {4};
113 m_params = {5, 6};
114
115 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
116 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
117 SaveAxisTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
118 SaveActivationTensor(OH_NN_INT8, m_paramDim, nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
119
120 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
121 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
122 }
123
124 /**
125 * @tc.name: scale_build_004
126 * @tc.desc: Provide one more than normal output to verify the abnormal behavior of the Build function
127 * @tc.type: FUNC
128 */
129 HWTEST_F(ScaleBuilderTest, scale_build_004, TestSize.Level0)
130 {
131 m_outputs = {3, 4};
132 m_params = {5, 6};
133
134 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
135 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
136 SaveAxisTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
137 SaveActivationTensor(OH_NN_INT8, m_paramDim, nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
138
139 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
140 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
141 }
142
143 /**
144 * @tc.name: scale_build_005
145 * @tc.desc: Verify that the build function return a failed message with null allTensor
146 * @tc.type: FUNC
147 */
148 HWTEST_F(ScaleBuilderTest, scale_build_005, TestSize.Level0)
149 {
150 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputs, m_outputs, m_allTensors);
151 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
152 }
153
154 /**
155 * @tc.name: scale_build_006
156 * @tc.desc: Verify that the build function return a failed message without output tensor
157 * @tc.type: FUNC
158 */
159 HWTEST_F(ScaleBuilderTest, scale_build_006, TestSize.Level0)
160 {
161 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
162
163 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputs, m_allTensors);
164 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
165 }
166
167 /**
168 * @tc.name: scale_build_007
169 * @tc.desc: Verify that the build function return a failed message with invalided axis's dataType
170 * @tc.type: FUNC
171 */
172 HWTEST_F(ScaleBuilderTest, scale_build_007, TestSize.Level0)
173 {
174 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
175 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
176
177 SaveActivationTensor(OH_NN_INT8, m_paramDim, nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
178
179 std::shared_ptr<NNTensor> axisTensor = TransToNNTensor(OH_NN_INT32, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
180 int32_t axisValue = 1;
181 axisTensor->SetBuffer(&axisValue, sizeof(axisValue));
182 m_allTensors.emplace_back(axisTensor);
183
184 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
185 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
186 axisTensor->SetBuffer(nullptr, 0);
187 }
188
189 /**
190 * @tc.name: scale_build_008
191 * @tc.desc: Verify that the build function return a failed message with invalided activation's dataType
192 * @tc.type: FUNC
193 */
194 HWTEST_F(ScaleBuilderTest, scale_build_008, TestSize.Level0)
195 {
196 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
197 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
198
199 SaveAxisTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
200
201 std::shared_ptr<NNTensor> activationTensor = TransToNNTensor(OH_NN_INT64, m_paramDim,
202 nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
203 int64_t activationValue = 0;
204 activationTensor->SetBuffer(&activationValue, sizeof(activationValue));
205 m_allTensors.emplace_back(activationTensor);
206
207 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
208 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
209 activationTensor->SetBuffer(nullptr, 0);
210 }
211
212 /**
213 * @tc.name: scale_build_009
214 * @tc.desc: Verify that the build function return a failed message with invalided axis's dimension
215 * @tc.type: FUNC
216 */
217 HWTEST_F(ScaleBuilderTest, scale_build_009, TestSize.Level0)
218 {
219 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
220 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
221
222 std::vector<int32_t> axistDim = {2};
223 std::shared_ptr<NNTensor> axisTensor = TransToNNTensor(OH_NN_INT64, axistDim, nullptr, OH_NN_SCALE_AXIS);
224 int64_t axisValue[2] = {1, 1};
225 axisTensor->SetBuffer(axisValue, 2 * sizeof(int64_t));
226 m_allTensors.emplace_back(axisTensor);
227
228 SaveActivationTensor(OH_NN_INT8, m_paramDim, nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
229
230 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
231 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
232 axisTensor->SetBuffer(nullptr, 0);
233 }
234
235 /**
236 * @tc.name: scale_build_010
237 * @tc.desc: Verify that the build function return a failed message with invalided activation's dimension
238 * @tc.type: FUNC
239 */
240 HWTEST_F(ScaleBuilderTest, scale_build_010, TestSize.Level0)
241 {
242 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
243 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
244
245 SaveAxisTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
246
247 std::vector<int32_t> activationDim = {2};
248 std::shared_ptr<NNTensor> activationTensor = TransToNNTensor(OH_NN_INT8,
249 activationDim, nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
250 int64_t activationValue[2] = {1, 1};
251 activationTensor->SetBuffer(activationValue, 2 * sizeof(int64_t));
252 m_allTensors.emplace_back(activationTensor);
253
254 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
255 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
256 activationTensor->SetBuffer(nullptr, 0);
257 }
258
259 /**
260 * @tc.name: scale_build_011
261 * @tc.desc: Verify that the build function return a failed message with invalided activation's buffer
262 * @tc.type: FUNC
263 */
264 HWTEST_F(ScaleBuilderTest, scale_build_011, TestSize.Level0)
265 {
266 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
267 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
268
269 SaveAxisTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
270
271 std::shared_ptr<NNTensor> activationTensor = TransToNNTensor(OH_NN_INT8,
272 m_paramDim, nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
273 int8_t activationValue = -1;
274 activationTensor->SetBuffer(&activationValue, sizeof(activationValue));
275 m_allTensors.emplace_back(activationTensor);
276
277 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
278 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
279 activationTensor->SetBuffer(nullptr, 0);
280 }
281
282 /**
283 * @tc.name: scale_build_012
284 * @tc.desc: Verify that the build function return a failed message with invalided parameter
285 * @tc.type: FUNC
286 */
287 HWTEST_F(ScaleBuilderTest, scale_build_012, TestSize.Level0)
288 {
289 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
290 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
291 SaveAxisTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
292 SaveActivationTensor(OH_NN_INT8, m_paramDim, nullptr, OH_NN_QUANT_DTYPE_CAST_SRC_T);
293
294 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
295 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
296 }
297
298 /**
299 * @tc.name: scale_build_013
300 * @tc.desc: Verify that the build function return a failed message with empty axis's buffer
301 * @tc.type: FUNC
302 */
303 HWTEST_F(ScaleBuilderTest, scale_build_013, TestSize.Level0)
304 {
305 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
306 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
307
308 SaveActivationTensor(OH_NN_INT8, m_paramDim, nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
309
310 std::shared_ptr<NNTensor> axisTensor = TransToNNTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
311 m_allTensors.emplace_back(axisTensor);
312
313 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
314 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
315 axisTensor->SetBuffer(nullptr, 0);
316 }
317
318 /**
319 * @tc.name: scale_build_014
320 * @tc.desc: Verify that the build function return a failed message with empty activation's buffer
321 * @tc.type: FUNC
322 */
323 HWTEST_F(ScaleBuilderTest, scale_build_014, TestSize.Level0)
324 {
325 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
326 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
327
328 SaveAxisTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
329
330 std::shared_ptr<NNTensor> activationTensor = TransToNNTensor(OH_NN_INT8, m_paramDim,
331 nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
332 m_allTensors.emplace_back(activationTensor);
333
334 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
335 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
336 activationTensor->SetBuffer(nullptr, 0);
337 }
338
339 /**
340 * @tc.name: scale_get_primitive_001
341 * @tc.desc: Verify the GetPrimitive function return nullptr
342 * @tc.type: FUNC
343 */
344 HWTEST_F(ScaleBuilderTest, scale_get_primitive_001, TestSize.Level0)
345 {
346 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
347 LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
348 EXPECT_EQ(primitive, expectPrimitive);
349 }
350
351 /**
352 * @tc.name: scale_get_primitive_002
353 * @tc.desc: Verify the normal params return behavior of the getprimitive function
354 * @tc.type: FUNC
355 */
356 HWTEST_F(ScaleBuilderTest, scale_get_primitive_002, TestSize.Level0)
357 {
358 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
359 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
360 SaveAxisTensor(OH_NN_INT64, m_paramDim, nullptr, OH_NN_SCALE_AXIS);
361 SaveActivationTensor(OH_NN_INT8, m_paramDim, nullptr, OH_NN_SCALE_ACTIVATIONTYPE);
362
363 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
364 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
365 LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
366 EXPECT_NE(primitive, expectPrimitive);
367
368 int64_t axisValue = 1;
369 int8_t activationValue = 0;
370 auto axisReturn = mindspore::lite::MindIR_ScaleFusion_GetAxis(primitive.get());
371 EXPECT_EQ(axisReturn, axisValue);
372 auto activationReturn = mindspore::lite::MindIR_ScaleFusion_GetActivationType(primitive.get());
373 EXPECT_EQ(activationReturn, activationValue);
374 }
375 } // namespace UnitTest
376 } // namespace NeuralNetworkRuntime
377 } // namespace OHOS