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