blob: 7181f01e6ba2adeaeaaac1583a44029059ace8a6 [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
Jim Flynnac25a1b2019-02-28 10:40:49 +0000503void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
504 const armnn::OriginsDescriptor& mergerDescriptor,
505 const char* name)
506{
507 auto flatBufferMergerBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merger);
508
509 std::vector<flatbuffers::Offset<UintVector>> views;
510 for (unsigned int v = 0; v < mergerDescriptor.GetNumViews(); ++v)
511 {
512 const uint32_t* origin = mergerDescriptor.GetViewOrigin(v);
513 std::vector<uint32_t> origins;
514 for (unsigned int d = 0; d < mergerDescriptor.GetNumDimensions(); ++d)
515 {
516 origins.push_back(origin[d]);
517 }
518 auto view = m_flatBufferBuilder.CreateVector(origins);
519 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
520 views.push_back(uintVector);
521 }
522
523 auto flatBufferMergerDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
524 mergerDescriptor.GetConcatAxis(),
525 mergerDescriptor.GetNumViews(),
526 mergerDescriptor.GetNumDimensions(),
527 m_flatBufferBuilder.CreateVector(views));
528
529 auto flatBufferLayer = CreateMergerLayer(m_flatBufferBuilder,
530 flatBufferMergerBaseLayer,
531 flatBufferMergerDescriptor);
532
533 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_MergerLayer);
534}
535
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000536void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000537{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000538 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
539 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
540 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000541
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000542 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000543}
544
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000545void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
546 const armnn::PadDescriptor& padDescriptor,
547 const char* name)
548{
549 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
550
551 std::vector<unsigned int> padList;
552 for (auto& p: padDescriptor.m_PadList)
553 {
554 padList.push_back(p.first);
555 padList.push_back(p.second);
556 }
557
558 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
559 m_flatBufferBuilder.CreateVector(padList));
560
561 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
562 flatBufferBaseLayer,
563 flatBufferPadDesc);
564
565 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
566}
567
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000568void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
569 const armnn::PermuteDescriptor& permuteDescriptor,
570 const char* name)
571{
572 // Create FlatBuffer BaseLayer
573 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
574
575 std::vector<unsigned int> dimMappings;
576 for (auto& v: permuteDescriptor.m_DimMappings)
577 {
578 dimMappings.push_back(v);
579 }
580
581 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
582 m_flatBufferBuilder.CreateVector(dimMappings));
583
584 // Create the FlatBuffer PermuteLayer
585 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
586 flatBufferPermuteBaseLayer,
587 flatBufferPermuteDesc);
588
589 // Add the AnyLayer to the FlatBufferLayers
590 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
591}
592
Saoirse Stewart263829c2019-02-19 15:54:14 +0000593// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000594void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000595 const armnn::ReshapeDescriptor& reshapeDescriptor,
596 const char* name)
597{
598 // Create FlatBuffer BaseLayer
599 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
600
601 std::vector<unsigned int> targetShape;
602 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
603 {
604 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
605 }
606
607 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
608 m_flatBufferBuilder.CreateVector(targetShape));
609
610 // Create the FlatBuffer ReshapeLayer
611 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
612 flatBufferReshapeDesc);
613
614 // Add the AnyLayer to the FlatBufferLayers
615 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
616}
617
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000618void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
619 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
620 const char* name)
621{
622 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
623
624 auto flatBufferDescriptor =
625 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
626 resizeDescriptor.m_TargetWidth,
627 resizeDescriptor.m_TargetHeight,
628 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
629
630 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
631 flatBufferBaseLayer,
632 flatBufferDescriptor);
633
634 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
635}
636
Sadik Armagan8b42a382019-03-01 14:24:49 +0000637void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
638{
639 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
640 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
641
642 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
643}
644
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000645// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000646void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
647 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000648 const char* name)
649{
650 // Create FlatBuffer BaseLayer
651 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
652
653 // Create the FlatBuffer SoftmaxDescriptor
654 auto flatBufferSoftmaxDesc =
655 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
656
657 // Create the FlatBuffer SoftmaxLayer
658 auto flatBufferSoftmaxLayer =
659 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
660 flatBufferSoftmaxBaseLayer,
661 flatBufferSoftmaxDesc);
662
663 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
664}
665
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000666void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
667 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000668 const char* name)
669{
670 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
671 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
672 m_flatBufferBuilder,
673 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
674 pooling2dDescriptor.m_PadLeft,
675 pooling2dDescriptor.m_PadRight,
676 pooling2dDescriptor.m_PadTop,
677 pooling2dDescriptor.m_PadBottom,
678 pooling2dDescriptor.m_PoolWidth,
679 pooling2dDescriptor.m_PoolHeight,
680 pooling2dDescriptor.m_StrideX,
681 pooling2dDescriptor.m_StrideY,
682 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
683 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
684 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
685
686 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
687 fbPooling2dBaseLayer,
688 fbPooling2dDescriptor);
689
690 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
691}
692
Derek Lamberti87acb272019-03-27 16:51:31 +0000693void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
694{
695 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
696 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
697 fbQuantizeBaseLayer);
698 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
699}
700
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000701// Build FlatBuffer for FullyConnected Layer
702void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
703 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
704 const armnn::ConstTensor& weights,
705 const armnn::Optional<armnn::ConstTensor>& biases,
706 const char* name)
707{
708 // Create FlatBuffer BaseLayer
709 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
710
711 // Create FlatBuffer FullyConnectedDescriptor
712 auto flatBufferDescriptor =
713 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
714 fullyConnectedDescriptor.m_BiasEnabled,
715 fullyConnectedDescriptor.m_TransposeWeightMatrix);
716
717 // Create FlatBuffer weights data
718 auto flatBufferWeights = CreateConstTensorInfo(weights);
719
720 // Create FlatBuffer bias data
721 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
722 if (fullyConnectedDescriptor.m_BiasEnabled)
723 {
724 flatBufferBiases = CreateConstTensorInfo(biases.value());
725 }
726
727 // Create FlatBuffer FullyConnectedLayer
728 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
729 flatBufferBaseLayer,
730 flatBufferDescriptor,
731 flatBufferWeights,
732 flatBufferBiases);
733
734 // Add created FullyConnectedLayer to the FlatBufferLayers
735 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
736}
737
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000738// Build FlatBuffer for SpaceToBatchNd Layer
739void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
740 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
741 const char* name)
742{
743 // Create FlatBuffer BaseLayer
744 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
745
746 std::vector<unsigned int> padList;
747 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
748 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
749 {
750 padList.push_back(pad.first);
751 padList.push_back(pad.second);
752 }
753
754 auto flatBufferDescriptor =
755 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
756 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
757 m_flatBufferBuilder.CreateVector(padList),
758 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
759
760 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
761 flatBufferBaseLayer,
762 flatBufferDescriptor);
763
764 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
765}
766
Jim Flynn18ce3382019-03-08 11:08:30 +0000767// Build FlatBuffer for Splitter Layer
768void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
769 const armnn::ViewsDescriptor& viewsDescriptor,
770 const char* name)
771{
772 // Create FlatBuffer ViewOrigins
773 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
774 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
775
776 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
777 {
778 std::vector<uint32_t> viewOrigin;
779 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
780
781 // Copy vector
782 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
783 {
784 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
785 }
786
787 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
788 m_flatBufferBuilder.CreateVector(viewOrigin)));
789 }
790
791 // Create FlatBuffer OriginsDescriptor
792 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
793 viewsDescriptor.GetOrigins().GetConcatAxis(),
794 viewsDescriptor.GetOrigins().GetNumViews(),
795 viewsDescriptor.GetOrigins().GetNumDimensions(),
796 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
797
798 // Create FlatBuffer ViewOrigins
799 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
800 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
801
802 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
803 {
804 std::vector<uint32_t> viewSize;
805 viewSize.reserve(viewsDescriptor.GetNumDimensions());
806
807 // Copy vector
808 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
809 {
810 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
811 }
812
813 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
814 m_flatBufferBuilder.CreateVector(viewSize)));
815 }
816
817 // Create FlatBuffer ViewsDescriptor
818 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
819 flatBufferOriginDescriptor,
820 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
821
822 // Create FlatBuffer BaseLayer
823 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
824
825 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
826 flatBufferBaseLayer,
827 flatBufferViewsDescriptor);
828
829 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
830}
831
Nina Drozd57728782019-02-27 10:53:27 +0000832void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
833 const armnn::NormalizationDescriptor& descriptor,
834 const char* name)
835{
836 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
837
838 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
839 m_flatBufferBuilder,
840 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
841 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
842 descriptor.m_NormSize,
843 descriptor.m_Alpha,
844 descriptor.m_Beta,
845 descriptor.m_K,
846 GetFlatBufferDataLayout(descriptor.m_DataLayout));
847
848 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
849 fbNormalizationBaseLayer,
850 fbNormalizationDescriptor);
851
852 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
853}
854
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000855void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
856 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
857 const char* name)
858{
859 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
860
861 auto flatBufferDescriptor =
862 CreateStridedSliceDescriptor(m_flatBufferBuilder,
863 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
864 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
865 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
866 stridedSliceDescriptor.m_BeginMask,
867 stridedSliceDescriptor.m_EndMask,
868 stridedSliceDescriptor.m_ShrinkAxisMask,
869 stridedSliceDescriptor.m_EllipsisMask,
870 stridedSliceDescriptor.m_NewAxisMask,
871 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
872
873 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
874 flatBufferBaseLayer,
875 flatBufferDescriptor);
876
877 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
878}
879
Conor Kennedyda1f9752019-03-01 14:37:12 +0000880void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
881{
882 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
883 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
884
885 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
886}
887
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000888fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000889 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000890{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000891 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
892
Mike Kelly8c1701a2019-02-11 17:01:27 +0000893 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
894 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
895
896 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000897 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000898 m_flatBufferBuilder.CreateString(layer->GetName()),
899 layerType,
900 m_flatBufferBuilder.CreateVector(inputSlots),
901 m_flatBufferBuilder.CreateVector(outputSlots));
902}
903
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000904void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000905{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000906 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000907 m_serializedLayers.push_back(anyLayer);
908}
909
Mike Kellya0766c32019-02-19 17:22:07 +0000910template <typename T>
911flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
912{
913 const T* buffer = reinterpret_cast<const T*>(memory);
914 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
915 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
916 return fbVector;
917}
918
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000919flatbuffers::Offset<serializer::ConstTensor>
920 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000921{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000922 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000923
924 // Get the dimensions
925 std::vector<unsigned int> shape;
926
927 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
928 {
929 shape.push_back(tensorInfo.GetShape()[dim]);
930 }
931
932 // Create FlatBuffer TensorInfo
933 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
934 m_flatBufferBuilder.CreateVector(shape),
935 GetFlatBufferDataType(tensorInfo.GetDataType()),
936 tensorInfo.GetQuantizationScale(),
937 tensorInfo.GetQuantizationOffset());
938 flatbuffers::Offset<void> fbPayload;
939
940 switch (tensorInfo.GetDataType())
941 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000942 case armnn::DataType::Float32:
943 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000944 {
945 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
946 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
947 m_flatBufferBuilder,
948 fbVector);
949 fbPayload = flatBuffersData.o;
950 break;
951 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000952 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000953 {
954 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
955 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
956 m_flatBufferBuilder,
957 fbVector);
958 fbPayload = flatBuffersData.o;
959 break;
960 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +0000961 case armnn::DataType::QuantisedSymm16:
962 {
963 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
964 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
965 m_flatBufferBuilder,
966 fbVector);
967 fbPayload = flatBuffersData.o;
968 break;
969 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000970 case armnn::DataType::QuantisedAsymm8:
971 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +0000972 default:
973 {
974 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
975 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
976 m_flatBufferBuilder,
977 fbVector);
978 fbPayload = flatBuffersData.o;
979 }
980 }
981 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
982 m_flatBufferBuilder,
983 flatBufferTensorInfo,
984 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
985 fbPayload);
986 return flatBufferConstTensor;
987}
988
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000989std::vector<fb::Offset<serializer::InputSlot>>
990 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000991{
Mike Kellya0766c32019-02-19 17:22:07 +0000992 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +0000993
994 // Get the InputSlots
995 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
996 {
997 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
998
999 // Get the Connection for the InputSlot
1000 const IOutputSlot* connection = inputSlot.GetConnection();
1001
1002 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001003 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1004 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001005 // Create FlatBuffer InputSlot
1006 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1007 }
1008 return inputSlots;
1009}
1010
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001011std::vector<fb::Offset<serializer::OutputSlot>>
1012 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001013{
1014 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1015
1016 // Get the OutputSlots
1017 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1018 {
1019 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001020 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001021
1022 // Get the dimensions
1023 std::vector<unsigned int> shape;
1024 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1025 {
1026 shape.push_back(tensorInfo.GetShape()[dim]);
1027 }
1028
1029 // Create FlatBuffer TensorInfo
1030 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1031 m_flatBufferBuilder.CreateVector(shape),
1032 GetFlatBufferDataType(tensorInfo.GetDataType()),
1033 tensorInfo.GetQuantizationScale(),
1034 tensorInfo.GetQuantizationOffset());
1035
1036 // Create FlatBuffer Outputslot
1037 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1038 slotIndex,
1039 flatBufferTensorInfo));
1040 }
1041 return outputSlots;
1042}
1043
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001044
1045ISerializer* ISerializer::CreateRaw()
1046{
1047 return new Serializer();
1048}
1049
1050ISerializerPtr ISerializer::Create()
1051{
1052 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1053}
1054
1055void ISerializer::Destroy(ISerializer* serializer)
1056{
1057 delete serializer;
1058}
1059
1060void Serializer::Serialize(const INetwork& inNetwork)
1061{
1062 // Iterate through to network
1063 inNetwork.Accept(m_SerializerVisitor);
1064 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1065
1066 // Create FlatBuffer SerializedGraph
1067 auto serializedGraph = serializer::CreateSerializedGraph(
1068 fbBuilder,
1069 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1070 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1071 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1072
1073 // Serialize the graph
1074 fbBuilder.Finish(serializedGraph);
1075}
1076
1077bool Serializer::SaveSerializedToStream(std::ostream& stream)
1078{
1079 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1080
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001081 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1082 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001083 return !stream.bad();
1084}
1085
Matteo Martincighec333912019-02-13 15:12:39 +00001086} // namespace armnnSerializer