ArmNN
 20.11
DepthwiseConvolution2D.cpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include <boost/test/unit_test.hpp>
8 #include "../TfLiteParser.hpp"
9 
10 #include <string>
11 #include <iostream>
12 
13 BOOST_AUTO_TEST_SUITE(TensorflowLiteParser)
14 
15 struct DepthwiseConvolution2dFixture : public ParserFlatbuffersFixture
16 {
17  explicit DepthwiseConvolution2dFixture(const std::string& inputShape,
18  const std::string& outputShape,
19  const std::string& filterShape,
20  const std::string& filterData,
21  const std::string& strides,
22  const std::string& paddingType,
23  const std::string biasShape = "",
24  const std::string biasData = "")
25  {
26  std::string inputTensors = "[ 0, 2 ]";
27  std::string biasTensor = "";
28  std::string biasBuffer = "";
29  if (biasShape.size() > 0 && biasData.size() > 0)
30  {
31  inputTensors = "[ 0, 2, 3 ]";
32  biasTensor = R"(
33  {
34  "shape": )" + biasShape + R"( ,
35  "type": "INT32",
36  "buffer": 3,
37  "name": "biasTensor",
38  "quantization": {
39  "min": [ 0.0 ],
40  "max": [ 255.0 ],
41  "scale": [ 1.0 ],
42  "zero_point": [ 0 ],
43  }
44  } )";
45  biasBuffer = R"(
46  { "data": )" + biasData + R"(, }, )";
47  }
48  m_JsonString = R"(
49  {
50  "version": 3,
51  "operator_codes": [ { "builtin_code": "DEPTHWISE_CONV_2D" } ],
52  "subgraphs": [ {
53  "tensors": [
54  {
55  "shape": )" + inputShape + R"(,
56  "type": "UINT8",
57  "buffer": 0,
58  "name": "inputTensor",
59  "quantization": {
60  "min": [ 0.0 ],
61  "max": [ 255.0 ],
62  "scale": [ 1.0 ],
63  "zero_point": [ 0 ],
64  }
65  },
66  {
67  "shape": )" + outputShape + R"(,
68  "type": "UINT8",
69  "buffer": 1,
70  "name": "outputTensor",
71  "quantization": {
72  "min": [ 0.0 ],
73  "max": [ 511.0 ],
74  "scale": [ 2.0 ],
75  "zero_point": [ 0 ],
76  }
77  },
78  {
79  "shape": )" + filterShape + R"(,
80  "type": "UINT8",
81  "buffer": 2,
82  "name": "filterTensor",
83  "quantization": {
84  "min": [ 0.0 ],
85  "max": [ 255.0 ],
86  "scale": [ 1.0 ],
87  "zero_point": [ 0 ],
88  }
89  }, )" + biasTensor + R"(
90  ],
91  "inputs": [ 0 ],
92  "outputs": [ 1 ],
93  "operators": [
94  {
95  "opcode_index": 0,
96  "inputs": )" + inputTensors + R"(,
97  "outputs": [ 1 ],
98  "builtin_options_type": "DepthwiseConv2DOptions",
99  "builtin_options": {
100  "padding": ")" + paddingType + R"(",
101  "stride_w": )" + strides+ R"(,
102  "stride_h": )" + strides+ R"(,
103  "depth_multiplier": 1,
104  "fused_activation_function": "NONE"
105  },
106  "custom_options_format": "FLEXBUFFERS"
107  }
108  ],
109  } ],
110  "buffers" : [
111  { },
112  { },
113  { "data": )" + filterData + R"(, }, )"
114  + biasBuffer + R"(
115  ]
116  }
117  )";
118  SetupSingleInputSingleOutput("inputTensor", "outputTensor");
119  }
120 };
121 
122 struct DepthwiseConvolution2dSameFixture : DepthwiseConvolution2dFixture
123 {
124  DepthwiseConvolution2dSameFixture()
125  : DepthwiseConvolution2dFixture("[ 1, 3, 3, 1 ]", // inputShape
126  "[ 1, 3, 3, 1 ]", // outputShape
127  "[ 1, 3, 3, 1 ]", // filterShape
128  "[ 9,8,7, 6,5,4, 3,2,1 ]", // filterData
129  "1", // stride w and h
130  "SAME") // padding type
131  {}
132 };
133 
134 BOOST_FIXTURE_TEST_CASE(ParseDepthwiseConv2DSame, DepthwiseConvolution2dSameFixture)
135 {
136  RunTest<4, armnn::DataType::QAsymmU8>(
137  0,
138  { 0, 1, 2,
139  3, 4, 5,
140  6, 7, 8 },
141  // the expected values were generated using the example python implementation at
142  // https://eli.thegreenplace.net/2018/depthwise-separable-convolutions-for-machine-learning/
143  // divide the expected values by the output scale, as it is not 1.0
144  { 14/2, 35/2, 38/2,
145  57/2, 120/2, 111/2,
146  110/2, 197/2, 158/2 });
147 }
148 
149 struct DepthwiseConvolution2dValidFixture : DepthwiseConvolution2dFixture
150 {
151  DepthwiseConvolution2dValidFixture ()
152  : DepthwiseConvolution2dFixture("[ 1, 3, 3, 1 ]", // inputShape
153  "[ 1, 1, 1, 1 ]", // outputShape
154  "[ 1, 3, 3, 1 ]", // filterShape
155  "[ 9,8,7, 6,5,4, 3,2,1 ]", // filterData
156  "1", // stride w and h
157  "VALID") // padding type
158  {}
159 };
160 
161 BOOST_FIXTURE_TEST_CASE(ParseDepthwiseConv2DValid, DepthwiseConvolution2dValidFixture)
162 {
163  RunTest<4, armnn::DataType::QAsymmU8>(
164  0,
165  { 0, 1, 2,
166  3, 4, 5,
167  6, 7, 8 },
168  // divide the expected values by the output scale, as it is not 1.0
169  { 120/2 });
170 }
171 
172 struct DepthwiseConvolution2dSameBiasFixture : DepthwiseConvolution2dFixture
173 {
174  DepthwiseConvolution2dSameBiasFixture()
175  : DepthwiseConvolution2dFixture("[ 1, 3, 3, 1 ]", // inputShape
176  "[ 1, 3, 3, 1 ]", // outputShape
177  "[ 1, 3, 3, 1 ]", // filterShape
178  "[ 9,8,7, 6,5,4, 3,2,1 ]", // filterData
179  "1", // stride w and h
180  "SAME", // padding type
181  "[ 1 ]", // biasShape
182  "[ 10, 0, 0, 0 ]") // biasData
183  {}
184 };
185 
186 BOOST_FIXTURE_TEST_CASE(ParseDepthwiseConv2DSameBias, DepthwiseConvolution2dSameBiasFixture)
187 {
188  RunTest<4, armnn::DataType::QAsymmU8>(
189  0,
190  { 0, 1, 2,
191  3, 4, 5,
192  6, 7, 8 },
193  // divide the expected values by the output scale, as it is not 1.0
194  { ( 14+10)/2, ( 35+10)/2, ( 38+10)/2,
195  ( 57+10)/2, (120+10)/2, (111+10)/2,
196  (110+10)/2, (197+10)/2, (158+10)/2 });
197 }
198 
199 struct DynamicDepthwiseConvolution2dSameBiasFixture : DepthwiseConvolution2dFixture
200 {
201  DynamicDepthwiseConvolution2dSameBiasFixture()
202  : DepthwiseConvolution2dFixture("[ 1, 3, 3, 1 ]", // inputShape
203  "[ ]", // outputShape
204  "[ 1, 3, 3, 1 ]", // filterShape
205  "[ 9,8,7, 6,5,4, 3,2,1 ]", // filterData
206  "1", // stride w and h
207  "SAME", // padding type
208  "[ 1 ]", // biasShape
209  "[ 10, 0, 0, 0 ]") // biasData
210  {}
211 };
212 
213 BOOST_FIXTURE_TEST_CASE(ParseDynamicDepthwiseConv2DSameBias, DynamicDepthwiseConvolution2dSameBiasFixture)
214 {
215  RunTest<4, armnn::DataType::QAsymmU8, armnn::DataType::QAsymmU8>(0,
216  { { "inputTensor", { 0, 1, 2,
217  3, 4, 5,
218  6, 7, 8 } } },
219  { { "outputTensor", { ( 14+10)/2, ( 35+10)/2, ( 38+10)/2,
220  ( 57+10)/2, (120+10)/2, (111+10)/2,
221  (110+10)/2, (197+10)/2, (158+10)/2 } } },
222  true);
223 }
224 
BOOST_AUTO_TEST_SUITE(TensorflowLiteParser)
BOOST_AUTO_TEST_SUITE_END()
void SetupSingleInputSingleOutput(const std::string &inputName, const std::string &outputName)
BOOST_FIXTURE_TEST_CASE(ParseDepthwiseConv2DSame, DepthwiseConvolution2dSameFixture)