blob: 012ed666f1cd92fecbf100733375fe0fb06ffa28 [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(
383 m_flatBufferBuilder, GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout));
384
385 // Create Flatuffer layer
386 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
387
388 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
389}
390
Jim Flynn11af3752019-03-19 17:22:29 +0000391void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer, const armnn::LstmDescriptor& descriptor,
392 const armnn::LstmInputParams& params, const char* name)
393{
394 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
395
396 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
397 m_flatBufferBuilder,
398 descriptor.m_ActivationFunc,
399 descriptor.m_ClippingThresCell,
400 descriptor.m_ClippingThresProj,
401 descriptor.m_CifgEnabled,
402 descriptor.m_PeepholeEnabled,
403 descriptor.m_ProjectionEnabled);
404
405 // Get mandatory input parameters
406 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
407 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
408 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
409 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
410 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
411 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
412 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
413 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
414 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
415
416 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
417 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
418 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
419 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
420 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
421 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
422 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
423 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
424 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
425
426 if (!descriptor.m_CifgEnabled)
427 {
428 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
429 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
430 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
431 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
432 }
433
434 if (descriptor.m_ProjectionEnabled)
435 {
436 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
437 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
438 }
439
440 if (descriptor.m_PeepholeEnabled)
441 {
442 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
443 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
444 }
445
446 auto fbLstmParams = serializer::CreateLstmInputParams(
447 m_flatBufferBuilder,
448 inputToForgetWeights,
449 inputToCellWeights,
450 inputToOutputWeights,
451 recurrentToForgetWeights,
452 recurrentToCellWeights,
453 recurrentToOutputWeights,
454 forgetGateBias,
455 cellBias,
456 outputGateBias,
457 inputToInputWeights,
458 recurrentToInputWeights,
459 cellToInputWeights,
460 inputGateBias,
461 projectionWeights,
462 projectionBias,
463 cellToForgetWeights,
464 cellToOutputWeights);
465
466 auto fbLstmLayer = serializer::CreateLstmLayer(
467 m_flatBufferBuilder,
468 fbLstmBaseLayer,
469 fbLstmDescriptor,
470 fbLstmParams);
471
472 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
473}
474
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000475void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
476{
477 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
478 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
479
480 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
481}
482
483void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
484 const armnn::MeanDescriptor& descriptor,
485 const char* name)
486{
487 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
488 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
489 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
490 descriptor.m_KeepDims);
491
492 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
493 fbMeanBaseLayer,
494 fbMeanDescriptor);
495
496 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
497}
498
499void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
500{
501 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
502 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
503
504 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
505}
506
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100507void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
508{
509 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
510 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
511
512 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
513}
514
Jim Flynnac25a1b2019-02-28 10:40:49 +0000515void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
Jim Flynne242f2d2019-05-22 14:24:13 +0100516 const armnn::MergerDescriptor& mergerDescriptor,
Jim Flynnac25a1b2019-02-28 10:40:49 +0000517 const char* name)
518{
Jim Flynne242f2d2019-05-22 14:24:13 +0100519 VisitConcatLayer(layer, mergerDescriptor, name);
520}
521
522void SerializerVisitor::VisitConcatLayer(const armnn::IConnectableLayer* layer,
523 const armnn::ConcatDescriptor& concatDescriptor,
524 const char* name)
525{
526 auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000527
528 std::vector<flatbuffers::Offset<UintVector>> views;
Jim Flynne242f2d2019-05-22 14:24:13 +0100529 for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000530 {
Jim Flynne242f2d2019-05-22 14:24:13 +0100531 const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000532 std::vector<uint32_t> origins;
Jim Flynne242f2d2019-05-22 14:24:13 +0100533 for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000534 {
535 origins.push_back(origin[d]);
536 }
537 auto view = m_flatBufferBuilder.CreateVector(origins);
538 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
539 views.push_back(uintVector);
540 }
541
Jim Flynne242f2d2019-05-22 14:24:13 +0100542 auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
543 concatDescriptor.GetConcatAxis(),
544 concatDescriptor.GetNumViews(),
545 concatDescriptor.GetNumDimensions(),
Jim Flynnac25a1b2019-02-28 10:40:49 +0000546 m_flatBufferBuilder.CreateVector(views));
547
Jim Flynne242f2d2019-05-22 14:24:13 +0100548 auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
549 flatBufferConcatBaseLayer,
550 flatBufferConcatDescriptor);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000551
Jim Flynne242f2d2019-05-22 14:24:13 +0100552 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000553}
554
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000555void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000556{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000557 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
558 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
559 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000560
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000561 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000562}
563
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000564void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
565 const armnn::PadDescriptor& padDescriptor,
566 const char* name)
567{
568 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
569
570 std::vector<unsigned int> padList;
571 for (auto& p: padDescriptor.m_PadList)
572 {
573 padList.push_back(p.first);
574 padList.push_back(p.second);
575 }
576
577 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
578 m_flatBufferBuilder.CreateVector(padList));
579
580 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
581 flatBufferBaseLayer,
582 flatBufferPadDesc);
583
584 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
585}
586
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000587void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
588 const armnn::PermuteDescriptor& permuteDescriptor,
589 const char* name)
590{
591 // Create FlatBuffer BaseLayer
592 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
593
594 std::vector<unsigned int> dimMappings;
595 for (auto& v: permuteDescriptor.m_DimMappings)
596 {
597 dimMappings.push_back(v);
598 }
599
600 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
601 m_flatBufferBuilder.CreateVector(dimMappings));
602
603 // Create the FlatBuffer PermuteLayer
604 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
605 flatBufferPermuteBaseLayer,
606 flatBufferPermuteDesc);
607
608 // Add the AnyLayer to the FlatBufferLayers
609 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
610}
611
Saoirse Stewart263829c2019-02-19 15:54:14 +0000612// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000613void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000614 const armnn::ReshapeDescriptor& reshapeDescriptor,
615 const char* name)
616{
617 // Create FlatBuffer BaseLayer
618 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
619
620 std::vector<unsigned int> targetShape;
621 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
622 {
623 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
624 }
625
626 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
627 m_flatBufferBuilder.CreateVector(targetShape));
628
629 // Create the FlatBuffer ReshapeLayer
630 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
631 flatBufferReshapeDesc);
632
633 // Add the AnyLayer to the FlatBufferLayers
634 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
635}
636
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000637void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
638 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
639 const char* name)
640{
641 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
642
643 auto flatBufferDescriptor =
644 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
645 resizeDescriptor.m_TargetWidth,
646 resizeDescriptor.m_TargetHeight,
647 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
648
649 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
650 flatBufferBaseLayer,
651 flatBufferDescriptor);
652
653 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
654}
655
Sadik Armagan8b42a382019-03-01 14:24:49 +0000656void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
657{
658 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
659 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
660
661 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
662}
663
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000664// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000665void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
666 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000667 const char* name)
668{
669 // Create FlatBuffer BaseLayer
670 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
671
672 // Create the FlatBuffer SoftmaxDescriptor
673 auto flatBufferSoftmaxDesc =
674 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
675
676 // Create the FlatBuffer SoftmaxLayer
677 auto flatBufferSoftmaxLayer =
678 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
679 flatBufferSoftmaxBaseLayer,
680 flatBufferSoftmaxDesc);
681
682 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
683}
684
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000685void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
686 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000687 const char* name)
688{
689 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
690 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
691 m_flatBufferBuilder,
692 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
693 pooling2dDescriptor.m_PadLeft,
694 pooling2dDescriptor.m_PadRight,
695 pooling2dDescriptor.m_PadTop,
696 pooling2dDescriptor.m_PadBottom,
697 pooling2dDescriptor.m_PoolWidth,
698 pooling2dDescriptor.m_PoolHeight,
699 pooling2dDescriptor.m_StrideX,
700 pooling2dDescriptor.m_StrideY,
701 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
702 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
703 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
704
705 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
706 fbPooling2dBaseLayer,
707 fbPooling2dDescriptor);
708
709 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
710}
711
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100712void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
713 const char* name)
714{
715 throw UnimplementedException("SerializerVisitor::VisitPreluLayer not yet implemented");
716}
717
Derek Lamberti87acb272019-03-27 16:51:31 +0000718void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
719{
720 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
721 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
722 fbQuantizeBaseLayer);
723 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
724}
725
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000726// Build FlatBuffer for FullyConnected Layer
727void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
728 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
729 const armnn::ConstTensor& weights,
730 const armnn::Optional<armnn::ConstTensor>& biases,
731 const char* name)
732{
733 // Create FlatBuffer BaseLayer
734 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
735
736 // Create FlatBuffer FullyConnectedDescriptor
737 auto flatBufferDescriptor =
738 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
739 fullyConnectedDescriptor.m_BiasEnabled,
740 fullyConnectedDescriptor.m_TransposeWeightMatrix);
741
742 // Create FlatBuffer weights data
743 auto flatBufferWeights = CreateConstTensorInfo(weights);
744
745 // Create FlatBuffer bias data
746 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
747 if (fullyConnectedDescriptor.m_BiasEnabled)
748 {
749 flatBufferBiases = CreateConstTensorInfo(biases.value());
750 }
751
752 // Create FlatBuffer FullyConnectedLayer
753 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
754 flatBufferBaseLayer,
755 flatBufferDescriptor,
756 flatBufferWeights,
757 flatBufferBiases);
758
759 // Add created FullyConnectedLayer to the FlatBufferLayers
760 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
761}
762
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000763// Build FlatBuffer for SpaceToBatchNd Layer
764void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
765 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
766 const char* name)
767{
768 // Create FlatBuffer BaseLayer
769 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
770
771 std::vector<unsigned int> padList;
772 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
773 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
774 {
775 padList.push_back(pad.first);
776 padList.push_back(pad.second);
777 }
778
779 auto flatBufferDescriptor =
780 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
781 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
782 m_flatBufferBuilder.CreateVector(padList),
783 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
784
785 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
786 flatBufferBaseLayer,
787 flatBufferDescriptor);
788
789 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
790}
791
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100792// Build FlatBuffer for SpaceToDepthLayer
793void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
794 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
795 const char* name)
796{
Aron Virginas-Taraa067142019-06-11 16:01:44 +0100797 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
798 auto flatBufferDescriptor =
799 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
800 spaceToDepthDescriptor.m_BlockSize,
801 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
802
803 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
804 flatBufferBaseLayer,
805 flatBufferDescriptor);
806
807 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100808}
809
Jim Flynn18ce3382019-03-08 11:08:30 +0000810// Build FlatBuffer for Splitter Layer
811void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
812 const armnn::ViewsDescriptor& viewsDescriptor,
813 const char* name)
814{
815 // Create FlatBuffer ViewOrigins
816 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
817 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
818
819 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
820 {
821 std::vector<uint32_t> viewOrigin;
822 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
823
824 // Copy vector
825 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
826 {
827 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
828 }
829
830 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
831 m_flatBufferBuilder.CreateVector(viewOrigin)));
832 }
833
834 // Create FlatBuffer OriginsDescriptor
835 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
836 viewsDescriptor.GetOrigins().GetConcatAxis(),
837 viewsDescriptor.GetOrigins().GetNumViews(),
838 viewsDescriptor.GetOrigins().GetNumDimensions(),
839 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
840
841 // Create FlatBuffer ViewOrigins
842 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
843 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
844
845 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
846 {
847 std::vector<uint32_t> viewSize;
848 viewSize.reserve(viewsDescriptor.GetNumDimensions());
849
850 // Copy vector
851 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
852 {
853 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
854 }
855
856 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
857 m_flatBufferBuilder.CreateVector(viewSize)));
858 }
859
860 // Create FlatBuffer ViewsDescriptor
861 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
862 flatBufferOriginDescriptor,
863 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
864
865 // Create FlatBuffer BaseLayer
866 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
867
868 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
869 flatBufferBaseLayer,
870 flatBufferViewsDescriptor);
871
872 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
873}
874
Nina Drozd57728782019-02-27 10:53:27 +0000875void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
876 const armnn::NormalizationDescriptor& descriptor,
877 const char* name)
878{
879 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
880
881 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
882 m_flatBufferBuilder,
883 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
884 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
885 descriptor.m_NormSize,
886 descriptor.m_Alpha,
887 descriptor.m_Beta,
888 descriptor.m_K,
889 GetFlatBufferDataLayout(descriptor.m_DataLayout));
890
891 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
892 fbNormalizationBaseLayer,
893 fbNormalizationDescriptor);
894
895 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
896}
897
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000898void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
899 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
900 const char* name)
901{
902 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
903
904 auto flatBufferDescriptor =
905 CreateStridedSliceDescriptor(m_flatBufferBuilder,
906 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
907 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
908 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
909 stridedSliceDescriptor.m_BeginMask,
910 stridedSliceDescriptor.m_EndMask,
911 stridedSliceDescriptor.m_ShrinkAxisMask,
912 stridedSliceDescriptor.m_EllipsisMask,
913 stridedSliceDescriptor.m_NewAxisMask,
914 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
915
916 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
917 flatBufferBaseLayer,
918 flatBufferDescriptor);
919
920 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
921}
922
Conor Kennedyda1f9752019-03-01 14:37:12 +0000923void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
924{
925 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
926 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
927
928 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
929}
930
Sadik Armaganeff363d2019-04-05 15:25:46 +0100931void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
932{
933 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
934 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
935
936 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
937}
938
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000939fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000940 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000941{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000942 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
943
Mike Kelly8c1701a2019-02-11 17:01:27 +0000944 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
945 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
946
947 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000948 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000949 m_flatBufferBuilder.CreateString(layer->GetName()),
950 layerType,
951 m_flatBufferBuilder.CreateVector(inputSlots),
952 m_flatBufferBuilder.CreateVector(outputSlots));
953}
954
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000955void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000956{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000957 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000958 m_serializedLayers.push_back(anyLayer);
959}
960
Mike Kellya0766c32019-02-19 17:22:07 +0000961template <typename T>
962flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
963{
964 const T* buffer = reinterpret_cast<const T*>(memory);
965 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
966 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
967 return fbVector;
968}
969
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000970flatbuffers::Offset<serializer::ConstTensor>
971 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000972{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000973 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000974
975 // Get the dimensions
976 std::vector<unsigned int> shape;
977
978 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
979 {
980 shape.push_back(tensorInfo.GetShape()[dim]);
981 }
982
983 // Create FlatBuffer TensorInfo
984 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
985 m_flatBufferBuilder.CreateVector(shape),
986 GetFlatBufferDataType(tensorInfo.GetDataType()),
987 tensorInfo.GetQuantizationScale(),
988 tensorInfo.GetQuantizationOffset());
989 flatbuffers::Offset<void> fbPayload;
990
991 switch (tensorInfo.GetDataType())
992 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000993 case armnn::DataType::Float32:
994 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000995 {
996 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
997 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
998 m_flatBufferBuilder,
999 fbVector);
1000 fbPayload = flatBuffersData.o;
1001 break;
1002 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001003 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +00001004 {
1005 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1006 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1007 m_flatBufferBuilder,
1008 fbVector);
1009 fbPayload = flatBuffersData.o;
1010 break;
1011 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001012 case armnn::DataType::QuantisedSymm16:
1013 {
1014 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1015 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1016 m_flatBufferBuilder,
1017 fbVector);
1018 fbPayload = flatBuffersData.o;
1019 break;
1020 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001021 case armnn::DataType::QuantisedAsymm8:
1022 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001023 default:
1024 {
1025 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1026 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1027 m_flatBufferBuilder,
1028 fbVector);
1029 fbPayload = flatBuffersData.o;
1030 }
1031 }
1032 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1033 m_flatBufferBuilder,
1034 flatBufferTensorInfo,
1035 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1036 fbPayload);
1037 return flatBufferConstTensor;
1038}
1039
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001040std::vector<fb::Offset<serializer::InputSlot>>
1041 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001042{
Mike Kellya0766c32019-02-19 17:22:07 +00001043 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001044
1045 // Get the InputSlots
1046 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1047 {
1048 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1049
1050 // Get the Connection for the InputSlot
1051 const IOutputSlot* connection = inputSlot.GetConnection();
1052
1053 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001054 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1055 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001056 // Create FlatBuffer InputSlot
1057 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1058 }
1059 return inputSlots;
1060}
1061
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001062std::vector<fb::Offset<serializer::OutputSlot>>
1063 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001064{
1065 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1066
1067 // Get the OutputSlots
1068 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1069 {
1070 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001071 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001072
1073 // Get the dimensions
1074 std::vector<unsigned int> shape;
1075 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1076 {
1077 shape.push_back(tensorInfo.GetShape()[dim]);
1078 }
1079
1080 // Create FlatBuffer TensorInfo
1081 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1082 m_flatBufferBuilder.CreateVector(shape),
1083 GetFlatBufferDataType(tensorInfo.GetDataType()),
1084 tensorInfo.GetQuantizationScale(),
1085 tensorInfo.GetQuantizationOffset());
1086
1087 // Create FlatBuffer Outputslot
1088 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1089 slotIndex,
1090 flatBufferTensorInfo));
1091 }
1092 return outputSlots;
1093}
1094
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001095
1096ISerializer* ISerializer::CreateRaw()
1097{
1098 return new Serializer();
1099}
1100
1101ISerializerPtr ISerializer::Create()
1102{
1103 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1104}
1105
1106void ISerializer::Destroy(ISerializer* serializer)
1107{
1108 delete serializer;
1109}
1110
1111void Serializer::Serialize(const INetwork& inNetwork)
1112{
1113 // Iterate through to network
1114 inNetwork.Accept(m_SerializerVisitor);
1115 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1116
1117 // Create FlatBuffer SerializedGraph
1118 auto serializedGraph = serializer::CreateSerializedGraph(
1119 fbBuilder,
1120 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1121 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1122 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1123
1124 // Serialize the graph
1125 fbBuilder.Finish(serializedGraph);
1126}
1127
1128bool Serializer::SaveSerializedToStream(std::ostream& stream)
1129{
1130 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1131
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001132 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1133 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001134 return !stream.bad();
1135}
1136
Matteo Martincighec333912019-02-13 15:12:39 +00001137} // namespace armnnSerializer