blob: a3fdcf8123740671cb4baa543cf1f469413a2559 [file] [log] [blame]
Mike Kelly8c1701a2019-02-11 17:01:27 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "Serializer.hpp"
Saoirse Stewart3166c3e2019-02-18 15:24:53 +00007
Matthew Benthamff130e22020-01-17 11:47:42 +00008#include <armnn/Descriptors.hpp>
9#include <armnn/LstmParams.hpp>
10#include <armnn/QuantizedLstmParams.hpp>
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000011
Mike Kelly8c1701a2019-02-11 17:01:27 +000012#include <iostream>
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000013
Derek Lamberti859f9ce2019-12-10 22:05:21 +000014#include <boost/core/ignore_unused.hpp>
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010015#include <boost/numeric/conversion/cast.hpp>
Mike Kelly8c1701a2019-02-11 17:01:27 +000016#include <flatbuffers/util.h>
17
Matthew Benthamff130e22020-01-17 11:47:42 +000018#include "SerializerUtils.hpp"
19
Mike Kelly8c1701a2019-02-11 17:01:27 +000020using namespace armnn;
21namespace fb = flatbuffers;
Derek Lamberti0028d1b2019-02-20 13:57:42 +000022namespace serializer = armnnSerializer;
Mike Kelly8c1701a2019-02-11 17:01:27 +000023
24namespace armnnSerializer
25{
26
Mike Kellyaf484012019-02-20 16:53:11 +000027serializer::ActivationFunction GetFlatBufferActivationFunction(armnn::ActivationFunction function)
28{
29 switch (function)
30 {
31 case armnn::ActivationFunction::Sigmoid:
32 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
33 case armnn::ActivationFunction::TanH:
34 return serializer::ActivationFunction::ActivationFunction_TanH;
35 case armnn::ActivationFunction::Linear:
36 return serializer::ActivationFunction::ActivationFunction_Linear;
37 case armnn::ActivationFunction::ReLu:
38 return serializer::ActivationFunction::ActivationFunction_ReLu;
39 case armnn::ActivationFunction::BoundedReLu:
40 return serializer::ActivationFunction::ActivationFunction_BoundedReLu;
41 case armnn::ActivationFunction::LeakyReLu:
42 return serializer::ActivationFunction::ActivationFunction_LeakyReLu;
43 case armnn::ActivationFunction::Abs:
44 return serializer::ActivationFunction::ActivationFunction_Abs;
45 case armnn::ActivationFunction::Sqrt:
46 return serializer::ActivationFunction::ActivationFunction_Sqrt;
47 case armnn::ActivationFunction::Square:
48 return serializer::ActivationFunction::ActivationFunction_Square;
David Monahan3b3c3812020-02-25 09:03:29 +000049 case armnn::ActivationFunction::Elu:
50 return serializer::ActivationFunction::ActivationFunction_Elu;
Mike Kellyaf484012019-02-20 16:53:11 +000051 default:
52 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
53 }
54}
55
Narumol Prangnawarat0cfcf232019-09-09 17:16:24 +010056serializer::ArgMinMaxFunction GetFlatBufferArgMinMaxFunction(armnn::ArgMinMaxFunction function)
57{
58 switch (function)
59 {
60 case armnn::ArgMinMaxFunction::Max:
61 return serializer::ArgMinMaxFunction::ArgMinMaxFunction_Max;
62 case armnn::ArgMinMaxFunction::Min:
63 default:
64 return serializer::ArgMinMaxFunction::ArgMinMaxFunction_Min;
65 }
66}
67
janeil013fec1ea2019-11-07 09:47:20 +000068uint32_t SerializerVisitor::GetSerializedId(armnn::LayerGuid guid)
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000069{
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000070 if (m_guidMap.empty())
71 {
janeil013fec1ea2019-11-07 09:47:20 +000072 m_guidMap.insert(std::make_pair(guid, m_layerId));
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000073 }
74 else if (m_guidMap.find(guid) == m_guidMap.end())
75 {
janeil013fec1ea2019-11-07 09:47:20 +000076 ++m_layerId;
77 m_guidMap.insert(std::make_pair(guid, m_layerId));
78
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000079 return m_layerId;
80 }
Saoirse Stewart30211042019-02-18 17:19:16 +000081 return m_guidMap[guid];
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000082}
83
Mike Kelly8c1701a2019-02-11 17:01:27 +000084// Build FlatBuffer for Input Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +000085void SerializerVisitor::VisitInputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000086{
Derek Lamberti859f9ce2019-12-10 22:05:21 +000087 boost::ignore_unused(name);
88
Mike Kelly8c1701a2019-02-11 17:01:27 +000089 // Create FlatBuffer BaseLayer
90 auto flatBufferInputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Input);
91
92 // Create FlatBuffer BindableBaseLayer
93 auto flatBufferInputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
94 flatBufferInputBaseLayer,
95 id);
Tee Jungaa920c52019-11-05 10:48:25 +000096 // Push layer binding id to outputIds.
97 m_inputIds.push_back(id);
Mike Kelly8c1701a2019-02-11 17:01:27 +000098
99 // Create the FlatBuffer InputLayer
100 auto flatBufferInputLayer = serializer::CreateInputLayer(m_flatBufferBuilder, flatBufferInputBindableBaseLayer);
101
102 // Add the AnyLayer to the FlatBufferLayers
103 CreateAnyLayer(flatBufferInputLayer.o, serializer::Layer::Layer_InputLayer);
104}
105
106// Build FlatBuffer for Output Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000107void SerializerVisitor::VisitOutputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000108{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000109 boost::ignore_unused(name);
110
Mike Kelly8c1701a2019-02-11 17:01:27 +0000111 // Create FlatBuffer BaseLayer
112 auto flatBufferOutputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Output);
113
114 // Create FlatBuffer BindableBaseLayer
115 auto flatBufferOutputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
116 flatBufferOutputBaseLayer,
117 id);
Tee Jungaa920c52019-11-05 10:48:25 +0000118 // Push layer binding id to outputIds.
119 m_outputIds.push_back(id);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000120
121 // Create the FlatBuffer OutputLayer
122 auto flatBufferOutputLayer = serializer::CreateOutputLayer(m_flatBufferBuilder, flatBufferOutputBindableBaseLayer);
123 // Add the AnyLayer to the FlatBufferLayers
124 CreateAnyLayer(flatBufferOutputLayer.o, serializer::Layer::Layer_OutputLayer);
125}
126
Kevin May868eb142019-09-04 17:29:31 +0100127void SerializerVisitor::VisitAbsLayer(const armnn::IConnectableLayer* layer, const char* name)
128{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000129 boost::ignore_unused(name);
FinnWilliamsArm4ffcc8f2019-09-05 14:34:20 +0100130 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Abs);
131 auto flatBufferAbsLayer = serializer::CreateAbsLayer(m_flatBufferBuilder, flatBufferBaseLayer);
132
133 CreateAnyLayer(flatBufferAbsLayer.o, serializer::Layer::Layer_AbsLayer);
Kevin May868eb142019-09-04 17:29:31 +0100134}
135
Mike Kellyaf484012019-02-20 16:53:11 +0000136// Build FlatBuffer for Activation Layer
137void SerializerVisitor::VisitActivationLayer(const armnn::IConnectableLayer* layer,
138 const armnn::ActivationDescriptor& descriptor,
139 const char* name)
140{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000141 boost::ignore_unused(name);
142
Mike Kellyaf484012019-02-20 16:53:11 +0000143 // Create FlatBuffer BaseLayer
144 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Activation);
145
146 // Create the FlatBuffer ActivationDescriptor
147 auto flatBufferDescriptor = CreateActivationDescriptor(m_flatBufferBuilder,
148 GetFlatBufferActivationFunction(descriptor.m_Function),
149 descriptor.m_A,
150 descriptor.m_B);
151
152 // Create the FlatBuffer ActivationLayer
153 auto flatBufferAdditionLayer = CreateActivationLayer(m_flatBufferBuilder,
154 flatBufferBaseLayer,
155 flatBufferDescriptor);
156
157 // Add the AnyLayer to the FlatBufferLayers
158 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_ActivationLayer);
159}
160
Mike Kelly8c1701a2019-02-11 17:01:27 +0000161// Build FlatBuffer for Addition Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000162void SerializerVisitor::VisitAdditionLayer(const armnn::IConnectableLayer* layer, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000163{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000164 boost::ignore_unused(name);
165
Mike Kelly8c1701a2019-02-11 17:01:27 +0000166 // Create FlatBuffer BaseLayer
167 auto flatBufferAdditionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Addition);
168
169 // Create the FlatBuffer AdditionLayer
170 auto flatBufferAdditionLayer = serializer::CreateAdditionLayer(m_flatBufferBuilder, flatBufferAdditionBaseLayer);
171
172 // Add the AnyLayer to the FlatBufferLayers
173 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_AdditionLayer);
174}
175
Nikhil Rajee391d52019-09-05 17:50:44 +0100176// Build FlatBuffer for ArgMinMax Layer
177void SerializerVisitor::VisitArgMinMaxLayer(const armnn::IConnectableLayer *layer,
178 const armnn::ArgMinMaxDescriptor& descriptor,
179 const char *name)
180{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000181 boost::ignore_unused(name);
182
Narumol Prangnawarat0cfcf232019-09-09 17:16:24 +0100183 // Create FlatBuffer BaseLayer
184 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ArgMinMax);
185
186 // Create FlatBuffer Descriptor
187 auto flatBufferDescriptor = CreateArgMinMaxDescriptor(m_flatBufferBuilder,
188 GetFlatBufferArgMinMaxFunction(descriptor.m_Function),
189 descriptor.m_Axis);
190
191 // Create FlatBuffer ArgMinMaxLayer
192 auto flatBufferLayer = CreateArgMinMaxLayer(m_flatBufferBuilder,
193 flatBufferBaseLayer,
194 flatBufferDescriptor);
195
196 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ArgMinMaxLayer);
Nikhil Rajee391d52019-09-05 17:50:44 +0100197}
198
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000199// Build FlatBuffer for BatchToSpaceNd Layer
200void SerializerVisitor::VisitBatchToSpaceNdLayer(const armnn::IConnectableLayer* layer,
201 const armnn::BatchToSpaceNdDescriptor& descriptor,
202 const char* name)
203{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000204 boost::ignore_unused(name);
205
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000206 // Create FlatBuffer BaseLayer
207 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchToSpaceNd);
208
209 std::vector<unsigned int> crops;
210 crops.reserve(descriptor.m_Crops.size() * 2);
211 for (auto& crop : descriptor.m_Crops)
212 {
213 crops.push_back(crop.first);
214 crops.push_back(crop.second);
215 }
216
217 auto flatBufferDescriptor =
218 CreateBatchToSpaceNdDescriptor(m_flatBufferBuilder,
219 m_flatBufferBuilder.CreateVector(descriptor.m_BlockShape),
220 m_flatBufferBuilder.CreateVector(crops),
221 GetFlatBufferDataLayout(descriptor.m_DataLayout));
222
223 auto flatBufferLayer = serializer::CreateBatchToSpaceNdLayer(m_flatBufferBuilder,
224 flatBufferBaseLayer,
225 flatBufferDescriptor);
226
227 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_BatchToSpaceNdLayer);
228}
229
ruoyan018e7fa232019-02-28 15:09:07 +0000230void SerializerVisitor::VisitBatchNormalizationLayer(const armnn::IConnectableLayer* layer,
231 const armnn::BatchNormalizationDescriptor& batchNormDescriptor,
232 const armnn::ConstTensor& mean,
233 const armnn::ConstTensor& variance,
234 const armnn::ConstTensor& beta,
235 const armnn::ConstTensor& gamma,
236 const char* name)
237{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000238 boost::ignore_unused(name);
239
ruoyan018e7fa232019-02-28 15:09:07 +0000240 auto fbBatchNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchNormalization);
241 auto fbBatchNormalizationDescriptor = serializer::CreateBatchNormalizationDescriptor(
242 m_flatBufferBuilder,
243 batchNormDescriptor.m_Eps,
244 GetFlatBufferDataLayout(batchNormDescriptor.m_DataLayout));
245
246 auto fbMeanConstTensorInfo = CreateConstTensorInfo(mean);
247 auto fbVarianceConstTensorInfo = CreateConstTensorInfo(variance);
248 auto fbBetaConstTensorInfo = CreateConstTensorInfo(beta);
249 auto fbGammaConstTensorInfo = CreateConstTensorInfo(gamma);
250 auto fbBatchNormalizationLayer = serializer::CreateBatchNormalizationLayer(m_flatBufferBuilder,
251 fbBatchNormalizationBaseLayer,
252 fbBatchNormalizationDescriptor,
253 fbMeanConstTensorInfo,
254 fbVarianceConstTensorInfo,
255 fbBetaConstTensorInfo,
256 fbGammaConstTensorInfo);
257
258 CreateAnyLayer(fbBatchNormalizationLayer.o, serializer::Layer::Layer_BatchNormalizationLayer);
259}
260
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100261void SerializerVisitor::VisitComparisonLayer(const armnn::IConnectableLayer* layer,
262 const armnn::ComparisonDescriptor& descriptor,
263 const char* name)
264{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000265 boost::ignore_unused(name);
266
Aron Virginas-Tare80ebd12019-10-17 16:11:54 +0100267 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Comparison);
268 auto fbDescriptor = serializer::CreateComparisonDescriptor(
269 m_flatBufferBuilder,
270 GetFlatBufferComparisonOperation(descriptor.m_Operation));
271
272 auto fbLayer = serializer::CreateComparisonLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
273 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_ComparisonLayer);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100274}
275
Conor Kennedy76277882019-02-26 08:29:54 +0000276// Build FlatBuffer for Constant Layer
277void SerializerVisitor::VisitConstantLayer(const armnn::IConnectableLayer* layer,
278 const armnn::ConstTensor& input,
279 const char* name)
280{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000281 boost::ignore_unused(name);
282
Conor Kennedy76277882019-02-26 08:29:54 +0000283 // Create FlatBuffer BaseLayer
284 auto flatBufferConstantBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Constant);
285
286 auto flatBufferConstTensorInfo = CreateConstTensorInfo(input);
287
288 // Create the FlatBuffer ConstantLayer
289 auto flatBufferLayer = CreateConstantLayer(m_flatBufferBuilder,
290 flatBufferConstantBaseLayer,
291 flatBufferConstTensorInfo);
292
293 // Add the AnyLayer to the FlatBufferLayers
294 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConstantLayer);
295}
296
Mike Kellya0766c32019-02-19 17:22:07 +0000297// Build FlatBuffer for Convolution2dLayer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000298void SerializerVisitor::VisitConvolution2dLayer(const armnn::IConnectableLayer* layer,
299 const armnn::Convolution2dDescriptor& descriptor,
300 const armnn::ConstTensor& weights,
301 const armnn::Optional<armnn::ConstTensor>& biases,
Mike Kellya0766c32019-02-19 17:22:07 +0000302 const char* name)
303{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000304 boost::ignore_unused(name);
305
Mike Kellya0766c32019-02-19 17:22:07 +0000306 // Create FlatBuffer BaseLayer
307 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
308
309 auto flatBufferDescriptor = CreateConvolution2dDescriptor(m_flatBufferBuilder,
310 descriptor.m_PadLeft,
311 descriptor.m_PadRight,
312 descriptor.m_PadTop,
313 descriptor.m_PadBottom,
314 descriptor.m_StrideX,
315 descriptor.m_StrideY,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100316 descriptor.m_DilationX,
317 descriptor.m_DilationY,
Mike Kellya0766c32019-02-19 17:22:07 +0000318 descriptor.m_BiasEnabled,
319 GetFlatBufferDataLayout(descriptor.m_DataLayout));
320 auto flatBufferWeightsConstTensorInfo = CreateConstTensorInfo(weights);
321 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiasesConstTensorInfo;
322
323 if (biases.has_value())
324 {
325 flatBufferBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
326 }
327
328 // Create the FlatBuffer Convolution2dLayer
329 auto flatBufferLayer = CreateConvolution2dLayer(m_flatBufferBuilder,
330 flatBufferBaseLayer,
331 flatBufferDescriptor,
332 flatBufferWeightsConstTensorInfo,
333 flatBufferBiasesConstTensorInfo);
334
335 // Add the AnyLayer to the FlatBufferLayers
336 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution2dLayer);
337}
338
Aron Virginas-Tardd6247f2019-09-19 14:31:17 +0100339void SerializerVisitor::VisitDepthToSpaceLayer(const armnn::IConnectableLayer* layer,
340 const armnn::DepthToSpaceDescriptor& descriptor,
341 const char* name)
342{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000343 boost::ignore_unused(name);
344
Aron Virginas-Tarda9d2d32019-09-20 10:42:02 +0100345 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthToSpace);
346 auto fbDescriptor = CreateDepthToSpaceDescriptor(m_flatBufferBuilder,
347 descriptor.m_BlockSize,
348 GetFlatBufferDataLayout(descriptor.m_DataLayout));
349
350 auto fbLayer = serializer::CreateDepthToSpaceLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
351
352 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_DepthToSpaceLayer);
Aron Virginas-Tardd6247f2019-09-19 14:31:17 +0100353}
354
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000355void SerializerVisitor::VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
356 const armnn::DepthwiseConvolution2dDescriptor& descriptor,
357 const armnn::ConstTensor& weights,
358 const armnn::Optional<armnn::ConstTensor>& biases,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000359 const char* name)
360{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000361 boost::ignore_unused(name);
362
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000363 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthwiseConvolution2d);
364 auto fbDescriptor = CreateDepthwiseConvolution2dDescriptor(m_flatBufferBuilder,
365 descriptor.m_PadLeft,
366 descriptor.m_PadRight,
367 descriptor.m_PadTop,
368 descriptor.m_PadBottom,
369 descriptor.m_StrideX,
370 descriptor.m_StrideY,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100371 descriptor.m_DilationX,
372 descriptor.m_DilationY,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000373 descriptor.m_BiasEnabled,
374 GetFlatBufferDataLayout(descriptor.m_DataLayout));
375
376 flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
377 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
378 if (biases.has_value())
379 {
380 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
381 }
382
383 auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
384 fbBaseLayer,
385 fbDescriptor,
386 fbWeightsConstTensorInfo,
387 fbBiasesConstTensorInfo);
388
389 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
390}
391
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000392void SerializerVisitor::VisitDequantizeLayer(const armnn::IConnectableLayer* layer,
393 const char* name)
394{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000395 boost::ignore_unused(name);
396
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000397 auto fbDequantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Dequantize);
398 auto fbDequantizeLayer = serializer::CreateDequantizeLayer(m_flatBufferBuilder, fbDequantizeBaseLayer);
399
400 CreateAnyLayer(fbDequantizeLayer.o, serializer::Layer::Layer_DequantizeLayer);
401}
402
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000403void SerializerVisitor::VisitDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
404 const armnn::DetectionPostProcessDescriptor& descriptor,
405 const armnn::ConstTensor& anchors,
406 const char* name)
407{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000408 boost::ignore_unused(name);
409
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000410 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
411 auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
412 descriptor.m_MaxDetections,
413 descriptor.m_MaxClassesPerDetection,
414 descriptor.m_DetectionsPerClass,
415 descriptor.m_NmsScoreThreshold,
416 descriptor.m_NmsIouThreshold,
417 descriptor.m_NumClasses,
418 descriptor.m_UseRegularNms,
419 descriptor.m_ScaleX,
420 descriptor.m_ScaleY,
421 descriptor.m_ScaleW,
422 descriptor.m_ScaleH);
423
424 flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);
425
426 auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
427 fbBaseLayer,
428 fbDescriptor,
429 fbAnchorsConstTensorInfo);
430
431 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
432}
433
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000434void SerializerVisitor::VisitDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
435{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000436 boost::ignore_unused(name);
437
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000438 auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
439 auto fbDivisionLayer = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000440
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000441 CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
442}
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000443
josh minor4a3c6102020-01-06 16:40:46 -0600444void SerializerVisitor::VisitElementwiseUnaryLayer(const armnn::IConnectableLayer* layer,
445 const armnn::ElementwiseUnaryDescriptor& descriptor,
446 const char* name)
447{
448 boost::ignore_unused(name);
449
450 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ElementwiseUnary);
451 auto fbDescriptor = serializer::CreateElementwiseUnaryDescriptor(
452 m_flatBufferBuilder,
453 GetFlatBufferUnaryOperation(descriptor.m_Operation));
454
455 auto fbLayer = serializer::CreateElementwiseUnaryLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
456 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_ElementwiseUnaryLayer);
457}
458
Aron Virginas-Tar377351e2019-02-27 14:42:31 +0000459void SerializerVisitor::VisitEqualLayer(const armnn::IConnectableLayer* layer, const char* name)
460{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000461 boost::ignore_unused(name);
462
Aron Virginas-Tar377351e2019-02-27 14:42:31 +0000463 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Equal);
464 auto fbEqualLayer = serializer::CreateEqualLayer(m_flatBufferBuilder, fbBaseLayer);
465
466 CreateAnyLayer(fbEqualLayer.o, serializer::Layer::Layer_EqualLayer);
467}
468
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000469void SerializerVisitor::VisitFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
470{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000471 boost::ignore_unused(name);
472
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000473 auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
474 auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);
475
476 CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
477}
478
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000479void SerializerVisitor::VisitGatherLayer(const armnn::IConnectableLayer* layer, const char* name)
480{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000481 boost::ignore_unused(name);
482
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000483 auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
484 auto flatBufferLayer = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer);
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000485
486 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
487}
488
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000489void SerializerVisitor::VisitGreaterLayer(const armnn::IConnectableLayer* layer, const char* name)
490{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000491 boost::ignore_unused(name);
492
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000493 auto fbGreaterBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Greater);
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000494 auto fbGreaterLayer = serializer::CreateGreaterLayer(m_flatBufferBuilder, fbGreaterBaseLayer);
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000495
496 CreateAnyLayer(fbGreaterLayer.o, serializer::Layer::Layer_GreaterLayer);
497}
498
Kevin Mayce5045a2019-10-02 14:07:47 +0100499void SerializerVisitor::VisitInstanceNormalizationLayer(
500 const armnn::IConnectableLayer* layer,
501 const armnn::InstanceNormalizationDescriptor& instanceNormalizationDescriptor,
502 const char* name)
503{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000504 boost::ignore_unused(name);
505
Aron Virginas-Tar781ced92019-10-03 11:15:39 +0100506 auto fbDescriptor = serializer::CreateInstanceNormalizationDescriptor(
507 m_flatBufferBuilder,
508 instanceNormalizationDescriptor.m_Gamma,
509 instanceNormalizationDescriptor.m_Beta,
510 instanceNormalizationDescriptor.m_Eps,
511 GetFlatBufferDataLayout(instanceNormalizationDescriptor.m_DataLayout));
512
513 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_InstanceNormalization);
514 auto fbLayer = serializer::CreateInstanceNormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
515
516 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_InstanceNormalizationLayer);
Kevin Mayce5045a2019-10-02 14:07:47 +0100517}
518
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000519void SerializerVisitor::VisitL2NormalizationLayer(const armnn::IConnectableLayer* layer,
520 const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
521 const char* name)
522{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000523 boost::ignore_unused(name);
524
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000525 // Create FlatBuffer BaseLayer
526 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);
527
528 // Create the FlatBuffer L2Normalization Descriptor
529 auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100530 m_flatBufferBuilder,
531 GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout),
532 l2NormalizationDescriptor.m_Eps);
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000533
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100534 // Create FlatBuffer layer
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000535 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
536
537 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
538}
539
Aron Virginas-Tarf982dea2019-10-11 14:07:53 +0100540void SerializerVisitor::VisitLogSoftmaxLayer(const armnn::IConnectableLayer* layer,
541 const armnn::LogSoftmaxDescriptor& logSoftmaxDescriptor,
542 const char* name)
543{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000544 boost::ignore_unused(name);
545
Sadik Armagan26257852019-10-14 13:00:47 +0100546 // Create FlatBuffer BaseLayer
547 auto flatBufferLogSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_LogSoftmax);
548
549 // Create the FlatBuffer LogSoftmaxDescriptor
550 auto flatBufferLogSoftmaxDesc =
551 serializer::CreateLogSoftmaxDescriptor(m_flatBufferBuilder,
552 logSoftmaxDescriptor.m_Beta,
553 logSoftmaxDescriptor.m_Axis);
554
555 // Create the FlatBuffer LogSoftmaxLayer
556 auto flatBufferLogSoftmaxLayer =
557 serializer::CreateLogSoftmaxLayer(m_flatBufferBuilder,
558 flatBufferLogSoftmaxBaseLayer,
559 flatBufferLogSoftmaxDesc);
560
561 CreateAnyLayer(flatBufferLogSoftmaxLayer.o, serializer::Layer::Layer_LogSoftmaxLayer);
Aron Virginas-Tarf982dea2019-10-11 14:07:53 +0100562}
563
564void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer,
565 const armnn::LstmDescriptor& descriptor,
566 const armnn::LstmInputParams& params,
567 const char* name)
Jim Flynn11af3752019-03-19 17:22:29 +0000568{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000569 boost::ignore_unused(name);
570
Jim Flynn11af3752019-03-19 17:22:29 +0000571 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
572
573 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
574 m_flatBufferBuilder,
575 descriptor.m_ActivationFunc,
576 descriptor.m_ClippingThresCell,
577 descriptor.m_ClippingThresProj,
578 descriptor.m_CifgEnabled,
579 descriptor.m_PeepholeEnabled,
Jan Eilersf8c62972019-07-17 11:07:49 +0100580 descriptor.m_ProjectionEnabled,
581 descriptor.m_LayerNormEnabled);
Jim Flynn11af3752019-03-19 17:22:29 +0000582
583 // Get mandatory input parameters
584 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
585 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
586 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
587 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
588 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
589 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
590 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
591 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
592 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
593
594 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
595 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
596 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
597 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
598 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
599 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
600 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
601 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
602 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
Jan Eilersf8c62972019-07-17 11:07:49 +0100603 flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
604 flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
605 flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
606 flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;
Jim Flynn11af3752019-03-19 17:22:29 +0000607
608 if (!descriptor.m_CifgEnabled)
609 {
610 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
611 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
612 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
613 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
614 }
615
616 if (descriptor.m_ProjectionEnabled)
617 {
618 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
619 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
620 }
621
622 if (descriptor.m_PeepholeEnabled)
623 {
624 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
625 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
626 }
627
Jan Eilersf8c62972019-07-17 11:07:49 +0100628 if (descriptor.m_LayerNormEnabled)
629 {
630 if (!descriptor.m_CifgEnabled)
631 {
632 inputLayerNormWeights = CreateConstTensorInfo((*params.m_InputLayerNormWeights));
633 }
634 forgetLayerNormWeights = CreateConstTensorInfo(*params.m_ForgetLayerNormWeights);
635 cellLayerNormWeights = CreateConstTensorInfo(*params.m_CellLayerNormWeights);
636 outputLayerNormWeights = CreateConstTensorInfo(*params.m_OutputLayerNormWeights);
637 }
638
Jim Flynn11af3752019-03-19 17:22:29 +0000639 auto fbLstmParams = serializer::CreateLstmInputParams(
640 m_flatBufferBuilder,
641 inputToForgetWeights,
642 inputToCellWeights,
643 inputToOutputWeights,
644 recurrentToForgetWeights,
645 recurrentToCellWeights,
646 recurrentToOutputWeights,
647 forgetGateBias,
648 cellBias,
649 outputGateBias,
650 inputToInputWeights,
651 recurrentToInputWeights,
652 cellToInputWeights,
653 inputGateBias,
654 projectionWeights,
655 projectionBias,
656 cellToForgetWeights,
Jan Eilersf8c62972019-07-17 11:07:49 +0100657 cellToOutputWeights,
658 inputLayerNormWeights,
659 forgetLayerNormWeights,
660 cellLayerNormWeights,
661 outputLayerNormWeights);
Jim Flynn11af3752019-03-19 17:22:29 +0000662
663 auto fbLstmLayer = serializer::CreateLstmLayer(
664 m_flatBufferBuilder,
665 fbLstmBaseLayer,
666 fbLstmDescriptor,
667 fbLstmParams);
668
669 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
670}
671
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000672void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
673{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000674 boost::ignore_unused(name);
675
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000676 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
677 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
678
679 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
680}
681
682void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
683 const armnn::MeanDescriptor& descriptor,
684 const char* name)
685{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000686 boost::ignore_unused(name);
687
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000688 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
689 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
690 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
691 descriptor.m_KeepDims);
692
693 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
694 fbMeanBaseLayer,
695 fbMeanDescriptor);
696
697 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
698}
699
700void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
701{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000702 boost::ignore_unused(name);
703
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000704 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
705 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
706
707 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
708}
709
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100710void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
711{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000712 boost::ignore_unused(name);
713
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100714 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
715 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
716
717 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
718}
719
Jim Flynnac25a1b2019-02-28 10:40:49 +0000720void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
Jim Flynne242f2d2019-05-22 14:24:13 +0100721 const armnn::MergerDescriptor& mergerDescriptor,
Jim Flynnac25a1b2019-02-28 10:40:49 +0000722 const char* name)
723{
Jim Flynne242f2d2019-05-22 14:24:13 +0100724 VisitConcatLayer(layer, mergerDescriptor, name);
725}
726
727void SerializerVisitor::VisitConcatLayer(const armnn::IConnectableLayer* layer,
728 const armnn::ConcatDescriptor& concatDescriptor,
729 const char* name)
730{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000731 boost::ignore_unused(name);
732
Jim Flynne242f2d2019-05-22 14:24:13 +0100733 auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000734
735 std::vector<flatbuffers::Offset<UintVector>> views;
Jim Flynne242f2d2019-05-22 14:24:13 +0100736 for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000737 {
Jim Flynne242f2d2019-05-22 14:24:13 +0100738 const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000739 std::vector<uint32_t> origins;
Jim Flynne242f2d2019-05-22 14:24:13 +0100740 for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000741 {
742 origins.push_back(origin[d]);
743 }
744 auto view = m_flatBufferBuilder.CreateVector(origins);
745 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
746 views.push_back(uintVector);
747 }
748
Jim Flynne242f2d2019-05-22 14:24:13 +0100749 auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
750 concatDescriptor.GetConcatAxis(),
751 concatDescriptor.GetNumViews(),
752 concatDescriptor.GetNumDimensions(),
Jim Flynnac25a1b2019-02-28 10:40:49 +0000753 m_flatBufferBuilder.CreateVector(views));
754
Jim Flynne242f2d2019-05-22 14:24:13 +0100755 auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
756 flatBufferConcatBaseLayer,
757 flatBufferConcatDescriptor);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000758
Jim Flynne242f2d2019-05-22 14:24:13 +0100759 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000760}
761
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000762void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000763{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000764 boost::ignore_unused(name);
765
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000766 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
767 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
768 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000769
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000770 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000771}
772
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000773void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
774 const armnn::PadDescriptor& padDescriptor,
775 const char* name)
776{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000777 boost::ignore_unused(name);
778
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000779 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
780
781 std::vector<unsigned int> padList;
782 for (auto& p: padDescriptor.m_PadList)
783 {
784 padList.push_back(p.first);
785 padList.push_back(p.second);
786 }
787
788 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
David Monahan34757812019-06-19 11:47:21 +0100789 m_flatBufferBuilder.CreateVector(padList),
Aron Virginas-Tarf3569052019-07-05 16:01:08 +0100790 padDescriptor.m_PadValue);
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000791
792 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
793 flatBufferBaseLayer,
794 flatBufferPadDesc);
795
796 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
797}
798
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000799void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
800 const armnn::PermuteDescriptor& permuteDescriptor,
801 const char* name)
802{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000803 boost::ignore_unused(name);
804
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000805 // Create FlatBuffer BaseLayer
806 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
807
808 std::vector<unsigned int> dimMappings;
Matthew Jacksondba634f2019-08-15 15:14:18 +0100809 for (unsigned int i=0; i<permuteDescriptor.m_DimMappings.GetSize(); ++i)
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000810 {
Matthew Jacksondba634f2019-08-15 15:14:18 +0100811 dimMappings.push_back(permuteDescriptor.m_DimMappings[i]);
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000812 }
813
814 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
815 m_flatBufferBuilder.CreateVector(dimMappings));
816
817 // Create the FlatBuffer PermuteLayer
818 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
819 flatBufferPermuteBaseLayer,
820 flatBufferPermuteDesc);
821
822 // Add the AnyLayer to the FlatBufferLayers
823 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
824}
825
Saoirse Stewart263829c2019-02-19 15:54:14 +0000826// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000827void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000828 const armnn::ReshapeDescriptor& reshapeDescriptor,
829 const char* name)
830{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000831 boost::ignore_unused(name);
832
Saoirse Stewart263829c2019-02-19 15:54:14 +0000833 // Create FlatBuffer BaseLayer
834 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
835
836 std::vector<unsigned int> targetShape;
837 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
838 {
839 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
840 }
841
842 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
843 m_flatBufferBuilder.CreateVector(targetShape));
844
845 // Create the FlatBuffer ReshapeLayer
846 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
847 flatBufferReshapeDesc);
848
849 // Add the AnyLayer to the FlatBufferLayers
850 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
851}
852
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000853void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
854 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
855 const char* name)
856{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000857 boost::ignore_unused(name);
858
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000859 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
860
861 auto flatBufferDescriptor =
862 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
863 resizeDescriptor.m_TargetWidth,
864 resizeDescriptor.m_TargetHeight,
865 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
866
867 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
868 flatBufferBaseLayer,
869 flatBufferDescriptor);
870
871 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
872}
873
Teresa Charlina9075df2019-06-27 15:41:57 +0100874void SerializerVisitor::VisitResizeLayer(const armnn::IConnectableLayer* layer,
875 const armnn::ResizeDescriptor& resizeDescriptor,
876 const char* name)
877{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000878 boost::ignore_unused(name);
879
FinnWilliamsArm6fb339a2019-06-28 15:07:10 +0100880 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Resize);
881
882 auto flatBufferDescriptor =
883 CreateResizeDescriptor(m_flatBufferBuilder,
884 resizeDescriptor.m_TargetHeight,
885 resizeDescriptor.m_TargetWidth,
886 GetFlatBufferResizeMethod(resizeDescriptor.m_Method),
887 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
888
889 auto flatBufferLayer = serializer::CreateResizeLayer(m_flatBufferBuilder,
890 flatBufferBaseLayer,
891 flatBufferDescriptor);
892
893 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeLayer);
Teresa Charlina9075df2019-06-27 15:41:57 +0100894}
895
Sadik Armagan8b42a382019-03-01 14:24:49 +0000896void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
897{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000898 boost::ignore_unused(name);
899
Sadik Armagan8b42a382019-03-01 14:24:49 +0000900 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
901 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
902
903 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
904}
905
Aron Virginas-Tar636ab402019-09-16 14:27:45 +0100906void SerializerVisitor::VisitSliceLayer(const armnn::IConnectableLayer* layer,
907 const armnn::SliceDescriptor& sliceDescriptor,
908 const char* name)
909{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000910 boost::ignore_unused(name);
911
Aron Virginas-Tar2fda80b2019-09-18 13:36:52 +0100912 auto fbSliceBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Slice);
913 auto fbSliceDescriptor = CreateSliceDescriptor(m_flatBufferBuilder,
914 m_flatBufferBuilder.CreateVector(sliceDescriptor.m_Begin),
915 m_flatBufferBuilder.CreateVector(sliceDescriptor.m_Size));
916
917 auto fbSliceLayer = serializer::CreateSliceLayer(m_flatBufferBuilder, fbSliceBaseLayer, fbSliceDescriptor);
918
919 CreateAnyLayer(fbSliceLayer.o, serializer::Layer::Layer_SliceLayer);
Aron Virginas-Tar636ab402019-09-16 14:27:45 +0100920}
921
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000922// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000923void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
924 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000925 const char* name)
926{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000927 boost::ignore_unused(name);
928
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000929 // Create FlatBuffer BaseLayer
930 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
931
932 // Create the FlatBuffer SoftmaxDescriptor
933 auto flatBufferSoftmaxDesc =
934 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
935
936 // Create the FlatBuffer SoftmaxLayer
937 auto flatBufferSoftmaxLayer =
938 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
939 flatBufferSoftmaxBaseLayer,
940 flatBufferSoftmaxDesc);
941
942 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
943}
944
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000945void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
946 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000947 const char* name)
948{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000949 boost::ignore_unused(name);
950
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000951 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
952 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
953 m_flatBufferBuilder,
954 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
955 pooling2dDescriptor.m_PadLeft,
956 pooling2dDescriptor.m_PadRight,
957 pooling2dDescriptor.m_PadTop,
958 pooling2dDescriptor.m_PadBottom,
959 pooling2dDescriptor.m_PoolWidth,
960 pooling2dDescriptor.m_PoolHeight,
961 pooling2dDescriptor.m_StrideX,
962 pooling2dDescriptor.m_StrideY,
963 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
964 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
965 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
966
967 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
968 fbPooling2dBaseLayer,
969 fbPooling2dDescriptor);
970
971 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
972}
973
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100974void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
975 const char* name)
976{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000977 boost::ignore_unused(name);
978
Ellen Norris-Thompson51982472019-06-19 11:46:21 +0100979 // Create FlatBuffer BaseLayer
980 auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
981
982 // Create the FlatBuffer AdditionLayer
983 auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
984
985 // Add the AnyLayer to the FlatBufferLayers
986 CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100987}
988
Derek Lamberti87acb272019-03-27 16:51:31 +0000989void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
990{
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000991 boost::ignore_unused(name);
992
Derek Lamberti87acb272019-03-27 16:51:31 +0000993 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
994 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
995 fbQuantizeBaseLayer);
996 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
997}
998
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000999// Build FlatBuffer for FullyConnected Layer
1000void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
1001 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
1002 const armnn::ConstTensor& weights,
1003 const armnn::Optional<armnn::ConstTensor>& biases,
1004 const char* name)
1005{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001006 boost::ignore_unused(name);
1007
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001008 // Create FlatBuffer BaseLayer
1009 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
1010
1011 // Create FlatBuffer FullyConnectedDescriptor
1012 auto flatBufferDescriptor =
1013 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
1014 fullyConnectedDescriptor.m_BiasEnabled,
1015 fullyConnectedDescriptor.m_TransposeWeightMatrix);
1016
1017 // Create FlatBuffer weights data
1018 auto flatBufferWeights = CreateConstTensorInfo(weights);
1019
1020 // Create FlatBuffer bias data
1021 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
1022 if (fullyConnectedDescriptor.m_BiasEnabled)
1023 {
1024 flatBufferBiases = CreateConstTensorInfo(biases.value());
1025 }
1026
1027 // Create FlatBuffer FullyConnectedLayer
1028 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
1029 flatBufferBaseLayer,
1030 flatBufferDescriptor,
1031 flatBufferWeights,
1032 flatBufferBiases);
1033
1034 // Add created FullyConnectedLayer to the FlatBufferLayers
1035 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
1036}
1037
Nattapat Chaimanowong45286992019-02-26 15:53:02 +00001038// Build FlatBuffer for SpaceToBatchNd Layer
1039void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
1040 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
1041 const char* name)
1042{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001043 boost::ignore_unused(name);
1044
Nattapat Chaimanowong45286992019-02-26 15:53:02 +00001045 // Create FlatBuffer BaseLayer
1046 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
1047
1048 std::vector<unsigned int> padList;
1049 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
1050 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
1051 {
1052 padList.push_back(pad.first);
1053 padList.push_back(pad.second);
1054 }
1055
1056 auto flatBufferDescriptor =
1057 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
1058 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
1059 m_flatBufferBuilder.CreateVector(padList),
1060 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
1061
1062 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
1063 flatBufferBaseLayer,
1064 flatBufferDescriptor);
1065
1066 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
1067}
1068
Aron Virginas-Tar972af152019-06-11 14:14:03 +01001069// Build FlatBuffer for SpaceToDepthLayer
1070void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
1071 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
1072 const char* name)
1073{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001074 boost::ignore_unused(name);
1075
Aron Virginas-Taraa067142019-06-11 16:01:44 +01001076 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
1077 auto flatBufferDescriptor =
1078 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
1079 spaceToDepthDescriptor.m_BlockSize,
1080 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
1081
1082 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
1083 flatBufferBaseLayer,
1084 flatBufferDescriptor);
1085
1086 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +01001087}
1088
Jim Flynn18ce3382019-03-08 11:08:30 +00001089// Build FlatBuffer for Splitter Layer
1090void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
1091 const armnn::ViewsDescriptor& viewsDescriptor,
1092 const char* name)
1093{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001094 boost::ignore_unused(name);
1095
Jim Flynn18ce3382019-03-08 11:08:30 +00001096 // Create FlatBuffer ViewOrigins
1097 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
1098 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
1099
1100 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
1101 {
1102 std::vector<uint32_t> viewOrigin;
1103 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
1104
1105 // Copy vector
1106 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
1107 {
1108 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
1109 }
1110
1111 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
1112 m_flatBufferBuilder.CreateVector(viewOrigin)));
1113 }
1114
1115 // Create FlatBuffer OriginsDescriptor
1116 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
1117 viewsDescriptor.GetOrigins().GetConcatAxis(),
1118 viewsDescriptor.GetOrigins().GetNumViews(),
1119 viewsDescriptor.GetOrigins().GetNumDimensions(),
1120 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
1121
1122 // Create FlatBuffer ViewOrigins
1123 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
1124 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
1125
1126 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
1127 {
1128 std::vector<uint32_t> viewSize;
1129 viewSize.reserve(viewsDescriptor.GetNumDimensions());
1130
1131 // Copy vector
1132 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
1133 {
1134 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
1135 }
1136
1137 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
1138 m_flatBufferBuilder.CreateVector(viewSize)));
1139 }
1140
1141 // Create FlatBuffer ViewsDescriptor
1142 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
1143 flatBufferOriginDescriptor,
1144 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
1145
1146 // Create FlatBuffer BaseLayer
1147 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
1148
1149 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
1150 flatBufferBaseLayer,
1151 flatBufferViewsDescriptor);
1152
1153 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
1154}
1155
Nina Drozd57728782019-02-27 10:53:27 +00001156void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
1157 const armnn::NormalizationDescriptor& descriptor,
1158 const char* name)
1159{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001160 boost::ignore_unused(name);
1161
Nina Drozd57728782019-02-27 10:53:27 +00001162 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
1163
1164 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
1165 m_flatBufferBuilder,
1166 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
1167 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
1168 descriptor.m_NormSize,
1169 descriptor.m_Alpha,
1170 descriptor.m_Beta,
1171 descriptor.m_K,
1172 GetFlatBufferDataLayout(descriptor.m_DataLayout));
1173
1174 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
1175 fbNormalizationBaseLayer,
1176 fbNormalizationDescriptor);
1177
1178 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
1179}
1180
Matthew Jackson2b8c1da2019-07-04 14:59:16 +01001181void SerializerVisitor::VisitStackLayer(const armnn::IConnectableLayer* layer,
1182 const armnn::StackDescriptor& stackDescriptor,
1183 const char* name)
1184{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001185 boost::ignore_unused(name);
1186
Matthew Jacksonb5433ee2019-07-11 15:54:20 +01001187 auto stackBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Stack);
1188
1189 std::vector<unsigned int> inputShape;
1190 for (unsigned int i =0; i < stackDescriptor.m_InputShape.GetNumDimensions(); i++)
1191 {
1192 inputShape.push_back(stackDescriptor.m_InputShape[i]);
1193 }
1194
1195 auto flatBufferStackDescriptor = CreateStackDescriptor(m_flatBufferBuilder,
1196 stackDescriptor.m_Axis,
1197 stackDescriptor.m_NumInputs,
1198 m_flatBufferBuilder.CreateVector(inputShape));
1199
1200 auto stackLayer = serializer::CreateStackLayer(m_flatBufferBuilder, stackBaseLayer, flatBufferStackDescriptor);
1201 CreateAnyLayer(stackLayer.o, serializer::Layer::Layer_StackLayer);
Matthew Jackson2b8c1da2019-07-04 14:59:16 +01001202}
1203
Derek Lamberti013c3902019-10-21 10:46:16 +01001204void SerializerVisitor::VisitStandInLayer(const armnn::IConnectableLayer *layer,
1205 const armnn::StandInDescriptor& standInDescriptor,
1206 const char *name)
1207{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001208 boost::ignore_unused(name);
1209
Aron Virginas-Tar85121a22019-10-23 10:41:35 +01001210 auto fbDescriptor = serializer::CreateStandInDescriptor(m_flatBufferBuilder,
1211 standInDescriptor.m_NumInputs,
1212 standInDescriptor.m_NumOutputs);
1213
1214 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StandIn);
1215 auto fbLayer = serializer::CreateStandInLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
1216
1217 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_StandInLayer);
Derek Lamberti013c3902019-10-21 10:46:16 +01001218}
1219
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +00001220void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
1221 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
1222 const char* name)
1223{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001224 boost::ignore_unused(name);
1225
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +00001226 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
1227
1228 auto flatBufferDescriptor =
1229 CreateStridedSliceDescriptor(m_flatBufferBuilder,
1230 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
1231 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
1232 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
1233 stridedSliceDescriptor.m_BeginMask,
1234 stridedSliceDescriptor.m_EndMask,
1235 stridedSliceDescriptor.m_ShrinkAxisMask,
1236 stridedSliceDescriptor.m_EllipsisMask,
1237 stridedSliceDescriptor.m_NewAxisMask,
1238 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
1239
1240 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
1241 flatBufferBaseLayer,
1242 flatBufferDescriptor);
1243
1244 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
1245}
1246
Conor Kennedyda1f9752019-03-01 14:37:12 +00001247void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
1248{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001249 boost::ignore_unused(name);
1250
Conor Kennedyda1f9752019-03-01 14:37:12 +00001251 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
1252 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
1253
1254 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
1255}
1256
Sadik Armaganeff363d2019-04-05 15:25:46 +01001257void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
1258{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001259 boost::ignore_unused(name);
1260
Sadik Armaganeff363d2019-04-05 15:25:46 +01001261 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
1262 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
1263
1264 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
1265}
1266
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001267void SerializerVisitor::VisitTransposeConvolution2dLayer(
1268 const armnn::IConnectableLayer* layer,
1269 const armnn::TransposeConvolution2dDescriptor& descriptor,
1270 const armnn::ConstTensor& weights,
1271 const armnn::Optional<armnn::ConstTensor>& biases,
1272 const char* name)
1273{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001274 boost::ignore_unused(name);
1275
Aron Virginas-Tarcb549302019-06-21 13:53:38 +01001276 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
1277 auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
1278 descriptor.m_PadLeft,
1279 descriptor.m_PadRight,
1280 descriptor.m_PadTop,
1281 descriptor.m_PadBottom,
1282 descriptor.m_StrideX,
1283 descriptor.m_StrideY,
1284 descriptor.m_BiasEnabled,
1285 GetFlatBufferDataLayout(descriptor.m_DataLayout));
1286
1287 // weights & biases
1288 auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
1289 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
1290 if (biases.has_value())
1291 {
1292 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
1293 }
1294
1295 auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
1296 fbBaseLayer,
1297 fbDescriptor,
1298 fbWeightsConstTensorInfo,
1299 fbBiasesConstTensorInfo);
1300
1301 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001302}
1303
Mike Kellyc9ea45a2020-02-28 18:11:58 +00001304void SerializerVisitor::VisitTransposeLayer(const armnn::IConnectableLayer* layer,
1305 const armnn::TransposeDescriptor& descriptor,
1306 const char* name)
1307{
1308 boost::ignore_unused(name);
1309
1310 // Create FlatBuffer BaseLayer
1311 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Transpose);
1312
1313 std::vector<unsigned int> dimMappings;
1314 for (unsigned int i=0; i<descriptor.m_DimMappings.GetSize(); ++i)
1315 {
1316 dimMappings.push_back(descriptor.m_DimMappings[i]);
1317 }
1318
1319 auto flatBufferDesc = serializer::CreateTransposeDescriptor(m_flatBufferBuilder,
1320 m_flatBufferBuilder.CreateVector(dimMappings));
1321
1322 // Create the FlatBuffer TransposeLayer
1323 auto flatBufferLayer = serializer::CreateTransposeLayer(m_flatBufferBuilder,
1324 flatBufferBaseLayer,
1325 flatBufferDesc);
1326
1327 // Add the AnyLayer to the FlatBufferLayers
1328 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_TransposeLayer);
1329}
1330
James Conroyee18dc82019-07-17 11:27:46 +01001331void SerializerVisitor::VisitQuantizedLstmLayer(const armnn::IConnectableLayer* layer,
1332 const armnn::QuantizedLstmInputParams& params,
1333 const char* name)
1334{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001335 boost::ignore_unused(name);
1336
Jan Eilers5b01a892019-07-23 09:47:43 +01001337 auto fbQuantizedLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_QuantizedLstm);
1338
1339 // Get input parameters
Francis Murtaghbb590b42019-08-14 09:51:36 +01001340 auto inputToInputWeights = CreateConstTensorInfo(params.GetInputToInputWeights());
1341 auto inputToForgetWeights = CreateConstTensorInfo(params.GetInputToForgetWeights());
1342 auto inputToCellWeights = CreateConstTensorInfo(params.GetInputToCellWeights());
1343 auto inputToOutputWeights = CreateConstTensorInfo(params.GetInputToOutputWeights());
Jan Eilers5b01a892019-07-23 09:47:43 +01001344
Francis Murtaghbb590b42019-08-14 09:51:36 +01001345 auto recurrentToInputWeights = CreateConstTensorInfo(params.GetRecurrentToInputWeights());
1346 auto recurrentToForgetWeights = CreateConstTensorInfo(params.GetRecurrentToForgetWeights());
1347 auto recurrentToCellWeights = CreateConstTensorInfo(params.GetRecurrentToCellWeights());
1348 auto recurrentToOutputWeights = CreateConstTensorInfo(params.GetRecurrentToOutputWeights());
Jan Eilers5b01a892019-07-23 09:47:43 +01001349
Francis Murtaghbb590b42019-08-14 09:51:36 +01001350 auto inputGateBias = CreateConstTensorInfo(params.GetInputGateBias());
1351 auto forgetGateBias = CreateConstTensorInfo(params.GetForgetGateBias());
1352 auto cellBias = CreateConstTensorInfo(params.GetCellBias());
1353 auto outputGateBias = CreateConstTensorInfo(params.GetOutputGateBias());
Jan Eilers5b01a892019-07-23 09:47:43 +01001354
1355 auto fbQuantizedLstmParams = serializer::CreateQuantizedLstmInputParams(
1356 m_flatBufferBuilder,
1357 inputToInputWeights,
1358 inputToForgetWeights,
1359 inputToCellWeights,
1360 inputToOutputWeights,
1361 recurrentToInputWeights,
1362 recurrentToForgetWeights,
1363 recurrentToCellWeights,
1364 recurrentToOutputWeights,
1365 inputGateBias,
1366 forgetGateBias,
1367 cellBias,
1368 outputGateBias);
1369
1370 auto fbQuantizedLstmLayer = serializer::CreateQuantizedLstmLayer(
1371 m_flatBufferBuilder,
1372 fbQuantizedLstmBaseLayer,
1373 fbQuantizedLstmParams);
1374
1375 CreateAnyLayer(fbQuantizedLstmLayer.o, serializer::Layer::Layer_QuantizedLstmLayer);
James Conroyee18dc82019-07-17 11:27:46 +01001376}
1377
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001378fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001379 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001380{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001381
Sadik Armagandb059fd2019-03-20 12:28:32 +00001382 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
1383
Mike Kelly8c1701a2019-02-11 17:01:27 +00001384 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
1385 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
1386
1387 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +00001388 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +00001389 m_flatBufferBuilder.CreateString(layer->GetName()),
1390 layerType,
1391 m_flatBufferBuilder.CreateVector(inputSlots),
1392 m_flatBufferBuilder.CreateVector(outputSlots));
1393}
1394
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001395void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001396{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001397
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001398 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +00001399 m_serializedLayers.push_back(anyLayer);
1400}
1401
Mike Kellya0766c32019-02-19 17:22:07 +00001402template <typename T>
1403flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
1404{
1405 const T* buffer = reinterpret_cast<const T*>(memory);
1406 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
1407 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
1408 return fbVector;
1409}
1410
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001411flatbuffers::Offset<serializer::ConstTensor>
1412 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +00001413{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001414 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +00001415
1416 // Get the dimensions
1417 std::vector<unsigned int> shape;
1418
1419 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1420 {
1421 shape.push_back(tensorInfo.GetShape()[dim]);
1422 }
1423
1424 // Create FlatBuffer TensorInfo
1425 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1426 m_flatBufferBuilder.CreateVector(shape),
1427 GetFlatBufferDataType(tensorInfo.GetDataType()),
1428 tensorInfo.GetQuantizationScale(),
1429 tensorInfo.GetQuantizationOffset());
1430 flatbuffers::Offset<void> fbPayload;
1431
1432 switch (tensorInfo.GetDataType())
1433 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001434 case armnn::DataType::Float32:
1435 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +00001436 {
1437 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1438 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1439 m_flatBufferBuilder,
1440 fbVector);
1441 fbPayload = flatBuffersData.o;
1442 break;
1443 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001444 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +00001445 {
1446 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1447 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1448 m_flatBufferBuilder,
1449 fbVector);
1450 fbPayload = flatBuffersData.o;
1451 break;
1452 }
Derek Lambertif90c56d2020-01-10 17:14:08 +00001453 case armnn::DataType::QSymmS16:
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001454 {
1455 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1456 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1457 m_flatBufferBuilder,
1458 fbVector);
1459 fbPayload = flatBuffersData.o;
1460 break;
1461 }
Derek Lambertif90c56d2020-01-10 17:14:08 +00001462 case armnn::DataType::QAsymmU8:
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001463 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001464 default:
1465 {
1466 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1467 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1468 m_flatBufferBuilder,
1469 fbVector);
1470 fbPayload = flatBuffersData.o;
1471 }
1472 }
1473 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1474 m_flatBufferBuilder,
1475 flatBufferTensorInfo,
1476 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1477 fbPayload);
1478 return flatBufferConstTensor;
1479}
1480
Tee Jungaa920c52019-11-05 10:48:25 +00001481flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> SerializerVisitor::GetVersionTable()
1482{
1483 flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> versionsTable =
1484 serializer::CreateFeatureCompatibilityVersions(
1485 m_flatBufferBuilder,
1486 1 // Binding ids scheme version
1487 );
1488 return versionsTable;
1489}
1490
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001491std::vector<fb::Offset<serializer::InputSlot>>
1492 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001493{
Mike Kellya0766c32019-02-19 17:22:07 +00001494 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001495
1496 // Get the InputSlots
1497 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1498 {
1499 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1500
1501 // Get the Connection for the InputSlot
1502 const IOutputSlot* connection = inputSlot.GetConnection();
1503
1504 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001505 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1506 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001507 // Create FlatBuffer InputSlot
1508 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1509 }
1510 return inputSlots;
1511}
1512
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001513std::vector<fb::Offset<serializer::OutputSlot>>
1514 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001515{
1516 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1517
1518 // Get the OutputSlots
1519 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1520 {
1521 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001522 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001523
1524 // Get the dimensions
1525 std::vector<unsigned int> shape;
1526 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1527 {
1528 shape.push_back(tensorInfo.GetShape()[dim]);
1529 }
1530
1531 // Create FlatBuffer TensorInfo
1532 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1533 m_flatBufferBuilder.CreateVector(shape),
1534 GetFlatBufferDataType(tensorInfo.GetDataType()),
1535 tensorInfo.GetQuantizationScale(),
1536 tensorInfo.GetQuantizationOffset());
1537
1538 // Create FlatBuffer Outputslot
1539 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1540 slotIndex,
1541 flatBufferTensorInfo));
1542 }
1543 return outputSlots;
1544}
1545
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001546
1547ISerializer* ISerializer::CreateRaw()
1548{
1549 return new Serializer();
1550}
1551
1552ISerializerPtr ISerializer::Create()
1553{
1554 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1555}
1556
1557void ISerializer::Destroy(ISerializer* serializer)
1558{
1559 delete serializer;
1560}
1561
1562void Serializer::Serialize(const INetwork& inNetwork)
1563{
1564 // Iterate through to network
1565 inNetwork.Accept(m_SerializerVisitor);
1566 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1567
1568 // Create FlatBuffer SerializedGraph
1569 auto serializedGraph = serializer::CreateSerializedGraph(
1570 fbBuilder,
1571 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1572 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
Tee Jungaa920c52019-11-05 10:48:25 +00001573 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()),
1574 m_SerializerVisitor.GetVersionTable());
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001575
1576 // Serialize the graph
1577 fbBuilder.Finish(serializedGraph);
1578}
1579
1580bool Serializer::SaveSerializedToStream(std::ostream& stream)
1581{
1582 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1583
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001584 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1585 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001586 return !stream.bad();
1587}
1588
Matteo Martincighec333912019-02-13 15:12:39 +00001589} // namespace armnnSerializer