blob: 131bb956082435623873821c1e22382155439a74 [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{
Aron Virginas-Taraa067142019-06-11 16:01:44 +0100791 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
792 auto flatBufferDescriptor =
793 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
794 spaceToDepthDescriptor.m_BlockSize,
795 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
796
797 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
798 flatBufferBaseLayer,
799 flatBufferDescriptor);
800
801 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100802}
803
Jim Flynn18ce3382019-03-08 11:08:30 +0000804// Build FlatBuffer for Splitter Layer
805void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
806 const armnn::ViewsDescriptor& viewsDescriptor,
807 const char* name)
808{
809 // Create FlatBuffer ViewOrigins
810 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
811 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
812
813 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
814 {
815 std::vector<uint32_t> viewOrigin;
816 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
817
818 // Copy vector
819 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
820 {
821 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
822 }
823
824 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
825 m_flatBufferBuilder.CreateVector(viewOrigin)));
826 }
827
828 // Create FlatBuffer OriginsDescriptor
829 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
830 viewsDescriptor.GetOrigins().GetConcatAxis(),
831 viewsDescriptor.GetOrigins().GetNumViews(),
832 viewsDescriptor.GetOrigins().GetNumDimensions(),
833 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
834
835 // Create FlatBuffer ViewOrigins
836 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
837 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
838
839 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
840 {
841 std::vector<uint32_t> viewSize;
842 viewSize.reserve(viewsDescriptor.GetNumDimensions());
843
844 // Copy vector
845 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
846 {
847 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
848 }
849
850 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
851 m_flatBufferBuilder.CreateVector(viewSize)));
852 }
853
854 // Create FlatBuffer ViewsDescriptor
855 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
856 flatBufferOriginDescriptor,
857 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
858
859 // Create FlatBuffer BaseLayer
860 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
861
862 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
863 flatBufferBaseLayer,
864 flatBufferViewsDescriptor);
865
866 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
867}
868
Nina Drozd57728782019-02-27 10:53:27 +0000869void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
870 const armnn::NormalizationDescriptor& descriptor,
871 const char* name)
872{
873 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
874
875 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
876 m_flatBufferBuilder,
877 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
878 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
879 descriptor.m_NormSize,
880 descriptor.m_Alpha,
881 descriptor.m_Beta,
882 descriptor.m_K,
883 GetFlatBufferDataLayout(descriptor.m_DataLayout));
884
885 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
886 fbNormalizationBaseLayer,
887 fbNormalizationDescriptor);
888
889 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
890}
891
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000892void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
893 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
894 const char* name)
895{
896 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
897
898 auto flatBufferDescriptor =
899 CreateStridedSliceDescriptor(m_flatBufferBuilder,
900 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
901 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
902 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
903 stridedSliceDescriptor.m_BeginMask,
904 stridedSliceDescriptor.m_EndMask,
905 stridedSliceDescriptor.m_ShrinkAxisMask,
906 stridedSliceDescriptor.m_EllipsisMask,
907 stridedSliceDescriptor.m_NewAxisMask,
908 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
909
910 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
911 flatBufferBaseLayer,
912 flatBufferDescriptor);
913
914 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
915}
916
Conor Kennedyda1f9752019-03-01 14:37:12 +0000917void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
918{
919 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
920 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
921
922 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
923}
924
Sadik Armaganeff363d2019-04-05 15:25:46 +0100925void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
926{
927 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
928 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
929
930 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
931}
932
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000933fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000934 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000935{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000936 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
937
Mike Kelly8c1701a2019-02-11 17:01:27 +0000938 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
939 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
940
941 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000942 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000943 m_flatBufferBuilder.CreateString(layer->GetName()),
944 layerType,
945 m_flatBufferBuilder.CreateVector(inputSlots),
946 m_flatBufferBuilder.CreateVector(outputSlots));
947}
948
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000949void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000950{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000951 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000952 m_serializedLayers.push_back(anyLayer);
953}
954
Mike Kellya0766c32019-02-19 17:22:07 +0000955template <typename T>
956flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
957{
958 const T* buffer = reinterpret_cast<const T*>(memory);
959 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
960 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
961 return fbVector;
962}
963
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000964flatbuffers::Offset<serializer::ConstTensor>
965 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000966{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000967 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000968
969 // Get the dimensions
970 std::vector<unsigned int> shape;
971
972 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
973 {
974 shape.push_back(tensorInfo.GetShape()[dim]);
975 }
976
977 // Create FlatBuffer TensorInfo
978 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
979 m_flatBufferBuilder.CreateVector(shape),
980 GetFlatBufferDataType(tensorInfo.GetDataType()),
981 tensorInfo.GetQuantizationScale(),
982 tensorInfo.GetQuantizationOffset());
983 flatbuffers::Offset<void> fbPayload;
984
985 switch (tensorInfo.GetDataType())
986 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000987 case armnn::DataType::Float32:
988 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000989 {
990 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
991 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
992 m_flatBufferBuilder,
993 fbVector);
994 fbPayload = flatBuffersData.o;
995 break;
996 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000997 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000998 {
999 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1000 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1001 m_flatBufferBuilder,
1002 fbVector);
1003 fbPayload = flatBuffersData.o;
1004 break;
1005 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001006 case armnn::DataType::QuantisedSymm16:
1007 {
1008 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1009 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1010 m_flatBufferBuilder,
1011 fbVector);
1012 fbPayload = flatBuffersData.o;
1013 break;
1014 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001015 case armnn::DataType::QuantisedAsymm8:
1016 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001017 default:
1018 {
1019 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1020 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1021 m_flatBufferBuilder,
1022 fbVector);
1023 fbPayload = flatBuffersData.o;
1024 }
1025 }
1026 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1027 m_flatBufferBuilder,
1028 flatBufferTensorInfo,
1029 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1030 fbPayload);
1031 return flatBufferConstTensor;
1032}
1033
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001034std::vector<fb::Offset<serializer::InputSlot>>
1035 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001036{
Mike Kellya0766c32019-02-19 17:22:07 +00001037 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001038
1039 // Get the InputSlots
1040 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1041 {
1042 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1043
1044 // Get the Connection for the InputSlot
1045 const IOutputSlot* connection = inputSlot.GetConnection();
1046
1047 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001048 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1049 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001050 // Create FlatBuffer InputSlot
1051 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1052 }
1053 return inputSlots;
1054}
1055
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001056std::vector<fb::Offset<serializer::OutputSlot>>
1057 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001058{
1059 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1060
1061 // Get the OutputSlots
1062 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1063 {
1064 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001065 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001066
1067 // Get the dimensions
1068 std::vector<unsigned int> shape;
1069 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1070 {
1071 shape.push_back(tensorInfo.GetShape()[dim]);
1072 }
1073
1074 // Create FlatBuffer TensorInfo
1075 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1076 m_flatBufferBuilder.CreateVector(shape),
1077 GetFlatBufferDataType(tensorInfo.GetDataType()),
1078 tensorInfo.GetQuantizationScale(),
1079 tensorInfo.GetQuantizationOffset());
1080
1081 // Create FlatBuffer Outputslot
1082 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1083 slotIndex,
1084 flatBufferTensorInfo));
1085 }
1086 return outputSlots;
1087}
1088
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001089
1090ISerializer* ISerializer::CreateRaw()
1091{
1092 return new Serializer();
1093}
1094
1095ISerializerPtr ISerializer::Create()
1096{
1097 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1098}
1099
1100void ISerializer::Destroy(ISerializer* serializer)
1101{
1102 delete serializer;
1103}
1104
1105void Serializer::Serialize(const INetwork& inNetwork)
1106{
1107 // Iterate through to network
1108 inNetwork.Accept(m_SerializerVisitor);
1109 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1110
1111 // Create FlatBuffer SerializedGraph
1112 auto serializedGraph = serializer::CreateSerializedGraph(
1113 fbBuilder,
1114 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1115 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1116 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1117
1118 // Serialize the graph
1119 fbBuilder.Finish(serializedGraph);
1120}
1121
1122bool Serializer::SaveSerializedToStream(std::ostream& stream)
1123{
1124 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1125
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001126 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1127 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001128 return !stream.bad();
1129}
1130
Matteo Martincighec333912019-02-13 15:12:39 +00001131} // namespace armnnSerializer