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/range_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 RangeBuilderTest : public OpsTest {
28 public:
29     void SetUp() override;
30     void TearDown() override;
31 
32 protected:
33     void SaveStart(OH_NN_DataType dataType,
34         const std::vector<int32_t> &dim,  const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35     void SaveLimit(OH_NN_DataType dataType,
36         const std::vector<int32_t> &dim,  const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
37     void SaveDelta(OH_NN_DataType dataType,
38         const std::vector<int32_t> &dim,  const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
39 
40 protected:
41     RangeBuilder 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 {3};
46     std::vector<int32_t> m_paramDim {};
47 };
48 
SetUp()49 void RangeBuilderTest::SetUp() {}
50 
TearDown()51 void RangeBuilderTest::TearDown() {}
52 
SaveStart(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)53 void RangeBuilderTest::SaveStart(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> startTensor = TransToNNTensor(dataType, dim, quantParam, type);
57     int64_t* startValue = new (std::nothrow) int64_t [1]{0};
58     EXPECT_NE(nullptr, startValue);
59     startTensor->SetBuffer(startValue, sizeof(int64_t));
60     m_allTensors.emplace_back(startTensor);
61 }
62 
SaveLimit(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)63 void RangeBuilderTest::SaveLimit(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> limitTensor = TransToNNTensor(dataType, dim, quantParam, type);
67     int64_t* limitValue = new (std::nothrow) int64_t [1]{3};
68     EXPECT_NE(nullptr, limitValue);
69     limitTensor->SetBuffer(limitValue, sizeof(int64_t));
70     m_allTensors.emplace_back(limitTensor);
71 }
72 
SaveDelta(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)73 void RangeBuilderTest::SaveDelta(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> deltaTensor = TransToNNTensor(dataType, dim, quantParam, type);
77     int64_t* deltaValue = new (std::nothrow) int64_t [1]{1};
78     EXPECT_NE(nullptr, deltaValue);
79     deltaTensor->SetBuffer(deltaValue, sizeof(int64_t));
80     m_allTensors.emplace_back(deltaTensor);
81 }
82 
83 /**
84  * @tc.name: range_build_001
85  * @tc.desc: Verify that the build function returns a successful message.
86  * @tc.type: FUNC
87  */
88 HWTEST_F(RangeBuilderTest, range_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     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
93     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
94     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
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: range_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(RangeBuilderTest, range_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     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
110     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
111     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
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: range_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(RangeBuilderTest, range_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     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
132     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
133     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
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: range_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(RangeBuilderTest, range_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     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
152     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
153     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
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: range_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(RangeBuilderTest, range_build_005, TestSize.Level1)
165 {
166     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputs, m_allTensors);
167     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
168 }
169 
170 /**
171  * @tc.name: range_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(RangeBuilderTest, range_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: range_build_007
185  * @tc.desc: Verify that the build function returns a failed message with invalid start's dataType.
186  * @tc.type: FUNC
187  */
188 HWTEST_F(RangeBuilderTest, range_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> startTensor = TransToNNTensor(OH_NN_FLOAT32, m_paramDim,
194         nullptr, OH_NN_RANGE_START);
__anonfb2cd37e0102null195     float* startValue = new (std::nothrow) float [1]{0.0f};
196     EXPECT_NE(nullptr, startValue);
197     startTensor->SetBuffer(startValue, sizeof(float));
198     m_allTensors.emplace_back(startTensor);
199     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
200     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
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: range_build_008
208  * @tc.desc: Verify that the build function returns a failed message with invalid limit's dataType.
209  * @tc.type: FUNC
210  */
211 HWTEST_F(RangeBuilderTest, range_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     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
217     std::shared_ptr<NNTensor> limitTensor = TransToNNTensor(OH_NN_FLOAT32, m_paramDim,
218         nullptr, OH_NN_RANGE_LIMIT);
__anonfb2cd37e0202null219     float* limitValue = new (std::nothrow) float [1]{3.0f};
220     EXPECT_NE(nullptr, limitValue);
221     limitTensor->SetBuffer(limitValue, sizeof(float));
222     m_allTensors.emplace_back(limitTensor);
223     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
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: range_build_009
231  * @tc.desc: Verify that the build function returns a failed message with invalid delta's dataType.
232  * @tc.type: FUNC
233  */
234 HWTEST_F(RangeBuilderTest, range_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     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
240     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
241     std::shared_ptr<NNTensor> deltaTensor = TransToNNTensor(OH_NN_FLOAT32, m_paramDim,
242         nullptr, OH_NN_RANGE_DELTA);
__anonfb2cd37e0302null243     float* deltaValue = new (std::nothrow) float [1]{1.0f};
244     EXPECT_NE(nullptr, deltaValue);
245     deltaTensor->SetBuffer(deltaValue, sizeof(float));
246     m_allTensors.emplace_back(deltaTensor);
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: range_build_010
254  * @tc.desc: Verify that the build function returns a failed message with passing invalid start param.
255  * @tc.type: FUNC
256  */
257 HWTEST_F(RangeBuilderTest, range_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     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
263     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
264     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
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: range_build_011
272  * @tc.desc: Verify that the build function returns a failed message with passing invalid limit param.
273  * @tc.type: FUNC
274  */
275 HWTEST_F(RangeBuilderTest, range_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     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
281     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
282     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
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: range_build_012
290  * @tc.desc: Verify that the build function returns a failed message with passing invalid delta param.
291  * @tc.type: FUNC
292  */
293 HWTEST_F(RangeBuilderTest, range_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     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
299     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
300     SaveDelta(OH_NN_INT64, 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: range_build_013
308  * @tc.desc: Verify that the build function returns a failed message without set buffer for start.
309  * @tc.type: FUNC
310  */
311 HWTEST_F(RangeBuilderTest, range_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> startTensor = TransToNNTensor(OH_NN_INT64, m_paramDim,
317         nullptr, OH_NN_RANGE_START);
318     m_allTensors.emplace_back(startTensor);
319     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
320     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
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: range_build_014
328  * @tc.desc: Verify that the build function returns a failed message without set buffer for limit.
329  * @tc.type: FUNC
330  */
331 HWTEST_F(RangeBuilderTest, range_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     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
337     std::shared_ptr<NNTensor> limitTensor = TransToNNTensor(OH_NN_INT64, m_paramDim,
338         nullptr, OH_NN_RANGE_LIMIT);
339     m_allTensors.emplace_back(limitTensor);
340     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
341 
342     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
343     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
344 }
345 
346 /**
347  * @tc.name: range_build_015
348  * @tc.desc: Verify that the build function returns a failed message without set buffer for delta.
349  * @tc.type: FUNC
350  */
351 HWTEST_F(RangeBuilderTest, range_build_015, TestSize.Level1)
352 {
353     SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
354     SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
355 
356     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
357     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
358     std::shared_ptr<NNTensor> deltaTensor = TransToNNTensor(OH_NN_INT64, m_paramDim,
359         nullptr, OH_NN_RANGE_DELTA);
360     m_allTensors.emplace_back(deltaTensor);
361 
362     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
363     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
364 }
365 
366 /**
367  * @tc.name: range_getprimitive_001
368  * @tc.desc: Verify that the getPrimitive function returns a successful message
369  * @tc.type: FUNC
370  */
371 HWTEST_F(RangeBuilderTest, range_getprimitive_001, TestSize.Level1)
372 {
373     SaveInputTensor(m_inputs, OH_NN_INT32, m_dim, nullptr);
374     SaveOutputTensor(m_outputs, OH_NN_INT32, m_dim, nullptr);
375     SaveStart(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_START);
376     SaveLimit(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_LIMIT);
377     SaveDelta(OH_NN_INT64, m_paramDim, nullptr, OH_NN_RANGE_DELTA);
378 
379     int64_t startValue = 0;
380     int64_t limitValue = 3;
381     int64_t deltaValue = 1;
382     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
383     LiteGraphPrimitvePtr primitive = m_builder.GetPrimitive();
384     LiteGraphPrimitvePtr expectPrimitive(nullptr, DestroyLiteGraphPrimitive);
385     EXPECT_NE(expectPrimitive, primitive);
386 
387     auto returnStartValue = mindspore::lite::MindIR_Range_GetStart(primitive.get());
388     EXPECT_EQ(returnStartValue, startValue);
389     auto returnLimitValue = mindspore::lite::MindIR_Range_GetLimit(primitive.get());
390     EXPECT_EQ(returnLimitValue, limitValue);
391     auto returnDeltaValue = mindspore::lite::MindIR_Range_GetDelta(primitive.get());
392     EXPECT_EQ(returnDeltaValue, deltaValue);
393 }
394 
395 /**
396  * @tc.name: range_getprimitive_002
397  * @tc.desc: Verify that the getPrimitive function returns a failed message without build.
398  * @tc.type: FUNC
399  */
400 HWTEST_F(RangeBuilderTest, range_getprimitive_002, TestSize.Level1)
401 {
402     LiteGraphPrimitvePtr primitive = m_builder.GetPrimitive();
403     LiteGraphPrimitvePtr expectPrimitive(nullptr, DestroyLiteGraphPrimitive);
404     EXPECT_EQ(expectPrimitive, primitive);
405 }
406 }
407 }
408 }