blob: 57d674095b3d9f1b2141f16b46655bcd3614c608 [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
Teresa Charlina9075df2019-06-27 15:41:57 +0100659void SerializerVisitor::VisitResizeLayer(const armnn::IConnectableLayer* layer,
660 const armnn::ResizeDescriptor& resizeDescriptor,
661 const char* name)
662{
FinnWilliamsArm6fb339a2019-06-28 15:07:10 +0100663 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Resize);
664
665 auto flatBufferDescriptor =
666 CreateResizeDescriptor(m_flatBufferBuilder,
667 resizeDescriptor.m_TargetHeight,
668 resizeDescriptor.m_TargetWidth,
669 GetFlatBufferResizeMethod(resizeDescriptor.m_Method),
670 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
671
672 auto flatBufferLayer = serializer::CreateResizeLayer(m_flatBufferBuilder,
673 flatBufferBaseLayer,
674 flatBufferDescriptor);
675
676 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeLayer);
Teresa Charlina9075df2019-06-27 15:41:57 +0100677}
678
Sadik Armagan8b42a382019-03-01 14:24:49 +0000679void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
680{
681 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
682 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
683
684 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
685}
686
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000687// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000688void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
689 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000690 const char* name)
691{
692 // Create FlatBuffer BaseLayer
693 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
694
695 // Create the FlatBuffer SoftmaxDescriptor
696 auto flatBufferSoftmaxDesc =
697 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
698
699 // Create the FlatBuffer SoftmaxLayer
700 auto flatBufferSoftmaxLayer =
701 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
702 flatBufferSoftmaxBaseLayer,
703 flatBufferSoftmaxDesc);
704
705 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
706}
707
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000708void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
709 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000710 const char* name)
711{
712 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
713 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
714 m_flatBufferBuilder,
715 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
716 pooling2dDescriptor.m_PadLeft,
717 pooling2dDescriptor.m_PadRight,
718 pooling2dDescriptor.m_PadTop,
719 pooling2dDescriptor.m_PadBottom,
720 pooling2dDescriptor.m_PoolWidth,
721 pooling2dDescriptor.m_PoolHeight,
722 pooling2dDescriptor.m_StrideX,
723 pooling2dDescriptor.m_StrideY,
724 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
725 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
726 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
727
728 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
729 fbPooling2dBaseLayer,
730 fbPooling2dDescriptor);
731
732 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
733}
734
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100735void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
736 const char* name)
737{
Ellen Norris-Thompson51982472019-06-19 11:46:21 +0100738 // Create FlatBuffer BaseLayer
739 auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
740
741 // Create the FlatBuffer AdditionLayer
742 auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
743
744 // Add the AnyLayer to the FlatBufferLayers
745 CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100746}
747
Derek Lamberti87acb272019-03-27 16:51:31 +0000748void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
749{
750 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
751 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
752 fbQuantizeBaseLayer);
753 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
754}
755
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000756// Build FlatBuffer for FullyConnected Layer
757void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
758 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
759 const armnn::ConstTensor& weights,
760 const armnn::Optional<armnn::ConstTensor>& biases,
761 const char* name)
762{
763 // Create FlatBuffer BaseLayer
764 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
765
766 // Create FlatBuffer FullyConnectedDescriptor
767 auto flatBufferDescriptor =
768 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
769 fullyConnectedDescriptor.m_BiasEnabled,
770 fullyConnectedDescriptor.m_TransposeWeightMatrix);
771
772 // Create FlatBuffer weights data
773 auto flatBufferWeights = CreateConstTensorInfo(weights);
774
775 // Create FlatBuffer bias data
776 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
777 if (fullyConnectedDescriptor.m_BiasEnabled)
778 {
779 flatBufferBiases = CreateConstTensorInfo(biases.value());
780 }
781
782 // Create FlatBuffer FullyConnectedLayer
783 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
784 flatBufferBaseLayer,
785 flatBufferDescriptor,
786 flatBufferWeights,
787 flatBufferBiases);
788
789 // Add created FullyConnectedLayer to the FlatBufferLayers
790 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
791}
792
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000793// Build FlatBuffer for SpaceToBatchNd Layer
794void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
795 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
796 const char* name)
797{
798 // Create FlatBuffer BaseLayer
799 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
800
801 std::vector<unsigned int> padList;
802 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
803 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
804 {
805 padList.push_back(pad.first);
806 padList.push_back(pad.second);
807 }
808
809 auto flatBufferDescriptor =
810 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
811 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
812 m_flatBufferBuilder.CreateVector(padList),
813 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
814
815 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
816 flatBufferBaseLayer,
817 flatBufferDescriptor);
818
819 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
820}
821
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100822// Build FlatBuffer for SpaceToDepthLayer
823void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
824 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
825 const char* name)
826{
Aron Virginas-Taraa067142019-06-11 16:01:44 +0100827 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
828 auto flatBufferDescriptor =
829 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
830 spaceToDepthDescriptor.m_BlockSize,
831 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
832
833 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
834 flatBufferBaseLayer,
835 flatBufferDescriptor);
836
837 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100838}
839
Jim Flynn18ce3382019-03-08 11:08:30 +0000840// Build FlatBuffer for Splitter Layer
841void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
842 const armnn::ViewsDescriptor& viewsDescriptor,
843 const char* name)
844{
845 // Create FlatBuffer ViewOrigins
846 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
847 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
848
849 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
850 {
851 std::vector<uint32_t> viewOrigin;
852 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
853
854 // Copy vector
855 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
856 {
857 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
858 }
859
860 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
861 m_flatBufferBuilder.CreateVector(viewOrigin)));
862 }
863
864 // Create FlatBuffer OriginsDescriptor
865 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
866 viewsDescriptor.GetOrigins().GetConcatAxis(),
867 viewsDescriptor.GetOrigins().GetNumViews(),
868 viewsDescriptor.GetOrigins().GetNumDimensions(),
869 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
870
871 // Create FlatBuffer ViewOrigins
872 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
873 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
874
875 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
876 {
877 std::vector<uint32_t> viewSize;
878 viewSize.reserve(viewsDescriptor.GetNumDimensions());
879
880 // Copy vector
881 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
882 {
883 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
884 }
885
886 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
887 m_flatBufferBuilder.CreateVector(viewSize)));
888 }
889
890 // Create FlatBuffer ViewsDescriptor
891 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
892 flatBufferOriginDescriptor,
893 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
894
895 // Create FlatBuffer BaseLayer
896 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
897
898 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
899 flatBufferBaseLayer,
900 flatBufferViewsDescriptor);
901
902 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
903}
904
Nina Drozd57728782019-02-27 10:53:27 +0000905void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
906 const armnn::NormalizationDescriptor& descriptor,
907 const char* name)
908{
909 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
910
911 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
912 m_flatBufferBuilder,
913 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
914 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
915 descriptor.m_NormSize,
916 descriptor.m_Alpha,
917 descriptor.m_Beta,
918 descriptor.m_K,
919 GetFlatBufferDataLayout(descriptor.m_DataLayout));
920
921 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
922 fbNormalizationBaseLayer,
923 fbNormalizationDescriptor);
924
925 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
926}
927
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000928void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
929 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
930 const char* name)
931{
932 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
933
934 auto flatBufferDescriptor =
935 CreateStridedSliceDescriptor(m_flatBufferBuilder,
936 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
937 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
938 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
939 stridedSliceDescriptor.m_BeginMask,
940 stridedSliceDescriptor.m_EndMask,
941 stridedSliceDescriptor.m_ShrinkAxisMask,
942 stridedSliceDescriptor.m_EllipsisMask,
943 stridedSliceDescriptor.m_NewAxisMask,
944 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
945
946 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
947 flatBufferBaseLayer,
948 flatBufferDescriptor);
949
950 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
951}
952
Conor Kennedyda1f9752019-03-01 14:37:12 +0000953void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
954{
955 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
956 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
957
958 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
959}
960
Sadik Armaganeff363d2019-04-05 15:25:46 +0100961void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
962{
963 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
964 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
965
966 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
967}
968
Aron Virginas-Tar639fb042019-06-20 14:28:19 +0100969void SerializerVisitor::VisitTransposeConvolution2dLayer(
970 const armnn::IConnectableLayer* layer,
971 const armnn::TransposeConvolution2dDescriptor& descriptor,
972 const armnn::ConstTensor& weights,
973 const armnn::Optional<armnn::ConstTensor>& biases,
974 const char* name)
975{
Aron Virginas-Tarcb549302019-06-21 13:53:38 +0100976 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
977 auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
978 descriptor.m_PadLeft,
979 descriptor.m_PadRight,
980 descriptor.m_PadTop,
981 descriptor.m_PadBottom,
982 descriptor.m_StrideX,
983 descriptor.m_StrideY,
984 descriptor.m_BiasEnabled,
985 GetFlatBufferDataLayout(descriptor.m_DataLayout));
986
987 // weights & biases
988 auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
989 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
990 if (biases.has_value())
991 {
992 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
993 }
994
995 auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
996 fbBaseLayer,
997 fbDescriptor,
998 fbWeightsConstTensorInfo,
999 fbBiasesConstTensorInfo);
1000
1001 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001002}
1003
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001004fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001005 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001006{
Sadik Armagandb059fd2019-03-20 12:28:32 +00001007 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
1008
Mike Kelly8c1701a2019-02-11 17:01:27 +00001009 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
1010 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
1011
1012 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +00001013 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +00001014 m_flatBufferBuilder.CreateString(layer->GetName()),
1015 layerType,
1016 m_flatBufferBuilder.CreateVector(inputSlots),
1017 m_flatBufferBuilder.CreateVector(outputSlots));
1018}
1019
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001020void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001021{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001022 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +00001023 m_serializedLayers.push_back(anyLayer);
1024}
1025
Mike Kellya0766c32019-02-19 17:22:07 +00001026template <typename T>
1027flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
1028{
1029 const T* buffer = reinterpret_cast<const T*>(memory);
1030 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
1031 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
1032 return fbVector;
1033}
1034
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001035flatbuffers::Offset<serializer::ConstTensor>
1036 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +00001037{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001038 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +00001039
1040 // Get the dimensions
1041 std::vector<unsigned int> shape;
1042
1043 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1044 {
1045 shape.push_back(tensorInfo.GetShape()[dim]);
1046 }
1047
1048 // Create FlatBuffer TensorInfo
1049 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1050 m_flatBufferBuilder.CreateVector(shape),
1051 GetFlatBufferDataType(tensorInfo.GetDataType()),
1052 tensorInfo.GetQuantizationScale(),
1053 tensorInfo.GetQuantizationOffset());
1054 flatbuffers::Offset<void> fbPayload;
1055
1056 switch (tensorInfo.GetDataType())
1057 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001058 case armnn::DataType::Float32:
1059 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +00001060 {
1061 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1062 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1063 m_flatBufferBuilder,
1064 fbVector);
1065 fbPayload = flatBuffersData.o;
1066 break;
1067 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001068 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +00001069 {
1070 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1071 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1072 m_flatBufferBuilder,
1073 fbVector);
1074 fbPayload = flatBuffersData.o;
1075 break;
1076 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001077 case armnn::DataType::QuantisedSymm16:
1078 {
1079 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1080 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1081 m_flatBufferBuilder,
1082 fbVector);
1083 fbPayload = flatBuffersData.o;
1084 break;
1085 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001086 case armnn::DataType::QuantisedAsymm8:
1087 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001088 default:
1089 {
1090 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1091 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1092 m_flatBufferBuilder,
1093 fbVector);
1094 fbPayload = flatBuffersData.o;
1095 }
1096 }
1097 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1098 m_flatBufferBuilder,
1099 flatBufferTensorInfo,
1100 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1101 fbPayload);
1102 return flatBufferConstTensor;
1103}
1104
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001105std::vector<fb::Offset<serializer::InputSlot>>
1106 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001107{
Mike Kellya0766c32019-02-19 17:22:07 +00001108 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001109
1110 // Get the InputSlots
1111 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1112 {
1113 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1114
1115 // Get the Connection for the InputSlot
1116 const IOutputSlot* connection = inputSlot.GetConnection();
1117
1118 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001119 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1120 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001121 // Create FlatBuffer InputSlot
1122 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1123 }
1124 return inputSlots;
1125}
1126
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001127std::vector<fb::Offset<serializer::OutputSlot>>
1128 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001129{
1130 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1131
1132 // Get the OutputSlots
1133 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1134 {
1135 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001136 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001137
1138 // Get the dimensions
1139 std::vector<unsigned int> shape;
1140 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1141 {
1142 shape.push_back(tensorInfo.GetShape()[dim]);
1143 }
1144
1145 // Create FlatBuffer TensorInfo
1146 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1147 m_flatBufferBuilder.CreateVector(shape),
1148 GetFlatBufferDataType(tensorInfo.GetDataType()),
1149 tensorInfo.GetQuantizationScale(),
1150 tensorInfo.GetQuantizationOffset());
1151
1152 // Create FlatBuffer Outputslot
1153 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1154 slotIndex,
1155 flatBufferTensorInfo));
1156 }
1157 return outputSlots;
1158}
1159
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001160
1161ISerializer* ISerializer::CreateRaw()
1162{
1163 return new Serializer();
1164}
1165
1166ISerializerPtr ISerializer::Create()
1167{
1168 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1169}
1170
1171void ISerializer::Destroy(ISerializer* serializer)
1172{
1173 delete serializer;
1174}
1175
1176void Serializer::Serialize(const INetwork& inNetwork)
1177{
1178 // Iterate through to network
1179 inNetwork.Accept(m_SerializerVisitor);
1180 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1181
1182 // Create FlatBuffer SerializedGraph
1183 auto serializedGraph = serializer::CreateSerializedGraph(
1184 fbBuilder,
1185 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1186 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1187 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1188
1189 // Serialize the graph
1190 fbBuilder.Finish(serializedGraph);
1191}
1192
1193bool Serializer::SaveSerializedToStream(std::ostream& stream)
1194{
1195 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1196
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001197 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1198 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001199 return !stream.bad();
1200}
1201
Matteo Martincighec333912019-02-13 15:12:39 +00001202} // namespace armnnSerializer