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 "frameworks/native/ops/top_k_builder.h"
17
18 #include <gtest/gtest.h>
19 #include "frameworks/native/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 TopKBuilderTest : public OpsTest {
30 protected:
31 void InitTensor(const std::vector<uint32_t>& inputsIndex,
32 const std::vector<uint32_t>& outputsIndex) override;
33 void SaveSortedTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
34 const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35
36 protected:
37 TopKBuilder m_builder;
38 bool m_topkValue {false};
39 };
40
InitTensor(const std::vector<uint32_t> & inputsIndex,const std::vector<uint32_t> & outputsIndex)41 void TopKBuilderTest::InitTensor(const std::vector<uint32_t>& inputsIndex, const std::vector<uint32_t>& outputsIndex)
42 {
43 std::vector<uint32_t> paramsIndex = { 4 };
44 std::vector<int32_t> inputDim = {9};
45 std::vector<int32_t> OutputDim = {3};
46
47 m_paramsIndex = paramsIndex;
48 SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
49 SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
50 }
51
SaveSortedTensor(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)52 void TopKBuilderTest::SaveSortedTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
53 const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
54 {
55 std::shared_ptr<NNTensor> topkTensor = TransToNNTensor(dataType, dim, quantParam, type);
56 bool* topkValue = new (std::nothrow) bool[1]{true};
57 EXPECT_NE(nullptr, topkValue);
58 topkTensor->SetBuffer(topkValue, sizeof(bool));
59 m_allTensors.emplace_back(topkTensor);
60 m_topkValue = *topkValue;
61 }
62
63 /**
64 * @tc.name: topk_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(TopKBuilderTest, topk_build_001, TestSize.Level0)
69 {
70 std::vector<uint32_t> inputsIndex = { 0, 1 };
71 std::vector<uint32_t> outputsIndex = { 2, 3 };
72 std::vector<int32_t> paramDim = {};
73
74 InitTensor(inputsIndex, outputsIndex);
75 SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED);
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: topk_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(TopKBuilderTest, topk_build_002, TestSize.Level0)
87 {
88 std::vector<uint32_t> inputsIndex = { 0, 1 };
89 std::vector<uint32_t> outputsIndex = { 2, 3 };
90 std::vector<int32_t> paramDim = {};
91
92 InitTensor(inputsIndex, outputsIndex);
93 SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED);
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: topk_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(TopKBuilderTest, topk_build_003, TestSize.Level0)
106 {
107 std::vector<uint32_t> inputsIndex = { 0, 1, 2, 3 };
108 std::vector<uint32_t> outputsIndex = { 4, 5 };
109 std::vector<int32_t> paramDim = {};
110
111 InitTensor(inputsIndex, outputsIndex);
112 SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED);
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: topk_builder_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(TopKBuilderTest, topk_builder_004, TestSize.Level0)
124 {
125 std::vector<uint32_t> inputsIndex = { 0, 1 };
126 std::vector<uint32_t> outputsIndex = { 2, 3, 4 };
127 std::vector<int32_t> paramDim = {};
128
129 InitTensor(inputsIndex, outputsIndex);
130 SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED);
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: topk_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(TopKBuilderTest, topk_build_005, TestSize.Level0)
142 {
143 std::vector<uint32_t> inputsIndex = { 0, 1, 2 };
144 std::vector<uint32_t> outputsIndex = { 3, 4 };
145 std::vector<uint32_t> paramsIndex = { 5 };
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: topk_build_006
153 * @tc.desc: Provide param type error to verify the abnormal behavior of the Build function
154 * @tc.type: FUNC
155 */
156 HWTEST_F(TopKBuilderTest, topk_build_006, TestSize.Level0)
157 {
158 std::vector<uint32_t> inputsIndex = { 0, 1 };
159 std::vector<uint32_t> outputsIndex = { 2, 3 };
160 std::vector<int32_t> paramDim = {};
161
162 InitTensor(inputsIndex, outputsIndex);
163 SaveSortedTensor(OH_NN_INT8, paramDim, nullptr, OH_NN_TOP_K_SORTED);
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: topk_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(TopKBuilderTest, topk_build_007, TestSize.Level0)
175 {
176 std::vector<uint32_t> inputsIndex = { 0, 1 };
177 std::vector<uint32_t> outputsIndex = { 2, 3 };
178 std::vector<int32_t> paramDim = {};
179
180 InitTensor(inputsIndex, outputsIndex);
181 SaveSortedTensor(OH_NN_INT32, paramDim, nullptr, OH_NN_TOP_K_SORTED);
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: topk_build_008
189 * @tc.desc: Provide sorted parameter buffer is nullptr to verify the abnormal behavior of the Build function
190 * @tc.type: FUNC
191 */
192 HWTEST_F(TopKBuilderTest, topk_build_008, TestSize.Level0)
193 {
194 std::vector<uint32_t> inputsIndex = { 0, 1 };
195 std::vector<uint32_t> outputsIndex = { 2, 3 };
196 std::vector<int32_t> paramDim = {};
197
198 InitTensor(inputsIndex, outputsIndex);
199
200 std::shared_ptr<NNTensor> topkTensor = TransToNNTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED);
201 topkTensor->SetBuffer(nullptr, 0);
202 m_allTensors.emplace_back(topkTensor);
203
204 OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
205 EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
206 }
207
208 /**
209 * @tc.name: topk_build_009
210 * @tc.desc: Provide invalid parameter type to verify the abnormal behavior of the Build function
211 * @tc.type: FUNC
212 */
213 HWTEST_F(TopKBuilderTest, topk_build_009, TestSize.Level0)
214 {
215 std::vector<uint32_t> inputsIndex = { 0, 1 };
216 std::vector<uint32_t> outputsIndex = { 2, 3 };
217 std::vector<int32_t> paramDim = {};
218
219 InitTensor(inputsIndex, outputsIndex);
220 SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_SCALE_AXIS);
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: topk_get_primitive_001
228 * @tc.desc: Verify the GetPrimitive function return nullptr
229 * @tc.type: FUNC
230 */
231 HWTEST_F(TopKBuilderTest, topk_get_primitive_001, TestSize.Level0)
232 {
233 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
234 LiteGraphTensorPtr expectPrimitive = { nullptr, DestroyLiteGraphPrimitive };
235 EXPECT_EQ(primitive, expectPrimitive);
236 }
237
238 /**
239 * @tc.name: topk_get_primitive_002
240 * @tc.desc: Verify the normal params return behavior of the getprimitive function
241 * @tc.type: FUNC
242 */
243 HWTEST_F(TopKBuilderTest, topk_get_primitive_002, TestSize.Level0)
244 {
245 std::vector<uint32_t> inputsIndex = { 0, 1 };
246 std::vector<uint32_t> outputsIndex = { 2, 3 };
247 std::vector<int32_t> paramDim = {};
248 InitTensor(inputsIndex, outputsIndex);
249 SaveSortedTensor(OH_NN_BOOL, paramDim, nullptr, OH_NN_TOP_K_SORTED);
250
251 EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
252 LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
253 LiteGraphTensorPtr expectPrimitive = { nullptr, DestroyLiteGraphPrimitive };
254 EXPECT_NE(primitive, expectPrimitive);
255
256 auto sortedReturn = mindspore::lite::MindIR_TopKFusion_GetSorted(primitive.get());
257 EXPECT_EQ(sortedReturn, m_topkValue);
258 }
259 } // namespace UnitTest
260 } // namespace NeuralNetworkRuntime
261 } // namespace OHOS
262