blob: 2d5877db63bf9e34eab7f420eeba4057ed3da0d5 [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
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010014#include <boost/numeric/conversion/cast.hpp>
15
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,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100238 descriptor.m_DilationX,
239 descriptor.m_DilationY,
Mike Kellya0766c32019-02-19 17:22:07 +0000240 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,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100275 descriptor.m_DilationX,
276 descriptor.m_DilationY,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000277 descriptor.m_BiasEnabled,
278 GetFlatBufferDataLayout(descriptor.m_DataLayout));
279
280 flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
281 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
282 if (biases.has_value())
283 {
284 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
285 }
286
287 auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
288 fbBaseLayer,
289 fbDescriptor,
290 fbWeightsConstTensorInfo,
291 fbBiasesConstTensorInfo);
292
293 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
294}
295
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000296void SerializerVisitor::VisitDequantizeLayer(const armnn::IConnectableLayer* layer,
297 const char* name)
298{
299 auto fbDequantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Dequantize);
300 auto fbDequantizeLayer = serializer::CreateDequantizeLayer(m_flatBufferBuilder, fbDequantizeBaseLayer);
301
302 CreateAnyLayer(fbDequantizeLayer.o, serializer::Layer::Layer_DequantizeLayer);
303}
304
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000305void SerializerVisitor::VisitDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
306 const armnn::DetectionPostProcessDescriptor& descriptor,
307 const armnn::ConstTensor& anchors,
308 const char* name)
309{
310 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
311 auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
312 descriptor.m_MaxDetections,
313 descriptor.m_MaxClassesPerDetection,
314 descriptor.m_DetectionsPerClass,
315 descriptor.m_NmsScoreThreshold,
316 descriptor.m_NmsIouThreshold,
317 descriptor.m_NumClasses,
318 descriptor.m_UseRegularNms,
319 descriptor.m_ScaleX,
320 descriptor.m_ScaleY,
321 descriptor.m_ScaleW,
322 descriptor.m_ScaleH);
323
324 flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);
325
326 auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
327 fbBaseLayer,
328 fbDescriptor,
329 fbAnchorsConstTensorInfo);
330
331 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
332}
333
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000334void SerializerVisitor::VisitDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
335{
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000336 auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
337 auto fbDivisionLayer = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000338
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000339 CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
340}
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000341
Aron Virginas-Tar377351e2019-02-27 14:42:31 +0000342void SerializerVisitor::VisitEqualLayer(const armnn::IConnectableLayer* layer, const char* name)
343{
344 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Equal);
345 auto fbEqualLayer = serializer::CreateEqualLayer(m_flatBufferBuilder, fbBaseLayer);
346
347 CreateAnyLayer(fbEqualLayer.o, serializer::Layer::Layer_EqualLayer);
348}
349
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000350void SerializerVisitor::VisitFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
351{
352 auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
353 auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);
354
355 CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
356}
357
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000358void SerializerVisitor::VisitGatherLayer(const armnn::IConnectableLayer* layer, const char* name)
359{
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000360 auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
361 auto flatBufferLayer = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer);
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000362
363 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
364}
365
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000366void SerializerVisitor::VisitGreaterLayer(const armnn::IConnectableLayer* layer, const char* name)
367{
368 auto fbGreaterBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Greater);
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000369 auto fbGreaterLayer = serializer::CreateGreaterLayer(m_flatBufferBuilder, fbGreaterBaseLayer);
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000370
371 CreateAnyLayer(fbGreaterLayer.o, serializer::Layer::Layer_GreaterLayer);
372}
373
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000374void SerializerVisitor::VisitL2NormalizationLayer(const armnn::IConnectableLayer* layer,
375 const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
376 const char* name)
377{
378 // Create FlatBuffer BaseLayer
379 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);
380
381 // Create the FlatBuffer L2Normalization Descriptor
382 auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100383 m_flatBufferBuilder,
384 GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout),
385 l2NormalizationDescriptor.m_Eps);
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000386
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100387 // Create FlatBuffer layer
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000388 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
389
390 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
391}
392
Jim Flynn11af3752019-03-19 17:22:29 +0000393void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer, const armnn::LstmDescriptor& descriptor,
394 const armnn::LstmInputParams& params, const char* name)
395{
396 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
397
398 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
399 m_flatBufferBuilder,
400 descriptor.m_ActivationFunc,
401 descriptor.m_ClippingThresCell,
402 descriptor.m_ClippingThresProj,
403 descriptor.m_CifgEnabled,
404 descriptor.m_PeepholeEnabled,
405 descriptor.m_ProjectionEnabled);
406
407 // Get mandatory input parameters
408 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
409 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
410 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
411 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
412 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
413 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
414 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
415 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
416 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
417
418 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
419 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
420 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
421 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
422 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
423 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
424 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
425 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
426 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
427
428 if (!descriptor.m_CifgEnabled)
429 {
430 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
431 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
432 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
433 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
434 }
435
436 if (descriptor.m_ProjectionEnabled)
437 {
438 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
439 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
440 }
441
442 if (descriptor.m_PeepholeEnabled)
443 {
444 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
445 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
446 }
447
448 auto fbLstmParams = serializer::CreateLstmInputParams(
449 m_flatBufferBuilder,
450 inputToForgetWeights,
451 inputToCellWeights,
452 inputToOutputWeights,
453 recurrentToForgetWeights,
454 recurrentToCellWeights,
455 recurrentToOutputWeights,
456 forgetGateBias,
457 cellBias,
458 outputGateBias,
459 inputToInputWeights,
460 recurrentToInputWeights,
461 cellToInputWeights,
462 inputGateBias,
463 projectionWeights,
464 projectionBias,
465 cellToForgetWeights,
466 cellToOutputWeights);
467
468 auto fbLstmLayer = serializer::CreateLstmLayer(
469 m_flatBufferBuilder,
470 fbLstmBaseLayer,
471 fbLstmDescriptor,
472 fbLstmParams);
473
474 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
475}
476
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000477void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
478{
479 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
480 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
481
482 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
483}
484
485void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
486 const armnn::MeanDescriptor& descriptor,
487 const char* name)
488{
489 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
490 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
491 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
492 descriptor.m_KeepDims);
493
494 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
495 fbMeanBaseLayer,
496 fbMeanDescriptor);
497
498 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
499}
500
501void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
502{
503 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
504 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
505
506 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
507}
508
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100509void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
510{
511 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
512 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
513
514 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
515}
516
Jim Flynnac25a1b2019-02-28 10:40:49 +0000517void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
Jim Flynne242f2d2019-05-22 14:24:13 +0100518 const armnn::MergerDescriptor& mergerDescriptor,
Jim Flynnac25a1b2019-02-28 10:40:49 +0000519 const char* name)
520{
Jim Flynne242f2d2019-05-22 14:24:13 +0100521 VisitConcatLayer(layer, mergerDescriptor, name);
522}
523
524void SerializerVisitor::VisitConcatLayer(const armnn::IConnectableLayer* layer,
525 const armnn::ConcatDescriptor& concatDescriptor,
526 const char* name)
527{
528 auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000529
530 std::vector<flatbuffers::Offset<UintVector>> views;
Jim Flynne242f2d2019-05-22 14:24:13 +0100531 for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000532 {
Jim Flynne242f2d2019-05-22 14:24:13 +0100533 const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000534 std::vector<uint32_t> origins;
Jim Flynne242f2d2019-05-22 14:24:13 +0100535 for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000536 {
537 origins.push_back(origin[d]);
538 }
539 auto view = m_flatBufferBuilder.CreateVector(origins);
540 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
541 views.push_back(uintVector);
542 }
543
Jim Flynne242f2d2019-05-22 14:24:13 +0100544 auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
545 concatDescriptor.GetConcatAxis(),
546 concatDescriptor.GetNumViews(),
547 concatDescriptor.GetNumDimensions(),
Jim Flynnac25a1b2019-02-28 10:40:49 +0000548 m_flatBufferBuilder.CreateVector(views));
549
Jim Flynne242f2d2019-05-22 14:24:13 +0100550 auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
551 flatBufferConcatBaseLayer,
552 flatBufferConcatDescriptor);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000553
Jim Flynne242f2d2019-05-22 14:24:13 +0100554 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000555}
556
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000557void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000558{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000559 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
560 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
561 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000562
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000563 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000564}
565
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000566void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
567 const armnn::PadDescriptor& padDescriptor,
568 const char* name)
569{
570 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
571
572 std::vector<unsigned int> padList;
573 for (auto& p: padDescriptor.m_PadList)
574 {
575 padList.push_back(p.first);
576 padList.push_back(p.second);
577 }
578
579 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
David Monahan34757812019-06-19 11:47:21 +0100580 m_flatBufferBuilder.CreateVector(padList),
581 padDescriptor.m_padValue);
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000582
583 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
584 flatBufferBaseLayer,
585 flatBufferPadDesc);
586
587 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
588}
589
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000590void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
591 const armnn::PermuteDescriptor& permuteDescriptor,
592 const char* name)
593{
594 // Create FlatBuffer BaseLayer
595 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
596
597 std::vector<unsigned int> dimMappings;
598 for (auto& v: permuteDescriptor.m_DimMappings)
599 {
600 dimMappings.push_back(v);
601 }
602
603 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
604 m_flatBufferBuilder.CreateVector(dimMappings));
605
606 // Create the FlatBuffer PermuteLayer
607 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
608 flatBufferPermuteBaseLayer,
609 flatBufferPermuteDesc);
610
611 // Add the AnyLayer to the FlatBufferLayers
612 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
613}
614
Saoirse Stewart263829c2019-02-19 15:54:14 +0000615// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000616void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000617 const armnn::ReshapeDescriptor& reshapeDescriptor,
618 const char* name)
619{
620 // Create FlatBuffer BaseLayer
621 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
622
623 std::vector<unsigned int> targetShape;
624 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
625 {
626 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
627 }
628
629 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
630 m_flatBufferBuilder.CreateVector(targetShape));
631
632 // Create the FlatBuffer ReshapeLayer
633 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
634 flatBufferReshapeDesc);
635
636 // Add the AnyLayer to the FlatBufferLayers
637 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
638}
639
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000640void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
641 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
642 const char* name)
643{
644 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
645
646 auto flatBufferDescriptor =
647 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
648 resizeDescriptor.m_TargetWidth,
649 resizeDescriptor.m_TargetHeight,
650 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
651
652 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
653 flatBufferBaseLayer,
654 flatBufferDescriptor);
655
656 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
657}
658
Teresa Charlina9075df2019-06-27 15:41:57 +0100659void SerializerVisitor::VisitResizeLayer(const armnn::IConnectableLayer* layer,
660 const armnn::ResizeDescriptor& resizeDescriptor,
661 const char* name)
662{
663 throw armnn::Exception("SerializerVisitor::VisitResizeLayer is not yet implemented");
664}
665
Sadik Armagan8b42a382019-03-01 14:24:49 +0000666void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
667{
668 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
669 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
670
671 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
672}
673
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000674// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000675void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
676 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000677 const char* name)
678{
679 // Create FlatBuffer BaseLayer
680 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
681
682 // Create the FlatBuffer SoftmaxDescriptor
683 auto flatBufferSoftmaxDesc =
684 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
685
686 // Create the FlatBuffer SoftmaxLayer
687 auto flatBufferSoftmaxLayer =
688 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
689 flatBufferSoftmaxBaseLayer,
690 flatBufferSoftmaxDesc);
691
692 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
693}
694
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000695void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
696 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000697 const char* name)
698{
699 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
700 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
701 m_flatBufferBuilder,
702 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
703 pooling2dDescriptor.m_PadLeft,
704 pooling2dDescriptor.m_PadRight,
705 pooling2dDescriptor.m_PadTop,
706 pooling2dDescriptor.m_PadBottom,
707 pooling2dDescriptor.m_PoolWidth,
708 pooling2dDescriptor.m_PoolHeight,
709 pooling2dDescriptor.m_StrideX,
710 pooling2dDescriptor.m_StrideY,
711 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
712 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
713 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
714
715 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
716 fbPooling2dBaseLayer,
717 fbPooling2dDescriptor);
718
719 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
720}
721
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100722void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
723 const char* name)
724{
Ellen Norris-Thompson51982472019-06-19 11:46:21 +0100725 // Create FlatBuffer BaseLayer
726 auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
727
728 // Create the FlatBuffer AdditionLayer
729 auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
730
731 // Add the AnyLayer to the FlatBufferLayers
732 CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100733}
734
Derek Lamberti87acb272019-03-27 16:51:31 +0000735void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
736{
737 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
738 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
739 fbQuantizeBaseLayer);
740 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
741}
742
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000743// Build FlatBuffer for FullyConnected Layer
744void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
745 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
746 const armnn::ConstTensor& weights,
747 const armnn::Optional<armnn::ConstTensor>& biases,
748 const char* name)
749{
750 // Create FlatBuffer BaseLayer
751 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
752
753 // Create FlatBuffer FullyConnectedDescriptor
754 auto flatBufferDescriptor =
755 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
756 fullyConnectedDescriptor.m_BiasEnabled,
757 fullyConnectedDescriptor.m_TransposeWeightMatrix);
758
759 // Create FlatBuffer weights data
760 auto flatBufferWeights = CreateConstTensorInfo(weights);
761
762 // Create FlatBuffer bias data
763 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
764 if (fullyConnectedDescriptor.m_BiasEnabled)
765 {
766 flatBufferBiases = CreateConstTensorInfo(biases.value());
767 }
768
769 // Create FlatBuffer FullyConnectedLayer
770 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
771 flatBufferBaseLayer,
772 flatBufferDescriptor,
773 flatBufferWeights,
774 flatBufferBiases);
775
776 // Add created FullyConnectedLayer to the FlatBufferLayers
777 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
778}
779
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000780// Build FlatBuffer for SpaceToBatchNd Layer
781void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
782 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
783 const char* name)
784{
785 // Create FlatBuffer BaseLayer
786 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
787
788 std::vector<unsigned int> padList;
789 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
790 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
791 {
792 padList.push_back(pad.first);
793 padList.push_back(pad.second);
794 }
795
796 auto flatBufferDescriptor =
797 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
798 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
799 m_flatBufferBuilder.CreateVector(padList),
800 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
801
802 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
803 flatBufferBaseLayer,
804 flatBufferDescriptor);
805
806 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
807}
808
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100809// Build FlatBuffer for SpaceToDepthLayer
810void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
811 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
812 const char* name)
813{
Aron Virginas-Taraa067142019-06-11 16:01:44 +0100814 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
815 auto flatBufferDescriptor =
816 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
817 spaceToDepthDescriptor.m_BlockSize,
818 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
819
820 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
821 flatBufferBaseLayer,
822 flatBufferDescriptor);
823
824 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100825}
826
Jim Flynn18ce3382019-03-08 11:08:30 +0000827// Build FlatBuffer for Splitter Layer
828void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
829 const armnn::ViewsDescriptor& viewsDescriptor,
830 const char* name)
831{
832 // Create FlatBuffer ViewOrigins
833 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
834 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
835
836 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
837 {
838 std::vector<uint32_t> viewOrigin;
839 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
840
841 // Copy vector
842 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
843 {
844 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
845 }
846
847 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
848 m_flatBufferBuilder.CreateVector(viewOrigin)));
849 }
850
851 // Create FlatBuffer OriginsDescriptor
852 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
853 viewsDescriptor.GetOrigins().GetConcatAxis(),
854 viewsDescriptor.GetOrigins().GetNumViews(),
855 viewsDescriptor.GetOrigins().GetNumDimensions(),
856 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
857
858 // Create FlatBuffer ViewOrigins
859 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
860 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
861
862 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
863 {
864 std::vector<uint32_t> viewSize;
865 viewSize.reserve(viewsDescriptor.GetNumDimensions());
866
867 // Copy vector
868 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
869 {
870 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
871 }
872
873 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
874 m_flatBufferBuilder.CreateVector(viewSize)));
875 }
876
877 // Create FlatBuffer ViewsDescriptor
878 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
879 flatBufferOriginDescriptor,
880 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
881
882 // Create FlatBuffer BaseLayer
883 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
884
885 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
886 flatBufferBaseLayer,
887 flatBufferViewsDescriptor);
888
889 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
890}
891
Nina Drozd57728782019-02-27 10:53:27 +0000892void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
893 const armnn::NormalizationDescriptor& descriptor,
894 const char* name)
895{
896 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
897
898 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
899 m_flatBufferBuilder,
900 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
901 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
902 descriptor.m_NormSize,
903 descriptor.m_Alpha,
904 descriptor.m_Beta,
905 descriptor.m_K,
906 GetFlatBufferDataLayout(descriptor.m_DataLayout));
907
908 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
909 fbNormalizationBaseLayer,
910 fbNormalizationDescriptor);
911
912 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
913}
914
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000915void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
916 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
917 const char* name)
918{
919 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
920
921 auto flatBufferDescriptor =
922 CreateStridedSliceDescriptor(m_flatBufferBuilder,
923 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
924 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
925 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
926 stridedSliceDescriptor.m_BeginMask,
927 stridedSliceDescriptor.m_EndMask,
928 stridedSliceDescriptor.m_ShrinkAxisMask,
929 stridedSliceDescriptor.m_EllipsisMask,
930 stridedSliceDescriptor.m_NewAxisMask,
931 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
932
933 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
934 flatBufferBaseLayer,
935 flatBufferDescriptor);
936
937 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
938}
939
Conor Kennedyda1f9752019-03-01 14:37:12 +0000940void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
941{
942 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
943 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
944
945 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
946}
947
Sadik Armaganeff363d2019-04-05 15:25:46 +0100948void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
949{
950 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
951 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
952
953 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
954}
955
Aron Virginas-Tar639fb042019-06-20 14:28:19 +0100956void SerializerVisitor::VisitTransposeConvolution2dLayer(
957 const armnn::IConnectableLayer* layer,
958 const armnn::TransposeConvolution2dDescriptor& descriptor,
959 const armnn::ConstTensor& weights,
960 const armnn::Optional<armnn::ConstTensor>& biases,
961 const char* name)
962{
Aron Virginas-Tarcb549302019-06-21 13:53:38 +0100963 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
964 auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
965 descriptor.m_PadLeft,
966 descriptor.m_PadRight,
967 descriptor.m_PadTop,
968 descriptor.m_PadBottom,
969 descriptor.m_StrideX,
970 descriptor.m_StrideY,
971 descriptor.m_BiasEnabled,
972 GetFlatBufferDataLayout(descriptor.m_DataLayout));
973
974 // weights & biases
975 auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
976 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
977 if (biases.has_value())
978 {
979 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
980 }
981
982 auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
983 fbBaseLayer,
984 fbDescriptor,
985 fbWeightsConstTensorInfo,
986 fbBiasesConstTensorInfo);
987
988 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
Aron Virginas-Tar639fb042019-06-20 14:28:19 +0100989}
990
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000991fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000992 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000993{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000994 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
995
Mike Kelly8c1701a2019-02-11 17:01:27 +0000996 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
997 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
998
999 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +00001000 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +00001001 m_flatBufferBuilder.CreateString(layer->GetName()),
1002 layerType,
1003 m_flatBufferBuilder.CreateVector(inputSlots),
1004 m_flatBufferBuilder.CreateVector(outputSlots));
1005}
1006
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001007void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001008{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001009 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +00001010 m_serializedLayers.push_back(anyLayer);
1011}
1012
Mike Kellya0766c32019-02-19 17:22:07 +00001013template <typename T>
1014flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
1015{
1016 const T* buffer = reinterpret_cast<const T*>(memory);
1017 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
1018 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
1019 return fbVector;
1020}
1021
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001022flatbuffers::Offset<serializer::ConstTensor>
1023 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +00001024{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001025 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +00001026
1027 // Get the dimensions
1028 std::vector<unsigned int> shape;
1029
1030 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1031 {
1032 shape.push_back(tensorInfo.GetShape()[dim]);
1033 }
1034
1035 // Create FlatBuffer TensorInfo
1036 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1037 m_flatBufferBuilder.CreateVector(shape),
1038 GetFlatBufferDataType(tensorInfo.GetDataType()),
1039 tensorInfo.GetQuantizationScale(),
1040 tensorInfo.GetQuantizationOffset());
1041 flatbuffers::Offset<void> fbPayload;
1042
1043 switch (tensorInfo.GetDataType())
1044 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001045 case armnn::DataType::Float32:
1046 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +00001047 {
1048 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1049 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1050 m_flatBufferBuilder,
1051 fbVector);
1052 fbPayload = flatBuffersData.o;
1053 break;
1054 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001055 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +00001056 {
1057 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1058 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1059 m_flatBufferBuilder,
1060 fbVector);
1061 fbPayload = flatBuffersData.o;
1062 break;
1063 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001064 case armnn::DataType::QuantisedSymm16:
1065 {
1066 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1067 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1068 m_flatBufferBuilder,
1069 fbVector);
1070 fbPayload = flatBuffersData.o;
1071 break;
1072 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001073 case armnn::DataType::QuantisedAsymm8:
1074 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001075 default:
1076 {
1077 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1078 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1079 m_flatBufferBuilder,
1080 fbVector);
1081 fbPayload = flatBuffersData.o;
1082 }
1083 }
1084 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1085 m_flatBufferBuilder,
1086 flatBufferTensorInfo,
1087 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1088 fbPayload);
1089 return flatBufferConstTensor;
1090}
1091
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001092std::vector<fb::Offset<serializer::InputSlot>>
1093 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001094{
Mike Kellya0766c32019-02-19 17:22:07 +00001095 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001096
1097 // Get the InputSlots
1098 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1099 {
1100 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1101
1102 // Get the Connection for the InputSlot
1103 const IOutputSlot* connection = inputSlot.GetConnection();
1104
1105 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001106 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1107 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001108 // Create FlatBuffer InputSlot
1109 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1110 }
1111 return inputSlots;
1112}
1113
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001114std::vector<fb::Offset<serializer::OutputSlot>>
1115 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001116{
1117 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1118
1119 // Get the OutputSlots
1120 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1121 {
1122 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001123 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001124
1125 // Get the dimensions
1126 std::vector<unsigned int> shape;
1127 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1128 {
1129 shape.push_back(tensorInfo.GetShape()[dim]);
1130 }
1131
1132 // Create FlatBuffer TensorInfo
1133 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1134 m_flatBufferBuilder.CreateVector(shape),
1135 GetFlatBufferDataType(tensorInfo.GetDataType()),
1136 tensorInfo.GetQuantizationScale(),
1137 tensorInfo.GetQuantizationOffset());
1138
1139 // Create FlatBuffer Outputslot
1140 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1141 slotIndex,
1142 flatBufferTensorInfo));
1143 }
1144 return outputSlots;
1145}
1146
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001147
1148ISerializer* ISerializer::CreateRaw()
1149{
1150 return new Serializer();
1151}
1152
1153ISerializerPtr ISerializer::Create()
1154{
1155 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1156}
1157
1158void ISerializer::Destroy(ISerializer* serializer)
1159{
1160 delete serializer;
1161}
1162
1163void Serializer::Serialize(const INetwork& inNetwork)
1164{
1165 // Iterate through to network
1166 inNetwork.Accept(m_SerializerVisitor);
1167 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1168
1169 // Create FlatBuffer SerializedGraph
1170 auto serializedGraph = serializer::CreateSerializedGraph(
1171 fbBuilder,
1172 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1173 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1174 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1175
1176 // Serialize the graph
1177 fbBuilder.Finish(serializedGraph);
1178}
1179
1180bool Serializer::SaveSerializedToStream(std::ostream& stream)
1181{
1182 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1183
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001184 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1185 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001186 return !stream.bad();
1187}
1188
Matteo Martincighec333912019-02-13 15:12:39 +00001189} // namespace armnnSerializer