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