1 /*
2 * Copyright (c) 2023 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/exp_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 ExpBuilderTest : public OpsTest {
28 public:
29 void SetUp() override;
30 void TearDown() override;
31
32 protected:
33 void SaveBase(OH_NN_DataType dataType,
34 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35 void SaveScale(OH_NN_DataType dataType,
36 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
37 void SaveShift(OH_NN_DataType dataType,
38 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
39
40 protected:
41 ExpBuilder m_builder;
42 std::vector<uint32_t> m_inputs {0};
43 std::vector<uint32_t> m_outputs {1};
44 std::vector<uint32_t> m_params {2, 3, 4};
45 std::vector<int32_t> m_dim {1, 2, 2, 1};
46 std::vector<int32_t> m_paramDim {};
47 };
48
SetUp()49 void ExpBuilderTest::SetUp() {}
50
TearDown()51 void ExpBuilderTest::TearDown() {}
52
SaveBase(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)53 void ExpBuilderTest::SaveBase(OH_NN_DataType dataType,
54 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
55 {
56 std::shared_ptr<NNTensor> baseTensor = TransToNNTensor(dataType, dim, quantParam, type);
57 float* baseValue = new (std::nothrow) float [1]{-1.0f};
58 EXPECT_NE(nullptr, baseValue);
59 baseTensor->SetBuffer(baseValue, sizeof(float));
60 m_allTensors.emplace_back(baseTensor);
61 }
62
SaveScale(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)63 void ExpBuilderTest::SaveScale(OH_NN_DataType dataType,
64 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
65 {
66 std::shared_ptr<NNTensor> scaleTensor = TransToNNTensor(dataType, dim, quantParam, type);
67 float* scaleValue = new (std::nothrow) float [1]{1.0f};
68 EXPECT_NE(nullptr, scaleValue);
69 scaleTensor->SetBuffer(scaleValue, sizeof(float));
70 m_allTensors.emplace_back(scaleTensor);
71 }
72
SaveShift(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)73 void ExpBuilderTest::SaveShift(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> shiftTensor = TransToNNTensor(dataType, dim, quantParam, type);
77 float* shiftValue = new (std::nothrow) float [1]{0.0f};
78 EXPECT_NE(nullptr, shiftValue);
79 shiftTensor->SetBuffer(shiftValue, sizeof(float));
80 m_allTensors.emplace_back(shiftTensor);
81 }
82
83 /**
84 * @tc.name: exp_build_001
85 * @tc.desc: Verify that the build function returns a successful message.
86 * @tc.type: FUNC
87 */
88 HWTEST_F(ExpBuilderTest, exp_build_001, TestSize.Level1)
89 {
90 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
91 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
92 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
93 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
94 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
95
96 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
97 EXPECT_EQ(OH_NN_SUCCESS, ret);
98 }
99
100 /**
101 * @tc.name: exp_build_002
102 * @tc.desc: Verify that the build function returns a failed message with true m_isBuild.
103 * @tc.type: FUNC
104 */
105 HWTEST_F(ExpBuilderTest, exp_build_002, TestSize.Level1)
106 {
107 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
108 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
109 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
110 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
111 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
112
113 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
114 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
115 EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, ret);
116 }
117
118 /**
119 * @tc.name: exp_build_003
120 * @tc.desc: Verify that the build function returns a failed message with invalided input.
121 * @tc.type: FUNC
122 */
123 HWTEST_F(ExpBuilderTest, exp_build_003, TestSize.Level1)
124 {
125 m_inputs = {0, 1};
126 m_outputs = {2};
127 m_params = {3, 4, 5};
128
129 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
130 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
131 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
132 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
133 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
134
135 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
136 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
137 }
138
139 /**
140 * @tc.name: exp_build_004
141 * @tc.desc: Verify that the build function returns a failed message with invalided output.
142 * @tc.type: FUNC
143 */
144 HWTEST_F(ExpBuilderTest, exp_build_004, TestSize.Level1)
145 {
146 m_outputs = {1, 2};
147 m_params = {3, 4, 5};
148
149 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
150 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
151 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
152 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
153 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
154
155 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
156 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
157 }
158
159 /**
160 * @tc.name: exp_build_005
161 * @tc.desc: Verify that the build function returns a failed message with empty allTensor.
162 * @tc.type: FUNC
163 */
164 HWTEST_F(ExpBuilderTest, exp_build_005, TestSize.Level1)
165 {
166 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputs, m_outputs, m_allTensors);
167 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
168 }
169
170 /**
171 * @tc.name: exp_build_006
172 * @tc.desc: Verify that the build function returns a failed message without output tensor.
173 * @tc.type: FUNC
174 */
175 HWTEST_F(ExpBuilderTest, exp_build_006, TestSize.Level1)
176 {
177 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
178
179 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputs, m_allTensors);
180 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
181 }
182
183 /**
184 * @tc.name: exp_build_007
185 * @tc.desc: Verify that the build function returns a failed message with invalid base's dataType.
186 * @tc.type: FUNC
187 */
188 HWTEST_F(ExpBuilderTest, exp_build_007, TestSize.Level1)
189 {
190 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
191 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
192
193 std::shared_ptr<NNTensor> baseTensor = TransToNNTensor(OH_NN_INT64, m_paramDim,
194 nullptr, OH_NN_EXP_BASE);
195 int64_t* baseValue = new (std::nothrow) int64_t [1]{-1};
196 EXPECT_NE(nullptr, baseValue);
197 baseTensor->SetBuffer(baseValue, sizeof(int64_t));
198 m_allTensors.emplace_back(baseTensor);
199 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
200 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
201
202 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
203 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
204 }
205
206 /**
207 * @tc.name: exp_build_008
208 * @tc.desc: Verify that the build function returns a failed message with invalid scale's dataType.
209 * @tc.type: FUNC
210 */
211 HWTEST_F(ExpBuilderTest, exp_build_008, TestSize.Level1)
212 {
213 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
214 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
215
216 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
217 std::shared_ptr<NNTensor> scaleTensor = TransToNNTensor(OH_NN_INT64, m_paramDim,
218 nullptr, OH_NN_EXP_SCALE);
219 int64_t* scaleValue = new (std::nothrow) int64_t [1]{1};
220 EXPECT_NE(nullptr, scaleValue);
221 scaleTensor->SetBuffer(scaleValue, sizeof(int64_t));
222 m_allTensors.emplace_back(scaleTensor);
223 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
224
225 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
226 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
227 }
228
229 /**
230 * @tc.name: exp_build_009
231 * @tc.desc: Verify that the build function returns a failed message with invalid base's dataType.
232 * @tc.type: FUNC
233 */
234 HWTEST_F(ExpBuilderTest, exp_build_009, TestSize.Level1)
235 {
236 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
237 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
238
239 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
240 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
241 std::shared_ptr<NNTensor> shiftTensor = TransToNNTensor(OH_NN_INT64, m_paramDim,
242 nullptr, OH_NN_EXP_SHIFT);
243 int64_t* shiftValue = new (std::nothrow) int64_t [1]{0};
244 EXPECT_NE(nullptr, shiftValue);
245 shiftTensor->SetBuffer(shiftValue, sizeof(int64_t));
246 m_allTensors.emplace_back(shiftTensor);
247
248 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
249 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
250 }
251
252 /**
253 * @tc.name: exp_build_010
254 * @tc.desc: Verify that the build function returns a failed message with passing invalid base param.
255 * @tc.type: FUNC
256 */
257 HWTEST_F(ExpBuilderTest, exp_build_010, TestSize.Level1)
258 {
259 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
260 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
261
262 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
263 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
264 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
265
266 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
267 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
268 }
269
270 /**
271 * @tc.name: exp_build_011
272 * @tc.desc: Verify that the build function returns a failed message with passing invalid scale param.
273 * @tc.type: FUNC
274 */
275 HWTEST_F(ExpBuilderTest, exp_build_011, TestSize.Level1)
276 {
277 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
278 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
279
280 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
281 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
282 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
283
284 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
285 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
286 }
287
288 /**
289 * @tc.name: exp_build_012
290 * @tc.desc: Verify that the build function returns a failed message with passing invalid shift param.
291 * @tc.type: FUNC
292 */
293 HWTEST_F(ExpBuilderTest, exp_build_012, TestSize.Level1)
294 {
295 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
296 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
297
298 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
299 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
300 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
301
302 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
303 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
304 }
305
306 /**
307 * @tc.name: exp_build_013
308 * @tc.desc: Verify that the build function returns a failed message without set buffer for base.
309 * @tc.type: FUNC
310 */
311 HWTEST_F(ExpBuilderTest, exp_build_013, TestSize.Level1)
312 {
313 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
314 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
315
316 std::shared_ptr<NNTensor> baseTensor = TransToNNTensor(OH_NN_FLOAT32, m_paramDim,
317 nullptr, OH_NN_EXP_BASE);
318 m_allTensors.emplace_back(baseTensor);
319 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
320 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
321
322 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
323 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
324 }
325
326 /**
327 * @tc.name: exp_build_014
328 * @tc.desc: Verify that the build function returns a failed message without set buffer for scale.
329 * @tc.type: FUNC
330 */
331 HWTEST_F(ExpBuilderTest, exp_build_014, TestSize.Level1)
332 {
333 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
334 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
335
336 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
337 std::shared_ptr<NNTensor> scaleTensor = TransToNNTensor(OH_NN_FLOAT32, m_paramDim,
338 nullptr, OH_NN_EXP_SCALE);
339 m_allTensors.emplace_back(scaleTensor);
340 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
341
342
343 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
344 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
345 }
346
347 /**
348 * @tc.name: exp_build_015
349 * @tc.desc: Verify that the build function returns a failed message without set buffer for shift.
350 * @tc.type: FUNC
351 */
352 HWTEST_F(ExpBuilderTest, exp_build_015, TestSize.Level1)
353 {
354 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
355 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
356
357 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
358 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
359 std::shared_ptr<NNTensor> shiftTensor = TransToNNTensor(OH_NN_FLOAT32, m_paramDim,
360 nullptr, OH_NN_EXP_SHIFT);
361 m_allTensors.emplace_back(shiftTensor);
362
363 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
364 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
365 }
366
367 /**
368 * @tc.name: exp_getprimitive_001
369 * @tc.desc: Verify that the getPrimitive function returns a successful message
370 * @tc.type: FUNC
371 */
372 HWTEST_F(ExpBuilderTest, exp_getprimitive_001, TestSize.Level1)
373 {
374 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
375 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
376 SaveBase(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_BASE);
377 SaveScale(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SCALE);
378 SaveShift(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_EXP_SHIFT);
379
380 float baseValue = -1.0f;
381 float scaleValue = 1.0f;
382 float shiftValue = 0.0f;
383 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
384 LiteGraphPrimitvePtr primitive = m_builder.GetPrimitive();
385 LiteGraphPrimitvePtr expectPrimitive(nullptr, DestroyLiteGraphPrimitive);
386 EXPECT_NE(expectPrimitive, primitive);
387
388 auto returnBaseValue = mindspore::lite::MindIR_ExpFusion_GetBase(primitive.get());
389 EXPECT_EQ(returnBaseValue, baseValue);
390 auto returnScaleValue = mindspore::lite::MindIR_ExpFusion_GetScale(primitive.get());
391 EXPECT_EQ(returnScaleValue, scaleValue);
392 auto returnShiftValue = mindspore::lite::MindIR_ExpFusion_GetShift(primitive.get());
393 EXPECT_EQ(returnShiftValue, shiftValue);
394 }
395
396 /**
397 * @tc.name: exp_getprimitive_002
398 * @tc.desc: Verify that the getPrimitive function returns a failed message without build.
399 * @tc.type: FUNC
400 */
401 HWTEST_F(ExpBuilderTest, exp_getprimitive_002, TestSize.Level1)
402 {
403 LiteGraphPrimitvePtr primitive = m_builder.GetPrimitive();
404 LiteGraphPrimitvePtr expectPrimitive(nullptr, DestroyLiteGraphPrimitive);
405 EXPECT_EQ(expectPrimitive, primitive);
406 }
407 }
408 }
409 }