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/pow_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 PowBuilderTest : public OpsTest {
28 public:
29 void SetUp() override;
30 void TearDown() override;
31
32 protected:
33 void SaveShift(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
38 protected:
39 PowBuilder m_builder;
40 std::vector<uint32_t> m_inputs {0, 1};
41 std::vector<uint32_t> m_outputs {2};
42 std::vector<uint32_t> m_params {3, 4};
43 std::vector<int32_t> m_dim {1, 2, 2, 1};
44 std::vector<int32_t> m_shiftDim {1};
45 std::vector<int32_t> m_scaleDim {1};
46 };
47
SetUp()48 void PowBuilderTest::SetUp() {}
49
TearDown()50 void PowBuilderTest::TearDown() {}
51
SaveShift(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)52 void PowBuilderTest::SaveShift(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> shiftTensor = TransToNNTensor(dataType, dim, quantParam, type);
56 float* shiftValue = new (std::nothrow) float[1] {0.0f};
57 EXPECT_NE(nullptr, shiftValue);
58 shiftTensor->SetBuffer(shiftValue, sizeof(float));
59 m_allTensors.emplace_back(shiftTensor);
60 }
61
SaveScale(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)62 void PowBuilderTest::SaveScale(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> scaleTensor = TransToNNTensor(dataType, dim, quantParam, type);
66 float* scaleValue = new (std::nothrow) float[1] {1.0f};
67 EXPECT_NE(nullptr, scaleValue);
68 scaleTensor->SetBuffer(scaleValue, sizeof(float));
69 m_allTensors.emplace_back(scaleTensor);
70 }
71
72 /**
73 * @tc.name: pow_build_001
74 * @tc.desc: Provide normal input, output, and parameters to verify the normal behavior of the Build function
75 * @tc.type: FUNC
76 */
77 HWTEST_F(PowBuilderTest, pow_build_001, TestSize.Level1)
78 {
79 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
80 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
81 SaveShift(OH_NN_FLOAT32, m_shiftDim, nullptr, OH_NN_POW_SHIFT);
82 SaveScale(OH_NN_FLOAT32, m_scaleDim, nullptr, OH_NN_POW_SCALE);
83
84 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
85 EXPECT_EQ(OH_NN_SUCCESS, ret);
86 }
87
88 /**
89 * @tc.name: pow_build_002
90 * @tc.desc: Call Build func twice to verify the abnormal behavior of the Build function
91 * @tc.type: FUNC
92 */
93 HWTEST_F(PowBuilderTest, pow_build_002, TestSize.Level1)
94 {
95 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
96 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
97 SaveShift(OH_NN_FLOAT32, m_shiftDim, nullptr, OH_NN_POW_SHIFT);
98 SaveScale(OH_NN_FLOAT32, m_scaleDim, nullptr, OH_NN_POW_SCALE);
99
100 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
101 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
102 EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, ret);
103 }
104
105 /**
106 * @tc.name: pow_build_003
107 * @tc.desc: Provide one more than normal input to verify the abnormal behavior of the Build function
108 * @tc.type: FUNC
109 */
110 HWTEST_F(PowBuilderTest, pow_build_003, TestSize.Level1)
111 {
112 m_inputs = {0, 1, 2};
113 m_outputs = {3};
114 m_params = {4, 5};
115
116 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
117 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
118 SaveShift(OH_NN_FLOAT32, m_shiftDim, nullptr, OH_NN_POW_SHIFT);
119 SaveScale(OH_NN_FLOAT32, m_scaleDim, nullptr, OH_NN_POW_SCALE);
120
121 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
122 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
123 }
124
125 /**
126 * @tc.name: pow_build_004
127 * @tc.desc: Provide one more than normal output to verify the abnormal behavior of the Build function
128 * @tc.type: FUNC
129 */
130 HWTEST_F(PowBuilderTest, pow_build_004, TestSize.Level1)
131 {
132 m_outputs = {2, 3};
133 m_params = {4, 5};
134
135 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
136 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
137 SaveShift(OH_NN_FLOAT32, m_shiftDim, nullptr, OH_NN_POW_SHIFT);
138 SaveScale(OH_NN_FLOAT32, m_scaleDim, nullptr, OH_NN_POW_SCALE);
139
140 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
141 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
142 }
143
144 /**
145 * @tc.name: pow_build_005
146 * @tc.desc: Verify that the build function return a failed message with null allTensor
147 * @tc.type: FUNC
148 */
149 HWTEST_F(PowBuilderTest, pow_build_005, TestSize.Level1)
150 {
151 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputs, m_outputs, m_allTensors);
152 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
153 }
154
155 /**
156 * @tc.name: pow_build_006
157 * @tc.desc: Verify that the build function return a failed message without output tensor
158 * @tc.type: FUNC
159 */
160 HWTEST_F(PowBuilderTest, pow_build_006, TestSize.Level1)
161 {
162 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
163
164 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputs, m_allTensors);
165 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
166 }
167
168 /**
169 * @tc.name: pow_build_007
170 * @tc.desc: Verify that the build function returns a failed message with invalid shift's dataType.
171 * @tc.type: FUNC
172 */
173 HWTEST_F(PowBuilderTest, pow_build_007, TestSize.Level1)
174 {
175 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
176 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
177
178 std::shared_ptr<NNTensor> shiftTensor = TransToNNTensor(OH_NN_INT64, m_shiftDim,
179 nullptr, OH_NN_POW_SHIFT);
180 int64_t* shiftValue = new (std::nothrow) int64_t[1] {0};
181 shiftTensor->SetBuffer(shiftValue, sizeof(shiftValue));
182 m_allTensors.emplace_back(shiftTensor);
183 SaveScale(OH_NN_FLOAT32, m_scaleDim, nullptr, OH_NN_POW_SCALE);
184
185 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
186 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
187 }
188
189 /**
190 * @tc.name: pow_build_008
191 * @tc.desc: Verify that the build function returns a failed message with invalid scale's dataType.
192 * @tc.type: FUNC
193 */
194 HWTEST_F(PowBuilderTest, pow_build_008, TestSize.Level1)
195 {
196 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
197 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
198
199 SaveShift(OH_NN_FLOAT32, m_shiftDim, nullptr, OH_NN_POW_SHIFT);
200 std::shared_ptr<NNTensor> scaleTensor = TransToNNTensor(OH_NN_INT64, m_scaleDim,
201 nullptr, OH_NN_POW_SCALE);
202 int64_t* scaleValue = new (std::nothrow) int64_t[1] {1};
203 scaleTensor->SetBuffer(scaleValue, sizeof(scaleValue));
204 m_allTensors.emplace_back(scaleTensor);
205
206 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
207 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
208 }
209
210 /**
211 * @tc.name: pow_build_009
212 * @tc.desc: Verify that the build function returns a failed message with passing invalid shift param.
213 * @tc.type: FUNC
214 */
215 HWTEST_F(PowBuilderTest, pow_build_009, TestSize.Level1)
216 {
217 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
218 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
219 SaveShift(OH_NN_FLOAT32, m_shiftDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
220 SaveScale(OH_NN_FLOAT32, m_scaleDim, nullptr, OH_NN_POW_SCALE);;
221
222 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
223 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
224 }
225
226 /**
227 * @tc.name: pow_build_010
228 * @tc.desc: Verify that the build function returns a failed message with passing invalid scale param.
229 * @tc.type: FUNC
230 */
231 HWTEST_F(PowBuilderTest, pow_build_010, TestSize.Level1)
232 {
233 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
234 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
235 SaveShift(OH_NN_FLOAT32, m_shiftDim, nullptr, OH_NN_POW_SHIFT);
236 SaveScale(OH_NN_FLOAT32, m_scaleDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
237
238 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
239 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
240 }
241
242 /**
243 * @tc.name: pow_build_011
244 * @tc.desc: Verify that the build function returns a failed message without set buffer for shift.
245 * @tc.type: FUNC
246 */
247 HWTEST_F(PowBuilderTest, pow_build_011, TestSize.Level1)
248 {
249 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
250 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
251
252 std::shared_ptr<NNTensor> shiftTensor = TransToNNTensor(OH_NN_FLOAT32, m_shiftDim,
253 nullptr, OH_NN_POW_SHIFT);
254 m_allTensors.emplace_back(shiftTensor);
255 SaveScale(OH_NN_FLOAT32, m_scaleDim, nullptr, OH_NN_POW_SCALE);;
256
257 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
258 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
259 }
260
261 /**
262 * @tc.name: pow_build_012
263 * @tc.desc: Verify that the build function returns a failed message without set buffer for scale.
264 * @tc.type: FUNC
265 */
266 HWTEST_F(PowBuilderTest, pow_build_012, TestSize.Level1)
267 {
268 SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
269 SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
270
271 SaveShift(OH_NN_FLOAT32, m_shiftDim, nullptr, OH_NN_POW_SHIFT);
272 std::shared_ptr<NNTensor> scaleTensor = TransToNNTensor(OH_NN_FLOAT32, m_scaleDim,
273 nullptr, OH_NN_POW_SCALE);
274 m_allTensors.emplace_back(scaleTensor);
275
276 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
277 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
278 }
279
280 /**
281 * @tc.name: pow_get_primitive_001
282 * @tc.desc: Verify the GetPrimitive function return nullptr
283 * @tc.type: FUNC
284 */
285 HWTEST_F(PowBuilderTest, pow_get_primitive_001, TestSize.Level1)
286 {
287 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
288 LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
289 EXPECT_EQ(primitive, expectPrimitive);
290 }
291
292 /**
293 * @tc.name: pow_get_primitive_002
294 * @tc.desc: Verify the normal params return behavior of the getprimitive function
295 * @tc.type: FUNC
296 */
297 HWTEST_F(PowBuilderTest, pow_get_primitive_002, TestSize.Level1)
298 {
299 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_dim, nullptr);
300 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_dim, nullptr);
301
302 SaveShift(OH_NN_FLOAT32, m_shiftDim, nullptr, OH_NN_POW_SHIFT);
303 SaveScale(OH_NN_FLOAT32, m_scaleDim, nullptr, OH_NN_POW_SCALE);
304
305 float shiftValue = 0.0f;
306 float scaleValue = 1.0f;
307 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
308 LiteGraphTensorPtr powPrimitive = m_builder.GetPrimitive();
309 LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
310 EXPECT_NE(powPrimitive, expectPrimitive);
311
312 auto returnShiftValue = mindspore::lite::MindIR_PowFusion_GetShift(powPrimitive.get());
313 EXPECT_EQ(shiftValue, returnShiftValue);
314 auto returnScaleValue = mindspore::lite::MindIR_PowFusion_GetScale(powPrimitive.get());
315 EXPECT_EQ(scaleValue, returnScaleValue);
316 }
317 } // namespace UnitTest
318 } // namespace NeuralNetworkRuntime
319 } // namespace OHOS