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/slice_builder.h"
17 
18 #include <gtest/gtest.h>
19 #include "nn_tensor.h"
20 #include "ops_test.h"
21 
22 using namespace testing;
23 using namespace testing::ext;
24 using namespace OHOS::NeuralNetworkRuntime::Ops;
25 
26 namespace OHOS {
27 namespace NeuralNetworkRuntime {
28 namespace UnitTest {
29 class SliceBuilderTest : public OpsTest {
30 protected:
31     void InitTensor(const std::vector<uint32_t>& inputsIndex,
32         const std::vector<uint32_t>& outputsIndex) override;
33     void SaveAxesTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
34         const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35 
36 protected:
37     SliceBuilder m_builder;
38     std::vector<uint32_t> inputsIndex = { 0, 1, 2 };
39     std::vector<uint32_t> outputsIndex = { 3 };
40     std::vector<uint32_t> paramsIndex = { 4 };
41     std::vector<int32_t> paramsDim = {};
42 };
43 
InitTensor(const std::vector<uint32_t> & inputsIndex,const std::vector<uint32_t> & outputsIndex)44 void SliceBuilderTest::InitTensor(const std::vector<uint32_t>& inputsIndex,
45                                   const std::vector<uint32_t>& outputsIndex)
46 {
47     std::vector<int32_t> inputDim = {3, 2, 3};
48     std::vector<int32_t> OutputDim = {1, 1, 3};
49 
50     m_paramsIndex = paramsIndex;
51     SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
52     SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
53 }
54 
SaveAxesTensor(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)55 void SliceBuilderTest::SaveAxesTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
56     const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
57 {
58     std::shared_ptr<NNTensor> axesTensor = TransToNNTensor(dataType, dim, quantParam, type);
59     int64_t* axesValue = new (std::nothrow) int64_t[1]{0};
60     EXPECT_NE(nullptr, axesValue);
61     axesTensor->SetBuffer(axesValue, sizeof(int64_t));
62     m_allTensors.emplace_back(axesTensor);
63 }
64 
65 /**
66  * @tc.name: slice_build_001
67  * @tc.desc: Provide normal input, output, and parameters to verify the normal behavior of the Build function
68  * @tc.type: FUNC
69  */
70 HWTEST_F(SliceBuilderTest, slice_build_001, TestSize.Level0)
71 {
72     InitTensor(inputsIndex, outputsIndex);
73     SaveAxesTensor(OH_NN_INT64, paramsDim, nullptr, OH_NN_SLICE_AXES);
74 
75     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
76     EXPECT_EQ(OH_NN_SUCCESS, ret);
77 }
78 
79 /**
80  * @tc.name: slice_build_002
81  * @tc.desc: Call Build func twice to verify the abnormal behavior of the Build function
82  * @tc.type: FUNC
83  */
84 HWTEST_F(SliceBuilderTest, slice_build_002, TestSize.Level0)
85 {
86     InitTensor(inputsIndex, outputsIndex);
87     SaveAxesTensor(OH_NN_INT64, paramsDim, nullptr, OH_NN_SLICE_AXES);
88 
89     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
90     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
91     EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, ret);
92 }
93 
94 /**
95  * @tc.name: slice_build_003
96  * @tc.desc: Provide one more than normal input to verify the abnormal behavior of the Build function
97  * @tc.type: FUNC
98  */
99 HWTEST_F(SliceBuilderTest, slice_build_003, TestSize.Level0)
100 {
101     inputsIndex = { 0, 1, 2, 3 };
102     outputsIndex = { 4 };
103     paramsIndex = { 5 };
104 
105     InitTensor(inputsIndex, outputsIndex);
106     SaveAxesTensor(OH_NN_INT64, paramsDim, nullptr, OH_NN_SLICE_AXES);
107 
108     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
109     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
110 }
111 
112 /**
113  * @tc.name: slice_build_004
114  * @tc.desc: Provide one more than normal output to verify the abnormal behavior of the Build function
115  * @tc.type: FUNC
116  */
117 HWTEST_F(SliceBuilderTest, slice_build_004, TestSize.Level0)
118 {
119     inputsIndex = { 0, 1, 2 };
120     outputsIndex = { 3, 4 };
121     paramsIndex = { 5 };
122 
123     InitTensor(inputsIndex, outputsIndex);
124     SaveAxesTensor(OH_NN_INT64, paramsDim, nullptr, OH_NN_SLICE_AXES);
125 
126     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
127     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
128 }
129 
130 /**
131  * @tc.name: slice_build_005
132  * @tc.desc: Provide empty input, output, and parameters to verify the abnormal behavior of the Build function
133  * @tc.type: FUNC
134  */
135 HWTEST_F(SliceBuilderTest, slice_build_005, TestSize.Level0)
136 {
137     inputsIndex = {};
138     outputsIndex = {};
139     paramsIndex = {};
140 
141     InitTensor(inputsIndex, outputsIndex);
142     SaveAxesTensor(OH_NN_INT64, paramsDim, nullptr, OH_NN_SLICE_AXES);
143 
144     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
145     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
146 }
147 
148 /**
149  * @tc.name: slice_build_006
150  * @tc.desc: Provide empty output to verify the abnormal behavior of the Build function
151  * @tc.type: FUNC
152  */
153 HWTEST_F(SliceBuilderTest, slice_build_006, TestSize.Level0)
154 {
155     inputsIndex = { 0, 1, 2 };
156     outputsIndex = {};
157     paramsIndex = {};
158 
159     InitTensor(inputsIndex, outputsIndex);
160     SaveAxesTensor(OH_NN_INT64, paramsDim, nullptr, OH_NN_SLICE_AXES);
161 
162     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
163     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
164 }
165 
166 /**
167  * @tc.name: slice_build_007
168  * @tc.desc: Provide a valid datatype param to verify the abnormal behavior of the Build function
169  * @tc.type: FUNC
170  */
171 HWTEST_F(SliceBuilderTest, slice_build_007, TestSize.Level0)
172 {
173     std::vector<int32_t> inputDim = { 3, 2, 3 };
174     std::vector<int32_t> OutputDim = { 1, 1, 3 };
175     std::vector<int32_t> paramsDim = {};
176 
177     m_paramsIndex = paramsIndex;
178     SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
179     SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
180 
181     std::shared_ptr<NNTensor> axesTensor = TransToNNTensor(OH_NN_FLOAT32, paramsDim,
182         nullptr, OH_NN_SLICE_AXES);
__anon33db19270102null183     float* axesValue = new (std::nothrow) float[1] {0.0f};
184     EXPECT_NE(nullptr, axesValue);
185     axesTensor->SetBuffer(axesValue, sizeof(float));
186     m_allTensors.emplace_back(axesTensor);
187 
188     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
189     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
190 }
191 
192 /**
193  * @tc.name: slice_build_008
194  * @tc.desc: Provide a valid type param to verify the abnormal behavior of the Build function
195  * @tc.type: FUNC
196  */
197 HWTEST_F(SliceBuilderTest, slice_build_008, TestSize.Level0)
198 {
199     std::vector<int32_t> inputDim = { 3, 2, 3 };
200     std::vector<int32_t> OutputDim = { 1, 1, 3 };
201     std::vector<int32_t> paramsDim = {};
202 
203     m_paramsIndex = paramsIndex;
204     SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
205     SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
206     SaveAxesTensor(OH_NN_INT64, paramsDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
207 
208     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
209     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
210 }
211 
212 /**
213  * @tc.name: slice_build_009
214  * @tc.desc: Provide a param without set buffer to verify the abnormal behavior of the Build function
215  * @tc.type: FUNC
216  */
217 HWTEST_F(SliceBuilderTest, slice_build_009, TestSize.Level0)
218 {
219     std::vector<int32_t> inputDim = { 3, 2, 3 };
220     std::vector<int32_t> OutputDim = { 1, 1, 3 };
221     std::vector<int32_t> paramsDim = {};
222 
223     m_paramsIndex = paramsIndex;
224     SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
225     SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
226 
227     std::shared_ptr<NNTensor> axesTensor = TransToNNTensor(OH_NN_INT64, paramsDim,
228         nullptr, OH_NN_SLICE_AXES);
229     m_allTensors.emplace_back(axesTensor);
230 
231 
232     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
233     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
234 }
235 
236 /**
237  * @tc.name: slice_getprimitive_001
238  * @tc.desc: Verify the GetPrimitive function return nullptr
239  * @tc.type: FUNC
240  */
241 HWTEST_F(SliceBuilderTest, slice_getprimitive_001, TestSize.Level0)
242 {
243     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
244     LiteGraphTensorPtr expectPrimitive(nullptr, DestroyLiteGraphPrimitive);
245     EXPECT_EQ(primitive, expectPrimitive);
246 }
247 
248 /**
249  * @tc.name: slice_getprimitive_002
250  * @tc.desc: Verify the normal params return behavior of the getprimitive function
251  * @tc.type: FUNC
252  */
253 HWTEST_F(SliceBuilderTest, slice_getprimitive_002, TestSize.Level0)
254 {
255     InitTensor(inputsIndex, outputsIndex);
256     SaveAxesTensor(OH_NN_INT64, paramsDim, nullptr, OH_NN_SLICE_AXES);
257 
258     std::vector<int64_t> expectAxesValue = {0};
259     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
260     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
261     LiteGraphTensorPtr expectPrimitive(nullptr, DestroyLiteGraphPrimitive);
262     EXPECT_NE(primitive, expectPrimitive);
263 
264     auto returnAxes = mindspore::lite::MindIR_SliceFusion_GetAxes(primitive.get());
265     auto returnAxesSize = returnAxes.size();
266     for (size_t i = 0; i < returnAxesSize; ++i) {
267         EXPECT_EQ(returnAxes[i], expectAxesValue[i]);
268     }
269 }
270 } // namespace UnitTest
271 } // namespace NeuralNetworkRuntime
272 } // namespace OHOS
273