1 /*
2  * Copyright (c) 2023 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/instance_norm_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 InstanceNormBuilderTest : public OpsTest {
28 public:
29     void SetUp() override;
30     void TearDown() override;
31 
32 protected:
33     void SaveParamsTensor(OH_NN_DataType dataType,
34         const std::vector<int32_t> &dim,  const OH_NN_QuantParam* quantParam, OH_NN_TensorType type);
35     void SetInputTensor();
36 
37 protected:
38     InstanceNormBuilder m_builder;
39     std::vector<uint32_t> m_inputs {0, 1, 2};
40     std::vector<uint32_t> m_outputs {3};
41     std::vector<uint32_t> m_params {4};
42     std::vector<int32_t> m_inputDim {2, 2, 2, 2};
43     std::vector<int32_t> m_scaleAndBiasDim {1};
44     std::vector<int32_t> m_outputDim {2, 2, 2, 2};
45     std::vector<int32_t> m_paramDim {};
46 };
47 
SetUp()48 void InstanceNormBuilderTest::SetUp() {}
49 
TearDown()50 void InstanceNormBuilderTest::TearDown() {}
51 
SaveParamsTensor(OH_NN_DataType dataType,const std::vector<int32_t> & dim,const OH_NN_QuantParam * quantParam,OH_NN_TensorType type)52 void InstanceNormBuilderTest::SaveParamsTensor(OH_NN_DataType dataType,
53     const std::vector<int32_t> &dim, const OH_NN_QuantParam* quantParam, OH_NN_TensorType type)
54 {
55     std::shared_ptr<NNTensor> epsilonTensor = TransToNNTensor(dataType, dim, quantParam, type);
56     float* epsilonValue = new (std::nothrow) float [1]{0.0f};
57     EXPECT_NE(nullptr, epsilonValue);
58     epsilonTensor->SetBuffer(epsilonValue, sizeof(float));
59     m_allTensors.emplace_back(epsilonTensor);
60 }
61 
SetInputTensor()62 void InstanceNormBuilderTest::SetInputTensor()
63 {
64     m_inputsIndex = m_inputs;
65     std::shared_ptr<NNTensor> inputTensor;
66     inputTensor = TransToNNTensor(OH_NN_FLOAT32, m_inputDim, nullptr, OH_NN_TENSOR);
67     m_allTensors.emplace_back(inputTensor);
68 
69     std::shared_ptr<NNTensor> scaleTensor;
70     scaleTensor = TransToNNTensor(OH_NN_FLOAT32, m_scaleAndBiasDim, nullptr, OH_NN_TENSOR);
71     m_allTensors.emplace_back(scaleTensor);
72 
73     std::shared_ptr<NNTensor> biasTensor;
74     biasTensor = TransToNNTensor(OH_NN_FLOAT32, m_scaleAndBiasDim, nullptr, OH_NN_TENSOR);
75     m_allTensors.emplace_back(biasTensor);
76 }
77 
78 /**
79  * @tc.name: instance_norm_build_001
80  * @tc.desc: Verify that the build function returns a successful message.
81  * @tc.type: FUNC
82  */
83 HWTEST_F(InstanceNormBuilderTest, instance_norm_build_001, TestSize.Level1)
84 {
85     SetInputTensor();
86     SaveOutputTensor(m_outputs, OH_NN_INT32, m_outputDim, nullptr);
87     SaveParamsTensor(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_INSTANCE_NORM_EPSILON);
88 
89     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
90     EXPECT_EQ(OH_NN_SUCCESS, ret);
91 }
92 
93 /**
94  * @tc.name: instance_norm_build_002
95  * @tc.desc: Verify that the build function returns a failed message with true m_isBuild.
96  * @tc.type: FUNC
97  */
98 HWTEST_F(InstanceNormBuilderTest, instance_norm_build_002, TestSize.Level1)
99 {
100     SetInputTensor();
101     SaveOutputTensor(m_outputs, OH_NN_INT32, m_outputDim, nullptr);
102     SaveParamsTensor(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_INSTANCE_NORM_EPSILON);
103 
104     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
105     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
106     EXPECT_EQ(OH_NN_OPERATION_FORBIDDEN, ret);
107 }
108 
109 /**
110  * @tc.name: instance_norm_build_003
111  * @tc.desc: Verify that the build function returns a failed message with invalided input.
112  * @tc.type: FUNC
113  */
114 HWTEST_F(InstanceNormBuilderTest, instance_norm_build_003, TestSize.Level1)
115 {
116     m_inputs = {0, 1, 2, 3};
117     m_outputs = {4};
118     m_params = {5};
119 
120     SetInputTensor();
121     SaveOutputTensor(m_outputs, OH_NN_INT32, m_outputDim, nullptr);
122     SaveParamsTensor(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_INSTANCE_NORM_EPSILON);
123 
124     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
125     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
126 }
127 
128 /**
129  * @tc.name: instance_norm_build_004
130  * @tc.desc: Verify that the build function returns a failed message with invalided output.
131  * @tc.type: FUNC
132  */
133 HWTEST_F(InstanceNormBuilderTest, instance_norm_build_004, TestSize.Level1)
134 {
135     m_outputs = {3, 4};
136     m_params = {5};
137 
138     SetInputTensor();
139     SaveOutputTensor(m_outputs, OH_NN_INT32, m_outputDim, nullptr);
140     SaveParamsTensor(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_INSTANCE_NORM_EPSILON);
141 
142     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
143     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
144 }
145 
146 /**
147  * @tc.name: instance_norm_build_005
148  * @tc.desc: Verify that the build function returns a failed message with empty allTensor.
149  * @tc.type: FUNC
150  */
151 HWTEST_F(InstanceNormBuilderTest, instance_norm_build_005, TestSize.Level1)
152 {
153     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputs, m_outputs, m_allTensors);
154     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
155 }
156 
157 /**
158  * @tc.name: instance_norm_build_006
159  * @tc.desc: Verify that the build function returns a failed message without output tensor.
160  * @tc.type: FUNC
161  */
162 HWTEST_F(InstanceNormBuilderTest, instance_norm_build_006, TestSize.Level1)
163 {
164     SetInputTensor();
165 
166     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputs, m_allTensors);
167     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
168 }
169 
170 /**
171  * @tc.name: instance_norm_build_007
172  * @tc.desc: Verify that the build function returns a failed message with invalid epsilon's dataType.
173  * @tc.type: FUNC
174  */
175 HWTEST_F(InstanceNormBuilderTest, instance_norm_build_007, TestSize.Level1)
176 {
177     SetInputTensor();
178     SaveOutputTensor(m_outputs, OH_NN_INT32, m_outputDim, nullptr);
179 
180     std::shared_ptr<NNTensor> epsilonTensor = TransToNNTensor(OH_NN_INT64, m_paramDim,
181         nullptr, OH_NN_INSTANCE_NORM_EPSILON);
182     int64_t* epsilonValue = new (std::nothrow) int64_t [1]{0.0f};
183     EXPECT_NE(nullptr, epsilonValue);
184     epsilonTensor->SetBuffer(epsilonValue, sizeof(epsilonValue));
185     m_allTensors.emplace_back(epsilonTensor);
186 
187     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
188     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
189 }
190 
191 /**
192  * @tc.name: instance_norm_build_008
193  * @tc.desc: Verify that the build function returns a failed message with passing invalid epsilon param.
194  * @tc.type: FUNC
195  */
196 HWTEST_F(InstanceNormBuilderTest, instance_norm_build_008, TestSize.Level1)
197 {
198     SetInputTensor();
199     SaveOutputTensor(m_outputs, OH_NN_INT32, m_outputDim, nullptr);
200     SaveParamsTensor(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_MUL_ACTIVATION_TYPE);
201 
202     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
203     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
204 }
205 
206 /**
207  * @tc.name: instance_norm_build_009
208  * @tc.desc: Verify that the build function returns a failed message without set buffer for epsilon.
209  * @tc.type: FUNC
210  */
211 HWTEST_F(InstanceNormBuilderTest, instance_norm_build_009, TestSize.Level1)
212 {
213     SetInputTensor();
214     SaveOutputTensor(m_outputs, OH_NN_INT32, m_outputDim, nullptr);
215 
216     std::shared_ptr<NNTensor> epsilonTensor = TransToNNTensor(OH_NN_FLOAT32, m_paramDim,
217         nullptr, OH_NN_INSTANCE_NORM_EPSILON);
218     m_allTensors.emplace_back(epsilonTensor);
219 
220     OH_NN_ReturnCode ret = m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors);
221     EXPECT_EQ(OH_NN_INVALID_PARAMETER, ret);
222 }
223 
224 /**
225  * @tc.name: instance_norm_getprimitive_001
226  * @tc.desc: Verify that the getPrimitive function returns a successful message
227  * @tc.type: FUNC
228  */
229 HWTEST_F(InstanceNormBuilderTest, instance_norm_getprimitive_001, TestSize.Level1)
230 {
231     SetInputTensor();
232     SaveOutputTensor(m_outputs, OH_NN_INT32, m_outputDim, nullptr);
233     SaveParamsTensor(OH_NN_FLOAT32, m_paramDim, nullptr, OH_NN_INSTANCE_NORM_EPSILON);
234 
235     float epsilonValue = 0.0f;
236     EXPECT_EQ(OH_NN_SUCCESS, m_builder.Build(m_params, m_inputsIndex, m_outputsIndex, m_allTensors));
237     LiteGraphPrimitvePtr primitive = m_builder.GetPrimitive();
238     LiteGraphPrimitvePtr expectPrimitive(nullptr, DestroyLiteGraphPrimitive);
239     EXPECT_NE(expectPrimitive, primitive);
240 
241     auto returnEpsilonValue = mindspore::lite::MindIR_InstanceNorm_GetEpsilon(primitive.get());
242     EXPECT_EQ(returnEpsilonValue, epsilonValue);
243 }
244 
245 /**
246  * @tc.name: instance_norm_getprimitive_002
247  * @tc.desc: Verify that the getPrimitive function returns a failed message without build.
248  * @tc.type: FUNC
249  */
250 HWTEST_F(InstanceNormBuilderTest, instance_norm_getprimitive_002, TestSize.Level1)
251 {
252     LiteGraphPrimitvePtr primitive = m_builder.GetPrimitive();
253     LiteGraphPrimitvePtr expectPrimitive(nullptr, DestroyLiteGraphPrimitive);
254     EXPECT_EQ(expectPrimitive, primitive);
255 }
256 }
257 }
258 }