blob: 865ed7af518cf8db1b2f2add4d039acfc0043f66 [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,
518 const armnn::OriginsDescriptor& mergerDescriptor,
519 const char* name)
520{
521 auto flatBufferMergerBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merger);
522
523 std::vector<flatbuffers::Offset<UintVector>> views;
524 for (unsigned int v = 0; v < mergerDescriptor.GetNumViews(); ++v)
525 {
526 const uint32_t* origin = mergerDescriptor.GetViewOrigin(v);
527 std::vector<uint32_t> origins;
528 for (unsigned int d = 0; d < mergerDescriptor.GetNumDimensions(); ++d)
529 {
530 origins.push_back(origin[d]);
531 }
532 auto view = m_flatBufferBuilder.CreateVector(origins);
533 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
534 views.push_back(uintVector);
535 }
536
537 auto flatBufferMergerDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
538 mergerDescriptor.GetConcatAxis(),
539 mergerDescriptor.GetNumViews(),
540 mergerDescriptor.GetNumDimensions(),
541 m_flatBufferBuilder.CreateVector(views));
542
543 auto flatBufferLayer = CreateMergerLayer(m_flatBufferBuilder,
544 flatBufferMergerBaseLayer,
545 flatBufferMergerDescriptor);
546
547 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_MergerLayer);
548}
549
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000550void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000551{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000552 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
553 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
554 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000555
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000556 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000557}
558
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000559void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
560 const armnn::PadDescriptor& padDescriptor,
561 const char* name)
562{
563 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
564
565 std::vector<unsigned int> padList;
566 for (auto& p: padDescriptor.m_PadList)
567 {
568 padList.push_back(p.first);
569 padList.push_back(p.second);
570 }
571
572 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
573 m_flatBufferBuilder.CreateVector(padList));
574
575 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
576 flatBufferBaseLayer,
577 flatBufferPadDesc);
578
579 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
580}
581
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000582void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
583 const armnn::PermuteDescriptor& permuteDescriptor,
584 const char* name)
585{
586 // Create FlatBuffer BaseLayer
587 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
588
589 std::vector<unsigned int> dimMappings;
590 for (auto& v: permuteDescriptor.m_DimMappings)
591 {
592 dimMappings.push_back(v);
593 }
594
595 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
596 m_flatBufferBuilder.CreateVector(dimMappings));
597
598 // Create the FlatBuffer PermuteLayer
599 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
600 flatBufferPermuteBaseLayer,
601 flatBufferPermuteDesc);
602
603 // Add the AnyLayer to the FlatBufferLayers
604 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
605}
606
Saoirse Stewart263829c2019-02-19 15:54:14 +0000607// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000608void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000609 const armnn::ReshapeDescriptor& reshapeDescriptor,
610 const char* name)
611{
612 // Create FlatBuffer BaseLayer
613 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
614
615 std::vector<unsigned int> targetShape;
616 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
617 {
618 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
619 }
620
621 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
622 m_flatBufferBuilder.CreateVector(targetShape));
623
624 // Create the FlatBuffer ReshapeLayer
625 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
626 flatBufferReshapeDesc);
627
628 // Add the AnyLayer to the FlatBufferLayers
629 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
630}
631
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000632void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
633 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
634 const char* name)
635{
636 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
637
638 auto flatBufferDescriptor =
639 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
640 resizeDescriptor.m_TargetWidth,
641 resizeDescriptor.m_TargetHeight,
642 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
643
644 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
645 flatBufferBaseLayer,
646 flatBufferDescriptor);
647
648 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
649}
650
Sadik Armagan8b42a382019-03-01 14:24:49 +0000651void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
652{
653 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
654 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
655
656 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
657}
658
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000659// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000660void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
661 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000662 const char* name)
663{
664 // Create FlatBuffer BaseLayer
665 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
666
667 // Create the FlatBuffer SoftmaxDescriptor
668 auto flatBufferSoftmaxDesc =
669 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
670
671 // Create the FlatBuffer SoftmaxLayer
672 auto flatBufferSoftmaxLayer =
673 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
674 flatBufferSoftmaxBaseLayer,
675 flatBufferSoftmaxDesc);
676
677 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
678}
679
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000680void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
681 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000682 const char* name)
683{
684 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
685 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
686 m_flatBufferBuilder,
687 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
688 pooling2dDescriptor.m_PadLeft,
689 pooling2dDescriptor.m_PadRight,
690 pooling2dDescriptor.m_PadTop,
691 pooling2dDescriptor.m_PadBottom,
692 pooling2dDescriptor.m_PoolWidth,
693 pooling2dDescriptor.m_PoolHeight,
694 pooling2dDescriptor.m_StrideX,
695 pooling2dDescriptor.m_StrideY,
696 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
697 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
698 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
699
700 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
701 fbPooling2dBaseLayer,
702 fbPooling2dDescriptor);
703
704 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
705}
706
Derek Lamberti87acb272019-03-27 16:51:31 +0000707void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
708{
709 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
710 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
711 fbQuantizeBaseLayer);
712 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
713}
714
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000715// Build FlatBuffer for FullyConnected Layer
716void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
717 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
718 const armnn::ConstTensor& weights,
719 const armnn::Optional<armnn::ConstTensor>& biases,
720 const char* name)
721{
722 // Create FlatBuffer BaseLayer
723 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
724
725 // Create FlatBuffer FullyConnectedDescriptor
726 auto flatBufferDescriptor =
727 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
728 fullyConnectedDescriptor.m_BiasEnabled,
729 fullyConnectedDescriptor.m_TransposeWeightMatrix);
730
731 // Create FlatBuffer weights data
732 auto flatBufferWeights = CreateConstTensorInfo(weights);
733
734 // Create FlatBuffer bias data
735 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
736 if (fullyConnectedDescriptor.m_BiasEnabled)
737 {
738 flatBufferBiases = CreateConstTensorInfo(biases.value());
739 }
740
741 // Create FlatBuffer FullyConnectedLayer
742 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
743 flatBufferBaseLayer,
744 flatBufferDescriptor,
745 flatBufferWeights,
746 flatBufferBiases);
747
748 // Add created FullyConnectedLayer to the FlatBufferLayers
749 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
750}
751
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000752// Build FlatBuffer for SpaceToBatchNd Layer
753void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
754 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
755 const char* name)
756{
757 // Create FlatBuffer BaseLayer
758 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
759
760 std::vector<unsigned int> padList;
761 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
762 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
763 {
764 padList.push_back(pad.first);
765 padList.push_back(pad.second);
766 }
767
768 auto flatBufferDescriptor =
769 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
770 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
771 m_flatBufferBuilder.CreateVector(padList),
772 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
773
774 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
775 flatBufferBaseLayer,
776 flatBufferDescriptor);
777
778 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
779}
780
Jim Flynn18ce3382019-03-08 11:08:30 +0000781// Build FlatBuffer for Splitter Layer
782void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
783 const armnn::ViewsDescriptor& viewsDescriptor,
784 const char* name)
785{
786 // Create FlatBuffer ViewOrigins
787 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
788 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
789
790 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
791 {
792 std::vector<uint32_t> viewOrigin;
793 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
794
795 // Copy vector
796 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
797 {
798 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
799 }
800
801 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
802 m_flatBufferBuilder.CreateVector(viewOrigin)));
803 }
804
805 // Create FlatBuffer OriginsDescriptor
806 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
807 viewsDescriptor.GetOrigins().GetConcatAxis(),
808 viewsDescriptor.GetOrigins().GetNumViews(),
809 viewsDescriptor.GetOrigins().GetNumDimensions(),
810 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
811
812 // Create FlatBuffer ViewOrigins
813 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
814 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
815
816 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
817 {
818 std::vector<uint32_t> viewSize;
819 viewSize.reserve(viewsDescriptor.GetNumDimensions());
820
821 // Copy vector
822 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
823 {
824 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
825 }
826
827 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
828 m_flatBufferBuilder.CreateVector(viewSize)));
829 }
830
831 // Create FlatBuffer ViewsDescriptor
832 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
833 flatBufferOriginDescriptor,
834 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
835
836 // Create FlatBuffer BaseLayer
837 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
838
839 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
840 flatBufferBaseLayer,
841 flatBufferViewsDescriptor);
842
843 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
844}
845
Nina Drozd57728782019-02-27 10:53:27 +0000846void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
847 const armnn::NormalizationDescriptor& descriptor,
848 const char* name)
849{
850 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
851
852 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
853 m_flatBufferBuilder,
854 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
855 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
856 descriptor.m_NormSize,
857 descriptor.m_Alpha,
858 descriptor.m_Beta,
859 descriptor.m_K,
860 GetFlatBufferDataLayout(descriptor.m_DataLayout));
861
862 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
863 fbNormalizationBaseLayer,
864 fbNormalizationDescriptor);
865
866 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
867}
868
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000869void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
870 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
871 const char* name)
872{
873 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
874
875 auto flatBufferDescriptor =
876 CreateStridedSliceDescriptor(m_flatBufferBuilder,
877 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
878 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
879 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
880 stridedSliceDescriptor.m_BeginMask,
881 stridedSliceDescriptor.m_EndMask,
882 stridedSliceDescriptor.m_ShrinkAxisMask,
883 stridedSliceDescriptor.m_EllipsisMask,
884 stridedSliceDescriptor.m_NewAxisMask,
885 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
886
887 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
888 flatBufferBaseLayer,
889 flatBufferDescriptor);
890
891 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
892}
893
Conor Kennedyda1f9752019-03-01 14:37:12 +0000894void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
895{
896 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
897 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
898
899 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
900}
901
Sadik Armaganeff363d2019-04-05 15:25:46 +0100902void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
903{
904 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
905 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
906
907 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
908}
909
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000910fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000911 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000912{
Sadik Armagandb059fd2019-03-20 12:28:32 +0000913 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
914
Mike Kelly8c1701a2019-02-11 17:01:27 +0000915 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
916 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
917
918 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +0000919 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +0000920 m_flatBufferBuilder.CreateString(layer->GetName()),
921 layerType,
922 m_flatBufferBuilder.CreateVector(inputSlots),
923 m_flatBufferBuilder.CreateVector(outputSlots));
924}
925
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000926void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000927{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000928 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000929 m_serializedLayers.push_back(anyLayer);
930}
931
Mike Kellya0766c32019-02-19 17:22:07 +0000932template <typename T>
933flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
934{
935 const T* buffer = reinterpret_cast<const T*>(memory);
936 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
937 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
938 return fbVector;
939}
940
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000941flatbuffers::Offset<serializer::ConstTensor>
942 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000943{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000944 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000945
946 // Get the dimensions
947 std::vector<unsigned int> shape;
948
949 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
950 {
951 shape.push_back(tensorInfo.GetShape()[dim]);
952 }
953
954 // Create FlatBuffer TensorInfo
955 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
956 m_flatBufferBuilder.CreateVector(shape),
957 GetFlatBufferDataType(tensorInfo.GetDataType()),
958 tensorInfo.GetQuantizationScale(),
959 tensorInfo.GetQuantizationOffset());
960 flatbuffers::Offset<void> fbPayload;
961
962 switch (tensorInfo.GetDataType())
963 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000964 case armnn::DataType::Float32:
965 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000966 {
967 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
968 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
969 m_flatBufferBuilder,
970 fbVector);
971 fbPayload = flatBuffersData.o;
972 break;
973 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000974 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000975 {
976 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
977 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
978 m_flatBufferBuilder,
979 fbVector);
980 fbPayload = flatBuffersData.o;
981 break;
982 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +0000983 case armnn::DataType::QuantisedSymm16:
984 {
985 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
986 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
987 m_flatBufferBuilder,
988 fbVector);
989 fbPayload = flatBuffersData.o;
990 break;
991 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000992 case armnn::DataType::QuantisedAsymm8:
993 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +0000994 default:
995 {
996 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
997 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
998 m_flatBufferBuilder,
999 fbVector);
1000 fbPayload = flatBuffersData.o;
1001 }
1002 }
1003 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1004 m_flatBufferBuilder,
1005 flatBufferTensorInfo,
1006 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1007 fbPayload);
1008 return flatBufferConstTensor;
1009}
1010
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001011std::vector<fb::Offset<serializer::InputSlot>>
1012 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001013{
Mike Kellya0766c32019-02-19 17:22:07 +00001014 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001015
1016 // Get the InputSlots
1017 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1018 {
1019 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1020
1021 // Get the Connection for the InputSlot
1022 const IOutputSlot* connection = inputSlot.GetConnection();
1023
1024 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001025 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1026 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001027 // Create FlatBuffer InputSlot
1028 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1029 }
1030 return inputSlots;
1031}
1032
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001033std::vector<fb::Offset<serializer::OutputSlot>>
1034 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001035{
1036 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1037
1038 // Get the OutputSlots
1039 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1040 {
1041 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001042 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001043
1044 // Get the dimensions
1045 std::vector<unsigned int> shape;
1046 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1047 {
1048 shape.push_back(tensorInfo.GetShape()[dim]);
1049 }
1050
1051 // Create FlatBuffer TensorInfo
1052 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1053 m_flatBufferBuilder.CreateVector(shape),
1054 GetFlatBufferDataType(tensorInfo.GetDataType()),
1055 tensorInfo.GetQuantizationScale(),
1056 tensorInfo.GetQuantizationOffset());
1057
1058 // Create FlatBuffer Outputslot
1059 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1060 slotIndex,
1061 flatBufferTensorInfo));
1062 }
1063 return outputSlots;
1064}
1065
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001066
1067ISerializer* ISerializer::CreateRaw()
1068{
1069 return new Serializer();
1070}
1071
1072ISerializerPtr ISerializer::Create()
1073{
1074 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1075}
1076
1077void ISerializer::Destroy(ISerializer* serializer)
1078{
1079 delete serializer;
1080}
1081
1082void Serializer::Serialize(const INetwork& inNetwork)
1083{
1084 // Iterate through to network
1085 inNetwork.Accept(m_SerializerVisitor);
1086 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1087
1088 // Create FlatBuffer SerializedGraph
1089 auto serializedGraph = serializer::CreateSerializedGraph(
1090 fbBuilder,
1091 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1092 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1093 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1094
1095 // Serialize the graph
1096 fbBuilder.Finish(serializedGraph);
1097}
1098
1099bool Serializer::SaveSerializedToStream(std::ostream& stream)
1100{
1101 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1102
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001103 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1104 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001105 return !stream.bad();
1106}
1107
Matteo Martincighec333912019-02-13 15:12:39 +00001108} // namespace armnnSerializer