blob: dabe9771790f8c8cdf12b34e1dd1a9b3e4f9043d [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
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100712void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
713 const char* name)
714{
Ellen Norris-Thompson51982472019-06-19 11:46:21 +0100715 // Create FlatBuffer BaseLayer
716 auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
717
718 // Create the FlatBuffer AdditionLayer
719 auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
720
721 // Add the AnyLayer to the FlatBufferLayers
722 CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100723}
724
Derek Lamberti87acb272019-03-27 16:51:31 +0000725void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
726{
727 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
728 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
729 fbQuantizeBaseLayer);
730 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
731}
732
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000733// Build FlatBuffer for FullyConnected Layer
734void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
735 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
736 const armnn::ConstTensor& weights,
737 const armnn::Optional<armnn::ConstTensor>& biases,
738 const char* name)
739{
740 // Create FlatBuffer BaseLayer
741 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
742
743 // Create FlatBuffer FullyConnectedDescriptor
744 auto flatBufferDescriptor =
745 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
746 fullyConnectedDescriptor.m_BiasEnabled,
747 fullyConnectedDescriptor.m_TransposeWeightMatrix);
748
749 // Create FlatBuffer weights data
750 auto flatBufferWeights = CreateConstTensorInfo(weights);
751
752 // Create FlatBuffer bias data
753 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
754 if (fullyConnectedDescriptor.m_BiasEnabled)
755 {
756 flatBufferBiases = CreateConstTensorInfo(biases.value());
757 }
758
759 // Create FlatBuffer FullyConnectedLayer
760 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
761 flatBufferBaseLayer,
762 flatBufferDescriptor,
763 flatBufferWeights,
764 flatBufferBiases);
765
766 // Add created FullyConnectedLayer to the FlatBufferLayers
767 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
768}
769
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000770// Build FlatBuffer for SpaceToBatchNd Layer
771void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
772 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
773 const char* name)
774{
775 // Create FlatBuffer BaseLayer
776 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
777
778 std::vector<unsigned int> padList;
779 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
780 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
781 {
782 padList.push_back(pad.first);
783 padList.push_back(pad.second);
784 }
785
786 auto flatBufferDescriptor =
787 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
788 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
789 m_flatBufferBuilder.CreateVector(padList),
790 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
791
792 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
793 flatBufferBaseLayer,
794 flatBufferDescriptor);
795
796 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
797}
798
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100799// Build FlatBuffer for SpaceToDepthLayer
800void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
801 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
802 const char* name)
803{
Aron Virginas-Taraa067142019-06-11 16:01:44 +0100804 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
805 auto flatBufferDescriptor =
806 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
807 spaceToDepthDescriptor.m_BlockSize,
808 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
809
810 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
811 flatBufferBaseLayer,
812 flatBufferDescriptor);
813
814 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100815}
816
Jim Flynn18ce3382019-03-08 11:08:30 +0000817// Build FlatBuffer for Splitter Layer
818void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
819 const armnn::ViewsDescriptor& viewsDescriptor,
820 const char* name)
821{
822 // Create FlatBuffer ViewOrigins
823 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
824 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
825
826 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
827 {
828 std::vector<uint32_t> viewOrigin;
829 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
830
831 // Copy vector
832 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
833 {
834 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
835 }
836
837 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
838 m_flatBufferBuilder.CreateVector(viewOrigin)));
839 }
840
841 // Create FlatBuffer OriginsDescriptor
842 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
843 viewsDescriptor.GetOrigins().GetConcatAxis(),
844 viewsDescriptor.GetOrigins().GetNumViews(),
845 viewsDescriptor.GetOrigins().GetNumDimensions(),
846 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
847
848 // Create FlatBuffer ViewOrigins
849 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
850 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
851
852 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
853 {
854 std::vector<uint32_t> viewSize;
855 viewSize.reserve(viewsDescriptor.GetNumDimensions());
856
857 // Copy vector
858 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
859 {
860 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
861 }
862
863 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
864 m_flatBufferBuilder.CreateVector(viewSize)));
865 }
866
867 // Create FlatBuffer ViewsDescriptor
868 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
869 flatBufferOriginDescriptor,
870 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
871
872 // Create FlatBuffer BaseLayer
873 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
874
875 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
876 flatBufferBaseLayer,
877 flatBufferViewsDescriptor);
878
879 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
880}
881
Nina Drozd57728782019-02-27 10:53:27 +0000882void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
883 const armnn::NormalizationDescriptor& descriptor,
884 const char* name)
885{
886 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
887
888 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
889 m_flatBufferBuilder,
890 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
891 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
892 descriptor.m_NormSize,
893 descriptor.m_Alpha,
894 descriptor.m_Beta,
895 descriptor.m_K,
896 GetFlatBufferDataLayout(descriptor.m_DataLayout));
897
898 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
899 fbNormalizationBaseLayer,
900 fbNormalizationDescriptor);
901
902 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
903}
904
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000905void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
906 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
907 const char* name)
908{
909 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
910
911 auto flatBufferDescriptor =
912 CreateStridedSliceDescriptor(m_flatBufferBuilder,
913 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
914 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
915 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
916 stridedSliceDescriptor.m_BeginMask,
917 stridedSliceDescriptor.m_EndMask,
918 stridedSliceDescriptor.m_ShrinkAxisMask,
919 stridedSliceDescriptor.m_EllipsisMask,
920 stridedSliceDescriptor.m_NewAxisMask,
921 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
922
923 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
924 flatBufferBaseLayer,
925 flatBufferDescriptor);
926
927 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
928}
929
Conor Kennedyda1f9752019-03-01 14:37:12 +0000930void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
931{
932 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
933 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
934
935 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
936}
937
Sadik Armaganeff363d2019-04-05 15:25:46 +0100938void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
939{
940 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
941 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
942
943 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
944}
945
Aron Virginas-Tar639fb042019-06-20 14:28:19 +0100946void SerializerVisitor::VisitTransposeConvolution2dLayer(
947 const armnn::IConnectableLayer* layer,
948 const armnn::TransposeConvolution2dDescriptor& descriptor,
949 const armnn::ConstTensor& weights,
950 const armnn::Optional<armnn::ConstTensor>& biases,
951 const char* name)
952{
953 throw UnimplementedException("SerializerVisitor::VisitTransposeConvolution2dLayer is not implemented");
954}
955
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000956fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000957 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000958{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000959 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
960
Mike Kelly8c1701a2019-02-11 17:01:27 +0000961 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
962 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
963
964 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000965 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000966 m_flatBufferBuilder.CreateString(layer->GetName()),
967 layerType,
968 m_flatBufferBuilder.CreateVector(inputSlots),
969 m_flatBufferBuilder.CreateVector(outputSlots));
970}
971
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000972void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000973{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000974 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000975 m_serializedLayers.push_back(anyLayer);
976}
977
Mike Kellya0766c32019-02-19 17:22:07 +0000978template <typename T>
979flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
980{
981 const T* buffer = reinterpret_cast<const T*>(memory);
982 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
983 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
984 return fbVector;
985}
986
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000987flatbuffers::Offset<serializer::ConstTensor>
988 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000989{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000990 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000991
992 // Get the dimensions
993 std::vector<unsigned int> shape;
994
995 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
996 {
997 shape.push_back(tensorInfo.GetShape()[dim]);
998 }
999
1000 // Create FlatBuffer TensorInfo
1001 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1002 m_flatBufferBuilder.CreateVector(shape),
1003 GetFlatBufferDataType(tensorInfo.GetDataType()),
1004 tensorInfo.GetQuantizationScale(),
1005 tensorInfo.GetQuantizationOffset());
1006 flatbuffers::Offset<void> fbPayload;
1007
1008 switch (tensorInfo.GetDataType())
1009 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001010 case armnn::DataType::Float32:
1011 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +00001012 {
1013 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1014 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1015 m_flatBufferBuilder,
1016 fbVector);
1017 fbPayload = flatBuffersData.o;
1018 break;
1019 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001020 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +00001021 {
1022 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1023 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1024 m_flatBufferBuilder,
1025 fbVector);
1026 fbPayload = flatBuffersData.o;
1027 break;
1028 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001029 case armnn::DataType::QuantisedSymm16:
1030 {
1031 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1032 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1033 m_flatBufferBuilder,
1034 fbVector);
1035 fbPayload = flatBuffersData.o;
1036 break;
1037 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001038 case armnn::DataType::QuantisedAsymm8:
1039 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001040 default:
1041 {
1042 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1043 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1044 m_flatBufferBuilder,
1045 fbVector);
1046 fbPayload = flatBuffersData.o;
1047 }
1048 }
1049 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1050 m_flatBufferBuilder,
1051 flatBufferTensorInfo,
1052 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1053 fbPayload);
1054 return flatBufferConstTensor;
1055}
1056
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001057std::vector<fb::Offset<serializer::InputSlot>>
1058 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001059{
Mike Kellya0766c32019-02-19 17:22:07 +00001060 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001061
1062 // Get the InputSlots
1063 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1064 {
1065 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1066
1067 // Get the Connection for the InputSlot
1068 const IOutputSlot* connection = inputSlot.GetConnection();
1069
1070 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001071 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1072 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001073 // Create FlatBuffer InputSlot
1074 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1075 }
1076 return inputSlots;
1077}
1078
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001079std::vector<fb::Offset<serializer::OutputSlot>>
1080 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001081{
1082 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1083
1084 // Get the OutputSlots
1085 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1086 {
1087 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001088 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001089
1090 // Get the dimensions
1091 std::vector<unsigned int> shape;
1092 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1093 {
1094 shape.push_back(tensorInfo.GetShape()[dim]);
1095 }
1096
1097 // Create FlatBuffer TensorInfo
1098 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1099 m_flatBufferBuilder.CreateVector(shape),
1100 GetFlatBufferDataType(tensorInfo.GetDataType()),
1101 tensorInfo.GetQuantizationScale(),
1102 tensorInfo.GetQuantizationOffset());
1103
1104 // Create FlatBuffer Outputslot
1105 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1106 slotIndex,
1107 flatBufferTensorInfo));
1108 }
1109 return outputSlots;
1110}
1111
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001112
1113ISerializer* ISerializer::CreateRaw()
1114{
1115 return new Serializer();
1116}
1117
1118ISerializerPtr ISerializer::Create()
1119{
1120 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1121}
1122
1123void ISerializer::Destroy(ISerializer* serializer)
1124{
1125 delete serializer;
1126}
1127
1128void Serializer::Serialize(const INetwork& inNetwork)
1129{
1130 // Iterate through to network
1131 inNetwork.Accept(m_SerializerVisitor);
1132 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1133
1134 // Create FlatBuffer SerializedGraph
1135 auto serializedGraph = serializer::CreateSerializedGraph(
1136 fbBuilder,
1137 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1138 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1139 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1140
1141 // Serialize the graph
1142 fbBuilder.Finish(serializedGraph);
1143}
1144
1145bool Serializer::SaveSerializedToStream(std::ostream& stream)
1146{
1147 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1148
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001149 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1150 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001151 return !stream.bad();
1152}
1153
Matteo Martincighec333912019-02-13 15:12:39 +00001154} // namespace armnnSerializer