blob: 0b8ad06d18a888f853af8c253c0d55044695baab [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
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010016#include <boost/numeric/conversion/cast.hpp>
17
Mike Kelly8c1701a2019-02-11 17:01:27 +000018#include <flatbuffers/util.h>
19
20using namespace armnn;
21namespace fb = flatbuffers;
Derek Lamberti0028d1b2019-02-20 13:57:42 +000022namespace serializer = armnnSerializer;
Mike Kelly8c1701a2019-02-11 17:01:27 +000023
24namespace armnnSerializer
25{
26
Mike Kellyaf484012019-02-20 16:53:11 +000027serializer::ActivationFunction GetFlatBufferActivationFunction(armnn::ActivationFunction function)
28{
29 switch (function)
30 {
31 case armnn::ActivationFunction::Sigmoid:
32 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
33 case armnn::ActivationFunction::TanH:
34 return serializer::ActivationFunction::ActivationFunction_TanH;
35 case armnn::ActivationFunction::Linear:
36 return serializer::ActivationFunction::ActivationFunction_Linear;
37 case armnn::ActivationFunction::ReLu:
38 return serializer::ActivationFunction::ActivationFunction_ReLu;
39 case armnn::ActivationFunction::BoundedReLu:
40 return serializer::ActivationFunction::ActivationFunction_BoundedReLu;
41 case armnn::ActivationFunction::LeakyReLu:
42 return serializer::ActivationFunction::ActivationFunction_LeakyReLu;
43 case armnn::ActivationFunction::Abs:
44 return serializer::ActivationFunction::ActivationFunction_Abs;
45 case armnn::ActivationFunction::Sqrt:
46 return serializer::ActivationFunction::ActivationFunction_Sqrt;
47 case armnn::ActivationFunction::Square:
48 return serializer::ActivationFunction::ActivationFunction_Square;
49 default:
50 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
51 }
52}
53
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000054uint32_t SerializerVisitor::GetSerializedId(unsigned int guid)
55{
56 std::pair<unsigned int, uint32_t> guidPair(guid, m_layerId);
57
58 if (m_guidMap.empty())
59 {
60 m_guidMap.insert(guidPair);
61 }
62 else if (m_guidMap.find(guid) == m_guidMap.end())
63 {
64 guidPair.second = ++m_layerId;
65 m_guidMap.insert(guidPair);
66 return m_layerId;
67 }
Saoirse Stewart30211042019-02-18 17:19:16 +000068 return m_guidMap[guid];
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000069}
70
Mike Kelly8c1701a2019-02-11 17:01:27 +000071// Build FlatBuffer for Input Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +000072void SerializerVisitor::VisitInputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000073{
74 // Create FlatBuffer BaseLayer
75 auto flatBufferInputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Input);
76
77 // Create FlatBuffer BindableBaseLayer
78 auto flatBufferInputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
79 flatBufferInputBaseLayer,
80 id);
Mike Kelly8c1701a2019-02-11 17:01:27 +000081 // Push layer Guid to outputIds.
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000082 m_inputIds.push_back(GetSerializedId(layer->GetGuid()));
Mike Kelly8c1701a2019-02-11 17:01:27 +000083
84 // Create the FlatBuffer InputLayer
85 auto flatBufferInputLayer = serializer::CreateInputLayer(m_flatBufferBuilder, flatBufferInputBindableBaseLayer);
86
87 // Add the AnyLayer to the FlatBufferLayers
88 CreateAnyLayer(flatBufferInputLayer.o, serializer::Layer::Layer_InputLayer);
89}
90
91// Build FlatBuffer for Output Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +000092void SerializerVisitor::VisitOutputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000093{
94 // Create FlatBuffer BaseLayer
95 auto flatBufferOutputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Output);
96
97 // Create FlatBuffer BindableBaseLayer
98 auto flatBufferOutputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
99 flatBufferOutputBaseLayer,
100 id);
101 // Push layer Guid to outputIds.
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000102 m_outputIds.push_back(GetSerializedId(layer->GetGuid()));
Mike Kelly8c1701a2019-02-11 17:01:27 +0000103
104 // Create the FlatBuffer OutputLayer
105 auto flatBufferOutputLayer = serializer::CreateOutputLayer(m_flatBufferBuilder, flatBufferOutputBindableBaseLayer);
106 // Add the AnyLayer to the FlatBufferLayers
107 CreateAnyLayer(flatBufferOutputLayer.o, serializer::Layer::Layer_OutputLayer);
108}
109
Mike Kellyaf484012019-02-20 16:53:11 +0000110// Build FlatBuffer for Activation Layer
111void SerializerVisitor::VisitActivationLayer(const armnn::IConnectableLayer* layer,
112 const armnn::ActivationDescriptor& descriptor,
113 const char* name)
114{
115 // Create FlatBuffer BaseLayer
116 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Activation);
117
118 // Create the FlatBuffer ActivationDescriptor
119 auto flatBufferDescriptor = CreateActivationDescriptor(m_flatBufferBuilder,
120 GetFlatBufferActivationFunction(descriptor.m_Function),
121 descriptor.m_A,
122 descriptor.m_B);
123
124 // Create the FlatBuffer ActivationLayer
125 auto flatBufferAdditionLayer = CreateActivationLayer(m_flatBufferBuilder,
126 flatBufferBaseLayer,
127 flatBufferDescriptor);
128
129 // Add the AnyLayer to the FlatBufferLayers
130 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_ActivationLayer);
131}
132
Mike Kelly8c1701a2019-02-11 17:01:27 +0000133// Build FlatBuffer for Addition Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000134void SerializerVisitor::VisitAdditionLayer(const armnn::IConnectableLayer* layer, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000135{
136 // Create FlatBuffer BaseLayer
137 auto flatBufferAdditionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Addition);
138
139 // Create the FlatBuffer AdditionLayer
140 auto flatBufferAdditionLayer = serializer::CreateAdditionLayer(m_flatBufferBuilder, flatBufferAdditionBaseLayer);
141
142 // Add the AnyLayer to the FlatBufferLayers
143 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_AdditionLayer);
144}
145
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000146// Build FlatBuffer for BatchToSpaceNd Layer
147void SerializerVisitor::VisitBatchToSpaceNdLayer(const armnn::IConnectableLayer* layer,
148 const armnn::BatchToSpaceNdDescriptor& descriptor,
149 const char* name)
150{
151 // Create FlatBuffer BaseLayer
152 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchToSpaceNd);
153
154 std::vector<unsigned int> crops;
155 crops.reserve(descriptor.m_Crops.size() * 2);
156 for (auto& crop : descriptor.m_Crops)
157 {
158 crops.push_back(crop.first);
159 crops.push_back(crop.second);
160 }
161
162 auto flatBufferDescriptor =
163 CreateBatchToSpaceNdDescriptor(m_flatBufferBuilder,
164 m_flatBufferBuilder.CreateVector(descriptor.m_BlockShape),
165 m_flatBufferBuilder.CreateVector(crops),
166 GetFlatBufferDataLayout(descriptor.m_DataLayout));
167
168 auto flatBufferLayer = serializer::CreateBatchToSpaceNdLayer(m_flatBufferBuilder,
169 flatBufferBaseLayer,
170 flatBufferDescriptor);
171
172 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_BatchToSpaceNdLayer);
173}
174
ruoyan018e7fa232019-02-28 15:09:07 +0000175void SerializerVisitor::VisitBatchNormalizationLayer(const armnn::IConnectableLayer* layer,
176 const armnn::BatchNormalizationDescriptor& batchNormDescriptor,
177 const armnn::ConstTensor& mean,
178 const armnn::ConstTensor& variance,
179 const armnn::ConstTensor& beta,
180 const armnn::ConstTensor& gamma,
181 const char* name)
182{
183 auto fbBatchNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchNormalization);
184 auto fbBatchNormalizationDescriptor = serializer::CreateBatchNormalizationDescriptor(
185 m_flatBufferBuilder,
186 batchNormDescriptor.m_Eps,
187 GetFlatBufferDataLayout(batchNormDescriptor.m_DataLayout));
188
189 auto fbMeanConstTensorInfo = CreateConstTensorInfo(mean);
190 auto fbVarianceConstTensorInfo = CreateConstTensorInfo(variance);
191 auto fbBetaConstTensorInfo = CreateConstTensorInfo(beta);
192 auto fbGammaConstTensorInfo = CreateConstTensorInfo(gamma);
193 auto fbBatchNormalizationLayer = serializer::CreateBatchNormalizationLayer(m_flatBufferBuilder,
194 fbBatchNormalizationBaseLayer,
195 fbBatchNormalizationDescriptor,
196 fbMeanConstTensorInfo,
197 fbVarianceConstTensorInfo,
198 fbBetaConstTensorInfo,
199 fbGammaConstTensorInfo);
200
201 CreateAnyLayer(fbBatchNormalizationLayer.o, serializer::Layer::Layer_BatchNormalizationLayer);
202}
203
Conor Kennedy76277882019-02-26 08:29:54 +0000204// Build FlatBuffer for Constant Layer
205void SerializerVisitor::VisitConstantLayer(const armnn::IConnectableLayer* layer,
206 const armnn::ConstTensor& input,
207 const char* name)
208{
209 // Create FlatBuffer BaseLayer
210 auto flatBufferConstantBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Constant);
211
212 auto flatBufferConstTensorInfo = CreateConstTensorInfo(input);
213
214 // Create the FlatBuffer ConstantLayer
215 auto flatBufferLayer = CreateConstantLayer(m_flatBufferBuilder,
216 flatBufferConstantBaseLayer,
217 flatBufferConstTensorInfo);
218
219 // Add the AnyLayer to the FlatBufferLayers
220 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConstantLayer);
221}
222
Mike Kellya0766c32019-02-19 17:22:07 +0000223// Build FlatBuffer for Convolution2dLayer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000224void SerializerVisitor::VisitConvolution2dLayer(const armnn::IConnectableLayer* layer,
225 const armnn::Convolution2dDescriptor& descriptor,
226 const armnn::ConstTensor& weights,
227 const armnn::Optional<armnn::ConstTensor>& biases,
Mike Kellya0766c32019-02-19 17:22:07 +0000228 const char* name)
229{
230 // Create FlatBuffer BaseLayer
231 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
232
233 auto flatBufferDescriptor = CreateConvolution2dDescriptor(m_flatBufferBuilder,
234 descriptor.m_PadLeft,
235 descriptor.m_PadRight,
236 descriptor.m_PadTop,
237 descriptor.m_PadBottom,
238 descriptor.m_StrideX,
239 descriptor.m_StrideY,
240 descriptor.m_BiasEnabled,
241 GetFlatBufferDataLayout(descriptor.m_DataLayout));
242 auto flatBufferWeightsConstTensorInfo = CreateConstTensorInfo(weights);
243 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiasesConstTensorInfo;
244
245 if (biases.has_value())
246 {
247 flatBufferBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
248 }
249
250 // Create the FlatBuffer Convolution2dLayer
251 auto flatBufferLayer = CreateConvolution2dLayer(m_flatBufferBuilder,
252 flatBufferBaseLayer,
253 flatBufferDescriptor,
254 flatBufferWeightsConstTensorInfo,
255 flatBufferBiasesConstTensorInfo);
256
257 // Add the AnyLayer to the FlatBufferLayers
258 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution2dLayer);
259}
260
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000261void SerializerVisitor::VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
262 const armnn::DepthwiseConvolution2dDescriptor& descriptor,
263 const armnn::ConstTensor& weights,
264 const armnn::Optional<armnn::ConstTensor>& biases,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000265 const char* name)
266{
267 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthwiseConvolution2d);
268 auto fbDescriptor = CreateDepthwiseConvolution2dDescriptor(m_flatBufferBuilder,
269 descriptor.m_PadLeft,
270 descriptor.m_PadRight,
271 descriptor.m_PadTop,
272 descriptor.m_PadBottom,
273 descriptor.m_StrideX,
274 descriptor.m_StrideY,
275 descriptor.m_BiasEnabled,
276 GetFlatBufferDataLayout(descriptor.m_DataLayout));
277
278 flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
279 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
280 if (biases.has_value())
281 {
282 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
283 }
284
285 auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
286 fbBaseLayer,
287 fbDescriptor,
288 fbWeightsConstTensorInfo,
289 fbBiasesConstTensorInfo);
290
291 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
292}
293
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000294void SerializerVisitor::VisitDequantizeLayer(const armnn::IConnectableLayer* layer,
295 const char* name)
296{
297 auto fbDequantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Dequantize);
298 auto fbDequantizeLayer = serializer::CreateDequantizeLayer(m_flatBufferBuilder, fbDequantizeBaseLayer);
299
300 CreateAnyLayer(fbDequantizeLayer.o, serializer::Layer::Layer_DequantizeLayer);
301}
302
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000303void SerializerVisitor::VisitDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
304 const armnn::DetectionPostProcessDescriptor& descriptor,
305 const armnn::ConstTensor& anchors,
306 const char* name)
307{
308 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
309 auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
310 descriptor.m_MaxDetections,
311 descriptor.m_MaxClassesPerDetection,
312 descriptor.m_DetectionsPerClass,
313 descriptor.m_NmsScoreThreshold,
314 descriptor.m_NmsIouThreshold,
315 descriptor.m_NumClasses,
316 descriptor.m_UseRegularNms,
317 descriptor.m_ScaleX,
318 descriptor.m_ScaleY,
319 descriptor.m_ScaleW,
320 descriptor.m_ScaleH);
321
322 flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);
323
324 auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
325 fbBaseLayer,
326 fbDescriptor,
327 fbAnchorsConstTensorInfo);
328
329 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
330}
331
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000332void SerializerVisitor::VisitDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
333{
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000334 auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
335 auto fbDivisionLayer = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000336
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000337 CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
338}
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000339
Aron Virginas-Tar377351e2019-02-27 14:42:31 +0000340void SerializerVisitor::VisitEqualLayer(const armnn::IConnectableLayer* layer, const char* name)
341{
342 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Equal);
343 auto fbEqualLayer = serializer::CreateEqualLayer(m_flatBufferBuilder, fbBaseLayer);
344
345 CreateAnyLayer(fbEqualLayer.o, serializer::Layer::Layer_EqualLayer);
346}
347
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000348void SerializerVisitor::VisitFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
349{
350 auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
351 auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);
352
353 CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
354}
355
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000356void SerializerVisitor::VisitGatherLayer(const armnn::IConnectableLayer* layer, const char* name)
357{
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000358 auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
359 auto flatBufferLayer = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer);
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000360
361 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
362}
363
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000364void SerializerVisitor::VisitGreaterLayer(const armnn::IConnectableLayer* layer, const char* name)
365{
366 auto fbGreaterBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Greater);
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000367 auto fbGreaterLayer = serializer::CreateGreaterLayer(m_flatBufferBuilder, fbGreaterBaseLayer);
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000368
369 CreateAnyLayer(fbGreaterLayer.o, serializer::Layer::Layer_GreaterLayer);
370}
371
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000372void SerializerVisitor::VisitL2NormalizationLayer(const armnn::IConnectableLayer* layer,
373 const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
374 const char* name)
375{
376 // Create FlatBuffer BaseLayer
377 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);
378
379 // Create the FlatBuffer L2Normalization Descriptor
380 auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
381 m_flatBufferBuilder, GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout));
382
383 // Create Flatuffer layer
384 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
385
386 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
387}
388
Jim Flynn11af3752019-03-19 17:22:29 +0000389void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer, const armnn::LstmDescriptor& descriptor,
390 const armnn::LstmInputParams& params, const char* name)
391{
392 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
393
394 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
395 m_flatBufferBuilder,
396 descriptor.m_ActivationFunc,
397 descriptor.m_ClippingThresCell,
398 descriptor.m_ClippingThresProj,
399 descriptor.m_CifgEnabled,
400 descriptor.m_PeepholeEnabled,
401 descriptor.m_ProjectionEnabled);
402
403 // Get mandatory input parameters
404 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
405 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
406 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
407 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
408 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
409 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
410 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
411 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
412 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
413
414 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
415 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
416 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
417 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
418 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
419 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
420 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
421 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
422 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
423
424 if (!descriptor.m_CifgEnabled)
425 {
426 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
427 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
428 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
429 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
430 }
431
432 if (descriptor.m_ProjectionEnabled)
433 {
434 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
435 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
436 }
437
438 if (descriptor.m_PeepholeEnabled)
439 {
440 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
441 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
442 }
443
444 auto fbLstmParams = serializer::CreateLstmInputParams(
445 m_flatBufferBuilder,
446 inputToForgetWeights,
447 inputToCellWeights,
448 inputToOutputWeights,
449 recurrentToForgetWeights,
450 recurrentToCellWeights,
451 recurrentToOutputWeights,
452 forgetGateBias,
453 cellBias,
454 outputGateBias,
455 inputToInputWeights,
456 recurrentToInputWeights,
457 cellToInputWeights,
458 inputGateBias,
459 projectionWeights,
460 projectionBias,
461 cellToForgetWeights,
462 cellToOutputWeights);
463
464 auto fbLstmLayer = serializer::CreateLstmLayer(
465 m_flatBufferBuilder,
466 fbLstmBaseLayer,
467 fbLstmDescriptor,
468 fbLstmParams);
469
470 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
471}
472
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000473void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
474{
475 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
476 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
477
478 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
479}
480
481void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
482 const armnn::MeanDescriptor& descriptor,
483 const char* name)
484{
485 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
486 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
487 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
488 descriptor.m_KeepDims);
489
490 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
491 fbMeanBaseLayer,
492 fbMeanDescriptor);
493
494 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
495}
496
497void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
498{
499 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
500 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
501
502 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
503}
504
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100505void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
506{
507 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
508 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
509
510 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
511}
512
Jim Flynnac25a1b2019-02-28 10:40:49 +0000513void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
514 const armnn::OriginsDescriptor& mergerDescriptor,
515 const char* name)
516{
517 auto flatBufferMergerBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merger);
518
519 std::vector<flatbuffers::Offset<UintVector>> views;
520 for (unsigned int v = 0; v < mergerDescriptor.GetNumViews(); ++v)
521 {
522 const uint32_t* origin = mergerDescriptor.GetViewOrigin(v);
523 std::vector<uint32_t> origins;
524 for (unsigned int d = 0; d < mergerDescriptor.GetNumDimensions(); ++d)
525 {
526 origins.push_back(origin[d]);
527 }
528 auto view = m_flatBufferBuilder.CreateVector(origins);
529 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
530 views.push_back(uintVector);
531 }
532
533 auto flatBufferMergerDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
534 mergerDescriptor.GetConcatAxis(),
535 mergerDescriptor.GetNumViews(),
536 mergerDescriptor.GetNumDimensions(),
537 m_flatBufferBuilder.CreateVector(views));
538
539 auto flatBufferLayer = CreateMergerLayer(m_flatBufferBuilder,
540 flatBufferMergerBaseLayer,
541 flatBufferMergerDescriptor);
542
543 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_MergerLayer);
544}
545
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000546void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000547{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000548 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
549 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
550 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000551
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000552 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000553}
554
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000555void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
556 const armnn::PadDescriptor& padDescriptor,
557 const char* name)
558{
559 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
560
561 std::vector<unsigned int> padList;
562 for (auto& p: padDescriptor.m_PadList)
563 {
564 padList.push_back(p.first);
565 padList.push_back(p.second);
566 }
567
568 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
569 m_flatBufferBuilder.CreateVector(padList));
570
571 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
572 flatBufferBaseLayer,
573 flatBufferPadDesc);
574
575 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
576}
577
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000578void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
579 const armnn::PermuteDescriptor& permuteDescriptor,
580 const char* name)
581{
582 // Create FlatBuffer BaseLayer
583 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
584
585 std::vector<unsigned int> dimMappings;
586 for (auto& v: permuteDescriptor.m_DimMappings)
587 {
588 dimMappings.push_back(v);
589 }
590
591 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
592 m_flatBufferBuilder.CreateVector(dimMappings));
593
594 // Create the FlatBuffer PermuteLayer
595 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
596 flatBufferPermuteBaseLayer,
597 flatBufferPermuteDesc);
598
599 // Add the AnyLayer to the FlatBufferLayers
600 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
601}
602
Saoirse Stewart263829c2019-02-19 15:54:14 +0000603// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000604void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000605 const armnn::ReshapeDescriptor& reshapeDescriptor,
606 const char* name)
607{
608 // Create FlatBuffer BaseLayer
609 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
610
611 std::vector<unsigned int> targetShape;
612 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
613 {
614 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
615 }
616
617 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
618 m_flatBufferBuilder.CreateVector(targetShape));
619
620 // Create the FlatBuffer ReshapeLayer
621 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
622 flatBufferReshapeDesc);
623
624 // Add the AnyLayer to the FlatBufferLayers
625 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
626}
627
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000628void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
629 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
630 const char* name)
631{
632 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
633
634 auto flatBufferDescriptor =
635 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
636 resizeDescriptor.m_TargetWidth,
637 resizeDescriptor.m_TargetHeight,
638 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
639
640 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
641 flatBufferBaseLayer,
642 flatBufferDescriptor);
643
644 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
645}
646
Sadik Armagan8b42a382019-03-01 14:24:49 +0000647void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
648{
649 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
650 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
651
652 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
653}
654
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000655// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000656void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
657 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000658 const char* name)
659{
660 // Create FlatBuffer BaseLayer
661 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
662
663 // Create the FlatBuffer SoftmaxDescriptor
664 auto flatBufferSoftmaxDesc =
665 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
666
667 // Create the FlatBuffer SoftmaxLayer
668 auto flatBufferSoftmaxLayer =
669 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
670 flatBufferSoftmaxBaseLayer,
671 flatBufferSoftmaxDesc);
672
673 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
674}
675
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000676void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
677 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000678 const char* name)
679{
680 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
681 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
682 m_flatBufferBuilder,
683 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
684 pooling2dDescriptor.m_PadLeft,
685 pooling2dDescriptor.m_PadRight,
686 pooling2dDescriptor.m_PadTop,
687 pooling2dDescriptor.m_PadBottom,
688 pooling2dDescriptor.m_PoolWidth,
689 pooling2dDescriptor.m_PoolHeight,
690 pooling2dDescriptor.m_StrideX,
691 pooling2dDescriptor.m_StrideY,
692 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
693 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
694 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
695
696 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
697 fbPooling2dBaseLayer,
698 fbPooling2dDescriptor);
699
700 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
701}
702
Derek Lamberti87acb272019-03-27 16:51:31 +0000703void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
704{
705 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
706 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
707 fbQuantizeBaseLayer);
708 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
709}
710
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000711// Build FlatBuffer for FullyConnected Layer
712void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
713 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
714 const armnn::ConstTensor& weights,
715 const armnn::Optional<armnn::ConstTensor>& biases,
716 const char* name)
717{
718 // Create FlatBuffer BaseLayer
719 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
720
721 // Create FlatBuffer FullyConnectedDescriptor
722 auto flatBufferDescriptor =
723 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
724 fullyConnectedDescriptor.m_BiasEnabled,
725 fullyConnectedDescriptor.m_TransposeWeightMatrix);
726
727 // Create FlatBuffer weights data
728 auto flatBufferWeights = CreateConstTensorInfo(weights);
729
730 // Create FlatBuffer bias data
731 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
732 if (fullyConnectedDescriptor.m_BiasEnabled)
733 {
734 flatBufferBiases = CreateConstTensorInfo(biases.value());
735 }
736
737 // Create FlatBuffer FullyConnectedLayer
738 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
739 flatBufferBaseLayer,
740 flatBufferDescriptor,
741 flatBufferWeights,
742 flatBufferBiases);
743
744 // Add created FullyConnectedLayer to the FlatBufferLayers
745 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
746}
747
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000748// Build FlatBuffer for SpaceToBatchNd Layer
749void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
750 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
751 const char* name)
752{
753 // Create FlatBuffer BaseLayer
754 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
755
756 std::vector<unsigned int> padList;
757 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
758 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
759 {
760 padList.push_back(pad.first);
761 padList.push_back(pad.second);
762 }
763
764 auto flatBufferDescriptor =
765 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
766 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
767 m_flatBufferBuilder.CreateVector(padList),
768 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
769
770 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
771 flatBufferBaseLayer,
772 flatBufferDescriptor);
773
774 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
775}
776
Jim Flynn18ce3382019-03-08 11:08:30 +0000777// Build FlatBuffer for Splitter Layer
778void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
779 const armnn::ViewsDescriptor& viewsDescriptor,
780 const char* name)
781{
782 // Create FlatBuffer ViewOrigins
783 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
784 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
785
786 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
787 {
788 std::vector<uint32_t> viewOrigin;
789 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
790
791 // Copy vector
792 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
793 {
794 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
795 }
796
797 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
798 m_flatBufferBuilder.CreateVector(viewOrigin)));
799 }
800
801 // Create FlatBuffer OriginsDescriptor
802 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
803 viewsDescriptor.GetOrigins().GetConcatAxis(),
804 viewsDescriptor.GetOrigins().GetNumViews(),
805 viewsDescriptor.GetOrigins().GetNumDimensions(),
806 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
807
808 // Create FlatBuffer ViewOrigins
809 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
810 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
811
812 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
813 {
814 std::vector<uint32_t> viewSize;
815 viewSize.reserve(viewsDescriptor.GetNumDimensions());
816
817 // Copy vector
818 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
819 {
820 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
821 }
822
823 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
824 m_flatBufferBuilder.CreateVector(viewSize)));
825 }
826
827 // Create FlatBuffer ViewsDescriptor
828 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
829 flatBufferOriginDescriptor,
830 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
831
832 // Create FlatBuffer BaseLayer
833 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
834
835 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
836 flatBufferBaseLayer,
837 flatBufferViewsDescriptor);
838
839 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
840}
841
Nina Drozd57728782019-02-27 10:53:27 +0000842void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
843 const armnn::NormalizationDescriptor& descriptor,
844 const char* name)
845{
846 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
847
848 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
849 m_flatBufferBuilder,
850 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
851 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
852 descriptor.m_NormSize,
853 descriptor.m_Alpha,
854 descriptor.m_Beta,
855 descriptor.m_K,
856 GetFlatBufferDataLayout(descriptor.m_DataLayout));
857
858 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
859 fbNormalizationBaseLayer,
860 fbNormalizationDescriptor);
861
862 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
863}
864
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000865void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
866 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
867 const char* name)
868{
869 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
870
871 auto flatBufferDescriptor =
872 CreateStridedSliceDescriptor(m_flatBufferBuilder,
873 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
874 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
875 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
876 stridedSliceDescriptor.m_BeginMask,
877 stridedSliceDescriptor.m_EndMask,
878 stridedSliceDescriptor.m_ShrinkAxisMask,
879 stridedSliceDescriptor.m_EllipsisMask,
880 stridedSliceDescriptor.m_NewAxisMask,
881 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
882
883 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
884 flatBufferBaseLayer,
885 flatBufferDescriptor);
886
887 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
888}
889
Conor Kennedyda1f9752019-03-01 14:37:12 +0000890void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
891{
892 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
893 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
894
895 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
896}
897
Sadik Armaganeff363d2019-04-05 15:25:46 +0100898void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
899{
900 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
901 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
902
903 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
904}
905
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000906fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000907 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000908{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000909 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
910
Mike Kelly8c1701a2019-02-11 17:01:27 +0000911 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
912 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
913
914 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000915 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000916 m_flatBufferBuilder.CreateString(layer->GetName()),
917 layerType,
918 m_flatBufferBuilder.CreateVector(inputSlots),
919 m_flatBufferBuilder.CreateVector(outputSlots));
920}
921
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000922void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000923{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000924 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000925 m_serializedLayers.push_back(anyLayer);
926}
927
Mike Kellya0766c32019-02-19 17:22:07 +0000928template <typename T>
929flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
930{
931 const T* buffer = reinterpret_cast<const T*>(memory);
932 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
933 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
934 return fbVector;
935}
936
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000937flatbuffers::Offset<serializer::ConstTensor>
938 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000939{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000940 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000941
942 // Get the dimensions
943 std::vector<unsigned int> shape;
944
945 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
946 {
947 shape.push_back(tensorInfo.GetShape()[dim]);
948 }
949
950 // Create FlatBuffer TensorInfo
951 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
952 m_flatBufferBuilder.CreateVector(shape),
953 GetFlatBufferDataType(tensorInfo.GetDataType()),
954 tensorInfo.GetQuantizationScale(),
955 tensorInfo.GetQuantizationOffset());
956 flatbuffers::Offset<void> fbPayload;
957
958 switch (tensorInfo.GetDataType())
959 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000960 case armnn::DataType::Float32:
961 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000962 {
963 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
964 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
965 m_flatBufferBuilder,
966 fbVector);
967 fbPayload = flatBuffersData.o;
968 break;
969 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000970 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000971 {
972 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
973 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
974 m_flatBufferBuilder,
975 fbVector);
976 fbPayload = flatBuffersData.o;
977 break;
978 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +0000979 case armnn::DataType::QuantisedSymm16:
980 {
981 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
982 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
983 m_flatBufferBuilder,
984 fbVector);
985 fbPayload = flatBuffersData.o;
986 break;
987 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000988 case armnn::DataType::QuantisedAsymm8:
989 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +0000990 default:
991 {
992 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
993 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
994 m_flatBufferBuilder,
995 fbVector);
996 fbPayload = flatBuffersData.o;
997 }
998 }
999 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1000 m_flatBufferBuilder,
1001 flatBufferTensorInfo,
1002 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1003 fbPayload);
1004 return flatBufferConstTensor;
1005}
1006
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001007std::vector<fb::Offset<serializer::InputSlot>>
1008 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001009{
Mike Kellya0766c32019-02-19 17:22:07 +00001010 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001011
1012 // Get the InputSlots
1013 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1014 {
1015 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1016
1017 // Get the Connection for the InputSlot
1018 const IOutputSlot* connection = inputSlot.GetConnection();
1019
1020 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001021 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1022 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001023 // Create FlatBuffer InputSlot
1024 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1025 }
1026 return inputSlots;
1027}
1028
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001029std::vector<fb::Offset<serializer::OutputSlot>>
1030 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001031{
1032 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1033
1034 // Get the OutputSlots
1035 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1036 {
1037 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001038 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001039
1040 // Get the dimensions
1041 std::vector<unsigned int> shape;
1042 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1043 {
1044 shape.push_back(tensorInfo.GetShape()[dim]);
1045 }
1046
1047 // Create FlatBuffer TensorInfo
1048 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1049 m_flatBufferBuilder.CreateVector(shape),
1050 GetFlatBufferDataType(tensorInfo.GetDataType()),
1051 tensorInfo.GetQuantizationScale(),
1052 tensorInfo.GetQuantizationOffset());
1053
1054 // Create FlatBuffer Outputslot
1055 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1056 slotIndex,
1057 flatBufferTensorInfo));
1058 }
1059 return outputSlots;
1060}
1061
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001062
1063ISerializer* ISerializer::CreateRaw()
1064{
1065 return new Serializer();
1066}
1067
1068ISerializerPtr ISerializer::Create()
1069{
1070 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1071}
1072
1073void ISerializer::Destroy(ISerializer* serializer)
1074{
1075 delete serializer;
1076}
1077
1078void Serializer::Serialize(const INetwork& inNetwork)
1079{
1080 // Iterate through to network
1081 inNetwork.Accept(m_SerializerVisitor);
1082 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1083
1084 // Create FlatBuffer SerializedGraph
1085 auto serializedGraph = serializer::CreateSerializedGraph(
1086 fbBuilder,
1087 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1088 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1089 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1090
1091 // Serialize the graph
1092 fbBuilder.Finish(serializedGraph);
1093}
1094
1095bool Serializer::SaveSerializedToStream(std::ostream& stream)
1096{
1097 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1098
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001099 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1100 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001101 return !stream.bad();
1102}
1103
Matteo Martincighec333912019-02-13 15:12:39 +00001104} // namespace armnnSerializer