blob: 83777c9849e8f5590bb14514ce6fd3e18f0947c5 [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
Derek Lamberti87acb272019-03-27 16:51:31 +0000684void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
685{
686 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
687 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
688 fbQuantizeBaseLayer);
689 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
690}
691
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000692// Build FlatBuffer for FullyConnected Layer
693void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
694 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
695 const armnn::ConstTensor& weights,
696 const armnn::Optional<armnn::ConstTensor>& biases,
697 const char* name)
698{
699 // Create FlatBuffer BaseLayer
700 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
701
702 // Create FlatBuffer FullyConnectedDescriptor
703 auto flatBufferDescriptor =
704 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
705 fullyConnectedDescriptor.m_BiasEnabled,
706 fullyConnectedDescriptor.m_TransposeWeightMatrix);
707
708 // Create FlatBuffer weights data
709 auto flatBufferWeights = CreateConstTensorInfo(weights);
710
711 // Create FlatBuffer bias data
712 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
713 if (fullyConnectedDescriptor.m_BiasEnabled)
714 {
715 flatBufferBiases = CreateConstTensorInfo(biases.value());
716 }
717
718 // Create FlatBuffer FullyConnectedLayer
719 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
720 flatBufferBaseLayer,
721 flatBufferDescriptor,
722 flatBufferWeights,
723 flatBufferBiases);
724
725 // Add created FullyConnectedLayer to the FlatBufferLayers
726 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
727}
728
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000729// Build FlatBuffer for SpaceToBatchNd Layer
730void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
731 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
732 const char* name)
733{
734 // Create FlatBuffer BaseLayer
735 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
736
737 std::vector<unsigned int> padList;
738 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
739 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
740 {
741 padList.push_back(pad.first);
742 padList.push_back(pad.second);
743 }
744
745 auto flatBufferDescriptor =
746 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
747 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
748 m_flatBufferBuilder.CreateVector(padList),
749 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
750
751 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
752 flatBufferBaseLayer,
753 flatBufferDescriptor);
754
755 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
756}
757
Jim Flynn18ce3382019-03-08 11:08:30 +0000758// Build FlatBuffer for Splitter Layer
759void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
760 const armnn::ViewsDescriptor& viewsDescriptor,
761 const char* name)
762{
763 // Create FlatBuffer ViewOrigins
764 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
765 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
766
767 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
768 {
769 std::vector<uint32_t> viewOrigin;
770 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
771
772 // Copy vector
773 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
774 {
775 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
776 }
777
778 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
779 m_flatBufferBuilder.CreateVector(viewOrigin)));
780 }
781
782 // Create FlatBuffer OriginsDescriptor
783 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
784 viewsDescriptor.GetOrigins().GetConcatAxis(),
785 viewsDescriptor.GetOrigins().GetNumViews(),
786 viewsDescriptor.GetOrigins().GetNumDimensions(),
787 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
788
789 // Create FlatBuffer ViewOrigins
790 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
791 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
792
793 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
794 {
795 std::vector<uint32_t> viewSize;
796 viewSize.reserve(viewsDescriptor.GetNumDimensions());
797
798 // Copy vector
799 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
800 {
801 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
802 }
803
804 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
805 m_flatBufferBuilder.CreateVector(viewSize)));
806 }
807
808 // Create FlatBuffer ViewsDescriptor
809 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
810 flatBufferOriginDescriptor,
811 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
812
813 // Create FlatBuffer BaseLayer
814 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
815
816 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
817 flatBufferBaseLayer,
818 flatBufferViewsDescriptor);
819
820 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
821}
822
Nina Drozd57728782019-02-27 10:53:27 +0000823void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
824 const armnn::NormalizationDescriptor& descriptor,
825 const char* name)
826{
827 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
828
829 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
830 m_flatBufferBuilder,
831 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
832 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
833 descriptor.m_NormSize,
834 descriptor.m_Alpha,
835 descriptor.m_Beta,
836 descriptor.m_K,
837 GetFlatBufferDataLayout(descriptor.m_DataLayout));
838
839 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
840 fbNormalizationBaseLayer,
841 fbNormalizationDescriptor);
842
843 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
844}
845
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000846void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
847 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
848 const char* name)
849{
850 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
851
852 auto flatBufferDescriptor =
853 CreateStridedSliceDescriptor(m_flatBufferBuilder,
854 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
855 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
856 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
857 stridedSliceDescriptor.m_BeginMask,
858 stridedSliceDescriptor.m_EndMask,
859 stridedSliceDescriptor.m_ShrinkAxisMask,
860 stridedSliceDescriptor.m_EllipsisMask,
861 stridedSliceDescriptor.m_NewAxisMask,
862 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
863
864 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
865 flatBufferBaseLayer,
866 flatBufferDescriptor);
867
868 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
869}
870
Conor Kennedyda1f9752019-03-01 14:37:12 +0000871void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
872{
873 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
874 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
875
876 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
877}
878
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000879fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000880 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000881{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000882 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
883
Mike Kelly8c1701a2019-02-11 17:01:27 +0000884 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
885 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
886
887 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000888 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000889 m_flatBufferBuilder.CreateString(layer->GetName()),
890 layerType,
891 m_flatBufferBuilder.CreateVector(inputSlots),
892 m_flatBufferBuilder.CreateVector(outputSlots));
893}
894
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000895void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000896{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000897 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000898 m_serializedLayers.push_back(anyLayer);
899}
900
Mike Kellya0766c32019-02-19 17:22:07 +0000901template <typename T>
902flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
903{
904 const T* buffer = reinterpret_cast<const T*>(memory);
905 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
906 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
907 return fbVector;
908}
909
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000910flatbuffers::Offset<serializer::ConstTensor>
911 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000912{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000913 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000914
915 // Get the dimensions
916 std::vector<unsigned int> shape;
917
918 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
919 {
920 shape.push_back(tensorInfo.GetShape()[dim]);
921 }
922
923 // Create FlatBuffer TensorInfo
924 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
925 m_flatBufferBuilder.CreateVector(shape),
926 GetFlatBufferDataType(tensorInfo.GetDataType()),
927 tensorInfo.GetQuantizationScale(),
928 tensorInfo.GetQuantizationOffset());
929 flatbuffers::Offset<void> fbPayload;
930
931 switch (tensorInfo.GetDataType())
932 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000933 case armnn::DataType::Float32:
934 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000935 {
936 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
937 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
938 m_flatBufferBuilder,
939 fbVector);
940 fbPayload = flatBuffersData.o;
941 break;
942 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000943 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000944 {
945 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
946 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
947 m_flatBufferBuilder,
948 fbVector);
949 fbPayload = flatBuffersData.o;
950 break;
951 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +0000952 case armnn::DataType::QuantisedSymm16:
953 {
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 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000961 case armnn::DataType::QuantisedAsymm8:
962 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +0000963 default:
964 {
965 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
966 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
967 m_flatBufferBuilder,
968 fbVector);
969 fbPayload = flatBuffersData.o;
970 }
971 }
972 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
973 m_flatBufferBuilder,
974 flatBufferTensorInfo,
975 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
976 fbPayload);
977 return flatBufferConstTensor;
978}
979
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000980std::vector<fb::Offset<serializer::InputSlot>>
981 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000982{
Mike Kellya0766c32019-02-19 17:22:07 +0000983 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +0000984
985 // Get the InputSlots
986 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
987 {
988 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
989
990 // Get the Connection for the InputSlot
991 const IOutputSlot* connection = inputSlot.GetConnection();
992
993 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000994 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
995 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +0000996 // Create FlatBuffer InputSlot
997 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
998 }
999 return inputSlots;
1000}
1001
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001002std::vector<fb::Offset<serializer::OutputSlot>>
1003 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001004{
1005 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1006
1007 // Get the OutputSlots
1008 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1009 {
1010 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001011 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001012
1013 // Get the dimensions
1014 std::vector<unsigned int> shape;
1015 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1016 {
1017 shape.push_back(tensorInfo.GetShape()[dim]);
1018 }
1019
1020 // Create FlatBuffer TensorInfo
1021 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1022 m_flatBufferBuilder.CreateVector(shape),
1023 GetFlatBufferDataType(tensorInfo.GetDataType()),
1024 tensorInfo.GetQuantizationScale(),
1025 tensorInfo.GetQuantizationOffset());
1026
1027 // Create FlatBuffer Outputslot
1028 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1029 slotIndex,
1030 flatBufferTensorInfo));
1031 }
1032 return outputSlots;
1033}
1034
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001035
1036ISerializer* ISerializer::CreateRaw()
1037{
1038 return new Serializer();
1039}
1040
1041ISerializerPtr ISerializer::Create()
1042{
1043 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1044}
1045
1046void ISerializer::Destroy(ISerializer* serializer)
1047{
1048 delete serializer;
1049}
1050
1051void Serializer::Serialize(const INetwork& inNetwork)
1052{
1053 // Iterate through to network
1054 inNetwork.Accept(m_SerializerVisitor);
1055 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1056
1057 // Create FlatBuffer SerializedGraph
1058 auto serializedGraph = serializer::CreateSerializedGraph(
1059 fbBuilder,
1060 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1061 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1062 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1063
1064 // Serialize the graph
1065 fbBuilder.Finish(serializedGraph);
1066}
1067
1068bool Serializer::SaveSerializedToStream(std::ostream& stream)
1069{
1070 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1071
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001072 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1073 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001074 return !stream.bad();
1075}
1076
Matteo Martincighec333912019-02-13 15:12:39 +00001077} // namespace armnnSerializer