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/unsqueeze_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 UnsqueezeBuilderTest : public OpsTest {
30 protected:
31 void InitTensor(const std::vector<uint32_t>& inputsIndex,
32 const std::vector<uint32_t>& outputsIndex) override;
33 void SaveAxisTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
34 const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35
36 protected:
37 UnsqueezeBuilder m_builder;
38 std::vector<int64_t> m_expectAxisValue;
39 };
40
SaveAxisTensor(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)41 void UnsqueezeBuilderTest::SaveAxisTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
42 const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
43 {
44 std::shared_ptr<NNTensor> axisTensor = TransToNNTensor(dataType, dim, quantParam, type);
45 int64_t* axisValue = new (std::nothrow) int64_t[1]{1};
46 axisTensor->SetBuffer(axisValue, sizeof(int64_t));
47 m_allTensors.emplace_back(axisTensor);
48 m_expectAxisValue.emplace_back(*axisValue);
49 }
50
InitTensor(const std::vector<uint32_t> & inputsIndex,const std::vector<uint32_t> & outputsIndex)51 void UnsqueezeBuilderTest::InitTensor(const std::vector<uint32_t>& inputsIndex,
52 const std::vector<uint32_t>& outputsIndex)
53 {
54 std::vector<uint32_t> paramsIndex = { 2 };
55 std::vector<int32_t> inputDim = {1, 5, 1};
56 std::vector<int32_t> OutputDim = {1, 1, 5, 1};
57
58 m_paramsIndex = paramsIndex;
59 SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
60 SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
61 }
62
63 /**
64 * @tc.name: unsqueeze_build_001
65 * @tc.desc: Provide normal input, output, and parameters to verify the normal behavior of the Build function
66 * @tc.type: FUNC
67 */
68 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_001, TestSize.Level0)
69 {
70 std::vector<uint32_t> inputsIndex = { 0 };
71 std::vector<uint32_t> outputsIndex = { 1 };
72 std::vector<int32_t> paramDim = {};
73
74 InitTensor(inputsIndex, outputsIndex);
75 SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_UNSQUEEZE_AXIS);
76
77 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
78 EXPECT_EQ(OH_NN_SUCCESS, ret);
79 }
80
81 /**
82 * @tc.name: unsqueeze_build_002
83 * @tc.desc: Call Build func twice to verify the abnormal behavior of the Build function
84 * @tc.type: FUNC
85 */
86 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_002, TestSize.Level0)
87 {
88 std::vector<uint32_t> inputsIndex = { 0 };
89 std::vector<uint32_t> outputsIndex = { 1 };
90 std::vector<int32_t> paramDim = {};
91
92 InitTensor(inputsIndex, outputsIndex);
93 SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_UNSQUEEZE_AXIS);
94
95 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
96 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
97 EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, ret);
98 }
99
100 /**
101 * @tc.name: unsqueeze_build_003
102 * @tc.desc: Provide one more than normal input to verify the abnormal behavior of the Build function
103 * @tc.type: FUNC
104 */
105 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_003, TestSize.Level0)
106 {
107 std::vector<uint32_t> inputsIndex = { 0, 1, 2 };
108 std::vector<uint32_t> outputsIndex = { 3 };
109 std::vector<int32_t> paramDim = {};
110
111 InitTensor(inputsIndex, outputsIndex);
112 SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_UNSQUEEZE_AXIS);
113
114 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
115 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
116 }
117
118 /**
119 * @tc.name: unsqueeze_build_004
120 * @tc.desc: Provide one more than normal output to verify the abnormal behavior of the Build function
121 * @tc.type: FUNC
122 */
123 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_004, TestSize.Level0)
124 {
125 std::vector<uint32_t> inputsIndex = { 0 };
126 std::vector<uint32_t> outputsIndex = { 1, 2 };
127 std::vector<int32_t> paramDim = {};
128
129 InitTensor(inputsIndex, outputsIndex);
130 SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_UNSQUEEZE_AXIS);
131
132 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
133 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
134 }
135
136 /**
137 * @tc.name: unsqueeze_build_005
138 * @tc.desc: Provide empty input, output, and parameters to verify the abnormal behavior of the Build function
139 * @tc.type: FUNC
140 */
141 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_005, TestSize.Level0)
142 {
143 std::vector<uint32_t> inputsIndex = { 0 };
144 std::vector<uint32_t> outputsIndex = { 1 };
145 std::vector<uint32_t> paramsIndex = { 2 };
146
147 OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, inputsIndex, outputsIndex, m_allTensors);
148 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
149 }
150
151 /**
152 * @tc.name: unsqueeze_build_006
153 * @tc.desc: Provide empty output to verify the abnormal behavior of the Build function
154 * @tc.type: FUNC
155 */
156 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_006, TestSize.Level0)
157 {
158 std::vector<uint32_t> inputsIndex = { 0 };
159 std::vector<uint32_t> outputsIndex = {};
160 std::vector<int32_t> paramDim = {};
161
162 InitTensor(inputsIndex, outputsIndex);
163 SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_UNSQUEEZE_AXIS);
164
165 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
166 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
167 }
168
169 /**
170 * @tc.name: unsqueeze_build_007
171 * @tc.desc: Provide param type error to verify the abnormal behavior of the Build function
172 * @tc.type: FUNC
173 */
174 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_007, TestSize.Level0)
175 {
176 std::vector<uint32_t> inputsIndex = { 0 };
177 std::vector<uint32_t> outputsIndex = { 1 };
178 std::vector<int32_t> paramDim = {};
179
180 InitTensor(inputsIndex, outputsIndex);
181 SaveAxisTensor(OH_NN_INT8, paramDim, nullptr, OH_NN_UNSQUEEZE_AXIS);
182
183 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
184 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
185 }
186
187 /**
188 * @tc.name: unsqueeze_build_008
189 * @tc.desc: Provide param type error to verify the abnormal behavior of the Build function
190 * @tc.type: FUNC
191 */
192 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_008, TestSize.Level0)
193 {
194 std::vector<uint32_t> inputsIndex = { 0 };
195 std::vector<uint32_t> outputsIndex = { 1 };
196 std::vector<int32_t> paramDim = {};
197
198 InitTensor(inputsIndex, outputsIndex);
199 SaveAxisTensor(OH_NN_INT32, paramDim, nullptr, OH_NN_UNSQUEEZE_AXIS);
200
201 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
202 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
203 }
204
205 /**
206 * @tc.name: unsqueeze_build_009
207 * @tc.desc: Provide axis parameter buffer is nullptr to verify the abnormal behavior of the Build function
208 * @tc.type: FUNC
209 */
210 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_009, TestSize.Level0)
211 {
212 std::vector<uint32_t> inputsIndex = { 0 };
213 std::vector<uint32_t> outputsIndex = { 1 };
214 std::vector<int32_t> paramDim = {};
215
216 InitTensor(inputsIndex, outputsIndex);
217
218 std::shared_ptr<NNTensor> axisTensor = TransToNNTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_UNSQUEEZE_AXIS);
219 axisTensor->SetBuffer(nullptr, 0);
220 m_allTensors.emplace_back(axisTensor);
221
222 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
223 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
224 }
225
226 /**
227 * @tc.name: unsqueeze_build_010
228 * @tc.desc: Provide axis parameter is not scaler to verify the abnormal behavior of the Build function
229 * @tc.type: FUNC
230 */
231 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_010, TestSize.Level0)
232 {
233 std::vector<uint32_t> inputsIndex = { 0 };
234 std::vector<uint32_t> outputsIndex = { 1 };
235 std::vector<int32_t> paramDim = {1, 2};
236
237 InitTensor(inputsIndex, outputsIndex);
238 SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_UNSQUEEZE_AXIS);
239
240 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
241 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
242 }
243
244 /**
245 * @tc.name: unsqueeze_build_011
246 * @tc.desc: Provide invalid parameter type to verify the abnormal behavior of the Build function
247 * @tc.type: FUNC
248 */
249 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_build_011, TestSize.Level0)
250 {
251 std::vector<uint32_t> inputsIndex = { 0 };
252 std::vector<uint32_t> outputsIndex = { 1 };
253 std::vector<int32_t> paramDim = {};
254
255 InitTensor(inputsIndex, outputsIndex);
256 SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_SCALE_AXIS);
257
258 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
259 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
260 }
261
262 /**
263 * @tc.name: unsqueeze_get_primitive_001
264 * @tc.desc: Verify the GetPrimitive function return nullptr
265 * @tc.type: FUNC
266 */
267 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_get_primitive_001, TestSize.Level0)
268 {
269 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
270 LiteGraphTensorPtr expectPrimitive = { nullptr, DestroyLiteGraphPrimitive };
271 EXPECT_EQ(primitive, expectPrimitive);
272 }
273
274 /**
275 * @tc.name: unsqueeze_get_primitive_002
276 * @tc.desc: Verify the normal params return behavior of the getprimitive function
277 * @tc.type: FUNC
278 */
279 HWTEST_F(UnsqueezeBuilderTest, unsqueeze_get_primitive_002, TestSize.Level0)
280 {
281 std::vector<uint32_t> inputsIndex = { 0 };
282 std::vector<uint32_t> outputsIndex = { 1 };
283 std::vector<int32_t> paramDim = {};
284
285 InitTensor(inputsIndex, outputsIndex);
286 SaveAxisTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_UNSQUEEZE_AXIS);
287
288 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
289 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
290 LiteGraphTensorPtr expectPrimitive = { nullptr, DestroyLiteGraphPrimitive };
291 EXPECT_NE(primitive, expectPrimitive);
292
293 auto axisReturn = mindspore::lite::MindIR_Unsqueeze_GetAxis(primitive.get());
294 auto axisReturnSize = axisReturn.size();
295 for (size_t i = 0; i < axisReturnSize; ++i) {
296 EXPECT_EQ(axisReturn[i], m_expectAxisValue[i]);
297 }
298 }
299 } // namespace UnitTest
300 } // namespace NeuralNetworkRuntime
301 } // namespace OHOS
302