blob: 2fd840258e3f4205b47d15a898845ca49e920892 [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 Chaimanowong3e14a9d2019-03-18 12:37:06 +0000292void SerializerVisitor::VisitDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
293 const armnn::DetectionPostProcessDescriptor& descriptor,
294 const armnn::ConstTensor& anchors,
295 const char* name)
296{
297 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
298 auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
299 descriptor.m_MaxDetections,
300 descriptor.m_MaxClassesPerDetection,
301 descriptor.m_DetectionsPerClass,
302 descriptor.m_NmsScoreThreshold,
303 descriptor.m_NmsIouThreshold,
304 descriptor.m_NumClasses,
305 descriptor.m_UseRegularNms,
306 descriptor.m_ScaleX,
307 descriptor.m_ScaleY,
308 descriptor.m_ScaleW,
309 descriptor.m_ScaleH);
310
311 flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);
312
313 auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
314 fbBaseLayer,
315 fbDescriptor,
316 fbAnchorsConstTensorInfo);
317
318 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
319}
320
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000321void SerializerVisitor::VisitDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
322{
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000323 auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
324 auto fbDivisionLayer = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000325
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000326 CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
327}
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000328
Aron Virginas-Tar377351e2019-02-27 14:42:31 +0000329void SerializerVisitor::VisitEqualLayer(const armnn::IConnectableLayer* layer, const char* name)
330{
331 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Equal);
332 auto fbEqualLayer = serializer::CreateEqualLayer(m_flatBufferBuilder, fbBaseLayer);
333
334 CreateAnyLayer(fbEqualLayer.o, serializer::Layer::Layer_EqualLayer);
335}
336
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000337void SerializerVisitor::VisitFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
338{
339 auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
340 auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);
341
342 CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
343}
344
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000345void SerializerVisitor::VisitGatherLayer(const armnn::IConnectableLayer* layer, const char* name)
346{
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000347 auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
348 auto flatBufferLayer = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer);
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000349
350 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
351}
352
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000353void SerializerVisitor::VisitGreaterLayer(const armnn::IConnectableLayer* layer, const char* name)
354{
355 auto fbGreaterBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Greater);
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000356 auto fbGreaterLayer = serializer::CreateGreaterLayer(m_flatBufferBuilder, fbGreaterBaseLayer);
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000357
358 CreateAnyLayer(fbGreaterLayer.o, serializer::Layer::Layer_GreaterLayer);
359}
360
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000361void SerializerVisitor::VisitL2NormalizationLayer(const armnn::IConnectableLayer* layer,
362 const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
363 const char* name)
364{
365 // Create FlatBuffer BaseLayer
366 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);
367
368 // Create the FlatBuffer L2Normalization Descriptor
369 auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
370 m_flatBufferBuilder, GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout));
371
372 // Create Flatuffer layer
373 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
374
375 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
376}
377
Jim Flynn11af3752019-03-19 17:22:29 +0000378void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer, const armnn::LstmDescriptor& descriptor,
379 const armnn::LstmInputParams& params, const char* name)
380{
381 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
382
383 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
384 m_flatBufferBuilder,
385 descriptor.m_ActivationFunc,
386 descriptor.m_ClippingThresCell,
387 descriptor.m_ClippingThresProj,
388 descriptor.m_CifgEnabled,
389 descriptor.m_PeepholeEnabled,
390 descriptor.m_ProjectionEnabled);
391
392 // Get mandatory input parameters
393 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
394 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
395 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
396 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
397 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
398 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
399 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
400 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
401 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
402
403 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
404 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
405 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
406 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
407 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
408 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
409 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
410 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
411 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
412
413 if (!descriptor.m_CifgEnabled)
414 {
415 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
416 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
417 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
418 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
419 }
420
421 if (descriptor.m_ProjectionEnabled)
422 {
423 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
424 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
425 }
426
427 if (descriptor.m_PeepholeEnabled)
428 {
429 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
430 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
431 }
432
433 auto fbLstmParams = serializer::CreateLstmInputParams(
434 m_flatBufferBuilder,
435 inputToForgetWeights,
436 inputToCellWeights,
437 inputToOutputWeights,
438 recurrentToForgetWeights,
439 recurrentToCellWeights,
440 recurrentToOutputWeights,
441 forgetGateBias,
442 cellBias,
443 outputGateBias,
444 inputToInputWeights,
445 recurrentToInputWeights,
446 cellToInputWeights,
447 inputGateBias,
448 projectionWeights,
449 projectionBias,
450 cellToForgetWeights,
451 cellToOutputWeights);
452
453 auto fbLstmLayer = serializer::CreateLstmLayer(
454 m_flatBufferBuilder,
455 fbLstmBaseLayer,
456 fbLstmDescriptor,
457 fbLstmParams);
458
459 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
460}
461
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000462void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
463{
464 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
465 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
466
467 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
468}
469
470void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
471 const armnn::MeanDescriptor& descriptor,
472 const char* name)
473{
474 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
475 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
476 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
477 descriptor.m_KeepDims);
478
479 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
480 fbMeanBaseLayer,
481 fbMeanDescriptor);
482
483 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
484}
485
486void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
487{
488 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
489 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
490
491 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
492}
493
Jim Flynnac25a1b2019-02-28 10:40:49 +0000494void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
495 const armnn::OriginsDescriptor& mergerDescriptor,
496 const char* name)
497{
498 auto flatBufferMergerBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merger);
499
500 std::vector<flatbuffers::Offset<UintVector>> views;
501 for (unsigned int v = 0; v < mergerDescriptor.GetNumViews(); ++v)
502 {
503 const uint32_t* origin = mergerDescriptor.GetViewOrigin(v);
504 std::vector<uint32_t> origins;
505 for (unsigned int d = 0; d < mergerDescriptor.GetNumDimensions(); ++d)
506 {
507 origins.push_back(origin[d]);
508 }
509 auto view = m_flatBufferBuilder.CreateVector(origins);
510 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
511 views.push_back(uintVector);
512 }
513
514 auto flatBufferMergerDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
515 mergerDescriptor.GetConcatAxis(),
516 mergerDescriptor.GetNumViews(),
517 mergerDescriptor.GetNumDimensions(),
518 m_flatBufferBuilder.CreateVector(views));
519
520 auto flatBufferLayer = CreateMergerLayer(m_flatBufferBuilder,
521 flatBufferMergerBaseLayer,
522 flatBufferMergerDescriptor);
523
524 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_MergerLayer);
525}
526
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000527void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000528{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000529 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
530 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
531 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000532
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000533 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000534}
535
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000536void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
537 const armnn::PadDescriptor& padDescriptor,
538 const char* name)
539{
540 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
541
542 std::vector<unsigned int> padList;
543 for (auto& p: padDescriptor.m_PadList)
544 {
545 padList.push_back(p.first);
546 padList.push_back(p.second);
547 }
548
549 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
550 m_flatBufferBuilder.CreateVector(padList));
551
552 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
553 flatBufferBaseLayer,
554 flatBufferPadDesc);
555
556 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
557}
558
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000559void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
560 const armnn::PermuteDescriptor& permuteDescriptor,
561 const char* name)
562{
563 // Create FlatBuffer BaseLayer
564 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
565
566 std::vector<unsigned int> dimMappings;
567 for (auto& v: permuteDescriptor.m_DimMappings)
568 {
569 dimMappings.push_back(v);
570 }
571
572 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
573 m_flatBufferBuilder.CreateVector(dimMappings));
574
575 // Create the FlatBuffer PermuteLayer
576 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
577 flatBufferPermuteBaseLayer,
578 flatBufferPermuteDesc);
579
580 // Add the AnyLayer to the FlatBufferLayers
581 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
582}
583
Saoirse Stewart263829c2019-02-19 15:54:14 +0000584// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000585void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000586 const armnn::ReshapeDescriptor& reshapeDescriptor,
587 const char* name)
588{
589 // Create FlatBuffer BaseLayer
590 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
591
592 std::vector<unsigned int> targetShape;
593 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
594 {
595 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
596 }
597
598 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
599 m_flatBufferBuilder.CreateVector(targetShape));
600
601 // Create the FlatBuffer ReshapeLayer
602 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
603 flatBufferReshapeDesc);
604
605 // Add the AnyLayer to the FlatBufferLayers
606 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
607}
608
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000609void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
610 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
611 const char* name)
612{
613 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
614
615 auto flatBufferDescriptor =
616 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
617 resizeDescriptor.m_TargetWidth,
618 resizeDescriptor.m_TargetHeight,
619 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
620
621 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
622 flatBufferBaseLayer,
623 flatBufferDescriptor);
624
625 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
626}
627
Sadik Armagan8b42a382019-03-01 14:24:49 +0000628void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
629{
630 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
631 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
632
633 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
634}
635
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000636// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000637void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
638 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000639 const char* name)
640{
641 // Create FlatBuffer BaseLayer
642 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
643
644 // Create the FlatBuffer SoftmaxDescriptor
645 auto flatBufferSoftmaxDesc =
646 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
647
648 // Create the FlatBuffer SoftmaxLayer
649 auto flatBufferSoftmaxLayer =
650 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
651 flatBufferSoftmaxBaseLayer,
652 flatBufferSoftmaxDesc);
653
654 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
655}
656
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000657void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
658 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000659 const char* name)
660{
661 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
662 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
663 m_flatBufferBuilder,
664 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
665 pooling2dDescriptor.m_PadLeft,
666 pooling2dDescriptor.m_PadRight,
667 pooling2dDescriptor.m_PadTop,
668 pooling2dDescriptor.m_PadBottom,
669 pooling2dDescriptor.m_PoolWidth,
670 pooling2dDescriptor.m_PoolHeight,
671 pooling2dDescriptor.m_StrideX,
672 pooling2dDescriptor.m_StrideY,
673 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
674 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
675 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
676
677 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
678 fbPooling2dBaseLayer,
679 fbPooling2dDescriptor);
680
681 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
682}
683
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000684// Build FlatBuffer for FullyConnected Layer
685void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
686 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
687 const armnn::ConstTensor& weights,
688 const armnn::Optional<armnn::ConstTensor>& biases,
689 const char* name)
690{
691 // Create FlatBuffer BaseLayer
692 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
693
694 // Create FlatBuffer FullyConnectedDescriptor
695 auto flatBufferDescriptor =
696 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
697 fullyConnectedDescriptor.m_BiasEnabled,
698 fullyConnectedDescriptor.m_TransposeWeightMatrix);
699
700 // Create FlatBuffer weights data
701 auto flatBufferWeights = CreateConstTensorInfo(weights);
702
703 // Create FlatBuffer bias data
704 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
705 if (fullyConnectedDescriptor.m_BiasEnabled)
706 {
707 flatBufferBiases = CreateConstTensorInfo(biases.value());
708 }
709
710 // Create FlatBuffer FullyConnectedLayer
711 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
712 flatBufferBaseLayer,
713 flatBufferDescriptor,
714 flatBufferWeights,
715 flatBufferBiases);
716
717 // Add created FullyConnectedLayer to the FlatBufferLayers
718 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
719}
720
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000721// Build FlatBuffer for SpaceToBatchNd Layer
722void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
723 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
724 const char* name)
725{
726 // Create FlatBuffer BaseLayer
727 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
728
729 std::vector<unsigned int> padList;
730 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
731 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
732 {
733 padList.push_back(pad.first);
734 padList.push_back(pad.second);
735 }
736
737 auto flatBufferDescriptor =
738 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
739 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
740 m_flatBufferBuilder.CreateVector(padList),
741 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
742
743 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
744 flatBufferBaseLayer,
745 flatBufferDescriptor);
746
747 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
748}
749
Jim Flynn18ce3382019-03-08 11:08:30 +0000750// Build FlatBuffer for Splitter Layer
751void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
752 const armnn::ViewsDescriptor& viewsDescriptor,
753 const char* name)
754{
755 // Create FlatBuffer ViewOrigins
756 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
757 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
758
759 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
760 {
761 std::vector<uint32_t> viewOrigin;
762 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
763
764 // Copy vector
765 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
766 {
767 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
768 }
769
770 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
771 m_flatBufferBuilder.CreateVector(viewOrigin)));
772 }
773
774 // Create FlatBuffer OriginsDescriptor
775 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
776 viewsDescriptor.GetOrigins().GetConcatAxis(),
777 viewsDescriptor.GetOrigins().GetNumViews(),
778 viewsDescriptor.GetOrigins().GetNumDimensions(),
779 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
780
781 // Create FlatBuffer ViewOrigins
782 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
783 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
784
785 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
786 {
787 std::vector<uint32_t> viewSize;
788 viewSize.reserve(viewsDescriptor.GetNumDimensions());
789
790 // Copy vector
791 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
792 {
793 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
794 }
795
796 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
797 m_flatBufferBuilder.CreateVector(viewSize)));
798 }
799
800 // Create FlatBuffer ViewsDescriptor
801 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
802 flatBufferOriginDescriptor,
803 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
804
805 // Create FlatBuffer BaseLayer
806 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
807
808 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
809 flatBufferBaseLayer,
810 flatBufferViewsDescriptor);
811
812 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
813}
814
Nina Drozd57728782019-02-27 10:53:27 +0000815void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
816 const armnn::NormalizationDescriptor& descriptor,
817 const char* name)
818{
819 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
820
821 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
822 m_flatBufferBuilder,
823 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
824 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
825 descriptor.m_NormSize,
826 descriptor.m_Alpha,
827 descriptor.m_Beta,
828 descriptor.m_K,
829 GetFlatBufferDataLayout(descriptor.m_DataLayout));
830
831 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
832 fbNormalizationBaseLayer,
833 fbNormalizationDescriptor);
834
835 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
836}
837
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000838void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
839 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
840 const char* name)
841{
842 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
843
844 auto flatBufferDescriptor =
845 CreateStridedSliceDescriptor(m_flatBufferBuilder,
846 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
847 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
848 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
849 stridedSliceDescriptor.m_BeginMask,
850 stridedSliceDescriptor.m_EndMask,
851 stridedSliceDescriptor.m_ShrinkAxisMask,
852 stridedSliceDescriptor.m_EllipsisMask,
853 stridedSliceDescriptor.m_NewAxisMask,
854 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
855
856 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
857 flatBufferBaseLayer,
858 flatBufferDescriptor);
859
860 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
861}
862
Conor Kennedyda1f9752019-03-01 14:37:12 +0000863void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
864{
865 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
866 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
867
868 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
869}
870
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000871fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000872 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000873{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000874 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
875
Mike Kelly8c1701a2019-02-11 17:01:27 +0000876 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
877 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
878
879 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000880 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000881 m_flatBufferBuilder.CreateString(layer->GetName()),
882 layerType,
883 m_flatBufferBuilder.CreateVector(inputSlots),
884 m_flatBufferBuilder.CreateVector(outputSlots));
885}
886
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000887void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000888{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000889 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000890 m_serializedLayers.push_back(anyLayer);
891}
892
Mike Kellya0766c32019-02-19 17:22:07 +0000893template <typename T>
894flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
895{
896 const T* buffer = reinterpret_cast<const T*>(memory);
897 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
898 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
899 return fbVector;
900}
901
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000902flatbuffers::Offset<serializer::ConstTensor>
903 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000904{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000905 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000906
907 // Get the dimensions
908 std::vector<unsigned int> shape;
909
910 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
911 {
912 shape.push_back(tensorInfo.GetShape()[dim]);
913 }
914
915 // Create FlatBuffer TensorInfo
916 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
917 m_flatBufferBuilder.CreateVector(shape),
918 GetFlatBufferDataType(tensorInfo.GetDataType()),
919 tensorInfo.GetQuantizationScale(),
920 tensorInfo.GetQuantizationOffset());
921 flatbuffers::Offset<void> fbPayload;
922
923 switch (tensorInfo.GetDataType())
924 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000925 case armnn::DataType::Float32:
926 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000927 {
928 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
929 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
930 m_flatBufferBuilder,
931 fbVector);
932 fbPayload = flatBuffersData.o;
933 break;
934 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000935 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000936 {
937 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
938 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
939 m_flatBufferBuilder,
940 fbVector);
941 fbPayload = flatBuffersData.o;
942 break;
943 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +0000944 case armnn::DataType::QuantisedSymm16:
945 {
946 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
947 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
948 m_flatBufferBuilder,
949 fbVector);
950 fbPayload = flatBuffersData.o;
951 break;
952 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000953 case armnn::DataType::QuantisedAsymm8:
954 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +0000955 default:
956 {
957 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
958 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
959 m_flatBufferBuilder,
960 fbVector);
961 fbPayload = flatBuffersData.o;
962 }
963 }
964 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
965 m_flatBufferBuilder,
966 flatBufferTensorInfo,
967 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
968 fbPayload);
969 return flatBufferConstTensor;
970}
971
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000972std::vector<fb::Offset<serializer::InputSlot>>
973 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000974{
Mike Kellya0766c32019-02-19 17:22:07 +0000975 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +0000976
977 // Get the InputSlots
978 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
979 {
980 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
981
982 // Get the Connection for the InputSlot
983 const IOutputSlot* connection = inputSlot.GetConnection();
984
985 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000986 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
987 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +0000988 // Create FlatBuffer InputSlot
989 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
990 }
991 return inputSlots;
992}
993
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000994std::vector<fb::Offset<serializer::OutputSlot>>
995 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000996{
997 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
998
999 // Get the OutputSlots
1000 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1001 {
1002 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001003 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001004
1005 // Get the dimensions
1006 std::vector<unsigned int> shape;
1007 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1008 {
1009 shape.push_back(tensorInfo.GetShape()[dim]);
1010 }
1011
1012 // Create FlatBuffer TensorInfo
1013 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1014 m_flatBufferBuilder.CreateVector(shape),
1015 GetFlatBufferDataType(tensorInfo.GetDataType()),
1016 tensorInfo.GetQuantizationScale(),
1017 tensorInfo.GetQuantizationOffset());
1018
1019 // Create FlatBuffer Outputslot
1020 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1021 slotIndex,
1022 flatBufferTensorInfo));
1023 }
1024 return outputSlots;
1025}
1026
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001027
1028ISerializer* ISerializer::CreateRaw()
1029{
1030 return new Serializer();
1031}
1032
1033ISerializerPtr ISerializer::Create()
1034{
1035 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1036}
1037
1038void ISerializer::Destroy(ISerializer* serializer)
1039{
1040 delete serializer;
1041}
1042
1043void Serializer::Serialize(const INetwork& inNetwork)
1044{
1045 // Iterate through to network
1046 inNetwork.Accept(m_SerializerVisitor);
1047 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1048
1049 // Create FlatBuffer SerializedGraph
1050 auto serializedGraph = serializer::CreateSerializedGraph(
1051 fbBuilder,
1052 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1053 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1054 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1055
1056 // Serialize the graph
1057 fbBuilder.Finish(serializedGraph);
1058}
1059
1060bool Serializer::SaveSerializedToStream(std::ostream& stream)
1061{
1062 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1063
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001064 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1065 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001066 return !stream.bad();
1067}
1068
Matteo Martincighec333912019-02-13 15:12:39 +00001069} // namespace armnnSerializer