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