blob: ccf219905f19f8796c2c3d0e0256b7f2bb26e344 [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(
383 m_flatBufferBuilder, GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout));
384
385 // Create Flatuffer layer
386 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
387
388 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
389}
390
Jim Flynn11af3752019-03-19 17:22:29 +0000391void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer, const armnn::LstmDescriptor& descriptor,
392 const armnn::LstmInputParams& params, const char* name)
393{
394 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
395
396 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
397 m_flatBufferBuilder,
398 descriptor.m_ActivationFunc,
399 descriptor.m_ClippingThresCell,
400 descriptor.m_ClippingThresProj,
401 descriptor.m_CifgEnabled,
402 descriptor.m_PeepholeEnabled,
403 descriptor.m_ProjectionEnabled);
404
405 // Get mandatory input parameters
406 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
407 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
408 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
409 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
410 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
411 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
412 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
413 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
414 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
415
416 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
417 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
418 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
419 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
420 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
421 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
422 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
423 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
424 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
425
426 if (!descriptor.m_CifgEnabled)
427 {
428 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
429 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
430 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
431 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
432 }
433
434 if (descriptor.m_ProjectionEnabled)
435 {
436 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
437 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
438 }
439
440 if (descriptor.m_PeepholeEnabled)
441 {
442 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
443 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
444 }
445
446 auto fbLstmParams = serializer::CreateLstmInputParams(
447 m_flatBufferBuilder,
448 inputToForgetWeights,
449 inputToCellWeights,
450 inputToOutputWeights,
451 recurrentToForgetWeights,
452 recurrentToCellWeights,
453 recurrentToOutputWeights,
454 forgetGateBias,
455 cellBias,
456 outputGateBias,
457 inputToInputWeights,
458 recurrentToInputWeights,
459 cellToInputWeights,
460 inputGateBias,
461 projectionWeights,
462 projectionBias,
463 cellToForgetWeights,
464 cellToOutputWeights);
465
466 auto fbLstmLayer = serializer::CreateLstmLayer(
467 m_flatBufferBuilder,
468 fbLstmBaseLayer,
469 fbLstmDescriptor,
470 fbLstmParams);
471
472 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
473}
474
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000475void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
476{
477 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
478 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
479
480 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
481}
482
483void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
484 const armnn::MeanDescriptor& descriptor,
485 const char* name)
486{
487 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
488 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
489 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
490 descriptor.m_KeepDims);
491
492 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
493 fbMeanBaseLayer,
494 fbMeanDescriptor);
495
496 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
497}
498
499void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
500{
501 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
502 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
503
504 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
505}
506
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100507void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
508{
509 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
510 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
511
512 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
513}
514
Jim Flynnac25a1b2019-02-28 10:40:49 +0000515void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
Jim Flynne242f2d2019-05-22 14:24:13 +0100516 const armnn::MergerDescriptor& mergerDescriptor,
Jim Flynnac25a1b2019-02-28 10:40:49 +0000517 const char* name)
518{
Jim Flynne242f2d2019-05-22 14:24:13 +0100519 VisitConcatLayer(layer, mergerDescriptor, name);
520}
521
522void SerializerVisitor::VisitConcatLayer(const armnn::IConnectableLayer* layer,
523 const armnn::ConcatDescriptor& concatDescriptor,
524 const char* name)
525{
526 auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000527
528 std::vector<flatbuffers::Offset<UintVector>> views;
Jim Flynne242f2d2019-05-22 14:24:13 +0100529 for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000530 {
Jim Flynne242f2d2019-05-22 14:24:13 +0100531 const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000532 std::vector<uint32_t> origins;
Jim Flynne242f2d2019-05-22 14:24:13 +0100533 for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000534 {
535 origins.push_back(origin[d]);
536 }
537 auto view = m_flatBufferBuilder.CreateVector(origins);
538 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
539 views.push_back(uintVector);
540 }
541
Jim Flynne242f2d2019-05-22 14:24:13 +0100542 auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
543 concatDescriptor.GetConcatAxis(),
544 concatDescriptor.GetNumViews(),
545 concatDescriptor.GetNumDimensions(),
Jim Flynnac25a1b2019-02-28 10:40:49 +0000546 m_flatBufferBuilder.CreateVector(views));
547
Jim Flynne242f2d2019-05-22 14:24:13 +0100548 auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
549 flatBufferConcatBaseLayer,
550 flatBufferConcatDescriptor);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000551
Jim Flynne242f2d2019-05-22 14:24:13 +0100552 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000553}
554
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000555void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000556{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000557 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
558 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
559 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000560
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000561 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000562}
563
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000564void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
565 const armnn::PadDescriptor& padDescriptor,
566 const char* name)
567{
568 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
569
570 std::vector<unsigned int> padList;
571 for (auto& p: padDescriptor.m_PadList)
572 {
573 padList.push_back(p.first);
574 padList.push_back(p.second);
575 }
576
577 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
578 m_flatBufferBuilder.CreateVector(padList));
579
580 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
581 flatBufferBaseLayer,
582 flatBufferPadDesc);
583
584 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
585}
586
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000587void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
588 const armnn::PermuteDescriptor& permuteDescriptor,
589 const char* name)
590{
591 // Create FlatBuffer BaseLayer
592 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
593
594 std::vector<unsigned int> dimMappings;
595 for (auto& v: permuteDescriptor.m_DimMappings)
596 {
597 dimMappings.push_back(v);
598 }
599
600 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
601 m_flatBufferBuilder.CreateVector(dimMappings));
602
603 // Create the FlatBuffer PermuteLayer
604 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
605 flatBufferPermuteBaseLayer,
606 flatBufferPermuteDesc);
607
608 // Add the AnyLayer to the FlatBufferLayers
609 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
610}
611
Saoirse Stewart263829c2019-02-19 15:54:14 +0000612// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000613void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000614 const armnn::ReshapeDescriptor& reshapeDescriptor,
615 const char* name)
616{
617 // Create FlatBuffer BaseLayer
618 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
619
620 std::vector<unsigned int> targetShape;
621 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
622 {
623 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
624 }
625
626 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
627 m_flatBufferBuilder.CreateVector(targetShape));
628
629 // Create the FlatBuffer ReshapeLayer
630 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
631 flatBufferReshapeDesc);
632
633 // Add the AnyLayer to the FlatBufferLayers
634 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
635}
636
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000637void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
638 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
639 const char* name)
640{
641 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
642
643 auto flatBufferDescriptor =
644 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
645 resizeDescriptor.m_TargetWidth,
646 resizeDescriptor.m_TargetHeight,
647 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
648
649 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
650 flatBufferBaseLayer,
651 flatBufferDescriptor);
652
653 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
654}
655
Sadik Armagan8b42a382019-03-01 14:24:49 +0000656void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
657{
658 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
659 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
660
661 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
662}
663
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000664// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000665void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
666 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000667 const char* name)
668{
669 // Create FlatBuffer BaseLayer
670 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
671
672 // Create the FlatBuffer SoftmaxDescriptor
673 auto flatBufferSoftmaxDesc =
674 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
675
676 // Create the FlatBuffer SoftmaxLayer
677 auto flatBufferSoftmaxLayer =
678 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
679 flatBufferSoftmaxBaseLayer,
680 flatBufferSoftmaxDesc);
681
682 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
683}
684
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000685void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
686 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000687 const char* name)
688{
689 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
690 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
691 m_flatBufferBuilder,
692 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
693 pooling2dDescriptor.m_PadLeft,
694 pooling2dDescriptor.m_PadRight,
695 pooling2dDescriptor.m_PadTop,
696 pooling2dDescriptor.m_PadBottom,
697 pooling2dDescriptor.m_PoolWidth,
698 pooling2dDescriptor.m_PoolHeight,
699 pooling2dDescriptor.m_StrideX,
700 pooling2dDescriptor.m_StrideY,
701 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
702 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
703 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
704
705 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
706 fbPooling2dBaseLayer,
707 fbPooling2dDescriptor);
708
709 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
710}
711
Derek Lamberti87acb272019-03-27 16:51:31 +0000712void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
713{
714 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
715 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
716 fbQuantizeBaseLayer);
717 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
718}
719
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000720// Build FlatBuffer for FullyConnected Layer
721void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
722 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
723 const armnn::ConstTensor& weights,
724 const armnn::Optional<armnn::ConstTensor>& biases,
725 const char* name)
726{
727 // Create FlatBuffer BaseLayer
728 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
729
730 // Create FlatBuffer FullyConnectedDescriptor
731 auto flatBufferDescriptor =
732 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
733 fullyConnectedDescriptor.m_BiasEnabled,
734 fullyConnectedDescriptor.m_TransposeWeightMatrix);
735
736 // Create FlatBuffer weights data
737 auto flatBufferWeights = CreateConstTensorInfo(weights);
738
739 // Create FlatBuffer bias data
740 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
741 if (fullyConnectedDescriptor.m_BiasEnabled)
742 {
743 flatBufferBiases = CreateConstTensorInfo(biases.value());
744 }
745
746 // Create FlatBuffer FullyConnectedLayer
747 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
748 flatBufferBaseLayer,
749 flatBufferDescriptor,
750 flatBufferWeights,
751 flatBufferBiases);
752
753 // Add created FullyConnectedLayer to the FlatBufferLayers
754 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
755}
756
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000757// Build FlatBuffer for SpaceToBatchNd Layer
758void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
759 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
760 const char* name)
761{
762 // Create FlatBuffer BaseLayer
763 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
764
765 std::vector<unsigned int> padList;
766 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
767 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
768 {
769 padList.push_back(pad.first);
770 padList.push_back(pad.second);
771 }
772
773 auto flatBufferDescriptor =
774 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
775 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
776 m_flatBufferBuilder.CreateVector(padList),
777 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
778
779 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
780 flatBufferBaseLayer,
781 flatBufferDescriptor);
782
783 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
784}
785
Jim Flynn18ce3382019-03-08 11:08:30 +0000786// Build FlatBuffer for Splitter Layer
787void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
788 const armnn::ViewsDescriptor& viewsDescriptor,
789 const char* name)
790{
791 // Create FlatBuffer ViewOrigins
792 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
793 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
794
795 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
796 {
797 std::vector<uint32_t> viewOrigin;
798 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
799
800 // Copy vector
801 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
802 {
803 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
804 }
805
806 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
807 m_flatBufferBuilder.CreateVector(viewOrigin)));
808 }
809
810 // Create FlatBuffer OriginsDescriptor
811 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
812 viewsDescriptor.GetOrigins().GetConcatAxis(),
813 viewsDescriptor.GetOrigins().GetNumViews(),
814 viewsDescriptor.GetOrigins().GetNumDimensions(),
815 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
816
817 // Create FlatBuffer ViewOrigins
818 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
819 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
820
821 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
822 {
823 std::vector<uint32_t> viewSize;
824 viewSize.reserve(viewsDescriptor.GetNumDimensions());
825
826 // Copy vector
827 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
828 {
829 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
830 }
831
832 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
833 m_flatBufferBuilder.CreateVector(viewSize)));
834 }
835
836 // Create FlatBuffer ViewsDescriptor
837 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
838 flatBufferOriginDescriptor,
839 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
840
841 // Create FlatBuffer BaseLayer
842 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
843
844 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
845 flatBufferBaseLayer,
846 flatBufferViewsDescriptor);
847
848 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
849}
850
Nina Drozd57728782019-02-27 10:53:27 +0000851void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
852 const armnn::NormalizationDescriptor& descriptor,
853 const char* name)
854{
855 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
856
857 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
858 m_flatBufferBuilder,
859 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
860 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
861 descriptor.m_NormSize,
862 descriptor.m_Alpha,
863 descriptor.m_Beta,
864 descriptor.m_K,
865 GetFlatBufferDataLayout(descriptor.m_DataLayout));
866
867 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
868 fbNormalizationBaseLayer,
869 fbNormalizationDescriptor);
870
871 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
872}
873
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000874void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
875 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
876 const char* name)
877{
878 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
879
880 auto flatBufferDescriptor =
881 CreateStridedSliceDescriptor(m_flatBufferBuilder,
882 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
883 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
884 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
885 stridedSliceDescriptor.m_BeginMask,
886 stridedSliceDescriptor.m_EndMask,
887 stridedSliceDescriptor.m_ShrinkAxisMask,
888 stridedSliceDescriptor.m_EllipsisMask,
889 stridedSliceDescriptor.m_NewAxisMask,
890 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
891
892 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
893 flatBufferBaseLayer,
894 flatBufferDescriptor);
895
896 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
897}
898
Conor Kennedyda1f9752019-03-01 14:37:12 +0000899void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
900{
901 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
902 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
903
904 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
905}
906
Sadik Armaganeff363d2019-04-05 15:25:46 +0100907void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
908{
909 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
910 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
911
912 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
913}
914
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000915fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000916 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000917{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000918 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
919
Mike Kelly8c1701a2019-02-11 17:01:27 +0000920 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
921 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
922
923 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000924 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000925 m_flatBufferBuilder.CreateString(layer->GetName()),
926 layerType,
927 m_flatBufferBuilder.CreateVector(inputSlots),
928 m_flatBufferBuilder.CreateVector(outputSlots));
929}
930
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000931void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000932{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000933 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000934 m_serializedLayers.push_back(anyLayer);
935}
936
Mike Kellya0766c32019-02-19 17:22:07 +0000937template <typename T>
938flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
939{
940 const T* buffer = reinterpret_cast<const T*>(memory);
941 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
942 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
943 return fbVector;
944}
945
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000946flatbuffers::Offset<serializer::ConstTensor>
947 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000948{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000949 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000950
951 // Get the dimensions
952 std::vector<unsigned int> shape;
953
954 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
955 {
956 shape.push_back(tensorInfo.GetShape()[dim]);
957 }
958
959 // Create FlatBuffer TensorInfo
960 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
961 m_flatBufferBuilder.CreateVector(shape),
962 GetFlatBufferDataType(tensorInfo.GetDataType()),
963 tensorInfo.GetQuantizationScale(),
964 tensorInfo.GetQuantizationOffset());
965 flatbuffers::Offset<void> fbPayload;
966
967 switch (tensorInfo.GetDataType())
968 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000969 case armnn::DataType::Float32:
970 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000971 {
972 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
973 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
974 m_flatBufferBuilder,
975 fbVector);
976 fbPayload = flatBuffersData.o;
977 break;
978 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000979 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000980 {
981 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
982 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
983 m_flatBufferBuilder,
984 fbVector);
985 fbPayload = flatBuffersData.o;
986 break;
987 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +0000988 case armnn::DataType::QuantisedSymm16:
989 {
990 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
991 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
992 m_flatBufferBuilder,
993 fbVector);
994 fbPayload = flatBuffersData.o;
995 break;
996 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000997 case armnn::DataType::QuantisedAsymm8:
998 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +0000999 default:
1000 {
1001 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1002 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1003 m_flatBufferBuilder,
1004 fbVector);
1005 fbPayload = flatBuffersData.o;
1006 }
1007 }
1008 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1009 m_flatBufferBuilder,
1010 flatBufferTensorInfo,
1011 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1012 fbPayload);
1013 return flatBufferConstTensor;
1014}
1015
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001016std::vector<fb::Offset<serializer::InputSlot>>
1017 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001018{
Mike Kellya0766c32019-02-19 17:22:07 +00001019 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001020
1021 // Get the InputSlots
1022 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1023 {
1024 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1025
1026 // Get the Connection for the InputSlot
1027 const IOutputSlot* connection = inputSlot.GetConnection();
1028
1029 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001030 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1031 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001032 // Create FlatBuffer InputSlot
1033 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1034 }
1035 return inputSlots;
1036}
1037
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001038std::vector<fb::Offset<serializer::OutputSlot>>
1039 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001040{
1041 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1042
1043 // Get the OutputSlots
1044 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1045 {
1046 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001047 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001048
1049 // Get the dimensions
1050 std::vector<unsigned int> shape;
1051 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1052 {
1053 shape.push_back(tensorInfo.GetShape()[dim]);
1054 }
1055
1056 // Create FlatBuffer TensorInfo
1057 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1058 m_flatBufferBuilder.CreateVector(shape),
1059 GetFlatBufferDataType(tensorInfo.GetDataType()),
1060 tensorInfo.GetQuantizationScale(),
1061 tensorInfo.GetQuantizationOffset());
1062
1063 // Create FlatBuffer Outputslot
1064 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1065 slotIndex,
1066 flatBufferTensorInfo));
1067 }
1068 return outputSlots;
1069}
1070
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001071
1072ISerializer* ISerializer::CreateRaw()
1073{
1074 return new Serializer();
1075}
1076
1077ISerializerPtr ISerializer::Create()
1078{
1079 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1080}
1081
1082void ISerializer::Destroy(ISerializer* serializer)
1083{
1084 delete serializer;
1085}
1086
1087void Serializer::Serialize(const INetwork& inNetwork)
1088{
1089 // Iterate through to network
1090 inNetwork.Accept(m_SerializerVisitor);
1091 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1092
1093 // Create FlatBuffer SerializedGraph
1094 auto serializedGraph = serializer::CreateSerializedGraph(
1095 fbBuilder,
1096 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1097 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1098 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1099
1100 // Serialize the graph
1101 fbBuilder.Finish(serializedGraph);
1102}
1103
1104bool Serializer::SaveSerializedToStream(std::ostream& stream)
1105{
1106 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1107
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001108 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1109 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001110 return !stream.bad();
1111}
1112
Matteo Martincighec333912019-02-13 15:12:39 +00001113} // namespace armnnSerializer