blob: 208262b699a4b16ceea9cdcb28e95b3fc761d7e1 [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,
David Monahan34757812019-06-19 11:47:21 +0100580 m_flatBufferBuilder.CreateVector(padList),
581 padDescriptor.m_padValue);
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000582
583 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
584 flatBufferBaseLayer,
585 flatBufferPadDesc);
586
587 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
588}
589
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000590void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
591 const armnn::PermuteDescriptor& permuteDescriptor,
592 const char* name)
593{
594 // Create FlatBuffer BaseLayer
595 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
596
597 std::vector<unsigned int> dimMappings;
598 for (auto& v: permuteDescriptor.m_DimMappings)
599 {
600 dimMappings.push_back(v);
601 }
602
603 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
604 m_flatBufferBuilder.CreateVector(dimMappings));
605
606 // Create the FlatBuffer PermuteLayer
607 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
608 flatBufferPermuteBaseLayer,
609 flatBufferPermuteDesc);
610
611 // Add the AnyLayer to the FlatBufferLayers
612 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
613}
614
Saoirse Stewart263829c2019-02-19 15:54:14 +0000615// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000616void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000617 const armnn::ReshapeDescriptor& reshapeDescriptor,
618 const char* name)
619{
620 // Create FlatBuffer BaseLayer
621 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
622
623 std::vector<unsigned int> targetShape;
624 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
625 {
626 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
627 }
628
629 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
630 m_flatBufferBuilder.CreateVector(targetShape));
631
632 // Create the FlatBuffer ReshapeLayer
633 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
634 flatBufferReshapeDesc);
635
636 // Add the AnyLayer to the FlatBufferLayers
637 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
638}
639
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000640void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
641 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
642 const char* name)
643{
644 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
645
646 auto flatBufferDescriptor =
647 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
648 resizeDescriptor.m_TargetWidth,
649 resizeDescriptor.m_TargetHeight,
650 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
651
652 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
653 flatBufferBaseLayer,
654 flatBufferDescriptor);
655
656 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
657}
658
Sadik Armagan8b42a382019-03-01 14:24:49 +0000659void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
660{
661 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
662 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
663
664 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
665}
666
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000667// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000668void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
669 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000670 const char* name)
671{
672 // Create FlatBuffer BaseLayer
673 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
674
675 // Create the FlatBuffer SoftmaxDescriptor
676 auto flatBufferSoftmaxDesc =
677 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
678
679 // Create the FlatBuffer SoftmaxLayer
680 auto flatBufferSoftmaxLayer =
681 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
682 flatBufferSoftmaxBaseLayer,
683 flatBufferSoftmaxDesc);
684
685 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
686}
687
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000688void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
689 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000690 const char* name)
691{
692 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
693 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
694 m_flatBufferBuilder,
695 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
696 pooling2dDescriptor.m_PadLeft,
697 pooling2dDescriptor.m_PadRight,
698 pooling2dDescriptor.m_PadTop,
699 pooling2dDescriptor.m_PadBottom,
700 pooling2dDescriptor.m_PoolWidth,
701 pooling2dDescriptor.m_PoolHeight,
702 pooling2dDescriptor.m_StrideX,
703 pooling2dDescriptor.m_StrideY,
704 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
705 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
706 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
707
708 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
709 fbPooling2dBaseLayer,
710 fbPooling2dDescriptor);
711
712 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
713}
714
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100715void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
716 const char* name)
717{
Ellen Norris-Thompson51982472019-06-19 11:46:21 +0100718 // Create FlatBuffer BaseLayer
719 auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
720
721 // Create the FlatBuffer AdditionLayer
722 auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
723
724 // Add the AnyLayer to the FlatBufferLayers
725 CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100726}
727
Derek Lamberti87acb272019-03-27 16:51:31 +0000728void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
729{
730 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
731 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
732 fbQuantizeBaseLayer);
733 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
734}
735
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000736// Build FlatBuffer for FullyConnected Layer
737void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
738 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
739 const armnn::ConstTensor& weights,
740 const armnn::Optional<armnn::ConstTensor>& biases,
741 const char* name)
742{
743 // Create FlatBuffer BaseLayer
744 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
745
746 // Create FlatBuffer FullyConnectedDescriptor
747 auto flatBufferDescriptor =
748 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
749 fullyConnectedDescriptor.m_BiasEnabled,
750 fullyConnectedDescriptor.m_TransposeWeightMatrix);
751
752 // Create FlatBuffer weights data
753 auto flatBufferWeights = CreateConstTensorInfo(weights);
754
755 // Create FlatBuffer bias data
756 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
757 if (fullyConnectedDescriptor.m_BiasEnabled)
758 {
759 flatBufferBiases = CreateConstTensorInfo(biases.value());
760 }
761
762 // Create FlatBuffer FullyConnectedLayer
763 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
764 flatBufferBaseLayer,
765 flatBufferDescriptor,
766 flatBufferWeights,
767 flatBufferBiases);
768
769 // Add created FullyConnectedLayer to the FlatBufferLayers
770 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
771}
772
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000773// Build FlatBuffer for SpaceToBatchNd Layer
774void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
775 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
776 const char* name)
777{
778 // Create FlatBuffer BaseLayer
779 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
780
781 std::vector<unsigned int> padList;
782 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
783 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
784 {
785 padList.push_back(pad.first);
786 padList.push_back(pad.second);
787 }
788
789 auto flatBufferDescriptor =
790 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
791 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
792 m_flatBufferBuilder.CreateVector(padList),
793 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
794
795 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
796 flatBufferBaseLayer,
797 flatBufferDescriptor);
798
799 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
800}
801
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100802// Build FlatBuffer for SpaceToDepthLayer
803void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
804 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
805 const char* name)
806{
Aron Virginas-Taraa067142019-06-11 16:01:44 +0100807 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
808 auto flatBufferDescriptor =
809 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
810 spaceToDepthDescriptor.m_BlockSize,
811 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
812
813 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
814 flatBufferBaseLayer,
815 flatBufferDescriptor);
816
817 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100818}
819
Jim Flynn18ce3382019-03-08 11:08:30 +0000820// Build FlatBuffer for Splitter Layer
821void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
822 const armnn::ViewsDescriptor& viewsDescriptor,
823 const char* name)
824{
825 // Create FlatBuffer ViewOrigins
826 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
827 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
828
829 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
830 {
831 std::vector<uint32_t> viewOrigin;
832 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
833
834 // Copy vector
835 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
836 {
837 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
838 }
839
840 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
841 m_flatBufferBuilder.CreateVector(viewOrigin)));
842 }
843
844 // Create FlatBuffer OriginsDescriptor
845 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
846 viewsDescriptor.GetOrigins().GetConcatAxis(),
847 viewsDescriptor.GetOrigins().GetNumViews(),
848 viewsDescriptor.GetOrigins().GetNumDimensions(),
849 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
850
851 // Create FlatBuffer ViewOrigins
852 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
853 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
854
855 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
856 {
857 std::vector<uint32_t> viewSize;
858 viewSize.reserve(viewsDescriptor.GetNumDimensions());
859
860 // Copy vector
861 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
862 {
863 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
864 }
865
866 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
867 m_flatBufferBuilder.CreateVector(viewSize)));
868 }
869
870 // Create FlatBuffer ViewsDescriptor
871 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
872 flatBufferOriginDescriptor,
873 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
874
875 // Create FlatBuffer BaseLayer
876 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
877
878 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
879 flatBufferBaseLayer,
880 flatBufferViewsDescriptor);
881
882 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
883}
884
Nina Drozd57728782019-02-27 10:53:27 +0000885void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
886 const armnn::NormalizationDescriptor& descriptor,
887 const char* name)
888{
889 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
890
891 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
892 m_flatBufferBuilder,
893 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
894 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
895 descriptor.m_NormSize,
896 descriptor.m_Alpha,
897 descriptor.m_Beta,
898 descriptor.m_K,
899 GetFlatBufferDataLayout(descriptor.m_DataLayout));
900
901 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
902 fbNormalizationBaseLayer,
903 fbNormalizationDescriptor);
904
905 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
906}
907
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000908void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
909 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
910 const char* name)
911{
912 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
913
914 auto flatBufferDescriptor =
915 CreateStridedSliceDescriptor(m_flatBufferBuilder,
916 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
917 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
918 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
919 stridedSliceDescriptor.m_BeginMask,
920 stridedSliceDescriptor.m_EndMask,
921 stridedSliceDescriptor.m_ShrinkAxisMask,
922 stridedSliceDescriptor.m_EllipsisMask,
923 stridedSliceDescriptor.m_NewAxisMask,
924 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
925
926 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
927 flatBufferBaseLayer,
928 flatBufferDescriptor);
929
930 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
931}
932
Conor Kennedyda1f9752019-03-01 14:37:12 +0000933void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
934{
935 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
936 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
937
938 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
939}
940
Sadik Armaganeff363d2019-04-05 15:25:46 +0100941void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
942{
943 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
944 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
945
946 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
947}
948
Aron Virginas-Tar639fb042019-06-20 14:28:19 +0100949void SerializerVisitor::VisitTransposeConvolution2dLayer(
950 const armnn::IConnectableLayer* layer,
951 const armnn::TransposeConvolution2dDescriptor& descriptor,
952 const armnn::ConstTensor& weights,
953 const armnn::Optional<armnn::ConstTensor>& biases,
954 const char* name)
955{
Aron Virginas-Tarcb549302019-06-21 13:53:38 +0100956 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
957 auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
958 descriptor.m_PadLeft,
959 descriptor.m_PadRight,
960 descriptor.m_PadTop,
961 descriptor.m_PadBottom,
962 descriptor.m_StrideX,
963 descriptor.m_StrideY,
964 descriptor.m_BiasEnabled,
965 GetFlatBufferDataLayout(descriptor.m_DataLayout));
966
967 // weights & biases
968 auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
969 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
970 if (biases.has_value())
971 {
972 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
973 }
974
975 auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
976 fbBaseLayer,
977 fbDescriptor,
978 fbWeightsConstTensorInfo,
979 fbBiasesConstTensorInfo);
980
981 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
Aron Virginas-Tar639fb042019-06-20 14:28:19 +0100982}
983
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000984fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000985 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000986{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000987 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
988
Mike Kelly8c1701a2019-02-11 17:01:27 +0000989 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
990 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
991
992 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000993 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000994 m_flatBufferBuilder.CreateString(layer->GetName()),
995 layerType,
996 m_flatBufferBuilder.CreateVector(inputSlots),
997 m_flatBufferBuilder.CreateVector(outputSlots));
998}
999
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001000void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001001{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001002 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +00001003 m_serializedLayers.push_back(anyLayer);
1004}
1005
Mike Kellya0766c32019-02-19 17:22:07 +00001006template <typename T>
1007flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
1008{
1009 const T* buffer = reinterpret_cast<const T*>(memory);
1010 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
1011 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
1012 return fbVector;
1013}
1014
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001015flatbuffers::Offset<serializer::ConstTensor>
1016 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +00001017{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001018 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +00001019
1020 // Get the dimensions
1021 std::vector<unsigned int> shape;
1022
1023 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1024 {
1025 shape.push_back(tensorInfo.GetShape()[dim]);
1026 }
1027
1028 // Create FlatBuffer TensorInfo
1029 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1030 m_flatBufferBuilder.CreateVector(shape),
1031 GetFlatBufferDataType(tensorInfo.GetDataType()),
1032 tensorInfo.GetQuantizationScale(),
1033 tensorInfo.GetQuantizationOffset());
1034 flatbuffers::Offset<void> fbPayload;
1035
1036 switch (tensorInfo.GetDataType())
1037 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001038 case armnn::DataType::Float32:
1039 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +00001040 {
1041 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1042 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1043 m_flatBufferBuilder,
1044 fbVector);
1045 fbPayload = flatBuffersData.o;
1046 break;
1047 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001048 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +00001049 {
1050 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1051 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1052 m_flatBufferBuilder,
1053 fbVector);
1054 fbPayload = flatBuffersData.o;
1055 break;
1056 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001057 case armnn::DataType::QuantisedSymm16:
1058 {
1059 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1060 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1061 m_flatBufferBuilder,
1062 fbVector);
1063 fbPayload = flatBuffersData.o;
1064 break;
1065 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001066 case armnn::DataType::QuantisedAsymm8:
1067 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001068 default:
1069 {
1070 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1071 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1072 m_flatBufferBuilder,
1073 fbVector);
1074 fbPayload = flatBuffersData.o;
1075 }
1076 }
1077 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1078 m_flatBufferBuilder,
1079 flatBufferTensorInfo,
1080 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1081 fbPayload);
1082 return flatBufferConstTensor;
1083}
1084
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001085std::vector<fb::Offset<serializer::InputSlot>>
1086 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001087{
Mike Kellya0766c32019-02-19 17:22:07 +00001088 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001089
1090 // Get the InputSlots
1091 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1092 {
1093 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1094
1095 // Get the Connection for the InputSlot
1096 const IOutputSlot* connection = inputSlot.GetConnection();
1097
1098 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001099 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1100 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001101 // Create FlatBuffer InputSlot
1102 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1103 }
1104 return inputSlots;
1105}
1106
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001107std::vector<fb::Offset<serializer::OutputSlot>>
1108 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001109{
1110 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1111
1112 // Get the OutputSlots
1113 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1114 {
1115 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001116 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001117
1118 // Get the dimensions
1119 std::vector<unsigned int> shape;
1120 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1121 {
1122 shape.push_back(tensorInfo.GetShape()[dim]);
1123 }
1124
1125 // Create FlatBuffer TensorInfo
1126 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1127 m_flatBufferBuilder.CreateVector(shape),
1128 GetFlatBufferDataType(tensorInfo.GetDataType()),
1129 tensorInfo.GetQuantizationScale(),
1130 tensorInfo.GetQuantizationOffset());
1131
1132 // Create FlatBuffer Outputslot
1133 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1134 slotIndex,
1135 flatBufferTensorInfo));
1136 }
1137 return outputSlots;
1138}
1139
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001140
1141ISerializer* ISerializer::CreateRaw()
1142{
1143 return new Serializer();
1144}
1145
1146ISerializerPtr ISerializer::Create()
1147{
1148 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1149}
1150
1151void ISerializer::Destroy(ISerializer* serializer)
1152{
1153 delete serializer;
1154}
1155
1156void Serializer::Serialize(const INetwork& inNetwork)
1157{
1158 // Iterate through to network
1159 inNetwork.Accept(m_SerializerVisitor);
1160 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1161
1162 // Create FlatBuffer SerializedGraph
1163 auto serializedGraph = serializer::CreateSerializedGraph(
1164 fbBuilder,
1165 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1166 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1167 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1168
1169 // Serialize the graph
1170 fbBuilder.Finish(serializedGraph);
1171}
1172
1173bool Serializer::SaveSerializedToStream(std::ostream& stream)
1174{
1175 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1176
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001177 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1178 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001179 return !stream.bad();
1180}
1181
Matteo Martincighec333912019-02-13 15:12:39 +00001182} // namespace armnnSerializer