blob: 6c50f8d3e4457e92fb608e1543fb139bca41bc1c [file] [log] [blame]
Sadik Armagan32ca1442020-11-13 17:51:56 +00001//
2// Copyright © 2020 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 <tensorflow/lite/schema/schema_generated.h>
15#include <tensorflow/lite/version.h>
16
17#include <doctest/doctest.h>
18
19namespace armnnDelegate
20{
21
22void Conv2DWithBiasesFp32Test(std::vector<armnn::BackendId>& backends)
23{
24 // Set input data
25 std::vector<int32_t> inputShape { 1, 5, 5, 1 };
26 std::vector<int32_t> filterShape { 1, 3, 3, 1 };
27 std::vector<int32_t> biasShape { 1 };
28 std::vector<int32_t> outputShape { 1, 3, 3, 1 };
29
30 static std::vector<float> inputValues =
31 {
32 1, 5, 2, 3, 5,
33 8, 7, 3, 6, 3,
34 3, 3, 9, 1, 9,
35 4, 1, 8, 1, 3,
36 6, 8, 1, 9, 2
37 };
38
39 std::vector<float> filterValues =
40 {
41 4, 5, 6,
42 0, 0, 0,
43 3, 2, 1
44 };
45
46 std::vector<float> biasValues = { 0 };
47
48 std::vector<float> expectedOutputValues =
49 {
50 23, 33, 24,
51 91, 99, 48,
52 26, 50, 19
53 };
54
55 tflite::Padding padding = tflite::Padding_SAME;
56
57 ConvolutionTest<float>(tflite::BuiltinOperator_CONV_2D,
58 ::tflite::TensorType_FLOAT32,
59 2, // strideX
60 2, // strideY
61 1, // dilationX
62 1, // dilationY
63 padding,
64 tflite::ActivationFunctionType_NONE,
65 backends,
66 inputShape,
67 filterShape,
68 outputShape,
69 inputValues,
70 filterValues,
71 expectedOutputValues,
72 biasShape,
73 biasValues);
74}
75
Jan Eilerseb616122020-11-20 11:59:40 +000076void Conv2DWithBiasesInt8Test(std::vector<armnn::BackendId>& backends)
Sadik Armagan32ca1442020-11-13 17:51:56 +000077{
78 // Set input data
79 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
80 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
81 std::vector<int32_t> biasShape { 1 };
82 std::vector<int32_t> outputShape { 1, 2, 2, 1 };
83
Jan Eilerseb616122020-11-20 11:59:40 +000084 static std::vector<int8_t> inputValues = { 1, 2, 3, 4 };
Sadik Armagan32ca1442020-11-13 17:51:56 +000085
Jan Eilerseb616122020-11-20 11:59:40 +000086 std::vector<int8_t> filterValues = { 2, 1, 0, 6 };
Sadik Armagan32ca1442020-11-13 17:51:56 +000087
88 std::vector<int32_t> biasValues = { 10 };
89
Jan Eilerseb616122020-11-20 11:59:40 +000090 std::vector<int8_t> expectedOutputValues =
Sadik Armagan32ca1442020-11-13 17:51:56 +000091 {
92 (1 * 2 + 2 * 1 + 3 * 0 + 4 * 6 + 10) / 2, // 19
93 (2 * 2 + 0 * 1 + 4 * 0 + 0 * 6 + 10) / 2, // 7
94 (3 * 2 + 4 * 1 + 0 * 0 + 0 * 6 + 10) / 2, // 10
95 (4 * 2 + 0 * 1 + 0 * 0 + 0 * 6 + 10) / 2, // 9
96 };
97
98 tflite::Padding padding = tflite::Padding_SAME;
99
Jan Eilerseb616122020-11-20 11:59:40 +0000100 ConvolutionTest<int8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
101 ::tflite::TensorType_INT8,
Sadik Armagan32ca1442020-11-13 17:51:56 +0000102 1, // strideX
103 1, // strideY
104 1, // dilationX
105 1, // dilationY
106 padding,
107 tflite::ActivationFunctionType_NONE,
108 backends,
109 inputShape,
110 filterShape,
111 outputShape,
112 inputValues,
113 filterValues,
114 expectedOutputValues,
115 biasShape,
116 biasValues);
117}
118
119void Conv2DWithBiasesReluUint8Test(std::vector<armnn::BackendId>& backends)
120{
121 // Set input data
122 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
123 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
124 std::vector<int32_t> biasShape { 1 };
125 std::vector<int32_t> outputShape { 1, 2, 2, 1 };
126
127 static std::vector<uint8_t> inputValues = { 1, 2, 4, 8 };
128
129 std::vector<uint8_t> filterValues = { 2, 1, 0, 6 };
130
131 std::vector<int32_t> biasValues = { 16 };
132
133 // factors to consider:
134 // - the filter zero point is non zero, hence the (x-fz)
135 // - the output scale is 2 hence the /2
136 // - output zero point is non zero, hence the +outZero
137 // - RELU cuts negative values and then we add the output zero point
138 uint8_t bias = 16;
139 uint8_t outZero = 20;
140 uint8_t fz = 4; // filter zero point
141
142 std::vector<uint8_t> expectedOutputValues =
143 {
144 std::max(outZero, static_cast<uint8_t>((1*(2-fz) + 2*(1-fz) + 4*(0-fz) + 8*(6-fz) + bias)/2 + outZero)),
145 std::max(outZero, static_cast<uint8_t>((2*(2-fz) + 0*(1-fz) + 8*(0-fz) + 0*(6-fz) + bias)/2 + outZero)),
146 std::max(outZero, static_cast<uint8_t>((4*(2-fz) + 8*(1-fz) + 0*(0-fz) + 0*(6-fz) + bias)/2 + outZero)),
147 std::max(outZero, static_cast<uint8_t>((8*(2-fz) + 0*(1-fz) + 0*(0-fz) + 0*(6-fz) + bias)/2 + outZero))
148 };
149
150 tflite::Padding padding = tflite::Padding_SAME;
151
152 ConvolutionTest<uint8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
153 ::tflite::TensorType_UINT8,
154 1, // strideX
155 1, // strideY
156 1, // dilationX
157 1, // dilationY
158 padding,
159 tflite::ActivationFunctionType_RELU,
160 backends,
161 inputShape,
162 filterShape,
163 outputShape,
164 inputValues,
165 filterValues,
166 expectedOutputValues,
167 biasShape,
168 biasValues,
169 1, // filter scale
170 4, // filter offset
171 2, // output scale
172 20); // output offset
173}
174
175void Conv2DWithBiasesRelu6Uint8Test(std::vector<armnn::BackendId>& backends)
176{
177 // Set input data
178 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
179 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
180 std::vector<int32_t> biasShape { 1 };
181 std::vector<int32_t> outputShape { 1, 2, 2, 1 };
182
183 static std::vector<uint8_t> inputValues = { 1, 2, 4, 1 };
184
185 std::vector<uint8_t> filterValues = { 2, 1, 0, 6 };
186
187 std::vector<int32_t> biasValues = { 0 };
188
189 // factors to consider:
190 // - the output scale is 2 hence the /2
191 // - RELU6 cuts output values at +6
192 uint8_t relu6Min = 6 / 2; // divide by output scale
193
194 std::vector<uint8_t> expectedOutputValues =
195 {
196 std::min(relu6Min, static_cast<uint8_t>((1 * 2 + 2 * 1 + 4 * 0 + 1 * 6) / 2)),
197 std::min(relu6Min, static_cast<uint8_t>((2 * 2 + 0 * 1 + 1 * 0 + 0 * 6) / 2)),
198 std::min(relu6Min, static_cast<uint8_t>((4 * 2 + 1 * 1 + 0 * 0 + 0 * 6) / 2)),
199 std::min(relu6Min, static_cast<uint8_t>((1 * 2 + 0 * 1 + 0 * 0 + 0 * 6) / 2))
200 };
201
202 tflite::Padding padding = tflite::Padding_SAME;
203
204 ConvolutionTest<uint8_t, int32_t>(tflite::BuiltinOperator_CONV_2D,
205 ::tflite::TensorType_UINT8,
206 1, // strideX
207 1, // strideY
208 1, // dilationX
209 1, // dilationY
210 padding,
211 tflite::ActivationFunctionType_RELU6,
212 backends,
213 inputShape,
214 filterShape,
215 outputShape,
216 inputValues,
217 filterValues,
218 expectedOutputValues,
219 biasShape,
220 biasValues);
221}
222
Jan Eilers187b3a72020-11-19 17:50:34 +0000223TEST_SUITE("Convolution2dTest_CpuRefTests")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000224{
225
226TEST_CASE ("Conv2DWithBiases_Fp32_CpuRef_Test")
227{
228 std::vector <armnn::BackendId> backends = {armnn::Compute::CpuRef};
229 Conv2DWithBiasesFp32Test(backends);
230}
231
Jan Eilerseb616122020-11-20 11:59:40 +0000232TEST_CASE ("Conv2DWithBiases_Int8_CpuRef_Test")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000233{
234 std::vector <armnn::BackendId> backends = {armnn::Compute::CpuRef};
Jan Eilerseb616122020-11-20 11:59:40 +0000235 Conv2DWithBiasesInt8Test(backends);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000236}
237
238} //End of TEST_SUITE("Convolution2dTest_CpuRef")
239
Jan Eilers187b3a72020-11-19 17:50:34 +0000240TEST_SUITE("Convolution2dTest_CpuAccTests")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000241{
242
243TEST_CASE ("Conv2DWithBiases_Fp32_CpuAcc_Test")
244{
245std::vector <armnn::BackendId> backends = {armnn::Compute::CpuAcc};
246Conv2DWithBiasesFp32Test(backends);
247}
248
Jan Eilerseb616122020-11-20 11:59:40 +0000249TEST_CASE ("Conv2DWithBiases_Int8_CpuAcc_Test")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000250{
251std::vector <armnn::BackendId> backends = {armnn::Compute::CpuAcc};
Jan Eilerseb616122020-11-20 11:59:40 +0000252Conv2DWithBiasesInt8Test(backends);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000253}
254
255} //End of TEST_SUITE("Convolution2dTest_CpuAcc")
256
Jan Eilers187b3a72020-11-19 17:50:34 +0000257TEST_SUITE("Convolution2dTest_GpuAccTests")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000258{
259
260TEST_CASE ("Conv2DWithBiases_Fp32_GpuAcc_Test")
261{
262std::vector <armnn::BackendId> backends = {armnn::Compute::GpuAcc};
263Conv2DWithBiasesFp32Test(backends);
264}
265
Jan Eilerseb616122020-11-20 11:59:40 +0000266TEST_CASE ("Conv2DWithBiases_Int8_GpuAcc_Test")
Sadik Armagan32ca1442020-11-13 17:51:56 +0000267{
268std::vector <armnn::BackendId> backends = {armnn::Compute::GpuAcc};
Jan Eilerseb616122020-11-20 11:59:40 +0000269Conv2DWithBiasesInt8Test(backends);
Sadik Armagan32ca1442020-11-13 17:51:56 +0000270}
271
272} //End of TEST_SUITE("Convolution2dTest_GpuAcc")
273
274void TransposeConvUint8Test(std::vector<armnn::BackendId>& backends)
275{
276 // Set input data
277 std::vector<int32_t> transposeTensorShape { 4 };
278 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
279 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
280 std::vector<int32_t> outputShape { 1, 3, 3, 1 };
281
282 std::vector<int32_t> transposeData = { 1, 3, 3, 1 };
283 static std::vector<uint8_t> inputValues = { 1, 2, 3, 4 };
284 std::vector<uint8_t> filterValues = { 0, 1, 2, 4 };
285 std::vector<uint8_t> expectedOutputValues =
286 {
287 0, 1, 2,
288 2, 11, 12,
289 6, 20, 16
290 };
291
292 tflite::Padding padding = tflite::Padding_VALID;
293 TransposeConvTest<uint8_t>(backends,
294 ::tflite::TensorType_UINT8,
295 1, // strideX
296 1, // strideY
297 padding,
298 transposeTensorShape,
299 filterShape,
300 inputShape,
301 outputShape,
302 transposeData,
303 filterValues,
304 inputValues,
305 expectedOutputValues);
306}
307
308void TransposeConvFp32Test(std::vector<armnn::BackendId>& backends)
309{
310 std::vector<int32_t> transposeTensorShape { 4 };
311 std::vector<int32_t> filterShape { 1, 2, 2, 1 };
312 std::vector<int32_t> inputShape { 1, 2, 2, 1 };
313 std::vector<int32_t> outputShape { 1, 3, 3, 1 };
314
315 std::vector<int32_t> transposeData = { 1, 3, 3, 1 };
316 static std::vector<float> inputValues = { 1, 2, 3, 4 };
317 std::vector<float> filterValues = { 0, 1, 2, 4 };
318 std::vector<float> expectedOutputValues =
319 {
320 0, 1, 2,
321 2, 11, 12,
322 6, 20, 16
323 };
324
325 tflite::Padding padding = tflite::Padding_VALID;
326 TransposeConvTest<float>(backends,
327 ::tflite::TensorType_FLOAT32,
328 1, // strideX
329 1, // strideY
330 padding,
331 transposeTensorShape,
332 filterShape,
333 inputShape,
334 outputShape,
335 transposeData,
336 filterValues,
337 inputValues,
338 expectedOutputValues);
339}
340
341TEST_SUITE("TransposeConv_CpuRef_Test")
342{
343
344TEST_CASE ("TransposeConv_Fp32_Test")
345{
346 std::vector <armnn::BackendId> backends = {armnn::Compute::CpuRef};
347 TransposeConvFp32Test(backends);
348}
349
350TEST_CASE ("TransposeConv_Uint8_Test")
351{
352 std::vector <armnn::BackendId> backends = {armnn::Compute::CpuRef};
353 TransposeConvUint8Test(backends);
354}
355
356} // End of TEST_SUITE(TransposeConv_CpuRef_Test)
357
358TEST_SUITE("TransposeConv_CpuAcc_Test")
359{
360
361TEST_CASE ("TransposeConv_Fp32_Test")
362{
363std::vector <armnn::BackendId> backends = {armnn::Compute::CpuAcc};
364TransposeConvFp32Test(backends);
365}
366
367TEST_CASE ("TransposeConv_Uint8_Test")
368{
369std::vector <armnn::BackendId> backends = {armnn::Compute::CpuAcc};
370TransposeConvUint8Test(backends);
371}
372
373} // End of TEST_SUITE(TransposeConv_CpuAcc_Test)
374
375TEST_SUITE("TransposeConv_GpuAcc_Test")
376{
377
378TEST_CASE ("TransposeConv_Fp32_Test")
379{
380std::vector <armnn::BackendId> backends = {armnn::Compute::GpuAcc};
381TransposeConvFp32Test(backends);
382}
383
384TEST_CASE ("TransposeConv_Uint8_Test")
385{
386std::vector <armnn::BackendId> backends = {armnn::Compute::GpuAcc};
387TransposeConvUint8Test(backends);
388}
389
390} // End of TEST_SUITE(TransposeConv_GpuAcc_Test)
391
392} // namespace armnnDelegate