blob: e78f5387d7e579660d71c88f8817cc8ceae3e211 [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
Colm Donelaneff204a2023-11-28 15:46:09 +000021void Conv2DWithBiasesFp32Test()
Sadik Armagan32ca1442020-11-13 17:51:56 +000022{
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,
Matthew Sloyan080ffd82023-04-24 12:53:04 +010064 inputShape,
65 filterShape,
66 outputShape,
67 inputValues,
68 filterValues,
69 expectedOutputValues,
70 biasShape,
71 biasValues);
Sadik Armagan32ca1442020-11-13 17:51:56 +000072}
73
Colm Donelaneff204a2023-11-28 15:46:09 +000074void Conv2DWithBiasesInt8Test()
Sadik Armagan32ca1442020-11-13 17:51:56 +000075{
76 // Set input data
77 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
78 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
79 std::vector<int32_t> biasShape { 1 };
80 std::vector<int32_t> outputShape { 1, 2, 2, 1 };
81
Jan Eilerseb616122020-11-20 11:59:40 +000082 static std::vector<int8_t> inputValues = { 1, 2, 3, 4 };
Sadik Armagan32ca1442020-11-13 17:51:56 +000083
Jan Eilerseb616122020-11-20 11:59:40 +000084 std::vector<int8_t> filterValues = { 2, 1, 0, 6 };
Sadik Armagan32ca1442020-11-13 17:51:56 +000085
86 std::vector<int32_t> biasValues = { 10 };
87
Jan Eilerseb616122020-11-20 11:59:40 +000088 std::vector<int8_t> expectedOutputValues =
Sadik Armagan32ca1442020-11-13 17:51:56 +000089 {
90 (1 * 2 + 2 * 1 + 3 * 0 + 4 * 6 + 10) / 2, // 19
91 (2 * 2 + 0 * 1 + 4 * 0 + 0 * 6 + 10) / 2, // 7
92 (3 * 2 + 4 * 1 + 0 * 0 + 0 * 6 + 10) / 2, // 10
93 (4 * 2 + 0 * 1 + 0 * 0 + 0 * 6 + 10) / 2, // 9
94 };
95
96 tflite::Padding padding = tflite::Padding_SAME;
97
Jan Eilerseb616122020-11-20 11:59:40 +000098 ConvolutionTest<int8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
Matthew Sloyan080ffd82023-04-24 12:53:04 +010099 ::tflite::TensorType_INT8,
100 1, // strideX
101 1, // strideY
102 1, // dilationX
103 1, // dilationY
104 padding,
105 tflite::ActivationFunctionType_NONE,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100106 inputShape,
107 filterShape,
108 outputShape,
109 inputValues,
110 filterValues,
111 expectedOutputValues,
112 biasShape,
113 biasValues);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000114}
115
Colm Donelaneff204a2023-11-28 15:46:09 +0000116void Conv2DWithBiasesReluUint8Test()
Sadik Armagan32ca1442020-11-13 17:51:56 +0000117{
118 // Set input data
119 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
120 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
121 std::vector<int32_t> biasShape { 1 };
122 std::vector<int32_t> outputShape { 1, 2, 2, 1 };
123
124 static std::vector<uint8_t> inputValues = { 1, 2, 4, 8 };
125
126 std::vector<uint8_t> filterValues = { 2, 1, 0, 6 };
127
128 std::vector<int32_t> biasValues = { 16 };
129
130 // factors to consider:
131 // - the filter zero point is non zero, hence the (x-fz)
132 // - the output scale is 2 hence the /2
133 // - output zero point is non zero, hence the +outZero
134 // - RELU cuts negative values and then we add the output zero point
135 uint8_t bias = 16;
136 uint8_t outZero = 20;
137 uint8_t fz = 4; // filter zero point
138
139 std::vector<uint8_t> expectedOutputValues =
140 {
141 std::max(outZero, static_cast<uint8_t>((1*(2-fz) + 2*(1-fz) + 4*(0-fz) + 8*(6-fz) + bias)/2 + outZero)),
142 std::max(outZero, static_cast<uint8_t>((2*(2-fz) + 0*(1-fz) + 8*(0-fz) + 0*(6-fz) + bias)/2 + outZero)),
143 std::max(outZero, static_cast<uint8_t>((4*(2-fz) + 8*(1-fz) + 0*(0-fz) + 0*(6-fz) + bias)/2 + outZero)),
144 std::max(outZero, static_cast<uint8_t>((8*(2-fz) + 0*(1-fz) + 0*(0-fz) + 0*(6-fz) + bias)/2 + outZero))
145 };
146
147 tflite::Padding padding = tflite::Padding_SAME;
148
149 ConvolutionTest<uint8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100150 ::tflite::TensorType_UINT8,
151 1, // strideX
152 1, // strideY
153 1, // dilationX
154 1, // dilationY
155 padding,
156 tflite::ActivationFunctionType_RELU,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100157 inputShape,
158 filterShape,
159 outputShape,
160 inputValues,
161 filterValues,
162 expectedOutputValues,
163 biasShape,
164 biasValues,
165 {1.0f}, // biasScale
166 {0}, // biasOffset
167 {1.0f}, // filterScale
168 {4}, // filterOffsets
169 2, // output scale
170 20); // output offset
Sadik Armagan32ca1442020-11-13 17:51:56 +0000171}
172
Colm Donelaneff204a2023-11-28 15:46:09 +0000173void Conv2DWithBiasesRelu6Uint8Test()
Sadik Armagan32ca1442020-11-13 17:51:56 +0000174{
175 // Set input data
176 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
177 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
178 std::vector<int32_t> biasShape { 1 };
179 std::vector<int32_t> outputShape { 1, 2, 2, 1 };
180
181 static std::vector<uint8_t> inputValues = { 1, 2, 4, 1 };
182
183 std::vector<uint8_t> filterValues = { 2, 1, 0, 6 };
184
185 std::vector<int32_t> biasValues = { 0 };
186
187 // factors to consider:
188 // - the output scale is 2 hence the /2
189 // - RELU6 cuts output values at +6
190 uint8_t relu6Min = 6 / 2; // divide by output scale
191
192 std::vector<uint8_t> expectedOutputValues =
193 {
194 std::min(relu6Min, static_cast<uint8_t>((1 * 2 + 2 * 1 + 4 * 0 + 1 * 6) / 2)),
195 std::min(relu6Min, static_cast<uint8_t>((2 * 2 + 0 * 1 + 1 * 0 + 0 * 6) / 2)),
196 std::min(relu6Min, static_cast<uint8_t>((4 * 2 + 1 * 1 + 0 * 0 + 0 * 6) / 2)),
197 std::min(relu6Min, static_cast<uint8_t>((1 * 2 + 0 * 1 + 0 * 0 + 0 * 6) / 2))
198 };
199
200 tflite::Padding padding = tflite::Padding_SAME;
201
202 ConvolutionTest<uint8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100203 ::tflite::TensorType_UINT8,
204 1, // strideX
205 1, // strideY
206 1, // dilationX
207 1, // dilationY
208 padding,
209 tflite::ActivationFunctionType_RELU6,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100210 inputShape,
211 filterShape,
212 outputShape,
213 inputValues,
214 filterValues,
215 expectedOutputValues,
216 biasShape,
217 biasValues);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000218}
219
Jan Eilersea835e72021-04-21 16:58:28 +0100220
Colm Donelaneff204a2023-11-28 15:46:09 +0000221void Conv2DPerChannelInt8Test()
Jan Eilersea835e72021-04-21 16:58:28 +0100222{
223 // Set input data
224 std::vector<int32_t> inputShape { 1,4,4,2 };
225 std::vector<int32_t> filterShape { 4,2,2,2 };
226 std::vector<int32_t> biasShape { 4 };
227 std::vector<int32_t> outputShape { 1,4,4,4 };
228
229 static std::vector<int8_t> inputValues =
230 {
231 -11, 40,-26, 11,-28, 8, 0, -8,
232 -10, 34, 47, 0,-33,-14, 28, 35,
233 6,-28,-26, 8, 13, 33,-31,-41,
234 31,-20,-31,-16, 8,-18,-44, 0
235 };
236
237 std::vector<float> filterScales = { 1.858268, 2.0, 1.992126, 1.905512 };
238 int32_t filterQuantizationDim = 0;
239 std::vector<int8_t> filterValues =
240 {
241 13,-44, 5,-14, 21,-45, 36,-25,
242 -42, -2, 24,-30,-31, 35, 43,-30,
243 -20, -5, 25, 17, 18, 20, 4,-46,
244 -49, 9, -3,-20, 46, 5, 7,-15
245 };
246
247 std::vector<int32_t> biasValues = { 0,0,0,0 };
248 std::vector<float> biasScales = { 0.721445, 0.7764700055, 0.773414, 0.739787 };
249
250 std::vector<int8_t> expectedOutputValues =
251 {
252 -1, 9, 3, 5, 1, -1, 5, 9,
253 2, 7, -1, 2, 2, 4, 5, 6,
254 1, 1, 4, 4, 2, 0, -4, -3,
255 0, 6, 12, 6, 3, 0, -1, -2,
256 7, -4, 4, 4, 3, 6, 6, 2,
257 0, -3, -1, 4, 4, 8, 3, 1,
258 5, 0, 0, 1, 4, 7, 4, 6,
259 4, 0, 1, 2, 2, 7, 5, 7
260 };
261 float outputQuantScale = 401.960785f;
262 int outputQuantOffset = 3;
263 float inputQuantScale = 0.388235f;
264 int inputQuantOffset = 1;
265
266 tflite::Padding padding = tflite::Padding_SAME;
267
268 ConvolutionTest<int8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100269 ::tflite::TensorType_INT8,
270 1, // strideX
271 1, // strideY
272 1, // dilationX
273 1, // dilationY
274 padding,
275 tflite::ActivationFunctionType_NONE,
Matthew Sloyan080ffd82023-04-24 12:53:04 +0100276 inputShape,
277 filterShape,
278 outputShape,
279 inputValues,
280 filterValues,
281 expectedOutputValues,
282 biasShape,
283 biasValues,
284 biasScales,
285 {0,0,0,0},
286 filterScales,
287 {0,0,0,0},
288 outputQuantScale,
289 outputQuantOffset,
290 inputQuantScale,
291 inputQuantOffset,
292 1, // depth_multiplier is ignored for conv2d value doesn't matter
293 filterQuantizationDim);
Jan Eilersea835e72021-04-21 16:58:28 +0100294}
295
Colm Donelaneff204a2023-11-28 15:46:09 +0000296TEST_SUITE("Convolution2dTest_Tests")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000297{
298
Colm Donelaneff204a2023-11-28 15:46:09 +0000299TEST_CASE ("Conv2DWithBiases_Fp32_Test")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000300{
Colm Donelaneff204a2023-11-28 15:46:09 +0000301 Conv2DWithBiasesFp32Test();
Sadik Armagan32ca1442020-11-13 17:51:56 +0000302}
303
Colm Donelaneff204a2023-11-28 15:46:09 +0000304TEST_CASE ("Conv2DWithBiases_Int8_Test")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000305{
Colm Donelaneff204a2023-11-28 15:46:09 +0000306 Conv2DWithBiasesInt8Test();
Sadik Armagan32ca1442020-11-13 17:51:56 +0000307}
308
Colm Donelaneff204a2023-11-28 15:46:09 +0000309TEST_CASE ("Conv2DPerChannel_Int8_Test")
Jan Eilersea835e72021-04-21 16:58:28 +0100310{
Colm Donelaneff204a2023-11-28 15:46:09 +0000311 Conv2DPerChannelInt8Test();
Jan Eilersea835e72021-04-21 16:58:28 +0100312}
313
Colm Donelaneff204a2023-11-28 15:46:09 +0000314} //End of TEST_SUITE("Convolution2dTest_Tests")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000315
Sadik Armagan32ca1442020-11-13 17:51:56 +0000316} // namespace armnnDelegate