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/tile_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 TileBuilderTest : public OpsTest {
30 protected:
31     void InitTensor(const std::vector<uint32_t>& inputsIndex,
32         const std::vector<uint32_t>& outputsIndex) override;
33     void SaveDimsTensor(OH_NN_DataType dataType, const std::vector<int32_t> &dim,
34         const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35 
36 protected:
37     TileBuilder m_builder;
38     std::vector<uint32_t> inputsIndex = { 0, 1 };
39     std::vector<uint32_t> outputsIndex = { 2 };
40     std::vector<uint32_t> paramsIndex = { 3 };
41     std::vector<int32_t> paramDim = {};
42 };
43 
InitTensor(const std::vector<uint32_t> & inputsIndex,const std::vector<uint32_t> & outputsIndex)44 void TileBuilderTest::InitTensor(const std::vector<uint32_t>& inputsIndex,
45                                  const std::vector<uint32_t>& outputsIndex)
46 {
47     std::vector<int32_t> inputDim = {2, 2};
48     std::vector<int32_t> OutputDim = {4, 4};
49 
50     m_paramsIndex = paramsIndex;
51     SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
52     SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
53 }
54 
SaveDimsTensor(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)55 void TileBuilderTest::SaveDimsTensor(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> dimsTensor = TransToNNTensor(dataType, dim, quantParam, type);
59     int64_t* dimsValue = new (std::nothrow) int64_t[1] {0};
60     EXPECT_NE(nullptr, dimsValue);
61     dimsTensor->SetBuffer(dimsValue, sizeof(int64_t));
62     m_allTensors.emplace_back(dimsTensor);
63 }
64 
65 /**
66  * @tc.name: tile_build_001
67  * @tc.desc: Provide normal input, output to verify the normal behavior of the Build function
68  * @tc.type: FUNC
69  */
70 HWTEST_F(TileBuilderTest, tile_build_001, TestSize.Level0)
71 {
72     InitTensor(inputsIndex, outputsIndex);
73     SaveDimsTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TILE_DIMS);
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: tile_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(TileBuilderTest, tile_build_002, TestSize.Level0)
85 {
86     InitTensor(inputsIndex, outputsIndex);
87     SaveDimsTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TILE_DIMS);
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: tile_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(TileBuilderTest, tile_build_003, TestSize.Level0)
100 {
101     inputsIndex = { 0, 1, 2 };
102     outputsIndex = { 3 };
103     paramsIndex = { 4 };
104 
105     InitTensor(inputsIndex, outputsIndex);
106     SaveDimsTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TILE_DIMS);
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: tile_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(TileBuilderTest, tile_build_004, TestSize.Level0)
118 {
119     outputsIndex = { 2, 3 };
120     paramsIndex = { 4 };
121 
122     InitTensor(inputsIndex, outputsIndex);
123     SaveDimsTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TILE_DIMS);
124 
125     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
126     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
127 }
128 
129 /**
130  * @tc.name: tile_build_005
131  * @tc.desc: Provide empty input, output, and parameters to verify the abnormal behavior of the Build function
132  * @tc.type: FUNC
133  */
134 HWTEST_F(TileBuilderTest, tile_build_005, TestSize.Level0)
135 {
136     OH_NN_ReturnCode ret = m_builder.Build(paramsIndex, inputsIndex, outputsIndex, m_allTensors);
137     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
138 }
139 
140 /**
141  * @tc.name: tile_build_006
142  * @tc.desc: Provide empty output to verify the abnormal behavior of the Build function
143  * @tc.type: FUNC
144  */
145 HWTEST_F(TileBuilderTest, tile_build_006, TestSize.Level0)
146 {
147     std::vector<int32_t> inputDim = {2, 2};
148 
149     SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
150 
151     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, outputsIndex, m_allTensors);
152     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
153 }
154 
155 /**
156  * @tc.name: tile_build_007
157  * @tc.desc: Provide a valid datatype param to verify the abnormal behavior of the Build function
158  * @tc.type: FUNC
159  */
160 HWTEST_F(TileBuilderTest, tile_build_007, TestSize.Level0)
161 {
162     std::vector<int32_t> inputDim = {2, 2};
163     std::vector<int32_t> OutputDim = {4, 4};
164 
165     m_paramsIndex = paramsIndex;
166     SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
167     SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
168 
169     std::shared_ptr<NNTensor> dimsTensor = TransToNNTensor(OH_NN_FLOAT32, paramDim,
170         nullptr, OH_NN_TILE_DIMS);
__anond68e77050102null171     float* dimsValue = new (std::nothrow) float[1] {0.0f};
172     EXPECT_NE(nullptr, dimsValue);
173     dimsTensor->SetBuffer(dimsValue, sizeof(float));
174     m_allTensors.emplace_back(dimsTensor);
175 
176     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
177     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
178 }
179 
180 /**
181  * @tc.name: tile_build_008
182  * @tc.desc: Provide a valid type param to verify the abnormal behavior of the Build function
183  * @tc.type: FUNC
184  */
185 HWTEST_F(TileBuilderTest, tile_build_008, TestSize.Level0)
186 {
187     std::vector<int32_t> inputDim = {2, 2};
188     std::vector<int32_t> OutputDim = {4, 4};
189     m_paramsIndex = paramsIndex;
190     SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
191     SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
192     SaveDimsTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
193 
194     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
195     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
196 }
197 
198 /**
199  * @tc.name: tile_build_009
200  * @tc.desc: Provide a param without set buffer to verify the abnormal behavior of the Build function
201  * @tc.type: FUNC
202  */
203 HWTEST_F(TileBuilderTest, tile_build_009, TestSize.Level0)
204 {
205     std::vector<int32_t> inputDim = {2, 2};
206     std::vector<int32_t> OutputDim = {4, 4};
207 
208     m_paramsIndex = paramsIndex;
209     SaveInputTensor(inputsIndex, OH_NN_FLOAT32, inputDim, nullptr);
210     SaveOutputTensor(outputsIndex, OH_NN_FLOAT32, OutputDim, nullptr);
211 
212     std::shared_ptr<NNTensor> dimsTensor = TransToNNTensor(OH_NN_INT64, paramDim,
213         nullptr, OH_NN_TILE_DIMS);
214     m_allTensors.emplace_back(dimsTensor);
215 
216 
217     OH_NN_ReturnCode ret = m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors);
218     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
219 }
220 
221 /**
222  * @tc.name: tile_get_primitive_001
223  * @tc.desc: Verify the GetPrimitive function return nullptr
224  * @tc.type: FUNC
225  */
226 HWTEST_F(TileBuilderTest, tile_get_primitive_001, TestSize.Level0)
227 {
228     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
229     LiteGraphTensorPtr expectPrimitive = { nullptr, DestroyLiteGraphPrimitive };
230     EXPECT_EQ(primitive, expectPrimitive);
231 }
232 
233 /**
234  * @tc.name: tile_getprimitive_002
235  * @tc.desc: Verify the normal params return behavior of the getprimitive function
236  * @tc.type: FUNC
237  */
238 HWTEST_F(TileBuilderTest, tile_getprimitive_002, TestSize.Level0)
239 {
240     InitTensor(inputsIndex, outputsIndex);
241     SaveDimsTensor(OH_NN_INT64, paramDim, nullptr, OH_NN_TILE_DIMS);
242 
243     std::vector<int64_t> expectDimsValue = {0};
244     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
245     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
246     LiteGraphTensorPtr expectPrimitive = { nullptr, DestroyLiteGraphPrimitive };
247     EXPECT_NE(primitive, expectPrimitive);
248 
249     auto returnDims = mindspore::lite::MindIR_TileFusion_GetDims(primitive.get());
250     auto returnDimsSize = returnDims.size();
251     for (size_t i = 0; i < returnDimsSize; ++i) {
252         EXPECT_EQ(returnDims[i], expectDimsValue[i]);
253     }
254 }
255 } // namespace UnitTest
256 } // namespace NeuralNetworkRuntime
257 } // namespace OHOS
258