blob: 74d0c435c69b88bed8e9972be45e4840cf569248 [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
Matthew Bentham268509a2019-02-25 13:58:24 +000014#include <ArmnnSchema_generated.h>
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000015
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,
238 descriptor.m_BiasEnabled,
239 GetFlatBufferDataLayout(descriptor.m_DataLayout));
240 auto flatBufferWeightsConstTensorInfo = CreateConstTensorInfo(weights);
241 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiasesConstTensorInfo;
242
243 if (biases.has_value())
244 {
245 flatBufferBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
246 }
247
248 // Create the FlatBuffer Convolution2dLayer
249 auto flatBufferLayer = CreateConvolution2dLayer(m_flatBufferBuilder,
250 flatBufferBaseLayer,
251 flatBufferDescriptor,
252 flatBufferWeightsConstTensorInfo,
253 flatBufferBiasesConstTensorInfo);
254
255 // Add the AnyLayer to the FlatBufferLayers
256 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution2dLayer);
257}
258
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000259void SerializerVisitor::VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
260 const armnn::DepthwiseConvolution2dDescriptor& descriptor,
261 const armnn::ConstTensor& weights,
262 const armnn::Optional<armnn::ConstTensor>& biases,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000263 const char* name)
264{
265 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthwiseConvolution2d);
266 auto fbDescriptor = CreateDepthwiseConvolution2dDescriptor(m_flatBufferBuilder,
267 descriptor.m_PadLeft,
268 descriptor.m_PadRight,
269 descriptor.m_PadTop,
270 descriptor.m_PadBottom,
271 descriptor.m_StrideX,
272 descriptor.m_StrideY,
273 descriptor.m_BiasEnabled,
274 GetFlatBufferDataLayout(descriptor.m_DataLayout));
275
276 flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
277 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
278 if (biases.has_value())
279 {
280 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
281 }
282
283 auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
284 fbBaseLayer,
285 fbDescriptor,
286 fbWeightsConstTensorInfo,
287 fbBiasesConstTensorInfo);
288
289 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
290}
291
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000292void SerializerVisitor::VisitDequantizeLayer(const armnn::IConnectableLayer* layer,
293 const char* name)
294{
295 auto fbDequantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Dequantize);
296 auto fbDequantizeLayer = serializer::CreateDequantizeLayer(m_flatBufferBuilder, fbDequantizeBaseLayer);
297
298 CreateAnyLayer(fbDequantizeLayer.o, serializer::Layer::Layer_DequantizeLayer);
299}
300
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000301void SerializerVisitor::VisitDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
302 const armnn::DetectionPostProcessDescriptor& descriptor,
303 const armnn::ConstTensor& anchors,
304 const char* name)
305{
306 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
307 auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
308 descriptor.m_MaxDetections,
309 descriptor.m_MaxClassesPerDetection,
310 descriptor.m_DetectionsPerClass,
311 descriptor.m_NmsScoreThreshold,
312 descriptor.m_NmsIouThreshold,
313 descriptor.m_NumClasses,
314 descriptor.m_UseRegularNms,
315 descriptor.m_ScaleX,
316 descriptor.m_ScaleY,
317 descriptor.m_ScaleW,
318 descriptor.m_ScaleH);
319
320 flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);
321
322 auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
323 fbBaseLayer,
324 fbDescriptor,
325 fbAnchorsConstTensorInfo);
326
327 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
328}
329
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000330void SerializerVisitor::VisitDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
331{
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000332 auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
333 auto fbDivisionLayer = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000334
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000335 CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
336}
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000337
Aron Virginas-Tar377351e2019-02-27 14:42:31 +0000338void SerializerVisitor::VisitEqualLayer(const armnn::IConnectableLayer* layer, const char* name)
339{
340 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Equal);
341 auto fbEqualLayer = serializer::CreateEqualLayer(m_flatBufferBuilder, fbBaseLayer);
342
343 CreateAnyLayer(fbEqualLayer.o, serializer::Layer::Layer_EqualLayer);
344}
345
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000346void SerializerVisitor::VisitFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
347{
348 auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
349 auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);
350
351 CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
352}
353
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000354void SerializerVisitor::VisitGatherLayer(const armnn::IConnectableLayer* layer, const char* name)
355{
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000356 auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
357 auto flatBufferLayer = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer);
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000358
359 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
360}
361
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000362void SerializerVisitor::VisitGreaterLayer(const armnn::IConnectableLayer* layer, const char* name)
363{
364 auto fbGreaterBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Greater);
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000365 auto fbGreaterLayer = serializer::CreateGreaterLayer(m_flatBufferBuilder, fbGreaterBaseLayer);
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000366
367 CreateAnyLayer(fbGreaterLayer.o, serializer::Layer::Layer_GreaterLayer);
368}
369
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000370void SerializerVisitor::VisitL2NormalizationLayer(const armnn::IConnectableLayer* layer,
371 const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
372 const char* name)
373{
374 // Create FlatBuffer BaseLayer
375 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);
376
377 // Create the FlatBuffer L2Normalization Descriptor
378 auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
379 m_flatBufferBuilder, GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout));
380
381 // Create Flatuffer layer
382 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
383
384 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
385}
386
Jim Flynn11af3752019-03-19 17:22:29 +0000387void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer, const armnn::LstmDescriptor& descriptor,
388 const armnn::LstmInputParams& params, const char* name)
389{
390 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
391
392 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
393 m_flatBufferBuilder,
394 descriptor.m_ActivationFunc,
395 descriptor.m_ClippingThresCell,
396 descriptor.m_ClippingThresProj,
397 descriptor.m_CifgEnabled,
398 descriptor.m_PeepholeEnabled,
399 descriptor.m_ProjectionEnabled);
400
401 // Get mandatory input parameters
402 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
403 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
404 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
405 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
406 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
407 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
408 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
409 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
410 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
411
412 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
413 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
414 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
415 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
416 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
417 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
418 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
419 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
420 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
421
422 if (!descriptor.m_CifgEnabled)
423 {
424 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
425 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
426 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
427 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
428 }
429
430 if (descriptor.m_ProjectionEnabled)
431 {
432 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
433 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
434 }
435
436 if (descriptor.m_PeepholeEnabled)
437 {
438 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
439 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
440 }
441
442 auto fbLstmParams = serializer::CreateLstmInputParams(
443 m_flatBufferBuilder,
444 inputToForgetWeights,
445 inputToCellWeights,
446 inputToOutputWeights,
447 recurrentToForgetWeights,
448 recurrentToCellWeights,
449 recurrentToOutputWeights,
450 forgetGateBias,
451 cellBias,
452 outputGateBias,
453 inputToInputWeights,
454 recurrentToInputWeights,
455 cellToInputWeights,
456 inputGateBias,
457 projectionWeights,
458 projectionBias,
459 cellToForgetWeights,
460 cellToOutputWeights);
461
462 auto fbLstmLayer = serializer::CreateLstmLayer(
463 m_flatBufferBuilder,
464 fbLstmBaseLayer,
465 fbLstmDescriptor,
466 fbLstmParams);
467
468 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
469}
470
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000471void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
472{
473 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
474 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
475
476 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
477}
478
479void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
480 const armnn::MeanDescriptor& descriptor,
481 const char* name)
482{
483 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
484 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
485 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
486 descriptor.m_KeepDims);
487
488 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
489 fbMeanBaseLayer,
490 fbMeanDescriptor);
491
492 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
493}
494
495void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
496{
497 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
498 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
499
500 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
501}
502
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100503void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
504{
505 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
506 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
507
508 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
509}
510
Jim Flynnac25a1b2019-02-28 10:40:49 +0000511void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
512 const armnn::OriginsDescriptor& mergerDescriptor,
513 const char* name)
514{
515 auto flatBufferMergerBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merger);
516
517 std::vector<flatbuffers::Offset<UintVector>> views;
518 for (unsigned int v = 0; v < mergerDescriptor.GetNumViews(); ++v)
519 {
520 const uint32_t* origin = mergerDescriptor.GetViewOrigin(v);
521 std::vector<uint32_t> origins;
522 for (unsigned int d = 0; d < mergerDescriptor.GetNumDimensions(); ++d)
523 {
524 origins.push_back(origin[d]);
525 }
526 auto view = m_flatBufferBuilder.CreateVector(origins);
527 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
528 views.push_back(uintVector);
529 }
530
531 auto flatBufferMergerDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
532 mergerDescriptor.GetConcatAxis(),
533 mergerDescriptor.GetNumViews(),
534 mergerDescriptor.GetNumDimensions(),
535 m_flatBufferBuilder.CreateVector(views));
536
537 auto flatBufferLayer = CreateMergerLayer(m_flatBufferBuilder,
538 flatBufferMergerBaseLayer,
539 flatBufferMergerDescriptor);
540
541 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_MergerLayer);
542}
543
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000544void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000545{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000546 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
547 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
548 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000549
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000550 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000551}
552
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000553void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
554 const armnn::PadDescriptor& padDescriptor,
555 const char* name)
556{
557 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
558
559 std::vector<unsigned int> padList;
560 for (auto& p: padDescriptor.m_PadList)
561 {
562 padList.push_back(p.first);
563 padList.push_back(p.second);
564 }
565
566 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
567 m_flatBufferBuilder.CreateVector(padList));
568
569 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
570 flatBufferBaseLayer,
571 flatBufferPadDesc);
572
573 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
574}
575
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000576void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
577 const armnn::PermuteDescriptor& permuteDescriptor,
578 const char* name)
579{
580 // Create FlatBuffer BaseLayer
581 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
582
583 std::vector<unsigned int> dimMappings;
584 for (auto& v: permuteDescriptor.m_DimMappings)
585 {
586 dimMappings.push_back(v);
587 }
588
589 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
590 m_flatBufferBuilder.CreateVector(dimMappings));
591
592 // Create the FlatBuffer PermuteLayer
593 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
594 flatBufferPermuteBaseLayer,
595 flatBufferPermuteDesc);
596
597 // Add the AnyLayer to the FlatBufferLayers
598 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
599}
600
Saoirse Stewart263829c2019-02-19 15:54:14 +0000601// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000602void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000603 const armnn::ReshapeDescriptor& reshapeDescriptor,
604 const char* name)
605{
606 // Create FlatBuffer BaseLayer
607 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
608
609 std::vector<unsigned int> targetShape;
610 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
611 {
612 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
613 }
614
615 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
616 m_flatBufferBuilder.CreateVector(targetShape));
617
618 // Create the FlatBuffer ReshapeLayer
619 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
620 flatBufferReshapeDesc);
621
622 // Add the AnyLayer to the FlatBufferLayers
623 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
624}
625
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000626void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
627 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
628 const char* name)
629{
630 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
631
632 auto flatBufferDescriptor =
633 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
634 resizeDescriptor.m_TargetWidth,
635 resizeDescriptor.m_TargetHeight,
636 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
637
638 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
639 flatBufferBaseLayer,
640 flatBufferDescriptor);
641
642 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
643}
644
Sadik Armagan8b42a382019-03-01 14:24:49 +0000645void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
646{
647 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
648 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
649
650 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
651}
652
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000653// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000654void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
655 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000656 const char* name)
657{
658 // Create FlatBuffer BaseLayer
659 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
660
661 // Create the FlatBuffer SoftmaxDescriptor
662 auto flatBufferSoftmaxDesc =
663 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
664
665 // Create the FlatBuffer SoftmaxLayer
666 auto flatBufferSoftmaxLayer =
667 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
668 flatBufferSoftmaxBaseLayer,
669 flatBufferSoftmaxDesc);
670
671 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
672}
673
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000674void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
675 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000676 const char* name)
677{
678 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
679 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
680 m_flatBufferBuilder,
681 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
682 pooling2dDescriptor.m_PadLeft,
683 pooling2dDescriptor.m_PadRight,
684 pooling2dDescriptor.m_PadTop,
685 pooling2dDescriptor.m_PadBottom,
686 pooling2dDescriptor.m_PoolWidth,
687 pooling2dDescriptor.m_PoolHeight,
688 pooling2dDescriptor.m_StrideX,
689 pooling2dDescriptor.m_StrideY,
690 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
691 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
692 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
693
694 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
695 fbPooling2dBaseLayer,
696 fbPooling2dDescriptor);
697
698 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
699}
700
Derek Lamberti87acb272019-03-27 16:51:31 +0000701void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
702{
703 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
704 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
705 fbQuantizeBaseLayer);
706 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
707}
708
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000709// Build FlatBuffer for FullyConnected Layer
710void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
711 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
712 const armnn::ConstTensor& weights,
713 const armnn::Optional<armnn::ConstTensor>& biases,
714 const char* name)
715{
716 // Create FlatBuffer BaseLayer
717 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
718
719 // Create FlatBuffer FullyConnectedDescriptor
720 auto flatBufferDescriptor =
721 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
722 fullyConnectedDescriptor.m_BiasEnabled,
723 fullyConnectedDescriptor.m_TransposeWeightMatrix);
724
725 // Create FlatBuffer weights data
726 auto flatBufferWeights = CreateConstTensorInfo(weights);
727
728 // Create FlatBuffer bias data
729 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
730 if (fullyConnectedDescriptor.m_BiasEnabled)
731 {
732 flatBufferBiases = CreateConstTensorInfo(biases.value());
733 }
734
735 // Create FlatBuffer FullyConnectedLayer
736 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
737 flatBufferBaseLayer,
738 flatBufferDescriptor,
739 flatBufferWeights,
740 flatBufferBiases);
741
742 // Add created FullyConnectedLayer to the FlatBufferLayers
743 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
744}
745
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000746// Build FlatBuffer for SpaceToBatchNd Layer
747void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
748 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
749 const char* name)
750{
751 // Create FlatBuffer BaseLayer
752 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
753
754 std::vector<unsigned int> padList;
755 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
756 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
757 {
758 padList.push_back(pad.first);
759 padList.push_back(pad.second);
760 }
761
762 auto flatBufferDescriptor =
763 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
764 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
765 m_flatBufferBuilder.CreateVector(padList),
766 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
767
768 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
769 flatBufferBaseLayer,
770 flatBufferDescriptor);
771
772 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
773}
774
Jim Flynn18ce3382019-03-08 11:08:30 +0000775// Build FlatBuffer for Splitter Layer
776void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
777 const armnn::ViewsDescriptor& viewsDescriptor,
778 const char* name)
779{
780 // Create FlatBuffer ViewOrigins
781 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
782 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
783
784 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
785 {
786 std::vector<uint32_t> viewOrigin;
787 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
788
789 // Copy vector
790 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
791 {
792 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
793 }
794
795 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
796 m_flatBufferBuilder.CreateVector(viewOrigin)));
797 }
798
799 // Create FlatBuffer OriginsDescriptor
800 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
801 viewsDescriptor.GetOrigins().GetConcatAxis(),
802 viewsDescriptor.GetOrigins().GetNumViews(),
803 viewsDescriptor.GetOrigins().GetNumDimensions(),
804 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
805
806 // Create FlatBuffer ViewOrigins
807 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
808 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
809
810 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
811 {
812 std::vector<uint32_t> viewSize;
813 viewSize.reserve(viewsDescriptor.GetNumDimensions());
814
815 // Copy vector
816 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
817 {
818 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
819 }
820
821 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
822 m_flatBufferBuilder.CreateVector(viewSize)));
823 }
824
825 // Create FlatBuffer ViewsDescriptor
826 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
827 flatBufferOriginDescriptor,
828 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
829
830 // Create FlatBuffer BaseLayer
831 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
832
833 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
834 flatBufferBaseLayer,
835 flatBufferViewsDescriptor);
836
837 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
838}
839
Nina Drozd57728782019-02-27 10:53:27 +0000840void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
841 const armnn::NormalizationDescriptor& descriptor,
842 const char* name)
843{
844 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
845
846 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
847 m_flatBufferBuilder,
848 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
849 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
850 descriptor.m_NormSize,
851 descriptor.m_Alpha,
852 descriptor.m_Beta,
853 descriptor.m_K,
854 GetFlatBufferDataLayout(descriptor.m_DataLayout));
855
856 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
857 fbNormalizationBaseLayer,
858 fbNormalizationDescriptor);
859
860 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
861}
862
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000863void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
864 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
865 const char* name)
866{
867 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
868
869 auto flatBufferDescriptor =
870 CreateStridedSliceDescriptor(m_flatBufferBuilder,
871 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
872 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
873 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
874 stridedSliceDescriptor.m_BeginMask,
875 stridedSliceDescriptor.m_EndMask,
876 stridedSliceDescriptor.m_ShrinkAxisMask,
877 stridedSliceDescriptor.m_EllipsisMask,
878 stridedSliceDescriptor.m_NewAxisMask,
879 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
880
881 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
882 flatBufferBaseLayer,
883 flatBufferDescriptor);
884
885 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
886}
887
Conor Kennedyda1f9752019-03-01 14:37:12 +0000888void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
889{
890 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
891 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
892
893 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
894}
895
Sadik Armaganeff363d2019-04-05 15:25:46 +0100896void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
897{
898 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
899 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
900
901 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
902}
903
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000904fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000905 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000906{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000907 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
908
Mike Kelly8c1701a2019-02-11 17:01:27 +0000909 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
910 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
911
912 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000913 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000914 m_flatBufferBuilder.CreateString(layer->GetName()),
915 layerType,
916 m_flatBufferBuilder.CreateVector(inputSlots),
917 m_flatBufferBuilder.CreateVector(outputSlots));
918}
919
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000920void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000921{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000922 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000923 m_serializedLayers.push_back(anyLayer);
924}
925
Mike Kellya0766c32019-02-19 17:22:07 +0000926template <typename T>
927flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
928{
929 const T* buffer = reinterpret_cast<const T*>(memory);
930 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
931 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
932 return fbVector;
933}
934
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000935flatbuffers::Offset<serializer::ConstTensor>
936 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000937{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000938 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000939
940 // Get the dimensions
941 std::vector<unsigned int> shape;
942
943 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
944 {
945 shape.push_back(tensorInfo.GetShape()[dim]);
946 }
947
948 // Create FlatBuffer TensorInfo
949 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
950 m_flatBufferBuilder.CreateVector(shape),
951 GetFlatBufferDataType(tensorInfo.GetDataType()),
952 tensorInfo.GetQuantizationScale(),
953 tensorInfo.GetQuantizationOffset());
954 flatbuffers::Offset<void> fbPayload;
955
956 switch (tensorInfo.GetDataType())
957 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000958 case armnn::DataType::Float32:
959 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000960 {
961 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
962 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
963 m_flatBufferBuilder,
964 fbVector);
965 fbPayload = flatBuffersData.o;
966 break;
967 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000968 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000969 {
970 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
971 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
972 m_flatBufferBuilder,
973 fbVector);
974 fbPayload = flatBuffersData.o;
975 break;
976 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +0000977 case armnn::DataType::QuantisedSymm16:
978 {
979 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
980 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
981 m_flatBufferBuilder,
982 fbVector);
983 fbPayload = flatBuffersData.o;
984 break;
985 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000986 case armnn::DataType::QuantisedAsymm8:
987 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +0000988 default:
989 {
990 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
991 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
992 m_flatBufferBuilder,
993 fbVector);
994 fbPayload = flatBuffersData.o;
995 }
996 }
997 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
998 m_flatBufferBuilder,
999 flatBufferTensorInfo,
1000 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1001 fbPayload);
1002 return flatBufferConstTensor;
1003}
1004
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001005std::vector<fb::Offset<serializer::InputSlot>>
1006 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001007{
Mike Kellya0766c32019-02-19 17:22:07 +00001008 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001009
1010 // Get the InputSlots
1011 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1012 {
1013 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1014
1015 // Get the Connection for the InputSlot
1016 const IOutputSlot* connection = inputSlot.GetConnection();
1017
1018 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001019 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1020 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001021 // Create FlatBuffer InputSlot
1022 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1023 }
1024 return inputSlots;
1025}
1026
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001027std::vector<fb::Offset<serializer::OutputSlot>>
1028 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001029{
1030 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1031
1032 // Get the OutputSlots
1033 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1034 {
1035 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001036 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001037
1038 // Get the dimensions
1039 std::vector<unsigned int> shape;
1040 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1041 {
1042 shape.push_back(tensorInfo.GetShape()[dim]);
1043 }
1044
1045 // Create FlatBuffer TensorInfo
1046 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1047 m_flatBufferBuilder.CreateVector(shape),
1048 GetFlatBufferDataType(tensorInfo.GetDataType()),
1049 tensorInfo.GetQuantizationScale(),
1050 tensorInfo.GetQuantizationOffset());
1051
1052 // Create FlatBuffer Outputslot
1053 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1054 slotIndex,
1055 flatBufferTensorInfo));
1056 }
1057 return outputSlots;
1058}
1059
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001060
1061ISerializer* ISerializer::CreateRaw()
1062{
1063 return new Serializer();
1064}
1065
1066ISerializerPtr ISerializer::Create()
1067{
1068 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1069}
1070
1071void ISerializer::Destroy(ISerializer* serializer)
1072{
1073 delete serializer;
1074}
1075
1076void Serializer::Serialize(const INetwork& inNetwork)
1077{
1078 // Iterate through to network
1079 inNetwork.Accept(m_SerializerVisitor);
1080 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1081
1082 // Create FlatBuffer SerializedGraph
1083 auto serializedGraph = serializer::CreateSerializedGraph(
1084 fbBuilder,
1085 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1086 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1087 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1088
1089 // Serialize the graph
1090 fbBuilder.Finish(serializedGraph);
1091}
1092
1093bool Serializer::SaveSerializedToStream(std::ostream& stream)
1094{
1095 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1096
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001097 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1098 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001099 return !stream.bad();
1100}
1101
Matteo Martincighec333912019-02-13 15:12:39 +00001102} // namespace armnnSerializer