blob: 676d10c0e49eacf8deba40a12f7a05ac4812acea [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
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100786// Build FlatBuffer for SpaceToDepthLayer
787void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
788 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
789 const char* name)
790{
791 throw armnn::Exception("SerializerVisitor::VisitSpaceToDepthLayer is not yet implemented");
792}
793
Jim Flynn18ce3382019-03-08 11:08:30 +0000794// Build FlatBuffer for Splitter Layer
795void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
796 const armnn::ViewsDescriptor& viewsDescriptor,
797 const char* name)
798{
799 // Create FlatBuffer ViewOrigins
800 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
801 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
802
803 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
804 {
805 std::vector<uint32_t> viewOrigin;
806 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
807
808 // Copy vector
809 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
810 {
811 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
812 }
813
814 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
815 m_flatBufferBuilder.CreateVector(viewOrigin)));
816 }
817
818 // Create FlatBuffer OriginsDescriptor
819 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
820 viewsDescriptor.GetOrigins().GetConcatAxis(),
821 viewsDescriptor.GetOrigins().GetNumViews(),
822 viewsDescriptor.GetOrigins().GetNumDimensions(),
823 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
824
825 // Create FlatBuffer ViewOrigins
826 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
827 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
828
829 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
830 {
831 std::vector<uint32_t> viewSize;
832 viewSize.reserve(viewsDescriptor.GetNumDimensions());
833
834 // Copy vector
835 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
836 {
837 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
838 }
839
840 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
841 m_flatBufferBuilder.CreateVector(viewSize)));
842 }
843
844 // Create FlatBuffer ViewsDescriptor
845 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
846 flatBufferOriginDescriptor,
847 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
848
849 // Create FlatBuffer BaseLayer
850 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
851
852 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
853 flatBufferBaseLayer,
854 flatBufferViewsDescriptor);
855
856 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
857}
858
Nina Drozd57728782019-02-27 10:53:27 +0000859void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
860 const armnn::NormalizationDescriptor& descriptor,
861 const char* name)
862{
863 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
864
865 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
866 m_flatBufferBuilder,
867 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
868 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
869 descriptor.m_NormSize,
870 descriptor.m_Alpha,
871 descriptor.m_Beta,
872 descriptor.m_K,
873 GetFlatBufferDataLayout(descriptor.m_DataLayout));
874
875 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
876 fbNormalizationBaseLayer,
877 fbNormalizationDescriptor);
878
879 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
880}
881
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000882void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
883 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
884 const char* name)
885{
886 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
887
888 auto flatBufferDescriptor =
889 CreateStridedSliceDescriptor(m_flatBufferBuilder,
890 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
891 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
892 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
893 stridedSliceDescriptor.m_BeginMask,
894 stridedSliceDescriptor.m_EndMask,
895 stridedSliceDescriptor.m_ShrinkAxisMask,
896 stridedSliceDescriptor.m_EllipsisMask,
897 stridedSliceDescriptor.m_NewAxisMask,
898 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
899
900 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
901 flatBufferBaseLayer,
902 flatBufferDescriptor);
903
904 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
905}
906
Conor Kennedyda1f9752019-03-01 14:37:12 +0000907void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
908{
909 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
910 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
911
912 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
913}
914
Sadik Armaganeff363d2019-04-05 15:25:46 +0100915void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
916{
917 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
918 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
919
920 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
921}
922
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000923fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000924 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000925{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000926 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
927
Mike Kelly8c1701a2019-02-11 17:01:27 +0000928 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
929 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
930
931 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000932 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000933 m_flatBufferBuilder.CreateString(layer->GetName()),
934 layerType,
935 m_flatBufferBuilder.CreateVector(inputSlots),
936 m_flatBufferBuilder.CreateVector(outputSlots));
937}
938
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000939void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000940{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000941 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000942 m_serializedLayers.push_back(anyLayer);
943}
944
Mike Kellya0766c32019-02-19 17:22:07 +0000945template <typename T>
946flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
947{
948 const T* buffer = reinterpret_cast<const T*>(memory);
949 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
950 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
951 return fbVector;
952}
953
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000954flatbuffers::Offset<serializer::ConstTensor>
955 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000956{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000957 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000958
959 // Get the dimensions
960 std::vector<unsigned int> shape;
961
962 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
963 {
964 shape.push_back(tensorInfo.GetShape()[dim]);
965 }
966
967 // Create FlatBuffer TensorInfo
968 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
969 m_flatBufferBuilder.CreateVector(shape),
970 GetFlatBufferDataType(tensorInfo.GetDataType()),
971 tensorInfo.GetQuantizationScale(),
972 tensorInfo.GetQuantizationOffset());
973 flatbuffers::Offset<void> fbPayload;
974
975 switch (tensorInfo.GetDataType())
976 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000977 case armnn::DataType::Float32:
978 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000979 {
980 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
981 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
982 m_flatBufferBuilder,
983 fbVector);
984 fbPayload = flatBuffersData.o;
985 break;
986 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000987 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000988 {
989 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
990 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
991 m_flatBufferBuilder,
992 fbVector);
993 fbPayload = flatBuffersData.o;
994 break;
995 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +0000996 case armnn::DataType::QuantisedSymm16:
997 {
998 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
999 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1000 m_flatBufferBuilder,
1001 fbVector);
1002 fbPayload = flatBuffersData.o;
1003 break;
1004 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001005 case armnn::DataType::QuantisedAsymm8:
1006 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001007 default:
1008 {
1009 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1010 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1011 m_flatBufferBuilder,
1012 fbVector);
1013 fbPayload = flatBuffersData.o;
1014 }
1015 }
1016 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1017 m_flatBufferBuilder,
1018 flatBufferTensorInfo,
1019 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1020 fbPayload);
1021 return flatBufferConstTensor;
1022}
1023
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001024std::vector<fb::Offset<serializer::InputSlot>>
1025 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001026{
Mike Kellya0766c32019-02-19 17:22:07 +00001027 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001028
1029 // Get the InputSlots
1030 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1031 {
1032 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1033
1034 // Get the Connection for the InputSlot
1035 const IOutputSlot* connection = inputSlot.GetConnection();
1036
1037 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001038 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1039 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001040 // Create FlatBuffer InputSlot
1041 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1042 }
1043 return inputSlots;
1044}
1045
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001046std::vector<fb::Offset<serializer::OutputSlot>>
1047 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001048{
1049 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1050
1051 // Get the OutputSlots
1052 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1053 {
1054 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001055 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001056
1057 // Get the dimensions
1058 std::vector<unsigned int> shape;
1059 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1060 {
1061 shape.push_back(tensorInfo.GetShape()[dim]);
1062 }
1063
1064 // Create FlatBuffer TensorInfo
1065 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1066 m_flatBufferBuilder.CreateVector(shape),
1067 GetFlatBufferDataType(tensorInfo.GetDataType()),
1068 tensorInfo.GetQuantizationScale(),
1069 tensorInfo.GetQuantizationOffset());
1070
1071 // Create FlatBuffer Outputslot
1072 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1073 slotIndex,
1074 flatBufferTensorInfo));
1075 }
1076 return outputSlots;
1077}
1078
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001079
1080ISerializer* ISerializer::CreateRaw()
1081{
1082 return new Serializer();
1083}
1084
1085ISerializerPtr ISerializer::Create()
1086{
1087 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1088}
1089
1090void ISerializer::Destroy(ISerializer* serializer)
1091{
1092 delete serializer;
1093}
1094
1095void Serializer::Serialize(const INetwork& inNetwork)
1096{
1097 // Iterate through to network
1098 inNetwork.Accept(m_SerializerVisitor);
1099 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1100
1101 // Create FlatBuffer SerializedGraph
1102 auto serializedGraph = serializer::CreateSerializedGraph(
1103 fbBuilder,
1104 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1105 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1106 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1107
1108 // Serialize the graph
1109 fbBuilder.Finish(serializedGraph);
1110}
1111
1112bool Serializer::SaveSerializedToStream(std::ostream& stream)
1113{
1114 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1115
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001116 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1117 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001118 return !stream.bad();
1119}
1120
Matteo Martincighec333912019-02-13 15:12:39 +00001121} // namespace armnnSerializer