blob: 05df2c942aa1ed49522765e7cf9a8ef283837aa2 [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,
Jan Eilersf8c62972019-07-17 11:07:49 +0100405 descriptor.m_ProjectionEnabled,
406 descriptor.m_LayerNormEnabled);
Jim Flynn11af3752019-03-19 17:22:29 +0000407
408 // Get mandatory input parameters
409 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
410 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
411 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
412 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
413 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
414 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
415 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
416 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
417 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
418
419 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
420 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
421 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
422 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
423 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
424 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
425 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
426 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
427 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
Jan Eilersf8c62972019-07-17 11:07:49 +0100428 flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
429 flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
430 flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
431 flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;
Jim Flynn11af3752019-03-19 17:22:29 +0000432
433 if (!descriptor.m_CifgEnabled)
434 {
435 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
436 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
437 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
438 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
439 }
440
441 if (descriptor.m_ProjectionEnabled)
442 {
443 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
444 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
445 }
446
447 if (descriptor.m_PeepholeEnabled)
448 {
449 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
450 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
451 }
452
Jan Eilersf8c62972019-07-17 11:07:49 +0100453 if (descriptor.m_LayerNormEnabled)
454 {
455 if (!descriptor.m_CifgEnabled)
456 {
457 inputLayerNormWeights = CreateConstTensorInfo((*params.m_InputLayerNormWeights));
458 }
459 forgetLayerNormWeights = CreateConstTensorInfo(*params.m_ForgetLayerNormWeights);
460 cellLayerNormWeights = CreateConstTensorInfo(*params.m_CellLayerNormWeights);
461 outputLayerNormWeights = CreateConstTensorInfo(*params.m_OutputLayerNormWeights);
462 }
463
Jim Flynn11af3752019-03-19 17:22:29 +0000464 auto fbLstmParams = serializer::CreateLstmInputParams(
465 m_flatBufferBuilder,
466 inputToForgetWeights,
467 inputToCellWeights,
468 inputToOutputWeights,
469 recurrentToForgetWeights,
470 recurrentToCellWeights,
471 recurrentToOutputWeights,
472 forgetGateBias,
473 cellBias,
474 outputGateBias,
475 inputToInputWeights,
476 recurrentToInputWeights,
477 cellToInputWeights,
478 inputGateBias,
479 projectionWeights,
480 projectionBias,
481 cellToForgetWeights,
Jan Eilersf8c62972019-07-17 11:07:49 +0100482 cellToOutputWeights,
483 inputLayerNormWeights,
484 forgetLayerNormWeights,
485 cellLayerNormWeights,
486 outputLayerNormWeights);
Jim Flynn11af3752019-03-19 17:22:29 +0000487
488 auto fbLstmLayer = serializer::CreateLstmLayer(
489 m_flatBufferBuilder,
490 fbLstmBaseLayer,
491 fbLstmDescriptor,
492 fbLstmParams);
493
494 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
495}
496
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000497void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
498{
499 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
500 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
501
502 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
503}
504
505void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
506 const armnn::MeanDescriptor& descriptor,
507 const char* name)
508{
509 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
510 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
511 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
512 descriptor.m_KeepDims);
513
514 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
515 fbMeanBaseLayer,
516 fbMeanDescriptor);
517
518 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
519}
520
521void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
522{
523 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
524 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
525
526 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
527}
528
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100529void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
530{
531 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
532 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
533
534 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
535}
536
Jim Flynnac25a1b2019-02-28 10:40:49 +0000537void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
Jim Flynne242f2d2019-05-22 14:24:13 +0100538 const armnn::MergerDescriptor& mergerDescriptor,
Jim Flynnac25a1b2019-02-28 10:40:49 +0000539 const char* name)
540{
Jim Flynne242f2d2019-05-22 14:24:13 +0100541 VisitConcatLayer(layer, mergerDescriptor, name);
542}
543
544void SerializerVisitor::VisitConcatLayer(const armnn::IConnectableLayer* layer,
545 const armnn::ConcatDescriptor& concatDescriptor,
546 const char* name)
547{
548 auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000549
550 std::vector<flatbuffers::Offset<UintVector>> views;
Jim Flynne242f2d2019-05-22 14:24:13 +0100551 for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000552 {
Jim Flynne242f2d2019-05-22 14:24:13 +0100553 const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000554 std::vector<uint32_t> origins;
Jim Flynne242f2d2019-05-22 14:24:13 +0100555 for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000556 {
557 origins.push_back(origin[d]);
558 }
559 auto view = m_flatBufferBuilder.CreateVector(origins);
560 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
561 views.push_back(uintVector);
562 }
563
Jim Flynne242f2d2019-05-22 14:24:13 +0100564 auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
565 concatDescriptor.GetConcatAxis(),
566 concatDescriptor.GetNumViews(),
567 concatDescriptor.GetNumDimensions(),
Jim Flynnac25a1b2019-02-28 10:40:49 +0000568 m_flatBufferBuilder.CreateVector(views));
569
Jim Flynne242f2d2019-05-22 14:24:13 +0100570 auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
571 flatBufferConcatBaseLayer,
572 flatBufferConcatDescriptor);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000573
Jim Flynne242f2d2019-05-22 14:24:13 +0100574 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000575}
576
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000577void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000578{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000579 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
580 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
581 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000582
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000583 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000584}
585
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000586void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
587 const armnn::PadDescriptor& padDescriptor,
588 const char* name)
589{
590 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
591
592 std::vector<unsigned int> padList;
593 for (auto& p: padDescriptor.m_PadList)
594 {
595 padList.push_back(p.first);
596 padList.push_back(p.second);
597 }
598
599 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
David Monahan34757812019-06-19 11:47:21 +0100600 m_flatBufferBuilder.CreateVector(padList),
Aron Virginas-Tarf3569052019-07-05 16:01:08 +0100601 padDescriptor.m_PadValue);
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000602
603 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
604 flatBufferBaseLayer,
605 flatBufferPadDesc);
606
607 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
608}
609
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000610void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
611 const armnn::PermuteDescriptor& permuteDescriptor,
612 const char* name)
613{
614 // Create FlatBuffer BaseLayer
615 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
616
617 std::vector<unsigned int> dimMappings;
618 for (auto& v: permuteDescriptor.m_DimMappings)
619 {
620 dimMappings.push_back(v);
621 }
622
623 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
624 m_flatBufferBuilder.CreateVector(dimMappings));
625
626 // Create the FlatBuffer PermuteLayer
627 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
628 flatBufferPermuteBaseLayer,
629 flatBufferPermuteDesc);
630
631 // Add the AnyLayer to the FlatBufferLayers
632 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
633}
634
Saoirse Stewart263829c2019-02-19 15:54:14 +0000635// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000636void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000637 const armnn::ReshapeDescriptor& reshapeDescriptor,
638 const char* name)
639{
640 // Create FlatBuffer BaseLayer
641 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
642
643 std::vector<unsigned int> targetShape;
644 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
645 {
646 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
647 }
648
649 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
650 m_flatBufferBuilder.CreateVector(targetShape));
651
652 // Create the FlatBuffer ReshapeLayer
653 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
654 flatBufferReshapeDesc);
655
656 // Add the AnyLayer to the FlatBufferLayers
657 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
658}
659
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000660void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
661 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
662 const char* name)
663{
664 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
665
666 auto flatBufferDescriptor =
667 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
668 resizeDescriptor.m_TargetWidth,
669 resizeDescriptor.m_TargetHeight,
670 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
671
672 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
673 flatBufferBaseLayer,
674 flatBufferDescriptor);
675
676 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
677}
678
Teresa Charlina9075df2019-06-27 15:41:57 +0100679void SerializerVisitor::VisitResizeLayer(const armnn::IConnectableLayer* layer,
680 const armnn::ResizeDescriptor& resizeDescriptor,
681 const char* name)
682{
FinnWilliamsArm6fb339a2019-06-28 15:07:10 +0100683 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Resize);
684
685 auto flatBufferDescriptor =
686 CreateResizeDescriptor(m_flatBufferBuilder,
687 resizeDescriptor.m_TargetHeight,
688 resizeDescriptor.m_TargetWidth,
689 GetFlatBufferResizeMethod(resizeDescriptor.m_Method),
690 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
691
692 auto flatBufferLayer = serializer::CreateResizeLayer(m_flatBufferBuilder,
693 flatBufferBaseLayer,
694 flatBufferDescriptor);
695
696 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeLayer);
Teresa Charlina9075df2019-06-27 15:41:57 +0100697}
698
Sadik Armagan8b42a382019-03-01 14:24:49 +0000699void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
700{
701 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
702 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
703
704 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
705}
706
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000707// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000708void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
709 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000710 const char* name)
711{
712 // Create FlatBuffer BaseLayer
713 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
714
715 // Create the FlatBuffer SoftmaxDescriptor
716 auto flatBufferSoftmaxDesc =
717 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
718
719 // Create the FlatBuffer SoftmaxLayer
720 auto flatBufferSoftmaxLayer =
721 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
722 flatBufferSoftmaxBaseLayer,
723 flatBufferSoftmaxDesc);
724
725 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
726}
727
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000728void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
729 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000730 const char* name)
731{
732 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
733 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
734 m_flatBufferBuilder,
735 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
736 pooling2dDescriptor.m_PadLeft,
737 pooling2dDescriptor.m_PadRight,
738 pooling2dDescriptor.m_PadTop,
739 pooling2dDescriptor.m_PadBottom,
740 pooling2dDescriptor.m_PoolWidth,
741 pooling2dDescriptor.m_PoolHeight,
742 pooling2dDescriptor.m_StrideX,
743 pooling2dDescriptor.m_StrideY,
744 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
745 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
746 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
747
748 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
749 fbPooling2dBaseLayer,
750 fbPooling2dDescriptor);
751
752 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
753}
754
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100755void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
756 const char* name)
757{
Ellen Norris-Thompson51982472019-06-19 11:46:21 +0100758 // Create FlatBuffer BaseLayer
759 auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
760
761 // Create the FlatBuffer AdditionLayer
762 auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
763
764 // Add the AnyLayer to the FlatBufferLayers
765 CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100766}
767
Derek Lamberti87acb272019-03-27 16:51:31 +0000768void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
769{
770 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
771 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
772 fbQuantizeBaseLayer);
773 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
774}
775
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000776// Build FlatBuffer for FullyConnected Layer
777void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
778 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
779 const armnn::ConstTensor& weights,
780 const armnn::Optional<armnn::ConstTensor>& biases,
781 const char* name)
782{
783 // Create FlatBuffer BaseLayer
784 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
785
786 // Create FlatBuffer FullyConnectedDescriptor
787 auto flatBufferDescriptor =
788 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
789 fullyConnectedDescriptor.m_BiasEnabled,
790 fullyConnectedDescriptor.m_TransposeWeightMatrix);
791
792 // Create FlatBuffer weights data
793 auto flatBufferWeights = CreateConstTensorInfo(weights);
794
795 // Create FlatBuffer bias data
796 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
797 if (fullyConnectedDescriptor.m_BiasEnabled)
798 {
799 flatBufferBiases = CreateConstTensorInfo(biases.value());
800 }
801
802 // Create FlatBuffer FullyConnectedLayer
803 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
804 flatBufferBaseLayer,
805 flatBufferDescriptor,
806 flatBufferWeights,
807 flatBufferBiases);
808
809 // Add created FullyConnectedLayer to the FlatBufferLayers
810 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
811}
812
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000813// Build FlatBuffer for SpaceToBatchNd Layer
814void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
815 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
816 const char* name)
817{
818 // Create FlatBuffer BaseLayer
819 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
820
821 std::vector<unsigned int> padList;
822 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
823 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
824 {
825 padList.push_back(pad.first);
826 padList.push_back(pad.second);
827 }
828
829 auto flatBufferDescriptor =
830 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
831 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
832 m_flatBufferBuilder.CreateVector(padList),
833 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
834
835 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
836 flatBufferBaseLayer,
837 flatBufferDescriptor);
838
839 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
840}
841
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100842// Build FlatBuffer for SpaceToDepthLayer
843void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
844 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
845 const char* name)
846{
Aron Virginas-Taraa067142019-06-11 16:01:44 +0100847 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
848 auto flatBufferDescriptor =
849 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
850 spaceToDepthDescriptor.m_BlockSize,
851 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
852
853 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
854 flatBufferBaseLayer,
855 flatBufferDescriptor);
856
857 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100858}
859
Jim Flynn18ce3382019-03-08 11:08:30 +0000860// Build FlatBuffer for Splitter Layer
861void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
862 const armnn::ViewsDescriptor& viewsDescriptor,
863 const char* name)
864{
865 // Create FlatBuffer ViewOrigins
866 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
867 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
868
869 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
870 {
871 std::vector<uint32_t> viewOrigin;
872 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
873
874 // Copy vector
875 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
876 {
877 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
878 }
879
880 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
881 m_flatBufferBuilder.CreateVector(viewOrigin)));
882 }
883
884 // Create FlatBuffer OriginsDescriptor
885 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
886 viewsDescriptor.GetOrigins().GetConcatAxis(),
887 viewsDescriptor.GetOrigins().GetNumViews(),
888 viewsDescriptor.GetOrigins().GetNumDimensions(),
889 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
890
891 // Create FlatBuffer ViewOrigins
892 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
893 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
894
895 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
896 {
897 std::vector<uint32_t> viewSize;
898 viewSize.reserve(viewsDescriptor.GetNumDimensions());
899
900 // Copy vector
901 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
902 {
903 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
904 }
905
906 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
907 m_flatBufferBuilder.CreateVector(viewSize)));
908 }
909
910 // Create FlatBuffer ViewsDescriptor
911 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
912 flatBufferOriginDescriptor,
913 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
914
915 // Create FlatBuffer BaseLayer
916 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
917
918 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
919 flatBufferBaseLayer,
920 flatBufferViewsDescriptor);
921
922 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
923}
924
Nina Drozd57728782019-02-27 10:53:27 +0000925void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
926 const armnn::NormalizationDescriptor& descriptor,
927 const char* name)
928{
929 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
930
931 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
932 m_flatBufferBuilder,
933 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
934 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
935 descriptor.m_NormSize,
936 descriptor.m_Alpha,
937 descriptor.m_Beta,
938 descriptor.m_K,
939 GetFlatBufferDataLayout(descriptor.m_DataLayout));
940
941 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
942 fbNormalizationBaseLayer,
943 fbNormalizationDescriptor);
944
945 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
946}
947
Matthew Jackson2b8c1da2019-07-04 14:59:16 +0100948void SerializerVisitor::VisitStackLayer(const armnn::IConnectableLayer* layer,
949 const armnn::StackDescriptor& stackDescriptor,
950 const char* name)
951{
Matthew Jacksonb5433ee2019-07-11 15:54:20 +0100952 auto stackBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Stack);
953
954 std::vector<unsigned int> inputShape;
955 for (unsigned int i =0; i < stackDescriptor.m_InputShape.GetNumDimensions(); i++)
956 {
957 inputShape.push_back(stackDescriptor.m_InputShape[i]);
958 }
959
960 auto flatBufferStackDescriptor = CreateStackDescriptor(m_flatBufferBuilder,
961 stackDescriptor.m_Axis,
962 stackDescriptor.m_NumInputs,
963 m_flatBufferBuilder.CreateVector(inputShape));
964
965 auto stackLayer = serializer::CreateStackLayer(m_flatBufferBuilder, stackBaseLayer, flatBufferStackDescriptor);
966 CreateAnyLayer(stackLayer.o, serializer::Layer::Layer_StackLayer);
Matthew Jackson2b8c1da2019-07-04 14:59:16 +0100967}
968
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000969void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
970 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
971 const char* name)
972{
973 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
974
975 auto flatBufferDescriptor =
976 CreateStridedSliceDescriptor(m_flatBufferBuilder,
977 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
978 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
979 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
980 stridedSliceDescriptor.m_BeginMask,
981 stridedSliceDescriptor.m_EndMask,
982 stridedSliceDescriptor.m_ShrinkAxisMask,
983 stridedSliceDescriptor.m_EllipsisMask,
984 stridedSliceDescriptor.m_NewAxisMask,
985 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
986
987 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
988 flatBufferBaseLayer,
989 flatBufferDescriptor);
990
991 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
992}
993
Conor Kennedyda1f9752019-03-01 14:37:12 +0000994void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
995{
996 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
997 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
998
999 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
1000}
1001
Sadik Armaganeff363d2019-04-05 15:25:46 +01001002void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
1003{
1004 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
1005 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
1006
1007 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
1008}
1009
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001010void SerializerVisitor::VisitTransposeConvolution2dLayer(
1011 const armnn::IConnectableLayer* layer,
1012 const armnn::TransposeConvolution2dDescriptor& descriptor,
1013 const armnn::ConstTensor& weights,
1014 const armnn::Optional<armnn::ConstTensor>& biases,
1015 const char* name)
1016{
Aron Virginas-Tarcb549302019-06-21 13:53:38 +01001017 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
1018 auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
1019 descriptor.m_PadLeft,
1020 descriptor.m_PadRight,
1021 descriptor.m_PadTop,
1022 descriptor.m_PadBottom,
1023 descriptor.m_StrideX,
1024 descriptor.m_StrideY,
1025 descriptor.m_BiasEnabled,
1026 GetFlatBufferDataLayout(descriptor.m_DataLayout));
1027
1028 // weights & biases
1029 auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
1030 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
1031 if (biases.has_value())
1032 {
1033 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
1034 }
1035
1036 auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
1037 fbBaseLayer,
1038 fbDescriptor,
1039 fbWeightsConstTensorInfo,
1040 fbBiasesConstTensorInfo);
1041
1042 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001043}
1044
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001045fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001046 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001047{
Sadik Armagandb059fd2019-03-20 12:28:32 +00001048 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
1049
Mike Kelly8c1701a2019-02-11 17:01:27 +00001050 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
1051 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
1052
1053 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +00001054 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +00001055 m_flatBufferBuilder.CreateString(layer->GetName()),
1056 layerType,
1057 m_flatBufferBuilder.CreateVector(inputSlots),
1058 m_flatBufferBuilder.CreateVector(outputSlots));
1059}
1060
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001061void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001062{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001063 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +00001064 m_serializedLayers.push_back(anyLayer);
1065}
1066
Mike Kellya0766c32019-02-19 17:22:07 +00001067template <typename T>
1068flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
1069{
1070 const T* buffer = reinterpret_cast<const T*>(memory);
1071 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
1072 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
1073 return fbVector;
1074}
1075
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001076flatbuffers::Offset<serializer::ConstTensor>
1077 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +00001078{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001079 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +00001080
1081 // Get the dimensions
1082 std::vector<unsigned int> shape;
1083
1084 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1085 {
1086 shape.push_back(tensorInfo.GetShape()[dim]);
1087 }
1088
1089 // Create FlatBuffer TensorInfo
1090 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1091 m_flatBufferBuilder.CreateVector(shape),
1092 GetFlatBufferDataType(tensorInfo.GetDataType()),
1093 tensorInfo.GetQuantizationScale(),
1094 tensorInfo.GetQuantizationOffset());
1095 flatbuffers::Offset<void> fbPayload;
1096
1097 switch (tensorInfo.GetDataType())
1098 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001099 case armnn::DataType::Float32:
1100 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +00001101 {
1102 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1103 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1104 m_flatBufferBuilder,
1105 fbVector);
1106 fbPayload = flatBuffersData.o;
1107 break;
1108 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001109 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +00001110 {
1111 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1112 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1113 m_flatBufferBuilder,
1114 fbVector);
1115 fbPayload = flatBuffersData.o;
1116 break;
1117 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001118 case armnn::DataType::QuantisedSymm16:
1119 {
1120 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1121 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1122 m_flatBufferBuilder,
1123 fbVector);
1124 fbPayload = flatBuffersData.o;
1125 break;
1126 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001127 case armnn::DataType::QuantisedAsymm8:
1128 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001129 default:
1130 {
1131 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1132 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1133 m_flatBufferBuilder,
1134 fbVector);
1135 fbPayload = flatBuffersData.o;
1136 }
1137 }
1138 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1139 m_flatBufferBuilder,
1140 flatBufferTensorInfo,
1141 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1142 fbPayload);
1143 return flatBufferConstTensor;
1144}
1145
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001146std::vector<fb::Offset<serializer::InputSlot>>
1147 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001148{
Mike Kellya0766c32019-02-19 17:22:07 +00001149 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001150
1151 // Get the InputSlots
1152 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1153 {
1154 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1155
1156 // Get the Connection for the InputSlot
1157 const IOutputSlot* connection = inputSlot.GetConnection();
1158
1159 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001160 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1161 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001162 // Create FlatBuffer InputSlot
1163 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1164 }
1165 return inputSlots;
1166}
1167
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001168std::vector<fb::Offset<serializer::OutputSlot>>
1169 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001170{
1171 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1172
1173 // Get the OutputSlots
1174 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1175 {
1176 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001177 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001178
1179 // Get the dimensions
1180 std::vector<unsigned int> shape;
1181 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1182 {
1183 shape.push_back(tensorInfo.GetShape()[dim]);
1184 }
1185
1186 // Create FlatBuffer TensorInfo
1187 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1188 m_flatBufferBuilder.CreateVector(shape),
1189 GetFlatBufferDataType(tensorInfo.GetDataType()),
1190 tensorInfo.GetQuantizationScale(),
1191 tensorInfo.GetQuantizationOffset());
1192
1193 // Create FlatBuffer Outputslot
1194 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1195 slotIndex,
1196 flatBufferTensorInfo));
1197 }
1198 return outputSlots;
1199}
1200
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001201
1202ISerializer* ISerializer::CreateRaw()
1203{
1204 return new Serializer();
1205}
1206
1207ISerializerPtr ISerializer::Create()
1208{
1209 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1210}
1211
1212void ISerializer::Destroy(ISerializer* serializer)
1213{
1214 delete serializer;
1215}
1216
1217void Serializer::Serialize(const INetwork& inNetwork)
1218{
1219 // Iterate through to network
1220 inNetwork.Accept(m_SerializerVisitor);
1221 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1222
1223 // Create FlatBuffer SerializedGraph
1224 auto serializedGraph = serializer::CreateSerializedGraph(
1225 fbBuilder,
1226 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1227 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1228 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1229
1230 // Serialize the graph
1231 fbBuilder.Finish(serializedGraph);
1232}
1233
1234bool Serializer::SaveSerializedToStream(std::ostream& stream)
1235{
1236 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1237
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001238 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1239 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001240 return !stream.bad();
1241}
1242
Matteo Martincighec333912019-02-13 15:12:39 +00001243} // namespace armnnSerializer