blob: fe30c3eee5b8969be7fcf4f5b3a0b22d9eb852ef [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 Armagandbb0c0c2019-02-21 09:01:41 +0000896fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000897 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000898{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000899 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
900
Mike Kelly8c1701a2019-02-11 17:01:27 +0000901 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
902 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
903
904 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000905 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000906 m_flatBufferBuilder.CreateString(layer->GetName()),
907 layerType,
908 m_flatBufferBuilder.CreateVector(inputSlots),
909 m_flatBufferBuilder.CreateVector(outputSlots));
910}
911
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000912void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000913{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000914 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000915 m_serializedLayers.push_back(anyLayer);
916}
917
Mike Kellya0766c32019-02-19 17:22:07 +0000918template <typename T>
919flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
920{
921 const T* buffer = reinterpret_cast<const T*>(memory);
922 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
923 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
924 return fbVector;
925}
926
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000927flatbuffers::Offset<serializer::ConstTensor>
928 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000929{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000930 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000931
932 // Get the dimensions
933 std::vector<unsigned int> shape;
934
935 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
936 {
937 shape.push_back(tensorInfo.GetShape()[dim]);
938 }
939
940 // Create FlatBuffer TensorInfo
941 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
942 m_flatBufferBuilder.CreateVector(shape),
943 GetFlatBufferDataType(tensorInfo.GetDataType()),
944 tensorInfo.GetQuantizationScale(),
945 tensorInfo.GetQuantizationOffset());
946 flatbuffers::Offset<void> fbPayload;
947
948 switch (tensorInfo.GetDataType())
949 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000950 case armnn::DataType::Float32:
951 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000952 {
953 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
954 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
955 m_flatBufferBuilder,
956 fbVector);
957 fbPayload = flatBuffersData.o;
958 break;
959 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000960 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000961 {
962 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
963 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
964 m_flatBufferBuilder,
965 fbVector);
966 fbPayload = flatBuffersData.o;
967 break;
968 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +0000969 case armnn::DataType::QuantisedSymm16:
970 {
971 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
972 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
973 m_flatBufferBuilder,
974 fbVector);
975 fbPayload = flatBuffersData.o;
976 break;
977 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000978 case armnn::DataType::QuantisedAsymm8:
979 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +0000980 default:
981 {
982 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
983 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
984 m_flatBufferBuilder,
985 fbVector);
986 fbPayload = flatBuffersData.o;
987 }
988 }
989 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
990 m_flatBufferBuilder,
991 flatBufferTensorInfo,
992 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
993 fbPayload);
994 return flatBufferConstTensor;
995}
996
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000997std::vector<fb::Offset<serializer::InputSlot>>
998 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000999{
Mike Kellya0766c32019-02-19 17:22:07 +00001000 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001001
1002 // Get the InputSlots
1003 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1004 {
1005 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1006
1007 // Get the Connection for the InputSlot
1008 const IOutputSlot* connection = inputSlot.GetConnection();
1009
1010 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001011 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1012 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001013 // Create FlatBuffer InputSlot
1014 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1015 }
1016 return inputSlots;
1017}
1018
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001019std::vector<fb::Offset<serializer::OutputSlot>>
1020 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001021{
1022 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1023
1024 // Get the OutputSlots
1025 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1026 {
1027 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001028 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001029
1030 // Get the dimensions
1031 std::vector<unsigned int> shape;
1032 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1033 {
1034 shape.push_back(tensorInfo.GetShape()[dim]);
1035 }
1036
1037 // Create FlatBuffer TensorInfo
1038 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1039 m_flatBufferBuilder.CreateVector(shape),
1040 GetFlatBufferDataType(tensorInfo.GetDataType()),
1041 tensorInfo.GetQuantizationScale(),
1042 tensorInfo.GetQuantizationOffset());
1043
1044 // Create FlatBuffer Outputslot
1045 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1046 slotIndex,
1047 flatBufferTensorInfo));
1048 }
1049 return outputSlots;
1050}
1051
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001052
1053ISerializer* ISerializer::CreateRaw()
1054{
1055 return new Serializer();
1056}
1057
1058ISerializerPtr ISerializer::Create()
1059{
1060 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1061}
1062
1063void ISerializer::Destroy(ISerializer* serializer)
1064{
1065 delete serializer;
1066}
1067
1068void Serializer::Serialize(const INetwork& inNetwork)
1069{
1070 // Iterate through to network
1071 inNetwork.Accept(m_SerializerVisitor);
1072 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1073
1074 // Create FlatBuffer SerializedGraph
1075 auto serializedGraph = serializer::CreateSerializedGraph(
1076 fbBuilder,
1077 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1078 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1079 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1080
1081 // Serialize the graph
1082 fbBuilder.Finish(serializedGraph);
1083}
1084
1085bool Serializer::SaveSerializedToStream(std::ostream& stream)
1086{
1087 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1088
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001089 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1090 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001091 return !stream.bad();
1092}
1093
Matteo Martincighec333912019-02-13 15:12:39 +00001094} // namespace armnnSerializer