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/crop_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 CropBuilderTest : public OpsTest {
28 public:
29 void SetUp() override;
30 void TearDown() override;
31
32 protected:
33 void SaveAxis(OH_NN_DataType dataType,
34 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35 void SaveOffset(OH_NN_DataType dataType,
36 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
37 void SetInputAndShape();
38
39 protected:
40 CropBuilder m_builder;
41 std::vector<uint32_t> m_inputs {0, 1};
42 std::vector<uint32_t> m_outputs {2};
43 std::vector<uint32_t> m_params {3, 4};
44 std::vector<int32_t> m_inputDim {2, 3, 4, 5};
45 std::vector<int32_t> m_shapeDim {1};
46 std::vector<int32_t> m_outputDim {2, 3, 4, 5};
47 std::vector<int32_t> m_axisDim {};
48 std::vector<int32_t> m_offsetDim {1};
49 };
50
SetUp()51 void CropBuilderTest::SetUp() {}
52
TearDown()53 void CropBuilderTest::TearDown() {}
54
SetInputAndShape()55 void CropBuilderTest::SetInputAndShape()
56 {
57 m_inputsIndex = m_inputs;
58 std::shared_ptr<NNTensor> inputTensor;
59 inputTensor = TransToNNTensor(OH_NN_FLOAT32, m_inputDim, nullptr, OH_NN_TENSOR);
60 m_allTensors.emplace_back(inputTensor);
61
62 std::shared_ptr<NNTensor> shapeTensor;
63 shapeTensor = TransToNNTensor(OH_NN_FLOAT32, m_shapeDim, nullptr, OH_NN_TENSOR);
64 m_allTensors.emplace_back(shapeTensor);
65 }
66
SaveAxis(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)67 void CropBuilderTest::SaveAxis(OH_NN_DataType dataType,
68 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
69 {
70 std::shared_ptr<NNTensor> axisTensor = TransToNNTensor(dataType, dim, quantParam, type);
71 int64_t* axisValue = new (std::nothrow) int64_t[1] {0};
72 axisTensor->SetBuffer(axisValue, sizeof(int64_t));
73 m_allTensors.emplace_back(axisTensor);
74 }
75
SaveOffset(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)76 void CropBuilderTest::SaveOffset(OH_NN_DataType dataType,
77 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
78 {
79 std::shared_ptr<NNTensor> offsetTensor = TransToNNTensor(dataType, dim, quantParam, type);
80 int64_t* offsetValue = new (std::nothrow) int64_t[1] {1};
81 offsetTensor->SetBuffer(offsetValue, sizeof(int64_t));
82 m_allTensors.emplace_back(offsetTensor);
83 }
84
85 /**
86 * @tc.name: crop_build_001
87 * @tc.desc: Verify that the build function returns a successful message.
88 * @tc.type: FUNC
89 */
90 HWTEST_F(CropBuilderTest, crop_build_001, TestSize.Level1)
91 {
92 SetInputAndShape();
93 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
94 SaveAxis(OH_NN_INT64, m_axisDim, nullptr, OH_NN_CROP_AXIS);
95 SaveOffset(OH_NN_INT64, m_offsetDim, nullptr, OH_NN_CROP_OFFSET);
96
97 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
98 EXPECT_EQ(OH_NN_SUCCESS, ret);
99 }
100
101 /**
102 * @tc.name: crop_build_002
103 * @tc.desc: Verify that the build function returns a failed message with true m_isBuild.
104 * @tc.type: FUNC
105 */
106 HWTEST_F(CropBuilderTest, crop_build_002, TestSize.Level1)
107 {
108 SetInputAndShape();
109 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
110 SaveAxis(OH_NN_INT64, m_axisDim, nullptr, OH_NN_CROP_AXIS);
111 SaveOffset(OH_NN_INT64, m_offsetDim, nullptr, OH_NN_CROP_OFFSET);
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: crop_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(CropBuilderTest, crop_build_003, TestSize.Level1)
124 {
125 m_inputs = {0, 1, 2};
126 m_outputs = {3};
127 m_params = {4, 5};
128
129 SetInputAndShape();
130 std::shared_ptr<NNTensor> inputTensor = TransToNNTensor(OH_NN_FLOAT32, m_inputDim, nullptr, OH_NN_TENSOR);
131 m_allTensors.emplace_back(inputTensor);
132
133 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
134 SaveAxis(OH_NN_INT64, m_axisDim, nullptr, OH_NN_CROP_AXIS);
135 SaveOffset(OH_NN_INT64, m_offsetDim, nullptr, OH_NN_CROP_OFFSET);
136
137 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputs, m_outputs, m_allTensors);
138 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
139 }
140
141 /**
142 * @tc.name: crop_build_004
143 * @tc.desc: Verify that the build function returns a failed message with invalided output.
144 * @tc.type: FUNC
145 */
146 HWTEST_F(CropBuilderTest, crop_build_004, TestSize.Level1)
147 {
148 m_outputs = {2, 3};
149 m_params = {4, 5};
150
151 SetInputAndShape();
152 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
153 SaveAxis(OH_NN_INT64, m_axisDim, nullptr, OH_NN_CROP_AXIS);
154 SaveOffset(OH_NN_INT64, m_offsetDim, nullptr, OH_NN_CROP_OFFSET);
155
156 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
157 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
158 }
159
160 /**
161 * @tc.name: crop_build_005
162 * @tc.desc: Verify that the build function returns a failed message with empty allTensor.
163 * @tc.type: FUNC
164 */
165 HWTEST_F(CropBuilderTest, crop_build_005, TestSize.Level1)
166 {
167 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputs, m_outputs, m_allTensors);
168 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
169 }
170
171 /**
172 * @tc.name: crop_build_006
173 * @tc.desc: Verify that the build function returns a failed message without output tensor.
174 * @tc.type: FUNC
175 */
176 HWTEST_F(CropBuilderTest, crop_build_006, TestSize.Level1)
177 {
178 SetInputAndShape();
179
180 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputs, m_allTensors);
181 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
182 }
183
184 /**
185 * @tc.name: crop_build_007
186 * @tc.desc: Verify that the build function returns a failed message with invalid axis's dataType.
187 * @tc.type: FUNC
188 */
189 HWTEST_F(CropBuilderTest, crop_build_007, TestSize.Level1)
190 {
191 SetInputAndShape();
192 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
193
194 std::shared_ptr<NNTensor> axisTensor = TransToNNTensor(OH_NN_FLOAT32, m_axisDim,
195 nullptr, OH_NN_CROP_AXIS);
__anonfbf230a50102null196 float* axisValue = new (std::nothrow) float [1]{0.0f};
197 axisTensor->SetBuffer(axisValue, sizeof(float));
198 m_allTensors.emplace_back(axisTensor);
199 SaveOffset(OH_NN_INT64, m_offsetDim, nullptr, OH_NN_CROP_OFFSET);
200
201 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
202 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
203 }
204
205 /**
206 * @tc.name: crop_build_008
207 * @tc.desc: Verify that the build function returns a failed message with invalid offset's dataType.
208 * @tc.type: FUNC
209 */
210 HWTEST_F(CropBuilderTest, crop_build_008, TestSize.Level1)
211 {
212 SetInputAndShape();
213 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
214
215 SaveAxis(OH_NN_INT64, m_axisDim, nullptr, OH_NN_CROP_AXIS);
216 std::shared_ptr<NNTensor> offsetTensor = TransToNNTensor(OH_NN_FLOAT32, m_offsetDim,
217 nullptr, OH_NN_CROP_OFFSET);
__anonfbf230a50202null218 float* offsetValue = new (std::nothrow) float[1] {1.0f};
219 int32_t offsetSize = 1;
220 EXPECT_NE(nullptr, offsetValue);
221 offsetTensor->SetBuffer(offsetValue, sizeof(float) * offsetSize);
222 m_allTensors.emplace_back(offsetTensor);
223
224 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
225 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
226 }
227
228 /**
229 * @tc.name: crop_build_009
230 * @tc.desc: Verify that the build function returns a failed message with passing invalid dataType param.
231 * @tc.type: FUNC
232 */
233 HWTEST_F(CropBuilderTest, crop_build_009, TestSize.Level1)
234 {
235 SetInputAndShape();
236 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
237 SaveAxis(OH_NN_INT64, m_axisDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
238 SaveOffset(OH_NN_INT64, m_offsetDim, nullptr, OH_NN_CROP_OFFSET);
239
240 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
241 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
242 }
243
244 /**
245 * @tc.name: crop_build_010
246 * @tc.desc: Verify that the build function returns a failed message with passing invalid value param.
247 * @tc.type: FUNC
248 */
249 HWTEST_F(CropBuilderTest, crop_build_010, TestSize.Level1)
250 {
251 SetInputAndShape();
252 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
253 SaveAxis(OH_NN_INT64, m_axisDim, nullptr, OH_NN_CROP_AXIS);
254 SaveOffset(OH_NN_INT64, m_offsetDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
255
256 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
257 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
258 }
259
260 /**
261 * @tc.name: crop_build_011
262 * @tc.desc: Verify that the build function returns a failed message without set buffer for dataType.
263 * @tc.type: FUNC
264 */
265 HWTEST_F(CropBuilderTest, crop_build_011, TestSize.Level1)
266 {
267 SetInputAndShape();
268 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
269
270 std::shared_ptr<NNTensor> dataTypeTensor = TransToNNTensor(OH_NN_INT64, m_axisDim,
271 nullptr, OH_NN_CROP_AXIS);
272 m_allTensors.emplace_back(dataTypeTensor);
273 SaveOffset(OH_NN_INT64, m_offsetDim, nullptr, OH_NN_CROP_OFFSET);
274
275 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
276 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
277 }
278
279 /**
280 * @tc.name: crop_build_012
281 * @tc.desc: Verify that the build function returns a failed message without set buffer for value.
282 * @tc.type: FUNC
283 */
284 HWTEST_F(CropBuilderTest, crop_build_012, TestSize.Level1)
285 {
286 SetInputAndShape();
287 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
288
289 SaveAxis(OH_NN_INT64, m_axisDim, nullptr, OH_NN_CROP_AXIS);
290 std::shared_ptr<NNTensor> valueTensor = TransToNNTensor(OH_NN_INT64, m_offsetDim,
291 nullptr, OH_NN_CROP_OFFSET);
292 m_allTensors.emplace_back(valueTensor);
293
294 OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
295 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
296 }
297
298 /**
299 * @tc.name: crop_getprimitive_001
300 * @tc.desc: Verify that the getPrimitive function returns a successful message
301 * @tc.type: FUNC
302 */
303 HWTEST_F(CropBuilderTest, crop_getprimitive_001, TestSize.Level1)
304 {
305 SetInputAndShape();
306 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_outputDim, nullptr);
307 SaveAxis(OH_NN_INT64, m_axisDim, nullptr, OH_NN_CROP_AXIS);
308 SaveOffset(OH_NN_INT64, m_offsetDim, nullptr, OH_NN_CROP_OFFSET);
309
310 int64_t axisValue = 0;
311 std::vector<int64_t> offsetsValue = {1};
312 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
313 LiteGraphPrimitvePtr primitive = m_builder.GetPrimitive();
314 LiteGraphPrimitvePtr expectPrimitive(nullptr, DestroyLiteGraphPrimitive);
315 EXPECT_NE(expectPrimitive, primitive);
316
317 auto returnAxisValue = mindspore::lite::MindIR_Crop_GetAxis(primitive.get());
318 EXPECT_EQ(returnAxisValue, axisValue);
319 auto returnOffsets = mindspore::lite::MindIR_Crop_GetOffsets(primitive.get());
320 auto returnOffsetsSize = returnOffsets.size();
321 for (size_t i = 0; i < returnOffsetsSize; ++i) {
322 EXPECT_EQ(returnOffsets[i], offsetsValue[i]);
323 }
324 }
325
326 /**
327 * @tc.name: crop_getprimitive_002
328 * @tc.desc: Verify that the getPrimitive function returns a failed message without build.
329 * @tc.type: FUNC
330 */
331 HWTEST_F(CropBuilderTest, crop_getprimitive_002, TestSize.Level1)
332 {
333 LiteGraphPrimitvePtr primitive = m_builder.GetPrimitive();
334 LiteGraphPrimitvePtr expectPrimitive(nullptr, DestroyLiteGraphPrimitive);
335 EXPECT_EQ(expectPrimitive, primitive);
336 }
337 }
338 }
339 }