blob: 32cd6fe3f419dfc0dd97514c001387bb2dc959a7 [file] [log] [blame]
Matthew Sloyaneb5f8102021-10-05 17:31:42 +01001//
2// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "ParserFlatbuffersFixture.hpp"
7#include <sstream>
8
9TEST_SUITE("TensorflowLiteParser_Conv3D")
10{
11struct SimpleConv3DFixture : public ParserFlatbuffersFixture
12{
13 explicit SimpleConv3DFixture()
14 {
15 m_JsonString = R"(
16 {
17 "version": 3,
18 "operator_codes": [ { "builtin_code": "CONV_3D" } ],
19 "subgraphs": [ {
20 "tensors": [
21 {
22 "shape": [ 1, 2, 3, 3, 1 ],
23 "type": "UINT8",
24 "buffer": 0,
25 "name": "inputTensor",
26 "quantization": {
27 "min": [ 0.0 ],
28 "max": [ 255.0 ],
29 "scale": [ 1.0 ],
30 "zero_point": [ 0 ],
31 }
32 },
33 {
34 "shape": [ 1, 1, 1, 1, 1 ],
35 "type": "UINT8",
36 "buffer": 1,
37 "name": "outputTensor",
38 "quantization": {
39 "min": [ 0.0 ],
40 "max": [ 511.0 ],
41 "scale": [ 2.0 ],
42 "zero_point": [ 0 ],
43 }
44 },
45 {
46 "shape": [ 2, 3, 3, 1, 1 ],
47 "type": "UINT8",
48 "buffer": 2,
49 "name": "filterTensor",
50 "quantization": {
51 "min": [ 0.0 ],
52 "max": [ 255.0 ],
53 "scale": [ 1.0 ],
54 "zero_point": [ 0 ],
55 }
56 }
57 ],
58 "inputs": [ 0 ],
59 "outputs": [ 1 ],
60 "operators": [
61 {
62 "opcode_index": 0,
63 "inputs": [ 0, 2 ],
64 "outputs": [ 1 ],
65 "builtin_options_type": "Conv3DOptions",
66 "builtin_options": {
67 "padding": "VALID",
68 "stride_d": 1,
69 "stride_w": 1,
70 "stride_h": 1,
71 "fused_activation_function": "NONE"
72 },
73 "custom_options_format": "FLEXBUFFERS"
74 }
75 ],
76 } ],
77 "buffers" : [
78 { },
79 { },
80 { "data": [ 2,1,0, 6,2,1, 4,1,2,
81 1,2,1, 2,0,2, 2,1,1 ], },
82 { },
83 ]
84 }
85 )";
86 SetupSingleInputSingleOutput("inputTensor", "outputTensor");
87 }
88};
89
90TEST_CASE_FIXTURE(SimpleConv3DFixture, "ParseSimpleConv3D")
91{
92 RunTest<5, armnn::DataType::QAsymmU8>(
93 0,
94 {
95 1, 2, 3,
96 4, 5, 6,
97 7, 8, 9,
98
99 10, 11, 12,
100 13, 14, 15,
101 16, 17, 18,
102 },
103 // Due to the output scaling we need to half the values.
104 {
105 (1*2 + 2*1 + 3*0 +
106 4*6 + 5*2 + 6*1 +
107 7*4 + 8*1 + 9*2 +
108
109 10*1 + 11*2 + 12*1 +
110 13*2 + 14*0 + 15*2 +
111 16*2 + 17*1 + 18*1) /2
112 });
113}
114struct Conv3DWithBiasesFixture : public ParserFlatbuffersFixture
115{
116 explicit Conv3DWithBiasesFixture(const std::string& inputShape,
117 const std::string& outputShape,
118 const std::string& filterShape,
119 const std::string& filterData,
120 const std::string& biasShape,
121 const std::string& biasData,
122 const std::string& strides,
123 const std::string& activation="NONE",
124 const std::string& filterScale="1.0",
125 const std::string& filterZeroPoint="0",
126 const std::string& outputScale="1.0",
127 const std::string& outputZeroPoint="0")
128 {
129 m_JsonString = R"(
130 {
131 "version": 3,
132 "operator_codes": [ { "builtin_code": "CONV_3D" } ],
133 "subgraphs": [ {
134 "tensors": [
135 {
136 "shape": )" + inputShape + R"(,
137 "type": "UINT8",
138 "buffer": 0,
139 "name": "inputTensor",
140 "quantization": {
141 "min": [ 0.0 ],
142 "max": [ 255.0 ],
143 "scale": [ 1.0 ],
144 "zero_point": [ 0 ],
145 }
146 },
147 {
148 "shape": )" + outputShape + R"(,
149 "type": "UINT8",
150 "buffer": 1,
151 "name": "outputTensor",
152 "quantization": {
153 "min": [ 0.0 ],
154 "max": [ 511.0 ],
155 "scale": [ )" + outputScale + R"( ],
156 "zero_point": [ )" + outputZeroPoint + R"( ],
157 }
158 },
159 {
160 "shape": )" + filterShape + R"( ,
161 "type": "UINT8",
162 "buffer": 2,
163 "name": "filterTensor",
164 "quantization": {
165 "min": [ 0.0 ],
166 "max": [ 255.0 ],
167 "scale": [ )" + filterScale + R"( ],
168 "zero_point": [ )" + filterZeroPoint + R"( ],
169 }
170 },
171 {
172 "shape": )" + biasShape + R"( ,
173 "type": "INT32",
174 "buffer": 3,
175 "name": "biasTensor",
176 "quantization": {
177 "min": [ 0.0 ],
178 "max": [ 255.0 ],
179 "scale": [ 1.0 ],
180 "zero_point": [ 0 ],
181 }
182 }
183 ],
184 "inputs": [ 0 ],
185 "outputs": [ 1 ],
186 "operators": [
187 {
188 "opcode_index": 0,
189 "inputs": [ 0, 2, 3 ],
190 "outputs": [ 1 ],
191 "builtin_options_type": "Conv3DOptions",
192 "builtin_options": {
193 "padding": "SAME",
194 "stride_d": )" + strides + R"(,
195 "stride_w": )" + strides + R"(,
196 "stride_h": )" + strides + R"(,
197 "fused_activation_function": )" + activation + R"(
198 },
199 "custom_options_format": "FLEXBUFFERS"
200 }
201 ],
202 } ],
203 "buffers" : [
204 { },
205 { },
206 { "data": )" + filterData + R"(, },
207 { "data": )" + biasData + R"(, },
208 ]
209 }
210 )";
211 SetupSingleInputSingleOutput("inputTensor", "outputTensor");
212 }
213};
214
215struct SimpleConv3DWithBiasesFixture : Conv3DWithBiasesFixture
216{
217 SimpleConv3DWithBiasesFixture()
218 : Conv3DWithBiasesFixture("[ 1, 2, 2, 2, 1 ]", // inputShape
219 "[ 1, 2, 2, 2, 1 ]", // outputShape
220 "[ 2, 2, 2, 1, 1 ]", // filterShape
221 "[ 2,1, 1,0, 0,1, 1,1 ]", // filterData
222 "[ 1 ]", // biasShape
223 "[ 5, 0, 0, 0 ]", // biasData
224 "1") // stride d, w and h
225 {}
226};
227
228TEST_CASE_FIXTURE(SimpleConv3DWithBiasesFixture, "ParseConv3DWithBias")
229{
230 RunTest<5,
231 armnn::DataType::QAsymmU8>(0,
232 { 1, 2, 3, 4, 5, 6, 7, 8 },
233 { 33, 21, 23, 13, 28, 25, 27, 21 });
234}
235
236TEST_CASE_FIXTURE(SimpleConv3DWithBiasesFixture, "ParseDynamicConv3DWithBias")
237{
238 RunTest<5,
239 armnn::DataType::QAsymmU8,
240 armnn::DataType::QAsymmU8>(0,
241 { { "inputTensor", { 2, 4, 6, 8, 10, 12, 14, 16 } } },
242 { { "outputTensor", { 61, 37, 41, 21, 51, 45, 49, 37 } } },
243 true);
244}
245
246struct Relu6Conv3DWithBiasesFixture : Conv3DWithBiasesFixture
247{
248 Relu6Conv3DWithBiasesFixture()
249 : Conv3DWithBiasesFixture("[ 1, 2, 2, 2, 1 ]", // inputShape
250 "[ 1, 2, 2, 2, 1 ]", // outputShape
251 "[ 2, 2, 2, 1, 1 ]", // filterShape
252 "[ 2,1, 1,0, 0,1, 1,1 ]", // filterData
253 "[ 1 ]", // biasShape
254 "[ 0, 0, 0, 0 ]", // biasData
255 "1", // stride d, w, and h
256 "RELU6", // activation
257 "1.0", // filter scale
258 "0", // filter zero point
259 "2.0", // output scale
260 "0") // output zero point
261 {}
262};
263
264TEST_CASE_FIXTURE(Relu6Conv3DWithBiasesFixture, "ParseConv3DAndRelu6WithBias")
265{
266 uint8_t relu6Min = 6 / 2; // Divide by output scale
267
268 RunTest<5, armnn::DataType::QAsymmU8>(
269 0,
270 {
271 1, 2, 3, 4, 5, 6, 7, 8
272 },
273 // RELU6 cuts output values at +6
274 {
275 std::min(relu6Min, static_cast<uint8_t>((1*2 + 2*1 + 3*1 + 4*0 + 5*0 + 6*1 + 7*1 + 8*1)/2)),
276 std::min(relu6Min, static_cast<uint8_t>((2*2 + 0*1 + 0*1 + 0*0 + 0*0 + 0*1 + 8*1 + 0*1)/2)),
277 std::min(relu6Min, static_cast<uint8_t>((3*2 + 0*1 + 0*1 + 0*0 + 0*0 + 8*1 + 0*1 + 0*1)/2)),
278 std::min(relu6Min, static_cast<uint8_t>((4*2 + 0*1 + 0*1 + 0*0 + 8*0 + 0*1 + 0*1 + 0*1)/2)),
279 std::min(relu6Min, static_cast<uint8_t>((5*2 + 0*1 + 0*1 + 8*0 + 0*0 + 0*1 + 0*1 + 0*1)/2)),
280 std::min(relu6Min, static_cast<uint8_t>((6*2 + 0*1 + 8*1 + 0*0 + 0*0 + 0*1 + 0*1 + 0*1)/2)),
281 std::min(relu6Min, static_cast<uint8_t>((7*2 + 8*1 + 0*1 + 0*0 + 0*0 + 0*1 + 0*1 + 0*1)/2)),
282 std::min(relu6Min, static_cast<uint8_t>((8*2 + 0*1 + 0*1 + 0*0 + 0*0 + 0*1 + 0*1 + 0*1)/2))
283 });
284}
285
286}