• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #include "Serializer.hpp"
6 
7 #include <armnn/Descriptors.hpp>
8 #include <armnn/LstmParams.hpp>
9 #include <armnn/QuantizedLstmParams.hpp>
10 #include <armnn/utility/IgnoreUnused.hpp>
11 #include <armnn/utility/NumericCast.hpp>
12 
13 #include <iostream>
14 
15 #include <flatbuffers/util.h>
16 
17 #include "SerializerUtils.hpp"
18 
19 using namespace armnn;
20 namespace fb = flatbuffers;
21 namespace serializer = armnnSerializer;
22 
23 namespace armnnSerializer
24 {
25 
GetFlatBufferActivationFunction(armnn::ActivationFunction function)26 serializer::ActivationFunction GetFlatBufferActivationFunction(armnn::ActivationFunction function)
27 {
28     switch (function)
29     {
30         case armnn::ActivationFunction::Sigmoid:
31             return serializer::ActivationFunction::ActivationFunction_Sigmoid;
32         case armnn::ActivationFunction::TanH:
33             return serializer::ActivationFunction::ActivationFunction_TanH;
34         case armnn::ActivationFunction::Linear:
35             return serializer::ActivationFunction::ActivationFunction_Linear;
36         case armnn::ActivationFunction::ReLu:
37             return serializer::ActivationFunction::ActivationFunction_ReLu;
38         case armnn::ActivationFunction::BoundedReLu:
39             return serializer::ActivationFunction::ActivationFunction_BoundedReLu;
40         case armnn::ActivationFunction::LeakyReLu:
41             return serializer::ActivationFunction::ActivationFunction_LeakyReLu;
42         case armnn::ActivationFunction::Abs:
43             return serializer::ActivationFunction::ActivationFunction_Abs;
44         case armnn::ActivationFunction::Sqrt:
45             return serializer::ActivationFunction::ActivationFunction_Sqrt;
46         case armnn::ActivationFunction::Square:
47             return serializer::ActivationFunction::ActivationFunction_Square;
48         case armnn::ActivationFunction::Elu:
49             return serializer::ActivationFunction::ActivationFunction_Elu;
50         case armnn::ActivationFunction::HardSwish:
51             return serializer::ActivationFunction::ActivationFunction_HardSwish;
52         default:
53             return serializer::ActivationFunction::ActivationFunction_Sigmoid;
54     }
55 }
56 
GetFlatBufferArgMinMaxFunction(armnn::ArgMinMaxFunction function)57 serializer::ArgMinMaxFunction GetFlatBufferArgMinMaxFunction(armnn::ArgMinMaxFunction function)
58 {
59     switch (function)
60     {
61         case armnn::ArgMinMaxFunction::Max:
62             return serializer::ArgMinMaxFunction::ArgMinMaxFunction_Max;
63         case armnn::ArgMinMaxFunction::Min:
64         default:
65             return serializer::ArgMinMaxFunction::ArgMinMaxFunction_Min;
66     }
67 }
68 
GetSerializedId(armnn::LayerGuid guid)69 uint32_t SerializerVisitor::GetSerializedId(armnn::LayerGuid guid)
70 {
71     if (m_guidMap.empty())
72     {
73         m_guidMap.insert(std::make_pair(guid, m_layerId));
74     }
75     else if (m_guidMap.find(guid) == m_guidMap.end())
76     {
77         ++m_layerId;
78         m_guidMap.insert(std::make_pair(guid, m_layerId));
79 
80         return m_layerId;
81     }
82     return m_guidMap[guid];
83 }
84 
85 // Build FlatBuffer for Input Layer
VisitInputLayer(const armnn::IConnectableLayer * layer,LayerBindingId id,const char * name)86 void SerializerVisitor::VisitInputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
87 {
88     IgnoreUnused(name);
89 
90     // Create FlatBuffer BaseLayer
91     auto flatBufferInputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Input);
92 
93     // Create FlatBuffer BindableBaseLayer
94     auto flatBufferInputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
95                                                                                 flatBufferInputBaseLayer,
96                                                                                 id);
97     // Push layer binding id to outputIds.
98     m_inputIds.push_back(id);
99 
100     // Create the FlatBuffer InputLayer
101     auto flatBufferInputLayer = serializer::CreateInputLayer(m_flatBufferBuilder, flatBufferInputBindableBaseLayer);
102 
103     // Add the AnyLayer to the FlatBufferLayers
104     CreateAnyLayer(flatBufferInputLayer.o, serializer::Layer::Layer_InputLayer);
105 }
106 
107 // Build FlatBuffer for Output Layer
VisitOutputLayer(const armnn::IConnectableLayer * layer,LayerBindingId id,const char * name)108 void SerializerVisitor::VisitOutputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
109 {
110     IgnoreUnused(name);
111 
112     // Create FlatBuffer BaseLayer
113     auto flatBufferOutputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Output);
114 
115     // Create FlatBuffer BindableBaseLayer
116     auto flatBufferOutputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
117                                                                                  flatBufferOutputBaseLayer,
118                                                                                  id);
119     // Push layer binding id to outputIds.
120     m_outputIds.push_back(id);
121 
122     // Create the FlatBuffer OutputLayer
123     auto flatBufferOutputLayer = serializer::CreateOutputLayer(m_flatBufferBuilder, flatBufferOutputBindableBaseLayer);
124     // Add the AnyLayer to the FlatBufferLayers
125     CreateAnyLayer(flatBufferOutputLayer.o, serializer::Layer::Layer_OutputLayer);
126 }
127 
VisitAbsLayer(const armnn::IConnectableLayer * layer,const char * name)128 void SerializerVisitor::VisitAbsLayer(const armnn::IConnectableLayer* layer, const char* name)
129 {
130     IgnoreUnused(name);
131     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Abs);
132     auto flatBufferAbsLayer  = serializer::CreateAbsLayer(m_flatBufferBuilder, flatBufferBaseLayer);
133 
134     CreateAnyLayer(flatBufferAbsLayer.o, serializer::Layer::Layer_AbsLayer);
135 }
136 
137 // Build FlatBuffer for Activation Layer
VisitActivationLayer(const armnn::IConnectableLayer * layer,const armnn::ActivationDescriptor & descriptor,const char * name)138 void SerializerVisitor::VisitActivationLayer(const armnn::IConnectableLayer* layer,
139                                              const armnn::ActivationDescriptor& descriptor,
140                                              const char* name)
141 {
142     IgnoreUnused(name);
143 
144     // Create FlatBuffer BaseLayer
145     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Activation);
146 
147     // Create the FlatBuffer ActivationDescriptor
148     auto flatBufferDescriptor = CreateActivationDescriptor(m_flatBufferBuilder,
149                                                            GetFlatBufferActivationFunction(descriptor.m_Function),
150                                                            descriptor.m_A,
151                                                            descriptor.m_B);
152 
153     // Create the FlatBuffer ActivationLayer
154     auto flatBufferAdditionLayer = CreateActivationLayer(m_flatBufferBuilder,
155                                                          flatBufferBaseLayer,
156                                                          flatBufferDescriptor);
157 
158     // Add the AnyLayer to the FlatBufferLayers
159     CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_ActivationLayer);
160 }
161 
162 // Build FlatBuffer for Addition Layer
VisitAdditionLayer(const armnn::IConnectableLayer * layer,const char * name)163 void SerializerVisitor::VisitAdditionLayer(const armnn::IConnectableLayer* layer, const char* name)
164 {
165     IgnoreUnused(name);
166 
167     // Create FlatBuffer BaseLayer
168     auto flatBufferAdditionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Addition);
169 
170     // Create the FlatBuffer AdditionLayer
171     auto flatBufferAdditionLayer = serializer::CreateAdditionLayer(m_flatBufferBuilder, flatBufferAdditionBaseLayer);
172 
173     // Add the AnyLayer to the FlatBufferLayers
174     CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_AdditionLayer);
175 }
176 
177 // Build FlatBuffer for ArgMinMax Layer
VisitArgMinMaxLayer(const armnn::IConnectableLayer * layer,const armnn::ArgMinMaxDescriptor & descriptor,const char * name)178 void SerializerVisitor::VisitArgMinMaxLayer(const armnn::IConnectableLayer *layer,
179                                             const armnn::ArgMinMaxDescriptor& descriptor,
180                                             const char *name)
181 {
182     IgnoreUnused(name);
183 
184     // Create FlatBuffer BaseLayer
185     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ArgMinMax);
186 
187     // Create FlatBuffer Descriptor
188     auto flatBufferDescriptor = CreateArgMinMaxDescriptor(m_flatBufferBuilder,
189                                                           GetFlatBufferArgMinMaxFunction(descriptor.m_Function),
190                                                           descriptor.m_Axis);
191 
192     // Create FlatBuffer ArgMinMaxLayer
193     auto flatBufferLayer = CreateArgMinMaxLayer(m_flatBufferBuilder,
194                                                 flatBufferBaseLayer,
195                                                 flatBufferDescriptor);
196 
197     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ArgMinMaxLayer);
198 }
199 
200 // Build FlatBuffer for BatchToSpaceNd Layer
VisitBatchToSpaceNdLayer(const armnn::IConnectableLayer * layer,const armnn::BatchToSpaceNdDescriptor & descriptor,const char * name)201 void SerializerVisitor::VisitBatchToSpaceNdLayer(const armnn::IConnectableLayer* layer,
202                                                  const armnn::BatchToSpaceNdDescriptor& descriptor,
203                                                  const char* name)
204 {
205     IgnoreUnused(name);
206 
207     // Create FlatBuffer BaseLayer
208     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchToSpaceNd);
209 
210     std::vector<unsigned int> crops;
211     crops.reserve(descriptor.m_Crops.size() * 2);
212     for (auto& crop : descriptor.m_Crops)
213     {
214         crops.push_back(crop.first);
215         crops.push_back(crop.second);
216     }
217 
218     auto flatBufferDescriptor =
219         CreateBatchToSpaceNdDescriptor(m_flatBufferBuilder,
220                                        m_flatBufferBuilder.CreateVector(descriptor.m_BlockShape),
221                                        m_flatBufferBuilder.CreateVector(crops),
222                                        GetFlatBufferDataLayout(descriptor.m_DataLayout));
223 
224     auto flatBufferLayer = serializer::CreateBatchToSpaceNdLayer(m_flatBufferBuilder,
225                                                                  flatBufferBaseLayer,
226                                                                  flatBufferDescriptor);
227 
228     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_BatchToSpaceNdLayer);
229 }
230 
VisitBatchNormalizationLayer(const armnn::IConnectableLayer * layer,const armnn::BatchNormalizationDescriptor & batchNormDescriptor,const armnn::ConstTensor & mean,const armnn::ConstTensor & variance,const armnn::ConstTensor & beta,const armnn::ConstTensor & gamma,const char * name)231 void SerializerVisitor::VisitBatchNormalizationLayer(const armnn::IConnectableLayer* layer,
232                                                      const armnn::BatchNormalizationDescriptor& batchNormDescriptor,
233                                                      const armnn::ConstTensor& mean,
234                                                      const armnn::ConstTensor& variance,
235                                                      const armnn::ConstTensor& beta,
236                                                      const armnn::ConstTensor& gamma,
237                                                      const char* name)
238 {
239     IgnoreUnused(name);
240 
241     auto fbBatchNormalizationBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchNormalization);
242     auto fbBatchNormalizationDescriptor = serializer::CreateBatchNormalizationDescriptor(
243                                                   m_flatBufferBuilder,
244                                                   batchNormDescriptor.m_Eps,
245                                                   GetFlatBufferDataLayout(batchNormDescriptor.m_DataLayout));
246 
247     auto fbMeanConstTensorInfo     = CreateConstTensorInfo(mean);
248     auto fbVarianceConstTensorInfo = CreateConstTensorInfo(variance);
249     auto fbBetaConstTensorInfo     = CreateConstTensorInfo(beta);
250     auto fbGammaConstTensorInfo    = CreateConstTensorInfo(gamma);
251     auto fbBatchNormalizationLayer = serializer::CreateBatchNormalizationLayer(m_flatBufferBuilder,
252                                                                                fbBatchNormalizationBaseLayer,
253                                                                                fbBatchNormalizationDescriptor,
254                                                                                fbMeanConstTensorInfo,
255                                                                                fbVarianceConstTensorInfo,
256                                                                                fbBetaConstTensorInfo,
257                                                                                fbGammaConstTensorInfo);
258 
259     CreateAnyLayer(fbBatchNormalizationLayer.o, serializer::Layer::Layer_BatchNormalizationLayer);
260 }
261 
VisitComparisonLayer(const armnn::IConnectableLayer * layer,const armnn::ComparisonDescriptor & descriptor,const char * name)262 void SerializerVisitor::VisitComparisonLayer(const armnn::IConnectableLayer* layer,
263                                              const armnn::ComparisonDescriptor& descriptor,
264                                              const char* name)
265 {
266     IgnoreUnused(name);
267 
268     auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Comparison);
269     auto fbDescriptor = serializer::CreateComparisonDescriptor(
270         m_flatBufferBuilder,
271         GetFlatBufferComparisonOperation(descriptor.m_Operation));
272 
273     auto fbLayer = serializer::CreateComparisonLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
274     CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_ComparisonLayer);
275 }
276 
277 // Build FlatBuffer for Constant Layer
VisitConstantLayer(const armnn::IConnectableLayer * layer,const armnn::ConstTensor & input,const char * name)278 void SerializerVisitor::VisitConstantLayer(const armnn::IConnectableLayer* layer,
279                                            const armnn::ConstTensor& input,
280                                            const char* name)
281 {
282     IgnoreUnused(name);
283 
284     // Create FlatBuffer BaseLayer
285     auto flatBufferConstantBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Constant);
286 
287     auto flatBufferConstTensorInfo = CreateConstTensorInfo(input);
288 
289     // Create the FlatBuffer ConstantLayer
290     auto flatBufferLayer = CreateConstantLayer(m_flatBufferBuilder,
291                                                flatBufferConstantBaseLayer,
292                                                flatBufferConstTensorInfo);
293 
294     // Add the AnyLayer to the FlatBufferLayers
295     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConstantLayer);
296 }
297 
298 // Build FlatBuffer for Convolution2dLayer
VisitConvolution2dLayer(const armnn::IConnectableLayer * layer,const armnn::Convolution2dDescriptor & descriptor,const armnn::ConstTensor & weights,const armnn::Optional<armnn::ConstTensor> & biases,const char * name)299 void SerializerVisitor::VisitConvolution2dLayer(const armnn::IConnectableLayer* layer,
300                                                 const armnn::Convolution2dDescriptor& descriptor,
301                                                 const armnn::ConstTensor& weights,
302                                                 const armnn::Optional<armnn::ConstTensor>& biases,
303                                                 const char* name)
304 {
305     IgnoreUnused(name);
306 
307     // Create FlatBuffer BaseLayer
308     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
309 
310     auto flatBufferDescriptor = CreateConvolution2dDescriptor(m_flatBufferBuilder,
311                                                               descriptor.m_PadLeft,
312                                                               descriptor.m_PadRight,
313                                                               descriptor.m_PadTop,
314                                                               descriptor.m_PadBottom,
315                                                               descriptor.m_StrideX,
316                                                               descriptor.m_StrideY,
317                                                               descriptor.m_DilationX,
318                                                               descriptor.m_DilationY,
319                                                               descriptor.m_BiasEnabled,
320                                                               GetFlatBufferDataLayout(descriptor.m_DataLayout));
321     auto flatBufferWeightsConstTensorInfo = CreateConstTensorInfo(weights);
322     flatbuffers::Offset<serializer::ConstTensor> flatBufferBiasesConstTensorInfo;
323 
324     if (biases.has_value())
325     {
326         flatBufferBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
327     }
328 
329     // Create the FlatBuffer Convolution2dLayer
330     auto flatBufferLayer = CreateConvolution2dLayer(m_flatBufferBuilder,
331                                                     flatBufferBaseLayer,
332                                                     flatBufferDescriptor,
333                                                     flatBufferWeightsConstTensorInfo,
334                                                     flatBufferBiasesConstTensorInfo);
335 
336     // Add the AnyLayer to the FlatBufferLayers
337     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution2dLayer);
338 }
339 
VisitDepthToSpaceLayer(const armnn::IConnectableLayer * layer,const armnn::DepthToSpaceDescriptor & descriptor,const char * name)340 void SerializerVisitor::VisitDepthToSpaceLayer(const armnn::IConnectableLayer* layer,
341                                                const armnn::DepthToSpaceDescriptor& descriptor,
342                                                const char* name)
343 {
344     IgnoreUnused(name);
345 
346     auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthToSpace);
347     auto fbDescriptor = CreateDepthToSpaceDescriptor(m_flatBufferBuilder,
348                                                      descriptor.m_BlockSize,
349                                                      GetFlatBufferDataLayout(descriptor.m_DataLayout));
350 
351     auto fbLayer = serializer::CreateDepthToSpaceLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
352 
353     CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_DepthToSpaceLayer);
354 }
355 
VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer * layer,const armnn::DepthwiseConvolution2dDescriptor & descriptor,const armnn::ConstTensor & weights,const armnn::Optional<armnn::ConstTensor> & biases,const char * name)356 void SerializerVisitor::VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
357                                                          const armnn::DepthwiseConvolution2dDescriptor& descriptor,
358                                                          const armnn::ConstTensor& weights,
359                                                          const armnn::Optional<armnn::ConstTensor>& biases,
360                                                          const char* name)
361 {
362     IgnoreUnused(name);
363 
364     auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthwiseConvolution2d);
365     auto fbDescriptor = CreateDepthwiseConvolution2dDescriptor(m_flatBufferBuilder,
366                                                                descriptor.m_PadLeft,
367                                                                descriptor.m_PadRight,
368                                                                descriptor.m_PadTop,
369                                                                descriptor.m_PadBottom,
370                                                                descriptor.m_StrideX,
371                                                                descriptor.m_StrideY,
372                                                                descriptor.m_DilationX,
373                                                                descriptor.m_DilationY,
374                                                                descriptor.m_BiasEnabled,
375                                                                GetFlatBufferDataLayout(descriptor.m_DataLayout));
376 
377     flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
378     flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
379     if (biases.has_value())
380     {
381         fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
382     }
383 
384     auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
385                                                              fbBaseLayer,
386                                                              fbDescriptor,
387                                                              fbWeightsConstTensorInfo,
388                                                              fbBiasesConstTensorInfo);
389 
390     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
391 }
392 
VisitDequantizeLayer(const armnn::IConnectableLayer * layer,const char * name)393 void SerializerVisitor::VisitDequantizeLayer(const armnn::IConnectableLayer* layer,
394                                              const char* name)
395 {
396     IgnoreUnused(name);
397 
398     auto fbDequantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Dequantize);
399     auto fbDequantizeLayer     = serializer::CreateDequantizeLayer(m_flatBufferBuilder, fbDequantizeBaseLayer);
400 
401     CreateAnyLayer(fbDequantizeLayer.o, serializer::Layer::Layer_DequantizeLayer);
402 }
403 
VisitDetectionPostProcessLayer(const armnn::IConnectableLayer * layer,const armnn::DetectionPostProcessDescriptor & descriptor,const armnn::ConstTensor & anchors,const char * name)404 void SerializerVisitor::VisitDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
405                                                        const armnn::DetectionPostProcessDescriptor& descriptor,
406                                                        const armnn::ConstTensor& anchors,
407                                                        const char* name)
408 {
409     IgnoreUnused(name);
410 
411     auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
412     auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
413                                                              descriptor.m_MaxDetections,
414                                                              descriptor.m_MaxClassesPerDetection,
415                                                              descriptor.m_DetectionsPerClass,
416                                                              descriptor.m_NmsScoreThreshold,
417                                                              descriptor.m_NmsIouThreshold,
418                                                              descriptor.m_NumClasses,
419                                                              descriptor.m_UseRegularNms,
420                                                              descriptor.m_ScaleX,
421                                                              descriptor.m_ScaleY,
422                                                              descriptor.m_ScaleW,
423                                                              descriptor.m_ScaleH);
424 
425     flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);
426 
427     auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
428                                                            fbBaseLayer,
429                                                            fbDescriptor,
430                                                            fbAnchorsConstTensorInfo);
431 
432     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
433 }
434 
VisitDivisionLayer(const armnn::IConnectableLayer * layer,const char * name)435 void SerializerVisitor::VisitDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
436 {
437     IgnoreUnused(name);
438 
439     auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
440     auto fbDivisionLayer     = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);
441 
442     CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
443 }
444 
VisitElementwiseUnaryLayer(const armnn::IConnectableLayer * layer,const armnn::ElementwiseUnaryDescriptor & descriptor,const char * name)445 void SerializerVisitor::VisitElementwiseUnaryLayer(const armnn::IConnectableLayer* layer,
446                                                    const armnn::ElementwiseUnaryDescriptor& descriptor,
447                                                    const char* name)
448 {
449     IgnoreUnused(name);
450 
451     auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_ElementwiseUnary);
452     auto fbDescriptor = serializer::CreateElementwiseUnaryDescriptor(
453         m_flatBufferBuilder,
454         GetFlatBufferUnaryOperation(descriptor.m_Operation));
455 
456     auto fbLayer = serializer::CreateElementwiseUnaryLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
457     CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_ElementwiseUnaryLayer);
458 }
459 
VisitEqualLayer(const armnn::IConnectableLayer * layer,const char * name)460 void SerializerVisitor::VisitEqualLayer(const armnn::IConnectableLayer* layer, const char* name)
461 {
462     IgnoreUnused(name);
463 
464     auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Equal);
465     auto fbEqualLayer = serializer::CreateEqualLayer(m_flatBufferBuilder, fbBaseLayer);
466 
467     CreateAnyLayer(fbEqualLayer.o, serializer::Layer::Layer_EqualLayer);
468 }
469 
VisitFillLayer(const armnn::IConnectableLayer * layer,const armnn::FillDescriptor & fillDescriptor,const char * name)470 void SerializerVisitor::VisitFillLayer(const armnn::IConnectableLayer* layer,
471                                        const armnn::FillDescriptor& fillDescriptor,
472                                        const char* name)
473 {
474     IgnoreUnused(name);
475 
476     auto fbFillBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Fill);
477 
478     auto fbDescriptor = serializer::CreateFillDescriptor(m_flatBufferBuilder, fillDescriptor.m_Value);
479 
480     auto fbFillLayer = serializer::CreateFillLayer(m_flatBufferBuilder, fbFillBaseLayer, fbDescriptor);
481 
482     CreateAnyLayer(fbFillLayer.o, serializer::Layer::Layer_FillLayer);
483 }
484 
VisitFloorLayer(const armnn::IConnectableLayer * layer,const char * name)485 void SerializerVisitor::VisitFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
486 {
487     IgnoreUnused(name);
488 
489     auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
490     auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);
491 
492     CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
493 }
494 
VisitGatherLayer(const armnn::IConnectableLayer * layer,const char * name)495 void SerializerVisitor::VisitGatherLayer(const armnn::IConnectableLayer* layer,
496                                          const char* name)
497 {
498     armnn::GatherDescriptor gatherDescriptor{};
499     VisitGatherLayer(layer, gatherDescriptor, name);
500 }
501 
VisitGatherLayer(const armnn::IConnectableLayer * layer,const armnn::GatherDescriptor & gatherDescriptor,const char * name)502 void SerializerVisitor::VisitGatherLayer(const armnn::IConnectableLayer* layer,
503                                          const armnn::GatherDescriptor& gatherDescriptor,
504                                          const char* name)
505 {
506     IgnoreUnused(name);
507 
508     auto fbGatherDescriptor = CreateGatherDescriptor(m_flatBufferBuilder,
509                                                      gatherDescriptor.m_Axis);
510     auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
511     auto flatBufferLayer   = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer, fbGatherDescriptor);
512 
513     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
514 }
515 
VisitGreaterLayer(const armnn::IConnectableLayer * layer,const char * name)516 void SerializerVisitor::VisitGreaterLayer(const armnn::IConnectableLayer* layer, const char* name)
517 {
518     IgnoreUnused(name);
519 
520     auto fbGreaterBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Greater);
521     auto fbGreaterLayer = serializer::CreateGreaterLayer(m_flatBufferBuilder, fbGreaterBaseLayer);
522 
523     CreateAnyLayer(fbGreaterLayer.o, serializer::Layer::Layer_GreaterLayer);
524 }
525 
VisitInstanceNormalizationLayer(const armnn::IConnectableLayer * layer,const armnn::InstanceNormalizationDescriptor & instanceNormalizationDescriptor,const char * name)526 void SerializerVisitor::VisitInstanceNormalizationLayer(
527     const armnn::IConnectableLayer* layer,
528     const armnn::InstanceNormalizationDescriptor& instanceNormalizationDescriptor,
529     const char* name)
530 {
531     IgnoreUnused(name);
532 
533     auto fbDescriptor = serializer::CreateInstanceNormalizationDescriptor(
534             m_flatBufferBuilder,
535             instanceNormalizationDescriptor.m_Gamma,
536             instanceNormalizationDescriptor.m_Beta,
537             instanceNormalizationDescriptor.m_Eps,
538             GetFlatBufferDataLayout(instanceNormalizationDescriptor.m_DataLayout));
539 
540     auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_InstanceNormalization);
541     auto fbLayer     = serializer::CreateInstanceNormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
542 
543     CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_InstanceNormalizationLayer);
544 }
545 
VisitL2NormalizationLayer(const armnn::IConnectableLayer * layer,const armnn::L2NormalizationDescriptor & l2NormalizationDescriptor,const char * name)546 void SerializerVisitor::VisitL2NormalizationLayer(const armnn::IConnectableLayer* layer,
547                                                   const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
548                                                   const char* name)
549 {
550     IgnoreUnused(name);
551 
552     // Create FlatBuffer BaseLayer
553     auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);
554 
555     // Create the FlatBuffer L2Normalization Descriptor
556     auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
557             m_flatBufferBuilder,
558             GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout),
559             l2NormalizationDescriptor.m_Eps);
560 
561     // Create FlatBuffer layer
562     auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
563 
564     CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
565 }
566 
VisitLogicalBinaryLayer(const armnn::IConnectableLayer * layer,const armnn::LogicalBinaryDescriptor & descriptor,const char * name)567 void SerializerVisitor::VisitLogicalBinaryLayer(const armnn::IConnectableLayer* layer,
568                                                 const armnn::LogicalBinaryDescriptor& descriptor,
569                                                 const char* name)
570 {
571     IgnoreUnused(name);
572 
573     auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_LogicalBinary);
574     auto fbDescriptor = serializer::CreateLogicalBinaryDescriptor(
575         m_flatBufferBuilder,
576         GetFlatBufferLogicalBinaryOperation(descriptor.m_Operation));
577 
578     auto fbLayer = serializer::CreateLogicalBinaryLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
579     CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_LogicalBinaryLayer);
580 }
581 
VisitLogSoftmaxLayer(const armnn::IConnectableLayer * layer,const armnn::LogSoftmaxDescriptor & logSoftmaxDescriptor,const char * name)582 void SerializerVisitor::VisitLogSoftmaxLayer(const armnn::IConnectableLayer* layer,
583                                              const armnn::LogSoftmaxDescriptor& logSoftmaxDescriptor,
584                                              const char* name)
585 {
586     IgnoreUnused(name);
587 
588     // Create FlatBuffer BaseLayer
589     auto flatBufferLogSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_LogSoftmax);
590 
591     // Create the FlatBuffer LogSoftmaxDescriptor
592     auto flatBufferLogSoftmaxDesc =
593         serializer::CreateLogSoftmaxDescriptor(m_flatBufferBuilder,
594                                                logSoftmaxDescriptor.m_Beta,
595                                                logSoftmaxDescriptor.m_Axis);
596 
597     // Create the FlatBuffer LogSoftmaxLayer
598     auto flatBufferLogSoftmaxLayer =
599         serializer::CreateLogSoftmaxLayer(m_flatBufferBuilder,
600                                           flatBufferLogSoftmaxBaseLayer,
601                                           flatBufferLogSoftmaxDesc);
602 
603     CreateAnyLayer(flatBufferLogSoftmaxLayer.o, serializer::Layer::Layer_LogSoftmaxLayer);
604 }
605 
VisitLstmLayer(const armnn::IConnectableLayer * layer,const armnn::LstmDescriptor & descriptor,const armnn::LstmInputParams & params,const char * name)606 void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer,
607                                        const armnn::LstmDescriptor& descriptor,
608                                        const armnn::LstmInputParams& params,
609                                        const char* name)
610 {
611     IgnoreUnused(name);
612 
613     auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
614 
615     auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
616         m_flatBufferBuilder,
617         descriptor.m_ActivationFunc,
618         descriptor.m_ClippingThresCell,
619         descriptor.m_ClippingThresProj,
620         descriptor.m_CifgEnabled,
621         descriptor.m_PeepholeEnabled,
622         descriptor.m_ProjectionEnabled,
623         descriptor.m_LayerNormEnabled);
624 
625     // Get mandatory input parameters
626     auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
627     auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
628     auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
629     auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
630     auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
631     auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
632     auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
633     auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
634     auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
635 
636     //Define optional parameters, these will be set depending on configuration in Lstm descriptor
637     flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
638     flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
639     flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
640     flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
641     flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
642     flatbuffers::Offset<serializer::ConstTensor> projectionBias;
643     flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
644     flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
645     flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
646     flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
647     flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
648     flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;
649 
650     if (!descriptor.m_CifgEnabled)
651     {
652         inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
653         recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
654         cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
655         inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
656     }
657 
658     if (descriptor.m_ProjectionEnabled)
659     {
660         projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
661         projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
662     }
663 
664     if (descriptor.m_PeepholeEnabled)
665     {
666         cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
667         cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
668     }
669 
670     if (descriptor.m_LayerNormEnabled)
671     {
672         if (!descriptor.m_CifgEnabled)
673         {
674             inputLayerNormWeights = CreateConstTensorInfo((*params.m_InputLayerNormWeights));
675         }
676         forgetLayerNormWeights = CreateConstTensorInfo(*params.m_ForgetLayerNormWeights);
677         cellLayerNormWeights   = CreateConstTensorInfo(*params.m_CellLayerNormWeights);
678         outputLayerNormWeights = CreateConstTensorInfo(*params.m_OutputLayerNormWeights);
679     }
680 
681     auto fbLstmParams = serializer::CreateLstmInputParams(
682         m_flatBufferBuilder,
683         inputToForgetWeights,
684         inputToCellWeights,
685         inputToOutputWeights,
686         recurrentToForgetWeights,
687         recurrentToCellWeights,
688         recurrentToOutputWeights,
689         forgetGateBias,
690         cellBias,
691         outputGateBias,
692         inputToInputWeights,
693         recurrentToInputWeights,
694         cellToInputWeights,
695         inputGateBias,
696         projectionWeights,
697         projectionBias,
698         cellToForgetWeights,
699         cellToOutputWeights,
700         inputLayerNormWeights,
701         forgetLayerNormWeights,
702         cellLayerNormWeights,
703         outputLayerNormWeights);
704 
705     auto fbLstmLayer = serializer::CreateLstmLayer(
706         m_flatBufferBuilder,
707         fbLstmBaseLayer,
708         fbLstmDescriptor,
709         fbLstmParams);
710 
711     CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
712 }
713 
VisitMaximumLayer(const armnn::IConnectableLayer * layer,const char * name)714 void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
715 {
716     IgnoreUnused(name);
717 
718     auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
719     auto fbMaximumLayer     = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
720 
721     CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
722 }
723 
VisitMeanLayer(const armnn::IConnectableLayer * layer,const armnn::MeanDescriptor & descriptor,const char * name)724 void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
725                                        const armnn::MeanDescriptor& descriptor,
726                                        const char* name)
727 {
728     IgnoreUnused(name);
729 
730     auto fbMeanBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
731     auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
732                                                              m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
733                                                              descriptor.m_KeepDims);
734 
735     auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
736                                                    fbMeanBaseLayer,
737                                                    fbMeanDescriptor);
738 
739     CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
740 }
741 
VisitMinimumLayer(const armnn::IConnectableLayer * layer,const char * name)742 void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
743 {
744     IgnoreUnused(name);
745 
746     auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
747     auto fbMinimumLayer     = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
748 
749     CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
750 }
751 
VisitMergeLayer(const armnn::IConnectableLayer * layer,const char * name)752 void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
753 {
754     IgnoreUnused(name);
755 
756     auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
757     auto fbMergeLayer     = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
758 
759     CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
760 }
761 
VisitMergerLayer(const armnn::IConnectableLayer * layer,const armnn::MergerDescriptor & mergerDescriptor,const char * name)762 void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
763                                          const armnn::MergerDescriptor& mergerDescriptor,
764                                          const char* name)
765 {
766     VisitConcatLayer(layer, mergerDescriptor, name);
767 }
768 
VisitConcatLayer(const armnn::IConnectableLayer * layer,const armnn::ConcatDescriptor & concatDescriptor,const char * name)769 void SerializerVisitor::VisitConcatLayer(const armnn::IConnectableLayer* layer,
770                                          const armnn::ConcatDescriptor& concatDescriptor,
771                                          const char* name)
772 {
773     IgnoreUnused(name);
774 
775     auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);
776 
777     std::vector<flatbuffers::Offset<UintVector>> views;
778     for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
779     {
780         const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
781         std::vector<uint32_t> origins;
782         for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
783         {
784             origins.push_back(origin[d]);
785         }
786         auto view = m_flatBufferBuilder.CreateVector(origins);
787         auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
788         views.push_back(uintVector);
789     }
790 
791     auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
792                                                               concatDescriptor.GetConcatAxis(),
793                                                               concatDescriptor.GetNumViews(),
794                                                               concatDescriptor.GetNumDimensions(),
795                                                               m_flatBufferBuilder.CreateVector(views));
796 
797     auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
798                                              flatBufferConcatBaseLayer,
799                                              flatBufferConcatDescriptor);
800 
801     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
802 }
803 
VisitMultiplicationLayer(const armnn::IConnectableLayer * layer,const char * name)804 void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
805 {
806     IgnoreUnused(name);
807 
808     auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
809     auto fbMultiplicationLayer     = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
810                                                                            fbMultiplicationBaseLayer);
811 
812     CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
813 }
814 
VisitPadLayer(const armnn::IConnectableLayer * layer,const armnn::PadDescriptor & padDescriptor,const char * name)815 void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
816                                       const armnn::PadDescriptor& padDescriptor,
817                                       const char* name)
818 {
819     IgnoreUnused(name);
820 
821     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
822 
823     std::vector<unsigned int> padList;
824     for (auto& p: padDescriptor.m_PadList)
825     {
826         padList.push_back(p.first);
827         padList.push_back(p.second);
828     }
829 
830     auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
831                                                              m_flatBufferBuilder.CreateVector(padList),
832                                                              padDescriptor.m_PadValue);
833 
834     auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
835                                                          flatBufferBaseLayer,
836                                                          flatBufferPadDesc);
837 
838     CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
839 }
840 
VisitPermuteLayer(const armnn::IConnectableLayer * layer,const armnn::PermuteDescriptor & permuteDescriptor,const char * name)841 void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
842                                           const armnn::PermuteDescriptor& permuteDescriptor,
843                                           const char* name)
844 {
845     IgnoreUnused(name);
846 
847     // Create FlatBuffer BaseLayer
848     auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
849 
850     std::vector<unsigned int> dimMappings;
851     for (unsigned int i=0; i<permuteDescriptor.m_DimMappings.GetSize(); ++i)
852     {
853         dimMappings.push_back(permuteDescriptor.m_DimMappings[i]);
854     }
855 
856     auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
857                                                                      m_flatBufferBuilder.CreateVector(dimMappings));
858 
859     // Create the FlatBuffer PermuteLayer
860     auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
861                                                                  flatBufferPermuteBaseLayer,
862                                                                  flatBufferPermuteDesc);
863 
864     // Add the AnyLayer to the FlatBufferLayers
865     CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
866 }
867 
868 // Build FlatBuffer for Rank Layer
VisitRankLayer(const armnn::IConnectableLayer * layer,const char * name)869 void SerializerVisitor::VisitRankLayer(const armnn::IConnectableLayer* layer,
870                                        const char* name)
871 {
872     IgnoreUnused(name);
873     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rank);
874     auto flatBufferRankLayer = serializer::CreateRankLayer(m_flatBufferBuilder, flatBufferBaseLayer);
875 
876     CreateAnyLayer(flatBufferRankLayer.o, serializer::Layer::Layer_RankLayer);
877 }
878 // Build FlatBuffer for Reshape Layer
VisitReshapeLayer(const armnn::IConnectableLayer * layer,const armnn::ReshapeDescriptor & reshapeDescriptor,const char * name)879 void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
880                                           const armnn::ReshapeDescriptor& reshapeDescriptor,
881                                           const char* name)
882 {
883     IgnoreUnused(name);
884 
885     // Create FlatBuffer BaseLayer
886     auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
887 
888     std::vector<unsigned int> targetShape;
889     for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
890     {
891         targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
892     }
893 
894     auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
895                                                                      m_flatBufferBuilder.CreateVector(targetShape));
896 
897     // Create the FlatBuffer ReshapeLayer
898     auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
899                                                                  flatBufferReshapeDesc);
900 
901     // Add the AnyLayer to the FlatBufferLayers
902     CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
903 }
904 
VisitResizeBilinearLayer(const armnn::IConnectableLayer * layer,const armnn::ResizeBilinearDescriptor & resizeDescriptor,const char * name)905 void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
906                                                  const armnn::ResizeBilinearDescriptor& resizeDescriptor,
907                                                  const char* name)
908 {
909     IgnoreUnused(name);
910 
911     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
912 
913     auto flatBufferDescriptor =
914         CreateResizeBilinearDescriptor(m_flatBufferBuilder,
915                                        resizeDescriptor.m_TargetWidth,
916                                        resizeDescriptor.m_TargetHeight,
917                                        GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout),
918                                        resizeDescriptor.m_AlignCorners,
919                                        resizeDescriptor.m_HalfPixelCenters);
920 
921     auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
922                                                                  flatBufferBaseLayer,
923                                                                  flatBufferDescriptor);
924 
925     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
926 }
927 
VisitResizeLayer(const armnn::IConnectableLayer * layer,const armnn::ResizeDescriptor & resizeDescriptor,const char * name)928 void SerializerVisitor::VisitResizeLayer(const armnn::IConnectableLayer* layer,
929                                          const armnn::ResizeDescriptor& resizeDescriptor,
930                                          const char* name)
931 {
932     IgnoreUnused(name);
933 
934     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Resize);
935 
936     auto flatBufferDescriptor =
937             CreateResizeDescriptor(m_flatBufferBuilder,
938                                    resizeDescriptor.m_TargetHeight,
939                                    resizeDescriptor.m_TargetWidth,
940                                    GetFlatBufferResizeMethod(resizeDescriptor.m_Method),
941                                    GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout),
942                                    resizeDescriptor.m_AlignCorners,
943                                    resizeDescriptor.m_HalfPixelCenters);
944 
945     auto flatBufferLayer = serializer::CreateResizeLayer(m_flatBufferBuilder,
946                                                          flatBufferBaseLayer,
947                                                          flatBufferDescriptor);
948 
949     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeLayer);
950 }
951 
VisitRsqrtLayer(const armnn::IConnectableLayer * layer,const char * name)952 void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
953 {
954     IgnoreUnused(name);
955 
956     auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
957     auto fbRsqrtLayer     = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
958 
959     CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
960 }
961 
VisitSliceLayer(const armnn::IConnectableLayer * layer,const armnn::SliceDescriptor & sliceDescriptor,const char * name)962 void SerializerVisitor::VisitSliceLayer(const armnn::IConnectableLayer* layer,
963                                         const armnn::SliceDescriptor& sliceDescriptor,
964                                         const char* name)
965 {
966     IgnoreUnused(name);
967 
968     auto fbSliceBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Slice);
969     auto fbSliceDescriptor = CreateSliceDescriptor(m_flatBufferBuilder,
970                                                    m_flatBufferBuilder.CreateVector(sliceDescriptor.m_Begin),
971                                                    m_flatBufferBuilder.CreateVector(sliceDescriptor.m_Size));
972 
973     auto fbSliceLayer = serializer::CreateSliceLayer(m_flatBufferBuilder, fbSliceBaseLayer, fbSliceDescriptor);
974 
975     CreateAnyLayer(fbSliceLayer.o, serializer::Layer::Layer_SliceLayer);
976 }
977 
978 // Build FlatBuffer for Softmax Layer
VisitSoftmaxLayer(const armnn::IConnectableLayer * layer,const armnn::SoftmaxDescriptor & softmaxDescriptor,const char * name)979 void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
980                                           const armnn::SoftmaxDescriptor& softmaxDescriptor,
981                                           const char* name)
982 {
983     IgnoreUnused(name);
984 
985     // Create FlatBuffer BaseLayer
986     auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
987 
988     // Create the FlatBuffer SoftmaxDescriptor
989     auto flatBufferSoftmaxDesc =
990         serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
991 
992     // Create the FlatBuffer SoftmaxLayer
993     auto flatBufferSoftmaxLayer =
994         serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
995                                        flatBufferSoftmaxBaseLayer,
996                                        flatBufferSoftmaxDesc);
997 
998     CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
999 }
1000 
VisitPooling2dLayer(const armnn::IConnectableLayer * layer,const armnn::Pooling2dDescriptor & pooling2dDescriptor,const char * name)1001 void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
1002                                             const armnn::Pooling2dDescriptor& pooling2dDescriptor,
1003                                             const char* name)
1004 {
1005     IgnoreUnused(name);
1006 
1007     auto fbPooling2dBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
1008     auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
1009         m_flatBufferBuilder,
1010         GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
1011         pooling2dDescriptor.m_PadLeft,
1012         pooling2dDescriptor.m_PadRight,
1013         pooling2dDescriptor.m_PadTop,
1014         pooling2dDescriptor.m_PadBottom,
1015         pooling2dDescriptor.m_PoolWidth,
1016         pooling2dDescriptor.m_PoolHeight,
1017         pooling2dDescriptor.m_StrideX,
1018         pooling2dDescriptor.m_StrideY,
1019         GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
1020         GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
1021         GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
1022 
1023     auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
1024                                                              fbPooling2dBaseLayer,
1025                                                              fbPooling2dDescriptor);
1026 
1027     CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
1028 }
1029 
VisitPreluLayer(const armnn::IConnectableLayer * layer,const char * name)1030 void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
1031                                         const char* name)
1032 {
1033     IgnoreUnused(name);
1034 
1035     // Create FlatBuffer BaseLayer
1036     auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
1037 
1038     // Create the FlatBuffer AdditionLayer
1039     auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
1040 
1041     // Add the AnyLayer to the FlatBufferLayers
1042     CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
1043 }
1044 
VisitQuantizeLayer(const armnn::IConnectableLayer * layer,const char * name)1045 void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
1046 {
1047     IgnoreUnused(name);
1048 
1049     auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
1050     auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
1051                                                            fbQuantizeBaseLayer);
1052     CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
1053 }
1054 
1055 // Build FlatBuffer for FullyConnected Layer
VisitFullyConnectedLayer(const armnn::IConnectableLayer * layer,const armnn::FullyConnectedDescriptor & fullyConnectedDescriptor,const armnn::ConstTensor & weights,const armnn::Optional<armnn::ConstTensor> & biases,const char * name)1056 void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
1057                                                  const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
1058                                                  const armnn::ConstTensor& weights,
1059                                                  const armnn::Optional<armnn::ConstTensor>& biases,
1060                                                  const char* name)
1061 {
1062     IgnoreUnused(name);
1063 
1064     // Create FlatBuffer BaseLayer
1065     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
1066 
1067     // Create FlatBuffer FullyConnectedDescriptor
1068     auto flatBufferDescriptor =
1069         serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
1070                                                    fullyConnectedDescriptor.m_BiasEnabled,
1071                                                    fullyConnectedDescriptor.m_TransposeWeightMatrix);
1072 
1073     // Create FlatBuffer weights data
1074     auto flatBufferWeights = CreateConstTensorInfo(weights);
1075 
1076     // Create FlatBuffer bias data
1077     flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
1078     if (fullyConnectedDescriptor.m_BiasEnabled)
1079     {
1080         flatBufferBiases = CreateConstTensorInfo(biases.value());
1081     }
1082 
1083     // Create FlatBuffer FullyConnectedLayer
1084     auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
1085                                                                  flatBufferBaseLayer,
1086                                                                  flatBufferDescriptor,
1087                                                                  flatBufferWeights,
1088                                                                  flatBufferBiases);
1089 
1090     // Add created FullyConnectedLayer to the FlatBufferLayers
1091     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
1092 }
1093 
1094 // Build FlatBuffer for SpaceToBatchNd Layer
VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer * layer,const armnn::SpaceToBatchNdDescriptor & spaceToBatchNdDescriptor,const char * name)1095 void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
1096                                                  const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
1097                                                  const char* name)
1098 {
1099     IgnoreUnused(name);
1100 
1101     // Create FlatBuffer BaseLayer
1102     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
1103 
1104     std::vector<unsigned int> padList;
1105     padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
1106     for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
1107     {
1108         padList.push_back(pad.first);
1109         padList.push_back(pad.second);
1110     }
1111 
1112     auto flatBufferDescriptor =
1113         CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
1114                                        m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
1115                                        m_flatBufferBuilder.CreateVector(padList),
1116                                        GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
1117 
1118     auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
1119                                                                  flatBufferBaseLayer,
1120                                                                  flatBufferDescriptor);
1121 
1122     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
1123 }
1124 
1125 // Build FlatBuffer for SpaceToDepthLayer
VisitSpaceToDepthLayer(const armnn::IConnectableLayer * layer,const armnn::SpaceToDepthDescriptor & spaceToDepthDescriptor,const char * name)1126 void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
1127                                                const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
1128                                                const char* name)
1129 {
1130     IgnoreUnused(name);
1131 
1132     auto flatBufferBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
1133     auto flatBufferDescriptor =
1134         CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
1135                                      spaceToDepthDescriptor.m_BlockSize,
1136                                      GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
1137 
1138     auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
1139                                                                flatBufferBaseLayer,
1140                                                                flatBufferDescriptor);
1141 
1142     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
1143 }
1144 
1145 // Build FlatBuffer for Splitter Layer
VisitSplitterLayer(const armnn::IConnectableLayer * layer,const armnn::ViewsDescriptor & viewsDescriptor,const char * name)1146 void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
1147                                            const armnn::ViewsDescriptor& viewsDescriptor,
1148                                            const char* name)
1149 {
1150     IgnoreUnused(name);
1151 
1152     // Create FlatBuffer ViewOrigins
1153     std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
1154     flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
1155 
1156     for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
1157     {
1158         std::vector<uint32_t> viewOrigin;
1159         viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
1160 
1161         // Copy vector
1162         for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
1163         {
1164             viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
1165         }
1166 
1167         flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
1168                                                          m_flatBufferBuilder.CreateVector(viewOrigin)));
1169     }
1170 
1171     // Create FlatBuffer OriginsDescriptor
1172     auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
1173                                                               viewsDescriptor.GetOrigins().GetConcatAxis(),
1174                                                               viewsDescriptor.GetOrigins().GetNumViews(),
1175                                                               viewsDescriptor.GetOrigins().GetNumDimensions(),
1176                                                               m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
1177 
1178     // Create FlatBuffer ViewOrigins
1179     std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
1180     flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
1181 
1182     for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
1183     {
1184         std::vector<uint32_t> viewSize;
1185         viewSize.reserve(viewsDescriptor.GetNumDimensions());
1186 
1187         // Copy vector
1188         for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
1189         {
1190             viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
1191         }
1192 
1193         flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
1194                                                        m_flatBufferBuilder.CreateVector(viewSize)));
1195     }
1196 
1197     // Create FlatBuffer ViewsDescriptor
1198     auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
1199                                                            flatBufferOriginDescriptor,
1200                                                            m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
1201 
1202     // Create FlatBuffer BaseLayer
1203     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
1204 
1205     auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
1206                                                                    flatBufferBaseLayer,
1207                                                                    flatBufferViewsDescriptor);
1208 
1209     CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
1210 }
1211 
VisitNormalizationLayer(const armnn::IConnectableLayer * layer,const armnn::NormalizationDescriptor & descriptor,const char * name)1212 void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
1213                                                 const armnn::NormalizationDescriptor& descriptor,
1214                                                 const char* name)
1215 {
1216     IgnoreUnused(name);
1217 
1218     auto fbNormalizationBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
1219 
1220     auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
1221         m_flatBufferBuilder,
1222         GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
1223         GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
1224         descriptor.m_NormSize,
1225         descriptor.m_Alpha,
1226         descriptor.m_Beta,
1227         descriptor.m_K,
1228         GetFlatBufferDataLayout(descriptor.m_DataLayout));
1229 
1230     auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
1231                                                                 fbNormalizationBaseLayer,
1232                                                                 fbNormalizationDescriptor);
1233 
1234     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
1235 }
1236 
VisitStackLayer(const armnn::IConnectableLayer * layer,const armnn::StackDescriptor & stackDescriptor,const char * name)1237 void SerializerVisitor::VisitStackLayer(const armnn::IConnectableLayer* layer,
1238                                         const armnn::StackDescriptor& stackDescriptor,
1239                                         const char* name)
1240 {
1241     IgnoreUnused(name);
1242 
1243     auto stackBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Stack);
1244 
1245     std::vector<unsigned int> inputShape;
1246     for (unsigned int i =0; i < stackDescriptor.m_InputShape.GetNumDimensions(); i++)
1247     {
1248         inputShape.push_back(stackDescriptor.m_InputShape[i]);
1249     }
1250 
1251     auto flatBufferStackDescriptor = CreateStackDescriptor(m_flatBufferBuilder,
1252                                                            stackDescriptor.m_Axis,
1253                                                            stackDescriptor.m_NumInputs,
1254                                                            m_flatBufferBuilder.CreateVector(inputShape));
1255 
1256     auto stackLayer = serializer::CreateStackLayer(m_flatBufferBuilder, stackBaseLayer, flatBufferStackDescriptor);
1257     CreateAnyLayer(stackLayer.o, serializer::Layer::Layer_StackLayer);
1258 }
1259 
VisitStandInLayer(const armnn::IConnectableLayer * layer,const armnn::StandInDescriptor & standInDescriptor,const char * name)1260 void SerializerVisitor::VisitStandInLayer(const armnn::IConnectableLayer *layer,
1261                                           const armnn::StandInDescriptor& standInDescriptor,
1262                                           const char *name)
1263 {
1264     IgnoreUnused(name);
1265 
1266     auto fbDescriptor = serializer::CreateStandInDescriptor(m_flatBufferBuilder,
1267                                                             standInDescriptor.m_NumInputs,
1268                                                             standInDescriptor.m_NumOutputs);
1269 
1270     auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StandIn);
1271     auto fbLayer     = serializer::CreateStandInLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
1272 
1273     CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_StandInLayer);
1274 }
1275 
VisitStridedSliceLayer(const armnn::IConnectableLayer * layer,const armnn::StridedSliceDescriptor & stridedSliceDescriptor,const char * name)1276 void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
1277                                                const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
1278                                                const char* name)
1279 {
1280     IgnoreUnused(name);
1281 
1282     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
1283 
1284     auto flatBufferDescriptor =
1285         CreateStridedSliceDescriptor(m_flatBufferBuilder,
1286                                      m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
1287                                      m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
1288                                      m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
1289                                      stridedSliceDescriptor.m_BeginMask,
1290                                      stridedSliceDescriptor.m_EndMask,
1291                                      stridedSliceDescriptor.m_ShrinkAxisMask,
1292                                      stridedSliceDescriptor.m_EllipsisMask,
1293                                      stridedSliceDescriptor.m_NewAxisMask,
1294                                      GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
1295 
1296     auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
1297                                                                flatBufferBaseLayer,
1298                                                                flatBufferDescriptor);
1299 
1300     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
1301 }
1302 
VisitSubtractionLayer(const armnn::IConnectableLayer * layer,const char * name)1303 void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
1304 {
1305     IgnoreUnused(name);
1306 
1307     auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
1308     auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
1309 
1310     CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
1311 }
1312 
VisitSwitchLayer(const armnn::IConnectableLayer * layer,const char * name)1313 void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
1314 {
1315     IgnoreUnused(name);
1316 
1317     auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
1318     auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
1319 
1320     CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
1321 }
1322 
VisitTransposeConvolution2dLayer(const armnn::IConnectableLayer * layer,const armnn::TransposeConvolution2dDescriptor & descriptor,const armnn::ConstTensor & weights,const armnn::Optional<armnn::ConstTensor> & biases,const char * name)1323 void SerializerVisitor::VisitTransposeConvolution2dLayer(
1324     const armnn::IConnectableLayer* layer,
1325     const armnn::TransposeConvolution2dDescriptor& descriptor,
1326     const armnn::ConstTensor& weights,
1327     const armnn::Optional<armnn::ConstTensor>& biases,
1328     const char* name)
1329 {
1330     IgnoreUnused(name);
1331 
1332     auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
1333     auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
1334                                                                descriptor.m_PadLeft,
1335                                                                descriptor.m_PadRight,
1336                                                                descriptor.m_PadTop,
1337                                                                descriptor.m_PadBottom,
1338                                                                descriptor.m_StrideX,
1339                                                                descriptor.m_StrideY,
1340                                                                descriptor.m_BiasEnabled,
1341                                                                GetFlatBufferDataLayout(descriptor.m_DataLayout));
1342 
1343     // weights & biases
1344     auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
1345     flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
1346     if (biases.has_value())
1347     {
1348         fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
1349     }
1350 
1351     auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
1352                                                      fbBaseLayer,
1353                                                      fbDescriptor,
1354                                                      fbWeightsConstTensorInfo,
1355                                                      fbBiasesConstTensorInfo);
1356 
1357     CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
1358 }
1359 
VisitTransposeLayer(const armnn::IConnectableLayer * layer,const armnn::TransposeDescriptor & descriptor,const char * name)1360 void SerializerVisitor::VisitTransposeLayer(const armnn::IConnectableLayer* layer,
1361                                             const armnn::TransposeDescriptor& descriptor,
1362                                             const char* name)
1363 {
1364     IgnoreUnused(name);
1365 
1366     // Create FlatBuffer BaseLayer
1367     auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Transpose);
1368 
1369     std::vector<unsigned int> dimMappings;
1370     for (unsigned int i=0; i<descriptor.m_DimMappings.GetSize(); ++i)
1371     {
1372         dimMappings.push_back(descriptor.m_DimMappings[i]);
1373     }
1374 
1375     auto flatBufferDesc = serializer::CreateTransposeDescriptor(m_flatBufferBuilder,
1376                                                                 m_flatBufferBuilder.CreateVector(dimMappings));
1377 
1378     // Create the FlatBuffer TransposeLayer
1379     auto flatBufferLayer = serializer::CreateTransposeLayer(m_flatBufferBuilder,
1380                                                             flatBufferBaseLayer,
1381                                                             flatBufferDesc);
1382 
1383     // Add the AnyLayer to the FlatBufferLayers
1384     CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_TransposeLayer);
1385 }
1386 
VisitQLstmLayer(const armnn::IConnectableLayer * layer,const armnn::QLstmDescriptor & descriptor,const armnn::LstmInputParams & params,const char * name)1387 void SerializerVisitor::VisitQLstmLayer(const armnn::IConnectableLayer* layer,
1388                                         const armnn::QLstmDescriptor& descriptor,
1389                                         const armnn::LstmInputParams& params,
1390                                         const char* name)
1391 {
1392     IgnoreUnused(name);
1393 
1394     auto fbQLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_QLstm);
1395 
1396     auto fbQLstmDescriptor = serializer::CreateQLstmDescriptor(
1397             m_flatBufferBuilder,
1398             descriptor.m_CifgEnabled,
1399             descriptor.m_PeepholeEnabled,
1400             descriptor.m_ProjectionEnabled,
1401             descriptor.m_LayerNormEnabled,
1402             descriptor.m_CellClip,
1403             descriptor.m_ProjectionClip,
1404             descriptor.m_InputIntermediateScale,
1405             descriptor.m_ForgetIntermediateScale,
1406             descriptor.m_CellIntermediateScale,
1407             descriptor.m_OutputIntermediateScale,
1408             descriptor.m_HiddenStateZeroPoint,
1409             descriptor.m_HiddenStateScale
1410             );
1411 
1412     // Mandatory params
1413     auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
1414     auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
1415     auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
1416     auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
1417     auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
1418     auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
1419     auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
1420     auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
1421     auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
1422 
1423     // CIFG
1424     flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
1425     flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
1426     flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
1427 
1428     if (!descriptor.m_CifgEnabled)
1429     {
1430         inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
1431         recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
1432         inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
1433     }
1434 
1435     // Projectiom
1436     flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
1437     flatbuffers::Offset<serializer::ConstTensor> projectionBias;
1438 
1439     if (descriptor.m_ProjectionEnabled)
1440     {
1441         projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
1442         projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
1443     }
1444 
1445     // Peephole
1446     flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
1447     flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
1448     flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
1449 
1450     if (descriptor.m_PeepholeEnabled)
1451     {
1452         if (!descriptor.m_CifgEnabled)
1453         {
1454             cellToInputWeights  = CreateConstTensorInfo(*params.m_CellToInputWeights);
1455         }
1456 
1457         cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
1458         cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
1459     }
1460 
1461     // Layer norm
1462     flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
1463     flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
1464     flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
1465     flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;
1466 
1467     if (descriptor.m_LayerNormEnabled)
1468     {
1469         if (!descriptor.m_CifgEnabled)
1470         {
1471             inputLayerNormWeights = CreateConstTensorInfo((*params.m_InputLayerNormWeights));
1472         }
1473 
1474         forgetLayerNormWeights = CreateConstTensorInfo(*params.m_ForgetLayerNormWeights);
1475         cellLayerNormWeights   = CreateConstTensorInfo(*params.m_CellLayerNormWeights);
1476         outputLayerNormWeights = CreateConstTensorInfo(*params.m_OutputLayerNormWeights);
1477     }
1478 
1479     auto fbQLstmParams = serializer::CreateQLstmInputParams(
1480             m_flatBufferBuilder,
1481             inputToForgetWeights,
1482             inputToCellWeights,
1483             inputToOutputWeights,
1484             recurrentToForgetWeights,
1485             recurrentToCellWeights,
1486             recurrentToOutputWeights,
1487             forgetGateBias,
1488             cellBias,
1489             outputGateBias,
1490             inputToInputWeights,
1491             recurrentToInputWeights,
1492             inputGateBias,
1493             projectionWeights,
1494             projectionBias,
1495             cellToInputWeights,
1496             cellToForgetWeights,
1497             cellToOutputWeights,
1498             inputLayerNormWeights,
1499             forgetLayerNormWeights,
1500             cellLayerNormWeights,
1501             outputLayerNormWeights);
1502 
1503     auto fbQLstmLayer = serializer::CreateQLstmLayer(
1504             m_flatBufferBuilder,
1505             fbQLstmBaseLayer,
1506             fbQLstmDescriptor,
1507             fbQLstmParams);
1508 
1509     CreateAnyLayer(fbQLstmLayer.o, serializer::Layer::Layer_QLstmLayer);
1510 }
1511 
VisitQuantizedLstmLayer(const armnn::IConnectableLayer * layer,const armnn::QuantizedLstmInputParams & params,const char * name)1512 void SerializerVisitor::VisitQuantizedLstmLayer(const armnn::IConnectableLayer* layer,
1513                                                 const armnn::QuantizedLstmInputParams& params,
1514                                                 const char* name)
1515 {
1516     IgnoreUnused(name);
1517 
1518     auto fbQuantizedLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_QuantizedLstm);
1519 
1520     // Get input parameters
1521     auto inputToInputWeights = CreateConstTensorInfo(params.GetInputToInputWeights());
1522     auto inputToForgetWeights = CreateConstTensorInfo(params.GetInputToForgetWeights());
1523     auto inputToCellWeights = CreateConstTensorInfo(params.GetInputToCellWeights());
1524     auto inputToOutputWeights = CreateConstTensorInfo(params.GetInputToOutputWeights());
1525 
1526     auto recurrentToInputWeights = CreateConstTensorInfo(params.GetRecurrentToInputWeights());
1527     auto recurrentToForgetWeights = CreateConstTensorInfo(params.GetRecurrentToForgetWeights());
1528     auto recurrentToCellWeights = CreateConstTensorInfo(params.GetRecurrentToCellWeights());
1529     auto recurrentToOutputWeights = CreateConstTensorInfo(params.GetRecurrentToOutputWeights());
1530 
1531     auto inputGateBias = CreateConstTensorInfo(params.GetInputGateBias());
1532     auto forgetGateBias = CreateConstTensorInfo(params.GetForgetGateBias());
1533     auto cellBias = CreateConstTensorInfo(params.GetCellBias());
1534     auto outputGateBias = CreateConstTensorInfo(params.GetOutputGateBias());
1535 
1536     auto fbQuantizedLstmParams = serializer::CreateQuantizedLstmInputParams(
1537         m_flatBufferBuilder,
1538         inputToInputWeights,
1539         inputToForgetWeights,
1540         inputToCellWeights,
1541         inputToOutputWeights,
1542         recurrentToInputWeights,
1543         recurrentToForgetWeights,
1544         recurrentToCellWeights,
1545         recurrentToOutputWeights,
1546         inputGateBias,
1547         forgetGateBias,
1548         cellBias,
1549         outputGateBias);
1550 
1551     auto fbQuantizedLstmLayer = serializer::CreateQuantizedLstmLayer(
1552         m_flatBufferBuilder,
1553         fbQuantizedLstmBaseLayer,
1554         fbQuantizedLstmParams);
1555 
1556     CreateAnyLayer(fbQuantizedLstmLayer.o, serializer::Layer::Layer_QuantizedLstmLayer);
1557 }
1558 
CreateLayerBase(const IConnectableLayer * layer,const serializer::LayerType layerType)1559 fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
1560                                                                      const serializer::LayerType layerType)
1561 {
1562 
1563     uint32_t fbIndex = GetSerializedId(layer->GetGuid());
1564 
1565     std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
1566     std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
1567 
1568     return serializer::CreateLayerBase(m_flatBufferBuilder,
1569                                        fbIndex,
1570                                        m_flatBufferBuilder.CreateString(layer->GetName()),
1571                                        layerType,
1572                                        m_flatBufferBuilder.CreateVector(inputSlots),
1573                                        m_flatBufferBuilder.CreateVector(outputSlots));
1574 }
1575 
CreateAnyLayer(const flatbuffers::Offset<void> & layer,const serializer::Layer serializerLayer)1576 void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
1577 {
1578 
1579     auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
1580     m_serializedLayers.push_back(anyLayer);
1581 }
1582 
1583 template <typename T>
CreateDataVector(const void * memory,unsigned int size)1584 flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
1585 {
1586     const T* buffer = reinterpret_cast<const T*>(memory);
1587     std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
1588     auto fbVector = m_flatBufferBuilder.CreateVector(vector);
1589     return fbVector;
1590 }
1591 
CreateTensorInfo(const armnn::TensorInfo & tensorInfo)1592 flatbuffers::Offset<TensorInfo>  SerializerVisitor::CreateTensorInfo(const armnn::TensorInfo& tensorInfo)
1593 {
1594     // Get the dimensions
1595     std::vector<unsigned int> shape;
1596     for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1597     {
1598         shape.push_back(tensorInfo.GetShape()[dim]);
1599     }
1600 
1601     if (tensorInfo.HasPerAxisQuantization())
1602     {
1603         // Create FlatBuffer TensorInfo
1604         auto flatBufferTensorInfo =
1605             serializer::CreateTensorInfo(m_flatBufferBuilder,
1606                                          m_flatBufferBuilder.CreateVector(shape),
1607                                          GetFlatBufferDataType(tensorInfo.GetDataType()),
1608                                          tensorInfo.GetQuantizationScales()[0],
1609                                          tensorInfo.GetQuantizationOffset(),
1610                                          m_flatBufferBuilder.CreateVector(tensorInfo.GetQuantizationScales()),
1611                                          tensorInfo.GetQuantizationDim().value(),
1612                                          static_cast<unsigned int>
1613                                          (tensorInfo.GetShape().GetDimensionality()));
1614         return flatBufferTensorInfo;
1615     }
1616 
1617     // Create FlatBuffer TensorInfo
1618     auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1619                                                              m_flatBufferBuilder.CreateVector(shape),
1620                                                              GetFlatBufferDataType(tensorInfo.GetDataType()),
1621                                                              tensorInfo.GetQuantizationScale(),
1622                                                              tensorInfo.GetQuantizationOffset(),
1623                                                              0,
1624                                                              0,
1625                                                              static_cast<unsigned int>
1626                                                              (tensorInfo.GetShape().GetDimensionality()));
1627     return flatBufferTensorInfo;
1628 }
1629 
1630 flatbuffers::Offset<serializer::ConstTensor>
CreateConstTensorInfo(const armnn::ConstTensor & constTensor)1631     SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
1632 {
1633     armnn::TensorInfo tensorInfo = constTensor.GetInfo();
1634 
1635     flatbuffers::Offset<void> fbPayload;
1636 
1637     switch (tensorInfo.GetDataType())
1638     {
1639         case armnn::DataType::Float32:
1640         case armnn::DataType::Signed32:
1641         {
1642             auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1643             flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1644                     m_flatBufferBuilder,
1645                     fbVector);
1646             fbPayload = flatBuffersData.o;
1647             break;
1648         }
1649         case armnn::DataType::Float16:
1650         case armnn::DataType::BFloat16:
1651         case armnn::DataType::QSymmS16:
1652         {
1653             auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1654             flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1655                     m_flatBufferBuilder,
1656                     fbVector);
1657             fbPayload = flatBuffersData.o;
1658             break;
1659         }
1660         case armnn::DataType::QSymmS8:
1661         case armnn::DataType::QAsymmS8:
1662         case armnn::DataType::QAsymmU8:
1663         case armnn::DataType::Boolean:
1664         default:
1665         {
1666             auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1667             flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1668                     m_flatBufferBuilder,
1669                     fbVector);
1670             fbPayload = flatBuffersData.o;
1671         }
1672     }
1673     flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1674             m_flatBufferBuilder,
1675             CreateTensorInfo(tensorInfo),
1676             GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1677             fbPayload);
1678     return flatBufferConstTensor;
1679 }
1680 
GetVersionTable()1681 flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> SerializerVisitor::GetVersionTable()
1682 {
1683     flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> versionsTable =
1684         serializer::CreateFeatureCompatibilityVersions(
1685                 m_flatBufferBuilder,
1686                 1 // Binding ids scheme version
1687             );
1688     return versionsTable;
1689 }
1690 
1691 std::vector<fb::Offset<serializer::InputSlot>>
CreateInputSlots(const armnn::IConnectableLayer * layer)1692     SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
1693 {
1694     std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
1695 
1696     // Get the InputSlots
1697     for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1698     {
1699         const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1700 
1701         // Get the Connection for the InputSlot
1702         const IOutputSlot* connection = inputSlot.GetConnection();
1703 
1704         // Create FlatBuffer Connection
1705         serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1706                                     connection->CalculateIndexOnOwner());
1707         // Create FlatBuffer InputSlot
1708         inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1709     }
1710     return inputSlots;
1711 }
1712 
1713 std::vector<fb::Offset<serializer::OutputSlot>>
CreateOutputSlots(const armnn::IConnectableLayer * layer)1714     SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
1715 {
1716     std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1717 
1718     // Get the OutputSlots
1719     for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1720     {
1721         const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
1722         const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
1723 
1724         // Create FlatBuffer Outputslot
1725         outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1726                                                            slotIndex,
1727                                                            CreateTensorInfo(tensorInfo)));
1728     }
1729     return outputSlots;
1730 }
1731 
1732 
CreateRaw()1733 ISerializer* ISerializer::CreateRaw()
1734 {
1735     return new Serializer();
1736 }
1737 
Create()1738 ISerializerPtr ISerializer::Create()
1739 {
1740     return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1741 }
1742 
Destroy(ISerializer * serializer)1743 void ISerializer::Destroy(ISerializer* serializer)
1744 {
1745     delete serializer;
1746 }
1747 
Serialize(const INetwork & inNetwork)1748 void Serializer::Serialize(const INetwork& inNetwork)
1749 {
1750     // Iterate through to network
1751     inNetwork.Accept(m_SerializerVisitor);
1752     flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1753 
1754     // Create FlatBuffer SerializedGraph
1755     auto serializedGraph = serializer::CreateSerializedGraph(
1756         fbBuilder,
1757         fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1758         fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1759         fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()),
1760         m_SerializerVisitor.GetVersionTable());
1761 
1762     // Serialize the graph
1763     fbBuilder.Finish(serializedGraph);
1764 }
1765 
SaveSerializedToStream(std::ostream & stream)1766 bool Serializer::SaveSerializedToStream(std::ostream& stream)
1767 {
1768     flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1769 
1770     auto bytesToWrite = armnn::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1771     stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
1772     return !stream.bad();
1773 }
1774 
1775 } // namespace armnnSerializer
1776