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