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