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/eltwise_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 EltwiseBuilderTest : public OpsTest {
28 public:
29     void SetUp();
30     void TearDown();
31 
32     void SetEltwiseMode(OH_NN_DataType dataType,
33         const std::vector<int32_t> &dim,  const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
34 public:
35     EltwiseBuilder m_builder;
36     std::vector<uint32_t> m_inputs {0, 1};
37     std::vector<uint32_t> m_outputs {2};
38     std::vector<uint32_t> m_params {3};
39     std::vector<int32_t> m_input_dim {3, 3};
40     std::vector<int32_t> m_output_dim {3, 3};
41     std::vector<int32_t> m_param_dim {};
42 };
43 
SetUp()44 void EltwiseBuilderTest::SetUp() {}
45 
TearDown()46 void EltwiseBuilderTest::TearDown() {}
47 
SetEltwiseMode(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)48 void EltwiseBuilderTest::SetEltwiseMode(OH_NN_DataType dataType,
49     const std::vector<int32_t> &dim,  const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
50 {
51     std::shared_ptr<NNTensor> tensor = TransToNNTensor(dataType, dim, quantParam, type);
52     int8_t* modeValue = new (std::nothrow) int8_t(0);
53     EXPECT_NE(nullptr, modeValue);
54     tensor->SetBuffer(modeValue, sizeof(int8_t));
55     m_allTensors.emplace_back(tensor);
56 }
57 
58 /**
59  * @tc.name: eltwise_build_001
60  * @tc.desc: Verify the success of the build function
61  * @tc.type: FUNC
62  */
63 HWTEST_F(EltwiseBuilderTest, eltwise_build_001, TestSize.Level1)
64 {
65     m_paramsIndex = m_params;
66     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
67     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
68 
69     SetEltwiseMode(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
70     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
71 }
72 
73 /**
74  * @tc.name: eltwise_build_002
75  * @tc.desc: Verify the forbidden of the build function
76  * @tc.type: FUNC
77  */
78 HWTEST_F(EltwiseBuilderTest, eltwise_build_002, TestSize.Level1)
79 {
80     m_paramsIndex = m_params;
81     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
82     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
83 
84     SetEltwiseMode(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
85     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
86     EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
87 }
88 
89 /**
90  * @tc.name: eltwise_build_003
91  * @tc.desc: Verify the missing input of the build function
92  * @tc.type: FUNC
93  */
94 HWTEST_F(EltwiseBuilderTest, eltwise_build_003, TestSize.Level1)
95 {
96     m_inputs = {0};
97     m_outputs = {1};
98     m_params = {2};
99     m_paramsIndex = m_params;
100 
101     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
102     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
103 
104     SetEltwiseMode(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
105     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
106 }
107 
108 /**
109  * @tc.name: eltwise_build_004
110  * @tc.desc: Verify the missing output of the build function
111  * @tc.type: FUNC
112  */
113 HWTEST_F(EltwiseBuilderTest, eltwise_build_004, TestSize.Level1)
114 {
115     m_outputs = {};
116     m_params = {2};
117     m_paramsIndex = m_params;
118 
119     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
120     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
121     SetEltwiseMode(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
122 
123     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
124 }
125 
126 /**
127  * @tc.name: eltwise_build_005
128  * @tc.desc: Verify the inputIndex out of bounds of the build function
129  * @tc.type: FUNC
130  */
131 HWTEST_F(EltwiseBuilderTest, eltwise_build_005, TestSize.Level1)
132 {
133     m_inputs = {0, 6};
134     m_paramsIndex = m_params;
135 
136     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
137     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
138     SetEltwiseMode(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
139 
140     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
141 }
142 
143 /**
144  * @tc.name: eltwise_build_006
145  * @tc.desc: Verify the outputIndex out of bounds of the build function
146  * @tc.type: FUNC
147  */
148 HWTEST_F(EltwiseBuilderTest, eltwise_build_006, TestSize.Level1)
149 {
150     m_outputs = {6};
151     m_paramsIndex = m_params;
152 
153     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
154     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
155     SetEltwiseMode(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
156     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
157 }
158 
159 /**
160  * @tc.name: eltwise_build_007
161  * @tc.desc: Verify the invalid eltwiseMode of the build function
162  * @tc.type: FUNC
163  */
164 
165 HWTEST_F(EltwiseBuilderTest, eltwise_build_007, TestSize.Level1)
166 {
167     m_paramsIndex = m_params;
168     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
169     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
170 
171     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT32, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
172     int32_t* modeValue = new (std::nothrow) int32_t(0);
173     EXPECT_NE(nullptr, modeValue);
174 
175     tensor->SetBuffer(modeValue, sizeof(int32_t));
176     m_allTensors.emplace_back(tensor);
177     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
178 }
179 
180 /**
181  * @tc.name: eltwise_build_008
182  * @tc.desc: Verify the scalar length of the build function
183  * @tc.type: FUNC
184  */
185 
186 HWTEST_F(EltwiseBuilderTest, eltwise_build_008, TestSize.Level1)
187 {
188     m_paramsIndex = m_params;
189     m_param_dim = {2};
190 
191     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
192     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
193 
194     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
195     int8_t* modeValue = new (std::nothrow) int8_t[2]{0, 0};
196     EXPECT_NE(nullptr, modeValue);
197 
198     tensor->SetBuffer(modeValue, 2 * sizeof(int8_t));
199     m_allTensors.emplace_back(tensor);
200     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
201 }
202 
203 /**
204  * @tc.name: eltwise_build_008
205  * @tc.desc: Verify the invalid mode value of the build function
206  * @tc.type: FUNC
207  */
208 
209 HWTEST_F(EltwiseBuilderTest, eltwise_build_009, TestSize.Level1)
210 {
211     m_paramsIndex = m_params;
212     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
213     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
214 
215     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
216     int8_t* modeValue = new (std::nothrow) int8_t(10);
217     EXPECT_NE(nullptr, modeValue);
218 
219     tensor->SetBuffer(modeValue, sizeof(int8_t));
220     m_allTensors.emplace_back(tensor);
221     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
222 }
223 
224 /**
225  * @tc.name: eltwise_build_010
226  * @tc.desc: Verify the invalid param to eltwise of the build function
227  * @tc.type: FUNC
228  */
229 
230 HWTEST_F(EltwiseBuilderTest, eltwise_build_010, TestSize.Level1)
231 {
232     m_paramsIndex = m_params;
233     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
234     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
235 
236     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr, OH_NN_DIV_ACTIVATIONTYPE);
237     int8_t* modeValue = new (std::nothrow) int8_t(0);
238     EXPECT_NE(nullptr, modeValue);
239 
240     tensor->SetBuffer(modeValue, sizeof(int8_t));
241     m_allTensors.emplace_back(tensor);
242     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
243 }
244 
245 /**
246  * @tc.name: eltwise_build_011
247  * @tc.desc: Verify the eltwise without set mode of the build function
248  * @tc.type: FUNC
249  */
250 HWTEST_F(EltwiseBuilderTest, eltwise_build_011, TestSize.Level1)
251 {
252     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
253     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
254     std::shared_ptr<NNTensor> tensor = TransToNNTensor(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
255     m_allTensors.emplace_back(tensor);
256     EXPECT_EQ(OH_NN_INVALID_PARAMETER, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
257 }
258 
259 /**
260  * @tc.name: eltwise_getprimitive_001
261  * @tc.desc: Verify the success of the GetPrimitive function
262  * @tc.type: FUNC
263  */
264 HWTEST_F(EltwiseBuilderTest, eltwise_getprimitive_001, TestSize.Level1)
265 {
266     m_paramsIndex = m_params;
267     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
268     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
269     SetEltwiseMode(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
270 
271     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_paramsIndex, m_inputsIndex, m_outputsIndex, m_allTensors));
272     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
273     LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
274     EXPECT_NE(expectPrimitive, primitive);
275     bool eltwiseModeReturn = mindspore::lite::MindIR_Eltwise_GetMode(primitive.get());
276     EXPECT_EQ(eltwiseModeReturn, eltwiseModeReturn);
277 }
278 
279 /**
280  * @tc.name: eltwise_getprimitive_002
281  * @tc.desc: Verify the nullptr return of the GetPrimitive function
282  * @tc.type: FUNC
283  */
284 HWTEST_F(EltwiseBuilderTest, eltwise_getprimitive_002, TestSize.Level1)
285 {
286     m_paramsIndex = m_params;
287     SaveInputTensor(m_inputs, OH_NN_FLOAT32, m_input_dim, nullptr);
288     SaveOutputTensor(m_outputs, OH_NN_FLOAT32, m_output_dim, nullptr);
289     SetEltwiseMode(OH_NN_INT8, m_param_dim, nullptr, OH_NN_ELTWISE_MODE);
290 
291     LiteGraphTensorPtr primitive = m_builder.GetPrimitive();
292     LiteGraphTensorPtr expectPrimitive = {nullptr, DestroyLiteGraphPrimitive};
293     EXPECT_EQ(expectPrimitive, primitive);
294 }
295 } // namespace UnitTest
296 } // namespace NeuralNetworkRuntime
297 } // namespace OHOS