blob: 0e11445b8e85065f76e814cc9e907702f2cc4b6b [file] [log] [blame]
Sadik Armagan32ca1442020-11-13 17:51:56 +00001//
Teresa Charlinad1b3d72023-03-14 12:10:28 +00002// Copyright © 2020, 2023 Arm Ltd and Contributors. All rights reserved.
Sadik Armagan32ca1442020-11-13 17:51:56 +00003// 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>
Sadik Armagan32ca1442020-11-13 17:51:56 +000014#include <tensorflow/lite/version.h>
15
16#include <doctest/doctest.h>
17
18namespace armnnDelegate
19{
20
21void Conv2DWithBiasesFp32Test(std::vector<armnn::BackendId>& backends)
22{
23 // Set input data
24 std::vector<int32_t> inputShape { 1, 5, 5, 1 };
25 std::vector<int32_t> filterShape { 1, 3, 3, 1 };
26 std::vector<int32_t> biasShape { 1 };
27 std::vector<int32_t> outputShape { 1, 3, 3, 1 };
28
29 static std::vector<float> inputValues =
30 {
31 1, 5, 2, 3, 5,
32 8, 7, 3, 6, 3,
33 3, 3, 9, 1, 9,
34 4, 1, 8, 1, 3,
35 6, 8, 1, 9, 2
36 };
37
38 std::vector<float> filterValues =
39 {
40 4, 5, 6,
41 0, 0, 0,
42 3, 2, 1
43 };
44
45 std::vector<float> biasValues = { 0 };
46
47 std::vector<float> expectedOutputValues =
48 {
49 23, 33, 24,
50 91, 99, 48,
51 26, 50, 19
52 };
53
54 tflite::Padding padding = tflite::Padding_SAME;
55
56 ConvolutionTest<float>(tflite::BuiltinOperator_CONV_2D,
Matthew Sloyan080ffd82023-04-24 12:53:04 +010057 ::tflite::TensorType_FLOAT32,
58 2, // strideX
59 2, // strideY
60 1, // dilationX
61 1, // dilationY
62 padding,
63 tflite::ActivationFunctionType_NONE,
64 backends,
65 inputShape,
66 filterShape,
67 outputShape,
68 inputValues,
69 filterValues,
70 expectedOutputValues,
71 biasShape,
72 biasValues);
Sadik Armagan32ca1442020-11-13 17:51:56 +000073}
74
Jan Eilerseb616122020-11-20 11:59:40 +000075void Conv2DWithBiasesInt8Test(std::vector<armnn::BackendId>& backends)
Sadik Armagan32ca1442020-11-13 17:51:56 +000076{
77 // Set input data
78 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
79 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
80 std::vector<int32_t> biasShape { 1 };
81 std::vector<int32_t> outputShape { 1, 2, 2, 1 };
82
Jan Eilerseb616122020-11-20 11:59:40 +000083 static std::vector<int8_t> inputValues = { 1, 2, 3, 4 };
Sadik Armagan32ca1442020-11-13 17:51:56 +000084
Jan Eilerseb616122020-11-20 11:59:40 +000085 std::vector<int8_t> filterValues = { 2, 1, 0, 6 };
Sadik Armagan32ca1442020-11-13 17:51:56 +000086
87 std::vector<int32_t> biasValues = { 10 };
88
Jan Eilerseb616122020-11-20 11:59:40 +000089 std::vector<int8_t> expectedOutputValues =
Sadik Armagan32ca1442020-11-13 17:51:56 +000090 {
91 (1 * 2 + 2 * 1 + 3 * 0 + 4 * 6 + 10) / 2, // 19
92 (2 * 2 + 0 * 1 + 4 * 0 + 0 * 6 + 10) / 2, // 7
93 (3 * 2 + 4 * 1 + 0 * 0 + 0 * 6 + 10) / 2, // 10
94 (4 * 2 + 0 * 1 + 0 * 0 + 0 * 6 + 10) / 2, // 9
95 };
96
97 tflite::Padding padding = tflite::Padding_SAME;
98
Jan Eilerseb616122020-11-20 11:59:40 +000099 ConvolutionTest<int8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100100 ::tflite::TensorType_INT8,
101 1, // strideX
102 1, // strideY
103 1, // dilationX
104 1, // dilationY
105 padding,
106 tflite::ActivationFunctionType_NONE,
107 backends,
108 inputShape,
109 filterShape,
110 outputShape,
111 inputValues,
112 filterValues,
113 expectedOutputValues,
114 biasShape,
115 biasValues);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000116}
117
118void Conv2DWithBiasesReluUint8Test(std::vector<armnn::BackendId>& backends)
119{
120 // Set input data
121 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
122 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
123 std::vector<int32_t> biasShape { 1 };
124 std::vector<int32_t> outputShape { 1, 2, 2, 1 };
125
126 static std::vector<uint8_t> inputValues = { 1, 2, 4, 8 };
127
128 std::vector<uint8_t> filterValues = { 2, 1, 0, 6 };
129
130 std::vector<int32_t> biasValues = { 16 };
131
132 // factors to consider:
133 // - the filter zero point is non zero, hence the (x-fz)
134 // - the output scale is 2 hence the /2
135 // - output zero point is non zero, hence the +outZero
136 // - RELU cuts negative values and then we add the output zero point
137 uint8_t bias = 16;
138 uint8_t outZero = 20;
139 uint8_t fz = 4; // filter zero point
140
141 std::vector<uint8_t> expectedOutputValues =
142 {
143 std::max(outZero, static_cast<uint8_t>((1*(2-fz) + 2*(1-fz) + 4*(0-fz) + 8*(6-fz) + bias)/2 + outZero)),
144 std::max(outZero, static_cast<uint8_t>((2*(2-fz) + 0*(1-fz) + 8*(0-fz) + 0*(6-fz) + bias)/2 + outZero)),
145 std::max(outZero, static_cast<uint8_t>((4*(2-fz) + 8*(1-fz) + 0*(0-fz) + 0*(6-fz) + bias)/2 + outZero)),
146 std::max(outZero, static_cast<uint8_t>((8*(2-fz) + 0*(1-fz) + 0*(0-fz) + 0*(6-fz) + bias)/2 + outZero))
147 };
148
149 tflite::Padding padding = tflite::Padding_SAME;
150
151 ConvolutionTest<uint8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100152 ::tflite::TensorType_UINT8,
153 1, // strideX
154 1, // strideY
155 1, // dilationX
156 1, // dilationY
157 padding,
158 tflite::ActivationFunctionType_RELU,
159 backends,
160 inputShape,
161 filterShape,
162 outputShape,
163 inputValues,
164 filterValues,
165 expectedOutputValues,
166 biasShape,
167 biasValues,
168 {1.0f}, // biasScale
169 {0}, // biasOffset
170 {1.0f}, // filterScale
171 {4}, // filterOffsets
172 2, // output scale
173 20); // output offset
Sadik Armagan32ca1442020-11-13 17:51:56 +0000174}
175
176void Conv2DWithBiasesRelu6Uint8Test(std::vector<armnn::BackendId>& backends)
177{
178 // Set input data
179 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
180 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
181 std::vector<int32_t> biasShape { 1 };
182 std::vector<int32_t> outputShape { 1, 2, 2, 1 };
183
184 static std::vector<uint8_t> inputValues = { 1, 2, 4, 1 };
185
186 std::vector<uint8_t> filterValues = { 2, 1, 0, 6 };
187
188 std::vector<int32_t> biasValues = { 0 };
189
190 // factors to consider:
191 // - the output scale is 2 hence the /2
192 // - RELU6 cuts output values at +6
193 uint8_t relu6Min = 6 / 2; // divide by output scale
194
195 std::vector<uint8_t> expectedOutputValues =
196 {
197 std::min(relu6Min, static_cast<uint8_t>((1 * 2 + 2 * 1 + 4 * 0 + 1 * 6) / 2)),
198 std::min(relu6Min, static_cast<uint8_t>((2 * 2 + 0 * 1 + 1 * 0 + 0 * 6) / 2)),
199 std::min(relu6Min, static_cast<uint8_t>((4 * 2 + 1 * 1 + 0 * 0 + 0 * 6) / 2)),
200 std::min(relu6Min, static_cast<uint8_t>((1 * 2 + 0 * 1 + 0 * 0 + 0 * 6) / 2))
201 };
202
203 tflite::Padding padding = tflite::Padding_SAME;
204
205 ConvolutionTest<uint8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100206 ::tflite::TensorType_UINT8,
207 1, // strideX
208 1, // strideY
209 1, // dilationX
210 1, // dilationY
211 padding,
212 tflite::ActivationFunctionType_RELU6,
213 backends,
214 inputShape,
215 filterShape,
216 outputShape,
217 inputValues,
218 filterValues,
219 expectedOutputValues,
220 biasShape,
221 biasValues);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000222}
223
Jan Eilersea835e72021-04-21 16:58:28 +0100224
225void Conv2DPerChannelInt8Test(std::vector<armnn::BackendId>& backends)
226{
227 // Set input data
228 std::vector<int32_t> inputShape { 1,4,4,2 };
229 std::vector<int32_t> filterShape { 4,2,2,2 };
230 std::vector<int32_t> biasShape { 4 };
231 std::vector<int32_t> outputShape { 1,4,4,4 };
232
233 static std::vector<int8_t> inputValues =
234 {
235 -11, 40,-26, 11,-28, 8, 0, -8,
236 -10, 34, 47, 0,-33,-14, 28, 35,
237 6,-28,-26, 8, 13, 33,-31,-41,
238 31,-20,-31,-16, 8,-18,-44, 0
239 };
240
241 std::vector<float> filterScales = { 1.858268, 2.0, 1.992126, 1.905512 };
242 int32_t filterQuantizationDim = 0;
243 std::vector<int8_t> filterValues =
244 {
245 13,-44, 5,-14, 21,-45, 36,-25,
246 -42, -2, 24,-30,-31, 35, 43,-30,
247 -20, -5, 25, 17, 18, 20, 4,-46,
248 -49, 9, -3,-20, 46, 5, 7,-15
249 };
250
251 std::vector<int32_t> biasValues = { 0,0,0,0 };
252 std::vector<float> biasScales = { 0.721445, 0.7764700055, 0.773414, 0.739787 };
253
254 std::vector<int8_t> expectedOutputValues =
255 {
256 -1, 9, 3, 5, 1, -1, 5, 9,
257 2, 7, -1, 2, 2, 4, 5, 6,
258 1, 1, 4, 4, 2, 0, -4, -3,
259 0, 6, 12, 6, 3, 0, -1, -2,
260 7, -4, 4, 4, 3, 6, 6, 2,
261 0, -3, -1, 4, 4, 8, 3, 1,
262 5, 0, 0, 1, 4, 7, 4, 6,
263 4, 0, 1, 2, 2, 7, 5, 7
264 };
265 float outputQuantScale = 401.960785f;
266 int outputQuantOffset = 3;
267 float inputQuantScale = 0.388235f;
268 int inputQuantOffset = 1;
269
270 tflite::Padding padding = tflite::Padding_SAME;
271
272 ConvolutionTest<int8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100273 ::tflite::TensorType_INT8,
274 1, // strideX
275 1, // strideY
276 1, // dilationX
277 1, // dilationY
278 padding,
279 tflite::ActivationFunctionType_NONE,
280 backends,
281 inputShape,
282 filterShape,
283 outputShape,
284 inputValues,
285 filterValues,
286 expectedOutputValues,
287 biasShape,
288 biasValues,
289 biasScales,
290 {0,0,0,0},
291 filterScales,
292 {0,0,0,0},
293 outputQuantScale,
294 outputQuantOffset,
295 inputQuantScale,
296 inputQuantOffset,
297 1, // depth_multiplier is ignored for conv2d value doesn't matter
298 filterQuantizationDim);
Jan Eilersea835e72021-04-21 16:58:28 +0100299}
300
Jan Eilers187b3a72020-11-19 17:50:34 +0000301TEST_SUITE("Convolution2dTest_CpuRefTests")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000302{
303
304TEST_CASE ("Conv2DWithBiases_Fp32_CpuRef_Test")
305{
306 std::vector <armnn::BackendId> backends = {armnn::Compute::CpuRef};
307 Conv2DWithBiasesFp32Test(backends);
308}
309
Jan Eilerseb616122020-11-20 11:59:40 +0000310TEST_CASE ("Conv2DWithBiases_Int8_CpuRef_Test")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000311{
312 std::vector <armnn::BackendId> backends = {armnn::Compute::CpuRef};
Jan Eilerseb616122020-11-20 11:59:40 +0000313 Conv2DWithBiasesInt8Test(backends);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000314}
315
Jan Eilersea835e72021-04-21 16:58:28 +0100316TEST_CASE ("Conv2DPerChannel_Int8_CpuRef_Test")
317{
318 std::vector <armnn::BackendId> backends = {armnn::Compute::CpuRef};
319 Conv2DPerChannelInt8Test(backends);
320}
321
Sadik Armagan32ca1442020-11-13 17:51:56 +0000322} //End of TEST_SUITE("Convolution2dTest_CpuRef")
323
Jan Eilers187b3a72020-11-19 17:50:34 +0000324TEST_SUITE("Convolution2dTest_CpuAccTests")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000325{
326
327TEST_CASE ("Conv2DWithBiases_Fp32_CpuAcc_Test")
328{
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100329 std::vector <armnn::BackendId> backends = {armnn::Compute::CpuAcc};
330 Conv2DWithBiasesFp32Test(backends);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000331}
332
Jan Eilerseb616122020-11-20 11:59:40 +0000333TEST_CASE ("Conv2DWithBiases_Int8_CpuAcc_Test")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000334{
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100335 std::vector <armnn::BackendId> backends = {armnn::Compute::CpuAcc};
336 Conv2DWithBiasesInt8Test(backends);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000337}
338
Jan Eilersea835e72021-04-21 16:58:28 +0100339TEST_CASE ("Conv2DPerChannel_Int8_CpuAcc_Test")
340{
341 std::vector <armnn::BackendId> backends = {armnn::Compute::CpuAcc};
342 Conv2DPerChannelInt8Test(backends);
343}
344
Sadik Armagan32ca1442020-11-13 17:51:56 +0000345} //End of TEST_SUITE("Convolution2dTest_CpuAcc")
346
Jan Eilers187b3a72020-11-19 17:50:34 +0000347TEST_SUITE("Convolution2dTest_GpuAccTests")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000348{
349
350TEST_CASE ("Conv2DWithBiases_Fp32_GpuAcc_Test")
351{
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100352 std::vector <armnn::BackendId> backends = {armnn::Compute::GpuAcc};
353 Conv2DWithBiasesFp32Test(backends);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000354}
355
Jan Eilerseb616122020-11-20 11:59:40 +0000356TEST_CASE ("Conv2DWithBiases_Int8_GpuAcc_Test")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000357{
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100358 std::vector <armnn::BackendId> backends = {armnn::Compute::GpuAcc};
359 Conv2DWithBiasesInt8Test(backends);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000360}
361
Jan Eilersea835e72021-04-21 16:58:28 +0100362TEST_CASE ("Conv2DPerChannel_Int8_GpuAcc_Test")
363{
364 std::vector <armnn::BackendId> backends = {armnn::Compute::GpuAcc};
365 Conv2DPerChannelInt8Test(backends);
366}
367
Sadik Armagan32ca1442020-11-13 17:51:56 +0000368} //End of TEST_SUITE("Convolution2dTest_GpuAcc")
369
Sadik Armagan32ca1442020-11-13 17:51:56 +0000370} // namespace armnnDelegate