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/concat_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 ConcatTwoInputBuilderTest : public OpsTest {
28 public:
29 void SetUp() override;
30 void TearDown() override;
31
32 void SetAxis(OH_NN_DataType dataType,
33 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
34
35 public:
36 ConcatBuilder m_builder;
37 std::vector<uint32_t> m_inputs{0, 1};
38 std::vector<uint32_t> m_outputs{2};
39 std::vector<uint32_t> m_params{3};
40 std::vector<int32_t> m_input_dim{3, 3};
41 std::vector<int32_t> m_output_dim{3, 3};
42 std::vector<int32_t> m_param_dim{};
43 };
44
SetUp()45 void ConcatTwoInputBuilderTest::SetUp() {}
46
TearDown()47 void ConcatTwoInputBuilderTest::TearDown() {}
48
SetAxis(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)49 void ConcatTwoInputBuilderTest::SetAxis(OH_NN_DataType dataType,
50 const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
51 {
52 std::shared_ptr<NNTensor> tensor = TransToNNTensor(dataType, dim, quantParam, type);
53 int64_t* axisValue = new (std::nothrow) int64_t(0);
54 EXPECT_NE(nullptr, axisValue);
55
56 tensor->SetBuffer(axisValue, sizeof(int64_t));
57 m_allTensors.emplace_back(tensor);
58 }
59
60 /**
61 * @tc.name: concat_build_two_input_001
62 * @tc.desc: Verify the success of the build function
63 * @tc.type: FUNC
64 */
65 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_001, TestSize.Level1)
66 {
67 m_paramsIndex = m_params;
68 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
69 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
70
71 SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
72 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
73 }
74
75 /**
76 * @tc.name: concat_build_two_input_002
77 * @tc.desc: Verify the forbidden of the build function
78 * @tc.type: FUNC
79 */
80 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_002, TestSize.Level1)
81 {
82 m_paramsIndex = m_params;
83 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
84 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
85
86 SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
87 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
88 EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
89 }
90
91 /**
92 * @tc.name: concat_build_two_input_003
93 * @tc.desc: Verify the missing input of the build function
94 * @tc.type: FUNC
95 */
96 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_003, TestSize.Level1)
97 {
98 m_inputs = {0};
99 m_outputs = {2};
100 m_params = {3};
101 m_paramsIndex = m_params;
102
103 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
104 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
105
106 SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
107 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
108 }
109
110 /**
111 * @tc.name: concat_build_two_input_004
112 * @tc.desc: Verify the missing output of the build function
113 * @tc.type: FUNC
114 */
115 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_004, TestSize.Level1)
116 {
117 m_inputs = {0, 1};
118 m_outputs = {};
119 m_params = {3};
120 m_paramsIndex = m_params;
121
122 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
123 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
124
125 SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
126 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
127 }
128
129 /**
130 * @tc.name: concat_build_two_input_005
131 * @tc.desc: Verify the inputIndex out of bounds of the build function
132 * @tc.type: FUNC
133 */
134 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_005, TestSize.Level1)
135 {
136 m_inputs = {0, 1, 6};
137 m_outputs = {3};
138 m_params = {4};
139 m_paramsIndex = m_params;
140
141 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
142 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
143
144 SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
145 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
146 }
147
148 /**
149 * @tc.name: concat_build_two_input_006
150 * @tc.desc: Verify the outputIndex out of bounds of the build function
151 * @tc.type: FUNC
152 */
153 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_006, TestSize.Level1)
154 {
155 m_inputs = {0, 1};
156 m_outputs = {6};
157 m_params = {3};
158 m_paramsIndex = m_params;
159
160 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
161 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
162
163 SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
164 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
165 }
166
167 /**
168 * @tc.name: concat_build_two_input_007
169 * @tc.desc: Verify the invalid axis of the build function
170 * @tc.type: FUNC
171 */
172 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_007, TestSize.Level1)
173 {
174 m_paramsIndex = m_params;
175 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
176 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
177
178 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT32, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
179 int32_t* axisValue = new (std::nothrow) int32_t(0);
180 EXPECT_NE(nullptr, axisValue);
181
182 tensor->SetBuffer(axisValue, sizeof(int32_t));
183 m_allTensors.emplace_back(tensor);
184 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
185 }
186
187 /**
188 * @tc.name: concat_build_two_input_008
189 * @tc.desc: Verify the scalar length of the build function
190 * @tc.type: FUNC
191 */
192 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_008, TestSize.Level1)
193 {
194 m_param_dim = {2};
195 m_paramsIndex = m_params;
196
197 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
198 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
199
200 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
201 int64_t* axisValue = new (std::nothrow) int64_t[2]{0, 0};
202 EXPECT_NE(nullptr, axisValue);
203
204 tensor->SetBuffer(axisValue, 2 * sizeof(int64_t));
205 m_allTensors.emplace_back(tensor);
206 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
207 }
208
209 /**
210 * @tc.name: concat_build_two_input_009
211 * @tc.desc: This is OH_NN_INVALID_PARAMETER case, course the value of axis is nullptr.
212 * @tc.type: FUNC
213 */
214 HWTEST_F(ConcatTwoInputBuilderTest, concat_build_two_input_010, TestSize.Level1)
215 {
216 m_paramsIndex = m_params;
217 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
218 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
219
220 std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
221 m_allTensors.emplace_back(tensor);
222
223 EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
224 }
225
226 /**
227 * @tc.name: concat_getprimitive_two_input_001
228 * @tc.desc: Verify the success of the GetPrimitive function
229 * @tc.type: FUNC
230 */
231 HWTEST_F(ConcatTwoInputBuilderTest, concat_getprimitive_two_input_001, TestSize.Level1)
232 {
233 m_paramsIndex = m_params;
234 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
235 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
236
237 SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
238 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
239 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
240 LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
241 EXPECT_NE(expectPrimitive, primitive);
242
243 int64_t returnValue = mindspore::lite::MindIR_Concat_GetAxis(primitive.get());
244 EXPECT_EQ(returnValue, 0);
245 }
246
247 /**
248 * @tc.name: concat_getprimitive_two_input_001
249 * @tc.desc: Verify the nullptr return of the GetPrimitive function
250 * @tc.type: FUNC
251 */
252 HWTEST_F(ConcatTwoInputBuilderTest, concat_getprimitive_two_input_002, TestSize.Level1)
253 {
254 m_paramsIndex = m_params;
255 SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
256 SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
257
258 SetAxis(OH_NN_INT64, m_param_dim, nullptr, OH_NN_CONCAT_AXIS);
259 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
260 LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
261 EXPECT_EQ(expectPrimitive, primitive);
262 }
263 } // namespace UnitTest
264 } // namespace NeuralNetworkRuntime
265 } // namespace OHOS