xref: /aosp_15_r20/external/armnn/delegate/test/DepthwiseConvolution2dTest.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "ConvolutionTestHelper.hpp"
7 
8 #include <armnn_delegate.hpp>
9 
10 #include <flatbuffers/flatbuffers.h>
11 #include <tensorflow/lite/interpreter.h>
12 #include <tensorflow/lite/kernels/register.h>
13 #include <tensorflow/lite/model.h>
14 #include <schema_generated.h>
15 #include <tensorflow/lite/version.h>
16 
17 #include <doctest/doctest.h>
18 
19 namespace armnnDelegate
20 {
21 
DepthwiseConv2dValidReluFp32Test(std::vector<armnn::BackendId> & backends)22 void DepthwiseConv2dValidReluFp32Test(std::vector<armnn::BackendId>& backends)
23 {
24     // Set input data
25     std::vector<int32_t> inputShape { 1, 3, 2, 2 };
26     std::vector<int32_t> filterShape { 1, 2, 2, 4 };
27     std::vector<int32_t> biasShape { 4 };
28     std::vector<int32_t> outputShape { 1, 2, 1, 4 };
29 
30     static std::vector<float> inputValues =
31         {
32             1, 2,  7,  8,
33             3, 4,  9, 10,
34             5, 6, 11, 12
35         };
36 
37     std::vector<float> filterValues =
38         {
39             1,    2,   3,   4,
40            -9,   10, -11,  12,
41             5,    6,   7,   8,
42             13,  -14,  15, -16
43         };
44 
45     std::vector<float> biasValues = { 1, 2, 3, 4 };
46 
47     std::vector<float> expectedOutputValues =
48         {
49             71, 0,  99, 0,
50             91, 0, 127, 0
51         };
52 
53     tflite::Padding padding = tflite::Padding_VALID;
54     int32_t depth_multiplier = 2;
55 
56     ConvolutionTest<float>(tflite::BuiltinOperator_DEPTHWISE_CONV_2D,
57                            ::tflite::TensorType_FLOAT32,
58                            1, // strideX
59                            1, // strideY
60                            1, // dilationX
61                            1, // dilationY
62                            padding,
63                            tflite::ActivationFunctionType_RELU,
64                            backends,
65                            inputShape,
66                            filterShape,
67                            outputShape,
68                            inputValues,
69                            filterValues,
70                            expectedOutputValues,
71                            biasShape,
72                            biasValues,
73                            {1.0f}, // biasScale
74                            {0},    // biasOffset
75                            {1.0f}, // filterScale
76                            {0},    // filterOffsets
77                            2.0f,   // outputQuantScale
78                            0,      // outputQuantOffset
79                            1.0f,   // quantScale
80                            0,      // quantOffset
81                            depth_multiplier);
82 }
83 
DepthwiseConv2dSameUint8Test(std::vector<armnn::BackendId> & backends)84 void DepthwiseConv2dSameUint8Test(std::vector<armnn::BackendId>& backends)
85 {
86     // Set input data
87     std::vector<int32_t> inputShape { 1, 3, 3, 1 };
88     std::vector<int32_t> filterShape { 1, 3, 3, 1 };
89     std::vector<int32_t> biasShape { 1 } ;
90     std::vector<int32_t> outputShape { 1, 3, 3, 1 };
91 
92     static std::vector<uint8_t> inputValues =
93         {
94             0, 1, 2,
95             3, 4, 5,
96             6, 7, 8
97         };
98 
99     std::vector<uint8_t> filterValues = { 9, 8, 7,  6, 5, 4,  3, 2, 1 };
100 
101     std::vector<int32_t> biasValues = { 10 };
102 
103     std::vector<uint8_t> expectedOutputValues =
104         {
105             12,  23, 24, // ( 14+10)/2, ( 35+10)/2, ( 38+10)/2,
106             34,  65, 61, // ( 57+10)/2, (120+10)/2, (111+10)/2,
107             60, 104, 84  // (110+10)/2, (197+10)/2, (158+10)/2
108         };
109 
110     tflite::Padding padding = tflite::Padding_SAME;
111 
112     ConvolutionTest<uint8_t, int32_t>(tflite::BuiltinOperator_DEPTHWISE_CONV_2D,
113                                       ::tflite::TensorType_UINT8,
114                                       1, // strideX
115                                       1, // strideY
116                                       1, // dilationX
117                                       1, // dilationY
118                                       padding,
119                                       tflite::ActivationFunctionType_NONE,
120                                       backends,
121                                       inputShape,
122                                       filterShape,
123                                       outputShape,
124                                       inputValues,
125                                       filterValues,
126                                       expectedOutputValues,
127                                       biasShape,
128                                       biasValues);
129 }
130 
DepthwiseConv2dSameInt8PerChannelTest(std::vector<armnn::BackendId> & backends)131 void DepthwiseConv2dSameInt8PerChannelTest(std::vector<armnn::BackendId>& backends)
132 {
133     // Set input data
134     std::vector<int32_t> inputShape { 1, 4, 4, 4 };
135     std::vector<int32_t> filterShape { 1, 2, 2, 16 };
136     std::vector<int32_t> biasShape {16} ;
137     std::vector<int32_t> outputShape { 1, 4, 4, 16 };
138 
139     static std::vector<int8_t> inputValues =
140         {
141             3,3,3,4, 4,4,0,0, 0,3,4,3, 0,2,2,3,
142             3,0,3,0, 0,3,2,1, 4,1,2,2, 0,0,0,4,
143             3,2,2,2, 2,1,0,4, 4,3,2,4, 3,2,0,0,
144             4,1,4,4, 1,0,4,3, 3,2,0,3, 1,1,0,2
145         };
146 
147     std::vector<int8_t> filterValues = { 12,20,10, 3, 2,24, 9,10, 5,16,30,12, 3,10, 4,32,
148                                            8, 0,30, 3, 0,16,12,15,20,12, 0, 3, 9,20, 8, 8,
149                                           12,15,20, 0, 0, 0, 3,15,15, 8,40,12, 9, 5, 2,24,
150                                            4, 0, 0, 6, 6, 0, 3, 5,20, 8,20, 3, 6,15, 4, 0 };
151     std::vector<float> filterScales = {         0.25,   0.2,        0.1, 0.3333333333,
152                                                  0.5, 0.125, 0.33333333,          0.2,
153                                                  0.2,  0.25,        0.1,  0.333333333,
154                                         0.3333333333,   0.2,        0.5,        0.125 };
155 
156     int32_t filterQuantizationDim = 3;
157 
158     int32_t depth_multiplier = 4;
159 
160     std::vector<int32_t> biasValues = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
161 
162     float inputScale = 1.0f;
163     std::vector<float> biasScales {};
164     std::vector<int64_t> biasOffsets {};
165     std::vector<int64_t> filterOffsets {};
166     for (const auto& filterScale: filterScales)
167     {
168         biasScales.push_back(inputScale * filterScale);
169         // filter and bias offset always needs to be zero for per channel. We don't support anything else
170         biasOffsets.push_back(0);
171         filterOffsets.push_back(0);
172     }
173 
174     std::vector<int8_t> expectedOutputValues =
175         {
176             26,21,21, 7,12,17,28,21,20,22,25,26, 6,11,10,16,
177             16,16, 4,12, 7,18,28,27,30,20,12,14,16,19,17, 6,
178             12,12, 8, 0, 3,13,18,15,18,26,20,26,26,32,28,21,
179             0, 0, 0, 0, 2, 6, 6, 4, 2, 8, 6, 8,15,10,10,24,
180             20,21, 9, 7, 3, 6,15,16,17,22,17,22,17,18,14, 7,
181             18, 6,16,12,12,11,17,15,18,18,10,12,27,26,22,18,
182             27,28,12,10, 7, 3, 8,13, 8,12,14,16,26,24,24,24,
183             9, 9, 6, 0, 0, 0, 2, 6, 0, 0, 0, 0, 4, 8, 8,16,
184             26,24,17, 7, 2, 8,11,10,30,24,30,28,32,33,30,24,
185             20,11,16,12, 7, 9,17,13,20,14,16,18,31,36,33,29,
186             28,25,19, 9, 6,13,20,19, 2, 8, 6, 8,17,17,15,25,
187             12,15, 5, 3, 2, 6, 7, 7, 0, 0, 0, 0, 6, 2, 2, 6,
188             14,16, 7, 5, 1, 3, 3, 2,20,28,12,20,13,20,20,19,
189             9, 4,10, 4, 0, 4, 8, 6, 4,16,12,16,12,18,18,15,
190             11,12, 6, 4, 2, 8,10, 7, 0, 0, 0, 0, 9,14,14,14,
191             3, 4, 1, 1, 1, 3, 3, 2, 0, 0, 0, 0, 2, 4, 4, 8
192         };
193 
194     tflite::Padding padding = tflite::Padding_SAME;
195 
196     ConvolutionTest<int8_t, int32_t>(tflite::BuiltinOperator_DEPTHWISE_CONV_2D,
197                                       ::tflite::TensorType_INT8,
198                                       1, // strideX
199                                       1, // strideY
200                                       1, // dilationX
201                                       1, // dilationY
202                                       padding,
203                                       tflite::ActivationFunctionType_NONE,
204                                       backends,
205                                       inputShape,
206                                       filterShape,
207                                       outputShape,
208                                       inputValues,
209                                       filterValues,
210                                       expectedOutputValues,
211                                       biasShape,
212                                       biasValues,
213                                       biasScales,
214                                       biasOffsets,
215                                       filterScales,
216                                       filterOffsets,
217                                       1.0f,
218                                       0,
219                                       inputScale,
220                                       0,
221                                       depth_multiplier,
222                                       filterQuantizationDim);
223 }
224 
225 TEST_SUITE("DepthwiseConv2d_CpuRef_Tests")
226 {
227 
228 TEST_CASE ("DepthwiseConv2d_Valid_Relu_Fp32_CpuRef_Test")
229 {
230     std::vector<armnn::BackendId> backends = {armnn::Compute::CpuRef};
231     DepthwiseConv2dValidReluFp32Test(backends);
232 }
233 
234 TEST_CASE ("DepthwiseConv2d_Same_Uint8_CpuRef_Test")
235 {
236     std::vector<armnn::BackendId> backends = {armnn::Compute::CpuRef};
237     DepthwiseConv2dSameUint8Test(backends);
238 }
239 
240 TEST_CASE ("DepthwiseConv2d_Same_Int8_PerChannelQuantization_CpuRef_Test")
241 {
242     std::vector<armnn::BackendId> backends = {armnn::Compute::CpuRef};
243     DepthwiseConv2dSameInt8PerChannelTest(backends);
244 }
245 
246 }//End of TEST_SUITE("DepthwiseConv2d_CpuRef_Tests")
247 
248 TEST_SUITE("DepthwiseConv2d_CpuAcc_Tests")
249 {
250 
251 TEST_CASE ("DepthwiseConv2d_Valid_Relu_Fp32_CpuAcc_Test")
252 {
253     std::vector<armnn::BackendId> backends = {armnn::Compute::CpuAcc};
254     DepthwiseConv2dValidReluFp32Test(backends);
255 }
256 
257 TEST_CASE ("DepthwiseConv2d_Same_Uint8_CpuAcc_Test")
258 {
259     std::vector<armnn::BackendId> backends = {armnn::Compute::CpuAcc};
260     DepthwiseConv2dSameUint8Test(backends);
261 }
262 
263 }//End of TEST_SUITE("DepthwiseConv2d_CpuAcc_Tests")
264 
265 TEST_SUITE("DepthwiseConv2d_GpuAcc_Tests")
266 {
267 
268 TEST_CASE ("DepthwiseConv2d_Valid_Relu_Fp32_GpuAcc_Test")
269 {
270     std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc};
271     DepthwiseConv2dValidReluFp32Test(backends);
272 }
273 
274 TEST_CASE ("DepthwiseConv2d_Same_Uint8_GpuAcc_Test")
275 {
276     std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc};
277     DepthwiseConv2dSameUint8Test(backends);
278 }
279 
280 }//End of TEST_SUITE("DepthwiseConv2d_GpuAcc_Tests")
281 
282 } // namespace armnnDelegate