blob: b59bac6041d6c8273a1ba1d2731b677bc53dba23 [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
8#include "SerializerUtils.hpp"
9
Mike Kelly8c1701a2019-02-11 17:01:27 +000010#include <armnn/ArmNN.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
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010014#include <boost/numeric/conversion/cast.hpp>
15
Mike Kelly8c1701a2019-02-11 17:01:27 +000016#include <flatbuffers/util.h>
17
18using namespace armnn;
19namespace fb = flatbuffers;
Derek Lamberti0028d1b2019-02-20 13:57:42 +000020namespace serializer = armnnSerializer;
Mike Kelly8c1701a2019-02-11 17:01:27 +000021
22namespace armnnSerializer
23{
24
Mike Kellyaf484012019-02-20 16:53:11 +000025serializer::ActivationFunction GetFlatBufferActivationFunction(armnn::ActivationFunction function)
26{
27 switch (function)
28 {
29 case armnn::ActivationFunction::Sigmoid:
30 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
31 case armnn::ActivationFunction::TanH:
32 return serializer::ActivationFunction::ActivationFunction_TanH;
33 case armnn::ActivationFunction::Linear:
34 return serializer::ActivationFunction::ActivationFunction_Linear;
35 case armnn::ActivationFunction::ReLu:
36 return serializer::ActivationFunction::ActivationFunction_ReLu;
37 case armnn::ActivationFunction::BoundedReLu:
38 return serializer::ActivationFunction::ActivationFunction_BoundedReLu;
39 case armnn::ActivationFunction::LeakyReLu:
40 return serializer::ActivationFunction::ActivationFunction_LeakyReLu;
41 case armnn::ActivationFunction::Abs:
42 return serializer::ActivationFunction::ActivationFunction_Abs;
43 case armnn::ActivationFunction::Sqrt:
44 return serializer::ActivationFunction::ActivationFunction_Sqrt;
45 case armnn::ActivationFunction::Square:
46 return serializer::ActivationFunction::ActivationFunction_Square;
47 default:
48 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
49 }
50}
51
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000052uint32_t SerializerVisitor::GetSerializedId(unsigned int guid)
53{
54 std::pair<unsigned int, uint32_t> guidPair(guid, m_layerId);
55
56 if (m_guidMap.empty())
57 {
58 m_guidMap.insert(guidPair);
59 }
60 else if (m_guidMap.find(guid) == m_guidMap.end())
61 {
62 guidPair.second = ++m_layerId;
63 m_guidMap.insert(guidPair);
64 return m_layerId;
65 }
Saoirse Stewart30211042019-02-18 17:19:16 +000066 return m_guidMap[guid];
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000067}
68
Mike Kelly8c1701a2019-02-11 17:01:27 +000069// Build FlatBuffer for Input Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +000070void SerializerVisitor::VisitInputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000071{
72 // Create FlatBuffer BaseLayer
73 auto flatBufferInputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Input);
74
75 // Create FlatBuffer BindableBaseLayer
76 auto flatBufferInputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
77 flatBufferInputBaseLayer,
78 id);
Mike Kelly8c1701a2019-02-11 17:01:27 +000079 // Push layer Guid to outputIds.
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000080 m_inputIds.push_back(GetSerializedId(layer->GetGuid()));
Mike Kelly8c1701a2019-02-11 17:01:27 +000081
82 // Create the FlatBuffer InputLayer
83 auto flatBufferInputLayer = serializer::CreateInputLayer(m_flatBufferBuilder, flatBufferInputBindableBaseLayer);
84
85 // Add the AnyLayer to the FlatBufferLayers
86 CreateAnyLayer(flatBufferInputLayer.o, serializer::Layer::Layer_InputLayer);
87}
88
89// Build FlatBuffer for Output Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +000090void SerializerVisitor::VisitOutputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000091{
92 // Create FlatBuffer BaseLayer
93 auto flatBufferOutputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Output);
94
95 // Create FlatBuffer BindableBaseLayer
96 auto flatBufferOutputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
97 flatBufferOutputBaseLayer,
98 id);
99 // Push layer Guid to outputIds.
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000100 m_outputIds.push_back(GetSerializedId(layer->GetGuid()));
Mike Kelly8c1701a2019-02-11 17:01:27 +0000101
102 // Create the FlatBuffer OutputLayer
103 auto flatBufferOutputLayer = serializer::CreateOutputLayer(m_flatBufferBuilder, flatBufferOutputBindableBaseLayer);
104 // Add the AnyLayer to the FlatBufferLayers
105 CreateAnyLayer(flatBufferOutputLayer.o, serializer::Layer::Layer_OutputLayer);
106}
107
Mike Kellyaf484012019-02-20 16:53:11 +0000108// Build FlatBuffer for Activation Layer
109void SerializerVisitor::VisitActivationLayer(const armnn::IConnectableLayer* layer,
110 const armnn::ActivationDescriptor& descriptor,
111 const char* name)
112{
113 // Create FlatBuffer BaseLayer
114 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Activation);
115
116 // Create the FlatBuffer ActivationDescriptor
117 auto flatBufferDescriptor = CreateActivationDescriptor(m_flatBufferBuilder,
118 GetFlatBufferActivationFunction(descriptor.m_Function),
119 descriptor.m_A,
120 descriptor.m_B);
121
122 // Create the FlatBuffer ActivationLayer
123 auto flatBufferAdditionLayer = CreateActivationLayer(m_flatBufferBuilder,
124 flatBufferBaseLayer,
125 flatBufferDescriptor);
126
127 // Add the AnyLayer to the FlatBufferLayers
128 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_ActivationLayer);
129}
130
Mike Kelly8c1701a2019-02-11 17:01:27 +0000131// Build FlatBuffer for Addition Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000132void SerializerVisitor::VisitAdditionLayer(const armnn::IConnectableLayer* layer, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000133{
134 // Create FlatBuffer BaseLayer
135 auto flatBufferAdditionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Addition);
136
137 // Create the FlatBuffer AdditionLayer
138 auto flatBufferAdditionLayer = serializer::CreateAdditionLayer(m_flatBufferBuilder, flatBufferAdditionBaseLayer);
139
140 // Add the AnyLayer to the FlatBufferLayers
141 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_AdditionLayer);
142}
143
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000144// Build FlatBuffer for BatchToSpaceNd Layer
145void SerializerVisitor::VisitBatchToSpaceNdLayer(const armnn::IConnectableLayer* layer,
146 const armnn::BatchToSpaceNdDescriptor& descriptor,
147 const char* name)
148{
149 // Create FlatBuffer BaseLayer
150 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchToSpaceNd);
151
152 std::vector<unsigned int> crops;
153 crops.reserve(descriptor.m_Crops.size() * 2);
154 for (auto& crop : descriptor.m_Crops)
155 {
156 crops.push_back(crop.first);
157 crops.push_back(crop.second);
158 }
159
160 auto flatBufferDescriptor =
161 CreateBatchToSpaceNdDescriptor(m_flatBufferBuilder,
162 m_flatBufferBuilder.CreateVector(descriptor.m_BlockShape),
163 m_flatBufferBuilder.CreateVector(crops),
164 GetFlatBufferDataLayout(descriptor.m_DataLayout));
165
166 auto flatBufferLayer = serializer::CreateBatchToSpaceNdLayer(m_flatBufferBuilder,
167 flatBufferBaseLayer,
168 flatBufferDescriptor);
169
170 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_BatchToSpaceNdLayer);
171}
172
ruoyan018e7fa232019-02-28 15:09:07 +0000173void SerializerVisitor::VisitBatchNormalizationLayer(const armnn::IConnectableLayer* layer,
174 const armnn::BatchNormalizationDescriptor& batchNormDescriptor,
175 const armnn::ConstTensor& mean,
176 const armnn::ConstTensor& variance,
177 const armnn::ConstTensor& beta,
178 const armnn::ConstTensor& gamma,
179 const char* name)
180{
181 auto fbBatchNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchNormalization);
182 auto fbBatchNormalizationDescriptor = serializer::CreateBatchNormalizationDescriptor(
183 m_flatBufferBuilder,
184 batchNormDescriptor.m_Eps,
185 GetFlatBufferDataLayout(batchNormDescriptor.m_DataLayout));
186
187 auto fbMeanConstTensorInfo = CreateConstTensorInfo(mean);
188 auto fbVarianceConstTensorInfo = CreateConstTensorInfo(variance);
189 auto fbBetaConstTensorInfo = CreateConstTensorInfo(beta);
190 auto fbGammaConstTensorInfo = CreateConstTensorInfo(gamma);
191 auto fbBatchNormalizationLayer = serializer::CreateBatchNormalizationLayer(m_flatBufferBuilder,
192 fbBatchNormalizationBaseLayer,
193 fbBatchNormalizationDescriptor,
194 fbMeanConstTensorInfo,
195 fbVarianceConstTensorInfo,
196 fbBetaConstTensorInfo,
197 fbGammaConstTensorInfo);
198
199 CreateAnyLayer(fbBatchNormalizationLayer.o, serializer::Layer::Layer_BatchNormalizationLayer);
200}
201
Conor Kennedy76277882019-02-26 08:29:54 +0000202// Build FlatBuffer for Constant Layer
203void SerializerVisitor::VisitConstantLayer(const armnn::IConnectableLayer* layer,
204 const armnn::ConstTensor& input,
205 const char* name)
206{
207 // Create FlatBuffer BaseLayer
208 auto flatBufferConstantBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Constant);
209
210 auto flatBufferConstTensorInfo = CreateConstTensorInfo(input);
211
212 // Create the FlatBuffer ConstantLayer
213 auto flatBufferLayer = CreateConstantLayer(m_flatBufferBuilder,
214 flatBufferConstantBaseLayer,
215 flatBufferConstTensorInfo);
216
217 // Add the AnyLayer to the FlatBufferLayers
218 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConstantLayer);
219}
220
Mike Kellya0766c32019-02-19 17:22:07 +0000221// Build FlatBuffer for Convolution2dLayer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000222void SerializerVisitor::VisitConvolution2dLayer(const armnn::IConnectableLayer* layer,
223 const armnn::Convolution2dDescriptor& descriptor,
224 const armnn::ConstTensor& weights,
225 const armnn::Optional<armnn::ConstTensor>& biases,
Mike Kellya0766c32019-02-19 17:22:07 +0000226 const char* name)
227{
228 // Create FlatBuffer BaseLayer
229 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
230
231 auto flatBufferDescriptor = CreateConvolution2dDescriptor(m_flatBufferBuilder,
232 descriptor.m_PadLeft,
233 descriptor.m_PadRight,
234 descriptor.m_PadTop,
235 descriptor.m_PadBottom,
236 descriptor.m_StrideX,
237 descriptor.m_StrideY,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100238 descriptor.m_DilationX,
239 descriptor.m_DilationY,
Mike Kellya0766c32019-02-19 17:22:07 +0000240 descriptor.m_BiasEnabled,
241 GetFlatBufferDataLayout(descriptor.m_DataLayout));
242 auto flatBufferWeightsConstTensorInfo = CreateConstTensorInfo(weights);
243 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiasesConstTensorInfo;
244
245 if (biases.has_value())
246 {
247 flatBufferBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
248 }
249
250 // Create the FlatBuffer Convolution2dLayer
251 auto flatBufferLayer = CreateConvolution2dLayer(m_flatBufferBuilder,
252 flatBufferBaseLayer,
253 flatBufferDescriptor,
254 flatBufferWeightsConstTensorInfo,
255 flatBufferBiasesConstTensorInfo);
256
257 // Add the AnyLayer to the FlatBufferLayers
258 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution2dLayer);
259}
260
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000261void SerializerVisitor::VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
262 const armnn::DepthwiseConvolution2dDescriptor& descriptor,
263 const armnn::ConstTensor& weights,
264 const armnn::Optional<armnn::ConstTensor>& biases,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000265 const char* name)
266{
267 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthwiseConvolution2d);
268 auto fbDescriptor = CreateDepthwiseConvolution2dDescriptor(m_flatBufferBuilder,
269 descriptor.m_PadLeft,
270 descriptor.m_PadRight,
271 descriptor.m_PadTop,
272 descriptor.m_PadBottom,
273 descriptor.m_StrideX,
274 descriptor.m_StrideY,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100275 descriptor.m_DilationX,
276 descriptor.m_DilationY,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000277 descriptor.m_BiasEnabled,
278 GetFlatBufferDataLayout(descriptor.m_DataLayout));
279
280 flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
281 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
282 if (biases.has_value())
283 {
284 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
285 }
286
287 auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
288 fbBaseLayer,
289 fbDescriptor,
290 fbWeightsConstTensorInfo,
291 fbBiasesConstTensorInfo);
292
293 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
294}
295
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000296void SerializerVisitor::VisitDequantizeLayer(const armnn::IConnectableLayer* layer,
297 const char* name)
298{
299 auto fbDequantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Dequantize);
300 auto fbDequantizeLayer = serializer::CreateDequantizeLayer(m_flatBufferBuilder, fbDequantizeBaseLayer);
301
302 CreateAnyLayer(fbDequantizeLayer.o, serializer::Layer::Layer_DequantizeLayer);
303}
304
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000305void SerializerVisitor::VisitDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
306 const armnn::DetectionPostProcessDescriptor& descriptor,
307 const armnn::ConstTensor& anchors,
308 const char* name)
309{
310 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
311 auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
312 descriptor.m_MaxDetections,
313 descriptor.m_MaxClassesPerDetection,
314 descriptor.m_DetectionsPerClass,
315 descriptor.m_NmsScoreThreshold,
316 descriptor.m_NmsIouThreshold,
317 descriptor.m_NumClasses,
318 descriptor.m_UseRegularNms,
319 descriptor.m_ScaleX,
320 descriptor.m_ScaleY,
321 descriptor.m_ScaleW,
322 descriptor.m_ScaleH);
323
324 flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);
325
326 auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
327 fbBaseLayer,
328 fbDescriptor,
329 fbAnchorsConstTensorInfo);
330
331 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
332}
333
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000334void SerializerVisitor::VisitDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
335{
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000336 auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
337 auto fbDivisionLayer = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000338
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000339 CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
340}
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000341
Aron Virginas-Tar377351e2019-02-27 14:42:31 +0000342void SerializerVisitor::VisitEqualLayer(const armnn::IConnectableLayer* layer, const char* name)
343{
344 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Equal);
345 auto fbEqualLayer = serializer::CreateEqualLayer(m_flatBufferBuilder, fbBaseLayer);
346
347 CreateAnyLayer(fbEqualLayer.o, serializer::Layer::Layer_EqualLayer);
348}
349
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000350void SerializerVisitor::VisitFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
351{
352 auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
353 auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);
354
355 CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
356}
357
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000358void SerializerVisitor::VisitGatherLayer(const armnn::IConnectableLayer* layer, const char* name)
359{
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000360 auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
361 auto flatBufferLayer = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer);
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000362
363 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
364}
365
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000366void SerializerVisitor::VisitGreaterLayer(const armnn::IConnectableLayer* layer, const char* name)
367{
368 auto fbGreaterBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Greater);
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000369 auto fbGreaterLayer = serializer::CreateGreaterLayer(m_flatBufferBuilder, fbGreaterBaseLayer);
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000370
371 CreateAnyLayer(fbGreaterLayer.o, serializer::Layer::Layer_GreaterLayer);
372}
373
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000374void SerializerVisitor::VisitL2NormalizationLayer(const armnn::IConnectableLayer* layer,
375 const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
376 const char* name)
377{
378 // Create FlatBuffer BaseLayer
379 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);
380
381 // Create the FlatBuffer L2Normalization Descriptor
382 auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100383 m_flatBufferBuilder,
384 GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout),
385 l2NormalizationDescriptor.m_Eps);
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000386
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100387 // Create FlatBuffer layer
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000388 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
389
390 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
391}
392
Jim Flynn11af3752019-03-19 17:22:29 +0000393void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer, const armnn::LstmDescriptor& descriptor,
394 const armnn::LstmInputParams& params, const char* name)
395{
396 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
397
398 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
399 m_flatBufferBuilder,
400 descriptor.m_ActivationFunc,
401 descriptor.m_ClippingThresCell,
402 descriptor.m_ClippingThresProj,
403 descriptor.m_CifgEnabled,
404 descriptor.m_PeepholeEnabled,
405 descriptor.m_ProjectionEnabled);
406
407 // Get mandatory input parameters
408 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
409 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
410 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
411 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
412 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
413 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
414 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
415 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
416 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
417
418 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
419 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
420 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
421 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
422 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
423 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
424 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
425 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
426 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
427
428 if (!descriptor.m_CifgEnabled)
429 {
430 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
431 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
432 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
433 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
434 }
435
436 if (descriptor.m_ProjectionEnabled)
437 {
438 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
439 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
440 }
441
442 if (descriptor.m_PeepholeEnabled)
443 {
444 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
445 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
446 }
447
448 auto fbLstmParams = serializer::CreateLstmInputParams(
449 m_flatBufferBuilder,
450 inputToForgetWeights,
451 inputToCellWeights,
452 inputToOutputWeights,
453 recurrentToForgetWeights,
454 recurrentToCellWeights,
455 recurrentToOutputWeights,
456 forgetGateBias,
457 cellBias,
458 outputGateBias,
459 inputToInputWeights,
460 recurrentToInputWeights,
461 cellToInputWeights,
462 inputGateBias,
463 projectionWeights,
464 projectionBias,
465 cellToForgetWeights,
466 cellToOutputWeights);
467
468 auto fbLstmLayer = serializer::CreateLstmLayer(
469 m_flatBufferBuilder,
470 fbLstmBaseLayer,
471 fbLstmDescriptor,
472 fbLstmParams);
473
474 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
475}
476
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000477void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
478{
479 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
480 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
481
482 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
483}
484
485void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
486 const armnn::MeanDescriptor& descriptor,
487 const char* name)
488{
489 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
490 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
491 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
492 descriptor.m_KeepDims);
493
494 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
495 fbMeanBaseLayer,
496 fbMeanDescriptor);
497
498 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
499}
500
501void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
502{
503 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
504 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
505
506 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
507}
508
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100509void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
510{
511 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
512 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
513
514 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
515}
516
Jim Flynnac25a1b2019-02-28 10:40:49 +0000517void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
Jim Flynne242f2d2019-05-22 14:24:13 +0100518 const armnn::MergerDescriptor& mergerDescriptor,
Jim Flynnac25a1b2019-02-28 10:40:49 +0000519 const char* name)
520{
Jim Flynne242f2d2019-05-22 14:24:13 +0100521 VisitConcatLayer(layer, mergerDescriptor, name);
522}
523
524void SerializerVisitor::VisitConcatLayer(const armnn::IConnectableLayer* layer,
525 const armnn::ConcatDescriptor& concatDescriptor,
526 const char* name)
527{
528 auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000529
530 std::vector<flatbuffers::Offset<UintVector>> views;
Jim Flynne242f2d2019-05-22 14:24:13 +0100531 for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000532 {
Jim Flynne242f2d2019-05-22 14:24:13 +0100533 const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000534 std::vector<uint32_t> origins;
Jim Flynne242f2d2019-05-22 14:24:13 +0100535 for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000536 {
537 origins.push_back(origin[d]);
538 }
539 auto view = m_flatBufferBuilder.CreateVector(origins);
540 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
541 views.push_back(uintVector);
542 }
543
Jim Flynne242f2d2019-05-22 14:24:13 +0100544 auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
545 concatDescriptor.GetConcatAxis(),
546 concatDescriptor.GetNumViews(),
547 concatDescriptor.GetNumDimensions(),
Jim Flynnac25a1b2019-02-28 10:40:49 +0000548 m_flatBufferBuilder.CreateVector(views));
549
Jim Flynne242f2d2019-05-22 14:24:13 +0100550 auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
551 flatBufferConcatBaseLayer,
552 flatBufferConcatDescriptor);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000553
Jim Flynne242f2d2019-05-22 14:24:13 +0100554 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000555}
556
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000557void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000558{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000559 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
560 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
561 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000562
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000563 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000564}
565
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000566void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
567 const armnn::PadDescriptor& padDescriptor,
568 const char* name)
569{
570 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
571
572 std::vector<unsigned int> padList;
573 for (auto& p: padDescriptor.m_PadList)
574 {
575 padList.push_back(p.first);
576 padList.push_back(p.second);
577 }
578
579 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
David Monahan34757812019-06-19 11:47:21 +0100580 m_flatBufferBuilder.CreateVector(padList),
Aron Virginas-Tarf3569052019-07-05 16:01:08 +0100581 padDescriptor.m_PadValue);
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000582
583 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
584 flatBufferBaseLayer,
585 flatBufferPadDesc);
586
587 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
588}
589
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000590void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
591 const armnn::PermuteDescriptor& permuteDescriptor,
592 const char* name)
593{
594 // Create FlatBuffer BaseLayer
595 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
596
597 std::vector<unsigned int> dimMappings;
598 for (auto& v: permuteDescriptor.m_DimMappings)
599 {
600 dimMappings.push_back(v);
601 }
602
603 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
604 m_flatBufferBuilder.CreateVector(dimMappings));
605
606 // Create the FlatBuffer PermuteLayer
607 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
608 flatBufferPermuteBaseLayer,
609 flatBufferPermuteDesc);
610
611 // Add the AnyLayer to the FlatBufferLayers
612 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
613}
614
Saoirse Stewart263829c2019-02-19 15:54:14 +0000615// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000616void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000617 const armnn::ReshapeDescriptor& reshapeDescriptor,
618 const char* name)
619{
620 // Create FlatBuffer BaseLayer
621 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
622
623 std::vector<unsigned int> targetShape;
624 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
625 {
626 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
627 }
628
629 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
630 m_flatBufferBuilder.CreateVector(targetShape));
631
632 // Create the FlatBuffer ReshapeLayer
633 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
634 flatBufferReshapeDesc);
635
636 // Add the AnyLayer to the FlatBufferLayers
637 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
638}
639
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000640void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
641 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
642 const char* name)
643{
644 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
645
646 auto flatBufferDescriptor =
647 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
648 resizeDescriptor.m_TargetWidth,
649 resizeDescriptor.m_TargetHeight,
650 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
651
652 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
653 flatBufferBaseLayer,
654 flatBufferDescriptor);
655
656 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
657}
658
Teresa Charlina9075df2019-06-27 15:41:57 +0100659void SerializerVisitor::VisitResizeLayer(const armnn::IConnectableLayer* layer,
660 const armnn::ResizeDescriptor& resizeDescriptor,
661 const char* name)
662{
FinnWilliamsArm6fb339a2019-06-28 15:07:10 +0100663 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Resize);
664
665 auto flatBufferDescriptor =
666 CreateResizeDescriptor(m_flatBufferBuilder,
667 resizeDescriptor.m_TargetHeight,
668 resizeDescriptor.m_TargetWidth,
669 GetFlatBufferResizeMethod(resizeDescriptor.m_Method),
670 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
671
672 auto flatBufferLayer = serializer::CreateResizeLayer(m_flatBufferBuilder,
673 flatBufferBaseLayer,
674 flatBufferDescriptor);
675
676 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeLayer);
Teresa Charlina9075df2019-06-27 15:41:57 +0100677}
678
Sadik Armagan8b42a382019-03-01 14:24:49 +0000679void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
680{
681 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
682 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
683
684 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
685}
686
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000687// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000688void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
689 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000690 const char* name)
691{
692 // Create FlatBuffer BaseLayer
693 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
694
695 // Create the FlatBuffer SoftmaxDescriptor
696 auto flatBufferSoftmaxDesc =
697 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
698
699 // Create the FlatBuffer SoftmaxLayer
700 auto flatBufferSoftmaxLayer =
701 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
702 flatBufferSoftmaxBaseLayer,
703 flatBufferSoftmaxDesc);
704
705 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
706}
707
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000708void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
709 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000710 const char* name)
711{
712 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
713 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
714 m_flatBufferBuilder,
715 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
716 pooling2dDescriptor.m_PadLeft,
717 pooling2dDescriptor.m_PadRight,
718 pooling2dDescriptor.m_PadTop,
719 pooling2dDescriptor.m_PadBottom,
720 pooling2dDescriptor.m_PoolWidth,
721 pooling2dDescriptor.m_PoolHeight,
722 pooling2dDescriptor.m_StrideX,
723 pooling2dDescriptor.m_StrideY,
724 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
725 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
726 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
727
728 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
729 fbPooling2dBaseLayer,
730 fbPooling2dDescriptor);
731
732 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
733}
734
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100735void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
736 const char* name)
737{
Ellen Norris-Thompson51982472019-06-19 11:46:21 +0100738 // Create FlatBuffer BaseLayer
739 auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
740
741 // Create the FlatBuffer AdditionLayer
742 auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
743
744 // Add the AnyLayer to the FlatBufferLayers
745 CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100746}
747
Derek Lamberti87acb272019-03-27 16:51:31 +0000748void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
749{
750 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
751 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
752 fbQuantizeBaseLayer);
753 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
754}
755
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000756// Build FlatBuffer for FullyConnected Layer
757void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
758 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
759 const armnn::ConstTensor& weights,
760 const armnn::Optional<armnn::ConstTensor>& biases,
761 const char* name)
762{
763 // Create FlatBuffer BaseLayer
764 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
765
766 // Create FlatBuffer FullyConnectedDescriptor
767 auto flatBufferDescriptor =
768 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
769 fullyConnectedDescriptor.m_BiasEnabled,
770 fullyConnectedDescriptor.m_TransposeWeightMatrix);
771
772 // Create FlatBuffer weights data
773 auto flatBufferWeights = CreateConstTensorInfo(weights);
774
775 // Create FlatBuffer bias data
776 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
777 if (fullyConnectedDescriptor.m_BiasEnabled)
778 {
779 flatBufferBiases = CreateConstTensorInfo(biases.value());
780 }
781
782 // Create FlatBuffer FullyConnectedLayer
783 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
784 flatBufferBaseLayer,
785 flatBufferDescriptor,
786 flatBufferWeights,
787 flatBufferBiases);
788
789 // Add created FullyConnectedLayer to the FlatBufferLayers
790 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
791}
792
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000793// Build FlatBuffer for SpaceToBatchNd Layer
794void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
795 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
796 const char* name)
797{
798 // Create FlatBuffer BaseLayer
799 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
800
801 std::vector<unsigned int> padList;
802 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
803 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
804 {
805 padList.push_back(pad.first);
806 padList.push_back(pad.second);
807 }
808
809 auto flatBufferDescriptor =
810 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
811 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
812 m_flatBufferBuilder.CreateVector(padList),
813 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
814
815 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
816 flatBufferBaseLayer,
817 flatBufferDescriptor);
818
819 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
820}
821
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100822// Build FlatBuffer for SpaceToDepthLayer
823void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
824 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
825 const char* name)
826{
Aron Virginas-Taraa067142019-06-11 16:01:44 +0100827 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
828 auto flatBufferDescriptor =
829 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
830 spaceToDepthDescriptor.m_BlockSize,
831 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
832
833 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
834 flatBufferBaseLayer,
835 flatBufferDescriptor);
836
837 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100838}
839
Jim Flynn18ce3382019-03-08 11:08:30 +0000840// Build FlatBuffer for Splitter Layer
841void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
842 const armnn::ViewsDescriptor& viewsDescriptor,
843 const char* name)
844{
845 // Create FlatBuffer ViewOrigins
846 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
847 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
848
849 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
850 {
851 std::vector<uint32_t> viewOrigin;
852 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
853
854 // Copy vector
855 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
856 {
857 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
858 }
859
860 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
861 m_flatBufferBuilder.CreateVector(viewOrigin)));
862 }
863
864 // Create FlatBuffer OriginsDescriptor
865 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
866 viewsDescriptor.GetOrigins().GetConcatAxis(),
867 viewsDescriptor.GetOrigins().GetNumViews(),
868 viewsDescriptor.GetOrigins().GetNumDimensions(),
869 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
870
871 // Create FlatBuffer ViewOrigins
872 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
873 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
874
875 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
876 {
877 std::vector<uint32_t> viewSize;
878 viewSize.reserve(viewsDescriptor.GetNumDimensions());
879
880 // Copy vector
881 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
882 {
883 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
884 }
885
886 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
887 m_flatBufferBuilder.CreateVector(viewSize)));
888 }
889
890 // Create FlatBuffer ViewsDescriptor
891 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
892 flatBufferOriginDescriptor,
893 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
894
895 // Create FlatBuffer BaseLayer
896 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
897
898 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
899 flatBufferBaseLayer,
900 flatBufferViewsDescriptor);
901
902 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
903}
904
Nina Drozd57728782019-02-27 10:53:27 +0000905void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
906 const armnn::NormalizationDescriptor& descriptor,
907 const char* name)
908{
909 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
910
911 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
912 m_flatBufferBuilder,
913 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
914 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
915 descriptor.m_NormSize,
916 descriptor.m_Alpha,
917 descriptor.m_Beta,
918 descriptor.m_K,
919 GetFlatBufferDataLayout(descriptor.m_DataLayout));
920
921 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
922 fbNormalizationBaseLayer,
923 fbNormalizationDescriptor);
924
925 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
926}
927
Matthew Jackson2b8c1da2019-07-04 14:59:16 +0100928void SerializerVisitor::VisitStackLayer(const armnn::IConnectableLayer* layer,
929 const armnn::StackDescriptor& stackDescriptor,
930 const char* name)
931{
Matthew Jacksonb5433ee2019-07-11 15:54:20 +0100932 auto stackBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Stack);
933
934 std::vector<unsigned int> inputShape;
935 for (unsigned int i =0; i < stackDescriptor.m_InputShape.GetNumDimensions(); i++)
936 {
937 inputShape.push_back(stackDescriptor.m_InputShape[i]);
938 }
939
940 auto flatBufferStackDescriptor = CreateStackDescriptor(m_flatBufferBuilder,
941 stackDescriptor.m_Axis,
942 stackDescriptor.m_NumInputs,
943 m_flatBufferBuilder.CreateVector(inputShape));
944
945 auto stackLayer = serializer::CreateStackLayer(m_flatBufferBuilder, stackBaseLayer, flatBufferStackDescriptor);
946 CreateAnyLayer(stackLayer.o, serializer::Layer::Layer_StackLayer);
Matthew Jackson2b8c1da2019-07-04 14:59:16 +0100947}
948
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000949void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
950 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
951 const char* name)
952{
953 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
954
955 auto flatBufferDescriptor =
956 CreateStridedSliceDescriptor(m_flatBufferBuilder,
957 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
958 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
959 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
960 stridedSliceDescriptor.m_BeginMask,
961 stridedSliceDescriptor.m_EndMask,
962 stridedSliceDescriptor.m_ShrinkAxisMask,
963 stridedSliceDescriptor.m_EllipsisMask,
964 stridedSliceDescriptor.m_NewAxisMask,
965 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
966
967 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
968 flatBufferBaseLayer,
969 flatBufferDescriptor);
970
971 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
972}
973
Conor Kennedyda1f9752019-03-01 14:37:12 +0000974void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
975{
976 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
977 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
978
979 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
980}
981
Sadik Armaganeff363d2019-04-05 15:25:46 +0100982void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
983{
984 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
985 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
986
987 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
988}
989
Aron Virginas-Tar639fb042019-06-20 14:28:19 +0100990void SerializerVisitor::VisitTransposeConvolution2dLayer(
991 const armnn::IConnectableLayer* layer,
992 const armnn::TransposeConvolution2dDescriptor& descriptor,
993 const armnn::ConstTensor& weights,
994 const armnn::Optional<armnn::ConstTensor>& biases,
995 const char* name)
996{
Aron Virginas-Tarcb549302019-06-21 13:53:38 +0100997 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
998 auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
999 descriptor.m_PadLeft,
1000 descriptor.m_PadRight,
1001 descriptor.m_PadTop,
1002 descriptor.m_PadBottom,
1003 descriptor.m_StrideX,
1004 descriptor.m_StrideY,
1005 descriptor.m_BiasEnabled,
1006 GetFlatBufferDataLayout(descriptor.m_DataLayout));
1007
1008 // weights & biases
1009 auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
1010 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
1011 if (biases.has_value())
1012 {
1013 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
1014 }
1015
1016 auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
1017 fbBaseLayer,
1018 fbDescriptor,
1019 fbWeightsConstTensorInfo,
1020 fbBiasesConstTensorInfo);
1021
1022 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001023}
1024
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001025fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001026 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001027{
Sadik Armagandb059fd2019-03-20 12:28:32 +00001028 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
1029
Mike Kelly8c1701a2019-02-11 17:01:27 +00001030 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
1031 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
1032
1033 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +00001034 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +00001035 m_flatBufferBuilder.CreateString(layer->GetName()),
1036 layerType,
1037 m_flatBufferBuilder.CreateVector(inputSlots),
1038 m_flatBufferBuilder.CreateVector(outputSlots));
1039}
1040
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001041void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001042{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001043 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +00001044 m_serializedLayers.push_back(anyLayer);
1045}
1046
Mike Kellya0766c32019-02-19 17:22:07 +00001047template <typename T>
1048flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
1049{
1050 const T* buffer = reinterpret_cast<const T*>(memory);
1051 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
1052 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
1053 return fbVector;
1054}
1055
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001056flatbuffers::Offset<serializer::ConstTensor>
1057 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +00001058{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001059 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +00001060
1061 // Get the dimensions
1062 std::vector<unsigned int> shape;
1063
1064 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1065 {
1066 shape.push_back(tensorInfo.GetShape()[dim]);
1067 }
1068
1069 // Create FlatBuffer TensorInfo
1070 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1071 m_flatBufferBuilder.CreateVector(shape),
1072 GetFlatBufferDataType(tensorInfo.GetDataType()),
1073 tensorInfo.GetQuantizationScale(),
1074 tensorInfo.GetQuantizationOffset());
1075 flatbuffers::Offset<void> fbPayload;
1076
1077 switch (tensorInfo.GetDataType())
1078 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001079 case armnn::DataType::Float32:
1080 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +00001081 {
1082 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1083 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1084 m_flatBufferBuilder,
1085 fbVector);
1086 fbPayload = flatBuffersData.o;
1087 break;
1088 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001089 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +00001090 {
1091 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1092 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1093 m_flatBufferBuilder,
1094 fbVector);
1095 fbPayload = flatBuffersData.o;
1096 break;
1097 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001098 case armnn::DataType::QuantisedSymm16:
1099 {
1100 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1101 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1102 m_flatBufferBuilder,
1103 fbVector);
1104 fbPayload = flatBuffersData.o;
1105 break;
1106 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001107 case armnn::DataType::QuantisedAsymm8:
1108 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001109 default:
1110 {
1111 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1112 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1113 m_flatBufferBuilder,
1114 fbVector);
1115 fbPayload = flatBuffersData.o;
1116 }
1117 }
1118 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1119 m_flatBufferBuilder,
1120 flatBufferTensorInfo,
1121 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1122 fbPayload);
1123 return flatBufferConstTensor;
1124}
1125
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001126std::vector<fb::Offset<serializer::InputSlot>>
1127 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001128{
Mike Kellya0766c32019-02-19 17:22:07 +00001129 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001130
1131 // Get the InputSlots
1132 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1133 {
1134 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1135
1136 // Get the Connection for the InputSlot
1137 const IOutputSlot* connection = inputSlot.GetConnection();
1138
1139 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001140 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1141 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001142 // Create FlatBuffer InputSlot
1143 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1144 }
1145 return inputSlots;
1146}
1147
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001148std::vector<fb::Offset<serializer::OutputSlot>>
1149 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001150{
1151 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1152
1153 // Get the OutputSlots
1154 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1155 {
1156 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001157 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001158
1159 // Get the dimensions
1160 std::vector<unsigned int> shape;
1161 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1162 {
1163 shape.push_back(tensorInfo.GetShape()[dim]);
1164 }
1165
1166 // Create FlatBuffer TensorInfo
1167 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1168 m_flatBufferBuilder.CreateVector(shape),
1169 GetFlatBufferDataType(tensorInfo.GetDataType()),
1170 tensorInfo.GetQuantizationScale(),
1171 tensorInfo.GetQuantizationOffset());
1172
1173 // Create FlatBuffer Outputslot
1174 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1175 slotIndex,
1176 flatBufferTensorInfo));
1177 }
1178 return outputSlots;
1179}
1180
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001181
1182ISerializer* ISerializer::CreateRaw()
1183{
1184 return new Serializer();
1185}
1186
1187ISerializerPtr ISerializer::Create()
1188{
1189 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1190}
1191
1192void ISerializer::Destroy(ISerializer* serializer)
1193{
1194 delete serializer;
1195}
1196
1197void Serializer::Serialize(const INetwork& inNetwork)
1198{
1199 // Iterate through to network
1200 inNetwork.Accept(m_SerializerVisitor);
1201 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1202
1203 // Create FlatBuffer SerializedGraph
1204 auto serializedGraph = serializer::CreateSerializedGraph(
1205 fbBuilder,
1206 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1207 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1208 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1209
1210 // Serialize the graph
1211 fbBuilder.Finish(serializedGraph);
1212}
1213
1214bool Serializer::SaveSerializedToStream(std::ostream& stream)
1215{
1216 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1217
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001218 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1219 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001220 return !stream.bad();
1221}
1222
Matteo Martincighec333912019-02-13 15:12:39 +00001223} // namespace armnnSerializer