blob: a8d9c23c04ed0ca783e3d009579897226659f002 [file] [log] [blame]
Mike Kelly8c1701a2019-02-11 17:01:27 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "Serializer.hpp"
Saoirse Stewart3166c3e2019-02-18 15:24:53 +00007
8#include "SerializerUtils.hpp"
9
Mike Kelly8c1701a2019-02-11 17:01:27 +000010#include <armnn/ArmNN.hpp>
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000011
Mike Kelly8c1701a2019-02-11 17:01:27 +000012#include <iostream>
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000013
Aron Virginas-Tard4f0fea2019-04-09 14:08:06 +010014#include <boost/numeric/conversion/cast.hpp>
15
Mike Kelly8c1701a2019-02-11 17:01:27 +000016#include <flatbuffers/util.h>
17
18using namespace armnn;
19namespace fb = flatbuffers;
Derek Lamberti0028d1b2019-02-20 13:57:42 +000020namespace serializer = armnnSerializer;
Mike Kelly8c1701a2019-02-11 17:01:27 +000021
22namespace armnnSerializer
23{
24
Mike Kellyaf484012019-02-20 16:53:11 +000025serializer::ActivationFunction GetFlatBufferActivationFunction(armnn::ActivationFunction function)
26{
27 switch (function)
28 {
29 case armnn::ActivationFunction::Sigmoid:
30 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
31 case armnn::ActivationFunction::TanH:
32 return serializer::ActivationFunction::ActivationFunction_TanH;
33 case armnn::ActivationFunction::Linear:
34 return serializer::ActivationFunction::ActivationFunction_Linear;
35 case armnn::ActivationFunction::ReLu:
36 return serializer::ActivationFunction::ActivationFunction_ReLu;
37 case armnn::ActivationFunction::BoundedReLu:
38 return serializer::ActivationFunction::ActivationFunction_BoundedReLu;
39 case armnn::ActivationFunction::LeakyReLu:
40 return serializer::ActivationFunction::ActivationFunction_LeakyReLu;
41 case armnn::ActivationFunction::Abs:
42 return serializer::ActivationFunction::ActivationFunction_Abs;
43 case armnn::ActivationFunction::Sqrt:
44 return serializer::ActivationFunction::ActivationFunction_Sqrt;
45 case armnn::ActivationFunction::Square:
46 return serializer::ActivationFunction::ActivationFunction_Square;
47 default:
48 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
49 }
50}
51
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000052uint32_t SerializerVisitor::GetSerializedId(unsigned int guid)
53{
54 std::pair<unsigned int, uint32_t> guidPair(guid, m_layerId);
55
56 if (m_guidMap.empty())
57 {
58 m_guidMap.insert(guidPair);
59 }
60 else if (m_guidMap.find(guid) == m_guidMap.end())
61 {
62 guidPair.second = ++m_layerId;
63 m_guidMap.insert(guidPair);
64 return m_layerId;
65 }
Saoirse Stewart30211042019-02-18 17:19:16 +000066 return m_guidMap[guid];
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000067}
68
Mike Kelly8c1701a2019-02-11 17:01:27 +000069// Build FlatBuffer for Input Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +000070void SerializerVisitor::VisitInputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000071{
72 // Create FlatBuffer BaseLayer
73 auto flatBufferInputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Input);
74
75 // Create FlatBuffer BindableBaseLayer
76 auto flatBufferInputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
77 flatBufferInputBaseLayer,
78 id);
Mike Kelly8c1701a2019-02-11 17:01:27 +000079 // Push layer Guid to outputIds.
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000080 m_inputIds.push_back(GetSerializedId(layer->GetGuid()));
Mike Kelly8c1701a2019-02-11 17:01:27 +000081
82 // Create the FlatBuffer InputLayer
83 auto flatBufferInputLayer = serializer::CreateInputLayer(m_flatBufferBuilder, flatBufferInputBindableBaseLayer);
84
85 // Add the AnyLayer to the FlatBufferLayers
86 CreateAnyLayer(flatBufferInputLayer.o, serializer::Layer::Layer_InputLayer);
87}
88
89// Build FlatBuffer for Output Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +000090void SerializerVisitor::VisitOutputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000091{
92 // Create FlatBuffer BaseLayer
93 auto flatBufferOutputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Output);
94
95 // Create FlatBuffer BindableBaseLayer
96 auto flatBufferOutputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
97 flatBufferOutputBaseLayer,
98 id);
99 // Push layer Guid to outputIds.
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000100 m_outputIds.push_back(GetSerializedId(layer->GetGuid()));
Mike Kelly8c1701a2019-02-11 17:01:27 +0000101
102 // Create the FlatBuffer OutputLayer
103 auto flatBufferOutputLayer = serializer::CreateOutputLayer(m_flatBufferBuilder, flatBufferOutputBindableBaseLayer);
104 // Add the AnyLayer to the FlatBufferLayers
105 CreateAnyLayer(flatBufferOutputLayer.o, serializer::Layer::Layer_OutputLayer);
106}
107
Kevin May868eb142019-09-04 17:29:31 +0100108void SerializerVisitor::VisitAbsLayer(const armnn::IConnectableLayer* layer, const char* name)
109{
110 throw UnimplementedException("SerializerVisitor::VisitAbsLayer is not implemented");
111}
112
Mike Kellyaf484012019-02-20 16:53:11 +0000113// Build FlatBuffer for Activation Layer
114void SerializerVisitor::VisitActivationLayer(const armnn::IConnectableLayer* layer,
115 const armnn::ActivationDescriptor& descriptor,
116 const char* name)
117{
118 // Create FlatBuffer BaseLayer
119 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Activation);
120
121 // Create the FlatBuffer ActivationDescriptor
122 auto flatBufferDescriptor = CreateActivationDescriptor(m_flatBufferBuilder,
123 GetFlatBufferActivationFunction(descriptor.m_Function),
124 descriptor.m_A,
125 descriptor.m_B);
126
127 // Create the FlatBuffer ActivationLayer
128 auto flatBufferAdditionLayer = CreateActivationLayer(m_flatBufferBuilder,
129 flatBufferBaseLayer,
130 flatBufferDescriptor);
131
132 // Add the AnyLayer to the FlatBufferLayers
133 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_ActivationLayer);
134}
135
Mike Kelly8c1701a2019-02-11 17:01:27 +0000136// Build FlatBuffer for Addition Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000137void SerializerVisitor::VisitAdditionLayer(const armnn::IConnectableLayer* layer, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000138{
139 // Create FlatBuffer BaseLayer
140 auto flatBufferAdditionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Addition);
141
142 // Create the FlatBuffer AdditionLayer
143 auto flatBufferAdditionLayer = serializer::CreateAdditionLayer(m_flatBufferBuilder, flatBufferAdditionBaseLayer);
144
145 // Add the AnyLayer to the FlatBufferLayers
146 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_AdditionLayer);
147}
148
Nikhil Rajee391d52019-09-05 17:50:44 +0100149// Build FlatBuffer for ArgMinMax Layer
150void SerializerVisitor::VisitArgMinMaxLayer(const armnn::IConnectableLayer *layer,
151 const armnn::ArgMinMaxDescriptor& descriptor,
152 const char *name)
153{
154 // This will be implemented in IVGCVSW-3724
155 throw UnimplementedException("SerializerVisitor::VisitArgMinMaxLayer is not implemented");
156}
157
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000158// Build FlatBuffer for BatchToSpaceNd Layer
159void SerializerVisitor::VisitBatchToSpaceNdLayer(const armnn::IConnectableLayer* layer,
160 const armnn::BatchToSpaceNdDescriptor& descriptor,
161 const char* name)
162{
163 // Create FlatBuffer BaseLayer
164 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchToSpaceNd);
165
166 std::vector<unsigned int> crops;
167 crops.reserve(descriptor.m_Crops.size() * 2);
168 for (auto& crop : descriptor.m_Crops)
169 {
170 crops.push_back(crop.first);
171 crops.push_back(crop.second);
172 }
173
174 auto flatBufferDescriptor =
175 CreateBatchToSpaceNdDescriptor(m_flatBufferBuilder,
176 m_flatBufferBuilder.CreateVector(descriptor.m_BlockShape),
177 m_flatBufferBuilder.CreateVector(crops),
178 GetFlatBufferDataLayout(descriptor.m_DataLayout));
179
180 auto flatBufferLayer = serializer::CreateBatchToSpaceNdLayer(m_flatBufferBuilder,
181 flatBufferBaseLayer,
182 flatBufferDescriptor);
183
184 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_BatchToSpaceNdLayer);
185}
186
ruoyan018e7fa232019-02-28 15:09:07 +0000187void SerializerVisitor::VisitBatchNormalizationLayer(const armnn::IConnectableLayer* layer,
188 const armnn::BatchNormalizationDescriptor& batchNormDescriptor,
189 const armnn::ConstTensor& mean,
190 const armnn::ConstTensor& variance,
191 const armnn::ConstTensor& beta,
192 const armnn::ConstTensor& gamma,
193 const char* name)
194{
195 auto fbBatchNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchNormalization);
196 auto fbBatchNormalizationDescriptor = serializer::CreateBatchNormalizationDescriptor(
197 m_flatBufferBuilder,
198 batchNormDescriptor.m_Eps,
199 GetFlatBufferDataLayout(batchNormDescriptor.m_DataLayout));
200
201 auto fbMeanConstTensorInfo = CreateConstTensorInfo(mean);
202 auto fbVarianceConstTensorInfo = CreateConstTensorInfo(variance);
203 auto fbBetaConstTensorInfo = CreateConstTensorInfo(beta);
204 auto fbGammaConstTensorInfo = CreateConstTensorInfo(gamma);
205 auto fbBatchNormalizationLayer = serializer::CreateBatchNormalizationLayer(m_flatBufferBuilder,
206 fbBatchNormalizationBaseLayer,
207 fbBatchNormalizationDescriptor,
208 fbMeanConstTensorInfo,
209 fbVarianceConstTensorInfo,
210 fbBetaConstTensorInfo,
211 fbGammaConstTensorInfo);
212
213 CreateAnyLayer(fbBatchNormalizationLayer.o, serializer::Layer::Layer_BatchNormalizationLayer);
214}
215
Conor Kennedy76277882019-02-26 08:29:54 +0000216// Build FlatBuffer for Constant Layer
217void SerializerVisitor::VisitConstantLayer(const armnn::IConnectableLayer* layer,
218 const armnn::ConstTensor& input,
219 const char* name)
220{
221 // Create FlatBuffer BaseLayer
222 auto flatBufferConstantBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Constant);
223
224 auto flatBufferConstTensorInfo = CreateConstTensorInfo(input);
225
226 // Create the FlatBuffer ConstantLayer
227 auto flatBufferLayer = CreateConstantLayer(m_flatBufferBuilder,
228 flatBufferConstantBaseLayer,
229 flatBufferConstTensorInfo);
230
231 // Add the AnyLayer to the FlatBufferLayers
232 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConstantLayer);
233}
234
Mike Kellya0766c32019-02-19 17:22:07 +0000235// Build FlatBuffer for Convolution2dLayer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000236void SerializerVisitor::VisitConvolution2dLayer(const armnn::IConnectableLayer* layer,
237 const armnn::Convolution2dDescriptor& descriptor,
238 const armnn::ConstTensor& weights,
239 const armnn::Optional<armnn::ConstTensor>& biases,
Mike Kellya0766c32019-02-19 17:22:07 +0000240 const char* name)
241{
242 // Create FlatBuffer BaseLayer
243 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
244
245 auto flatBufferDescriptor = CreateConvolution2dDescriptor(m_flatBufferBuilder,
246 descriptor.m_PadLeft,
247 descriptor.m_PadRight,
248 descriptor.m_PadTop,
249 descriptor.m_PadBottom,
250 descriptor.m_StrideX,
251 descriptor.m_StrideY,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100252 descriptor.m_DilationX,
253 descriptor.m_DilationY,
Mike Kellya0766c32019-02-19 17:22:07 +0000254 descriptor.m_BiasEnabled,
255 GetFlatBufferDataLayout(descriptor.m_DataLayout));
256 auto flatBufferWeightsConstTensorInfo = CreateConstTensorInfo(weights);
257 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiasesConstTensorInfo;
258
259 if (biases.has_value())
260 {
261 flatBufferBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
262 }
263
264 // Create the FlatBuffer Convolution2dLayer
265 auto flatBufferLayer = CreateConvolution2dLayer(m_flatBufferBuilder,
266 flatBufferBaseLayer,
267 flatBufferDescriptor,
268 flatBufferWeightsConstTensorInfo,
269 flatBufferBiasesConstTensorInfo);
270
271 // Add the AnyLayer to the FlatBufferLayers
272 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution2dLayer);
273}
274
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000275void SerializerVisitor::VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
276 const armnn::DepthwiseConvolution2dDescriptor& descriptor,
277 const armnn::ConstTensor& weights,
278 const armnn::Optional<armnn::ConstTensor>& biases,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000279 const char* name)
280{
281 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthwiseConvolution2d);
282 auto fbDescriptor = CreateDepthwiseConvolution2dDescriptor(m_flatBufferBuilder,
283 descriptor.m_PadLeft,
284 descriptor.m_PadRight,
285 descriptor.m_PadTop,
286 descriptor.m_PadBottom,
287 descriptor.m_StrideX,
288 descriptor.m_StrideY,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100289 descriptor.m_DilationX,
290 descriptor.m_DilationY,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000291 descriptor.m_BiasEnabled,
292 GetFlatBufferDataLayout(descriptor.m_DataLayout));
293
294 flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
295 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
296 if (biases.has_value())
297 {
298 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
299 }
300
301 auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
302 fbBaseLayer,
303 fbDescriptor,
304 fbWeightsConstTensorInfo,
305 fbBiasesConstTensorInfo);
306
307 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
308}
309
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000310void SerializerVisitor::VisitDequantizeLayer(const armnn::IConnectableLayer* layer,
311 const char* name)
312{
313 auto fbDequantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Dequantize);
314 auto fbDequantizeLayer = serializer::CreateDequantizeLayer(m_flatBufferBuilder, fbDequantizeBaseLayer);
315
316 CreateAnyLayer(fbDequantizeLayer.o, serializer::Layer::Layer_DequantizeLayer);
317}
318
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000319void SerializerVisitor::VisitDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
320 const armnn::DetectionPostProcessDescriptor& descriptor,
321 const armnn::ConstTensor& anchors,
322 const char* name)
323{
324 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
325 auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
326 descriptor.m_MaxDetections,
327 descriptor.m_MaxClassesPerDetection,
328 descriptor.m_DetectionsPerClass,
329 descriptor.m_NmsScoreThreshold,
330 descriptor.m_NmsIouThreshold,
331 descriptor.m_NumClasses,
332 descriptor.m_UseRegularNms,
333 descriptor.m_ScaleX,
334 descriptor.m_ScaleY,
335 descriptor.m_ScaleW,
336 descriptor.m_ScaleH);
337
338 flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);
339
340 auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
341 fbBaseLayer,
342 fbDescriptor,
343 fbAnchorsConstTensorInfo);
344
345 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
346}
347
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000348void SerializerVisitor::VisitDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
349{
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000350 auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
351 auto fbDivisionLayer = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000352
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000353 CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
354}
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000355
Aron Virginas-Tar377351e2019-02-27 14:42:31 +0000356void SerializerVisitor::VisitEqualLayer(const armnn::IConnectableLayer* layer, const char* name)
357{
358 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Equal);
359 auto fbEqualLayer = serializer::CreateEqualLayer(m_flatBufferBuilder, fbBaseLayer);
360
361 CreateAnyLayer(fbEqualLayer.o, serializer::Layer::Layer_EqualLayer);
362}
363
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000364void SerializerVisitor::VisitFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
365{
366 auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
367 auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);
368
369 CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
370}
371
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000372void SerializerVisitor::VisitGatherLayer(const armnn::IConnectableLayer* layer, const char* name)
373{
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000374 auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
375 auto flatBufferLayer = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer);
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000376
377 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
378}
379
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000380void SerializerVisitor::VisitGreaterLayer(const armnn::IConnectableLayer* layer, const char* name)
381{
382 auto fbGreaterBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Greater);
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000383 auto fbGreaterLayer = serializer::CreateGreaterLayer(m_flatBufferBuilder, fbGreaterBaseLayer);
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000384
385 CreateAnyLayer(fbGreaterLayer.o, serializer::Layer::Layer_GreaterLayer);
386}
387
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000388void SerializerVisitor::VisitL2NormalizationLayer(const armnn::IConnectableLayer* layer,
389 const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
390 const char* name)
391{
392 // Create FlatBuffer BaseLayer
393 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);
394
395 // Create the FlatBuffer L2Normalization Descriptor
396 auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100397 m_flatBufferBuilder,
398 GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout),
399 l2NormalizationDescriptor.m_Eps);
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000400
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100401 // Create FlatBuffer layer
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000402 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
403
404 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
405}
406
Jim Flynn11af3752019-03-19 17:22:29 +0000407void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer, const armnn::LstmDescriptor& descriptor,
408 const armnn::LstmInputParams& params, const char* name)
409{
410 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
411
412 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
413 m_flatBufferBuilder,
414 descriptor.m_ActivationFunc,
415 descriptor.m_ClippingThresCell,
416 descriptor.m_ClippingThresProj,
417 descriptor.m_CifgEnabled,
418 descriptor.m_PeepholeEnabled,
Jan Eilersf8c62972019-07-17 11:07:49 +0100419 descriptor.m_ProjectionEnabled,
420 descriptor.m_LayerNormEnabled);
Jim Flynn11af3752019-03-19 17:22:29 +0000421
422 // Get mandatory input parameters
423 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
424 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
425 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
426 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
427 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
428 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
429 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
430 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
431 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
432
433 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
434 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
435 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
436 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
437 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
438 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
439 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
440 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
441 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
Jan Eilersf8c62972019-07-17 11:07:49 +0100442 flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
443 flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
444 flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
445 flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;
Jim Flynn11af3752019-03-19 17:22:29 +0000446
447 if (!descriptor.m_CifgEnabled)
448 {
449 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
450 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
451 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
452 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
453 }
454
455 if (descriptor.m_ProjectionEnabled)
456 {
457 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
458 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
459 }
460
461 if (descriptor.m_PeepholeEnabled)
462 {
463 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
464 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
465 }
466
Jan Eilersf8c62972019-07-17 11:07:49 +0100467 if (descriptor.m_LayerNormEnabled)
468 {
469 if (!descriptor.m_CifgEnabled)
470 {
471 inputLayerNormWeights = CreateConstTensorInfo((*params.m_InputLayerNormWeights));
472 }
473 forgetLayerNormWeights = CreateConstTensorInfo(*params.m_ForgetLayerNormWeights);
474 cellLayerNormWeights = CreateConstTensorInfo(*params.m_CellLayerNormWeights);
475 outputLayerNormWeights = CreateConstTensorInfo(*params.m_OutputLayerNormWeights);
476 }
477
Jim Flynn11af3752019-03-19 17:22:29 +0000478 auto fbLstmParams = serializer::CreateLstmInputParams(
479 m_flatBufferBuilder,
480 inputToForgetWeights,
481 inputToCellWeights,
482 inputToOutputWeights,
483 recurrentToForgetWeights,
484 recurrentToCellWeights,
485 recurrentToOutputWeights,
486 forgetGateBias,
487 cellBias,
488 outputGateBias,
489 inputToInputWeights,
490 recurrentToInputWeights,
491 cellToInputWeights,
492 inputGateBias,
493 projectionWeights,
494 projectionBias,
495 cellToForgetWeights,
Jan Eilersf8c62972019-07-17 11:07:49 +0100496 cellToOutputWeights,
497 inputLayerNormWeights,
498 forgetLayerNormWeights,
499 cellLayerNormWeights,
500 outputLayerNormWeights);
Jim Flynn11af3752019-03-19 17:22:29 +0000501
502 auto fbLstmLayer = serializer::CreateLstmLayer(
503 m_flatBufferBuilder,
504 fbLstmBaseLayer,
505 fbLstmDescriptor,
506 fbLstmParams);
507
508 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
509}
510
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000511void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
512{
513 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
514 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
515
516 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
517}
518
519void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
520 const armnn::MeanDescriptor& descriptor,
521 const char* name)
522{
523 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
524 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
525 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
526 descriptor.m_KeepDims);
527
528 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
529 fbMeanBaseLayer,
530 fbMeanDescriptor);
531
532 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
533}
534
535void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
536{
537 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
538 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
539
540 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
541}
542
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100543void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
544{
545 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
546 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
547
548 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
549}
550
Jim Flynnac25a1b2019-02-28 10:40:49 +0000551void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
Jim Flynne242f2d2019-05-22 14:24:13 +0100552 const armnn::MergerDescriptor& mergerDescriptor,
Jim Flynnac25a1b2019-02-28 10:40:49 +0000553 const char* name)
554{
Jim Flynne242f2d2019-05-22 14:24:13 +0100555 VisitConcatLayer(layer, mergerDescriptor, name);
556}
557
558void SerializerVisitor::VisitConcatLayer(const armnn::IConnectableLayer* layer,
559 const armnn::ConcatDescriptor& concatDescriptor,
560 const char* name)
561{
562 auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000563
564 std::vector<flatbuffers::Offset<UintVector>> views;
Jim Flynne242f2d2019-05-22 14:24:13 +0100565 for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000566 {
Jim Flynne242f2d2019-05-22 14:24:13 +0100567 const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000568 std::vector<uint32_t> origins;
Jim Flynne242f2d2019-05-22 14:24:13 +0100569 for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000570 {
571 origins.push_back(origin[d]);
572 }
573 auto view = m_flatBufferBuilder.CreateVector(origins);
574 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
575 views.push_back(uintVector);
576 }
577
Jim Flynne242f2d2019-05-22 14:24:13 +0100578 auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
579 concatDescriptor.GetConcatAxis(),
580 concatDescriptor.GetNumViews(),
581 concatDescriptor.GetNumDimensions(),
Jim Flynnac25a1b2019-02-28 10:40:49 +0000582 m_flatBufferBuilder.CreateVector(views));
583
Jim Flynne242f2d2019-05-22 14:24:13 +0100584 auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
585 flatBufferConcatBaseLayer,
586 flatBufferConcatDescriptor);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000587
Jim Flynne242f2d2019-05-22 14:24:13 +0100588 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000589}
590
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000591void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000592{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000593 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
594 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
595 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000596
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000597 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000598}
599
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000600void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
601 const armnn::PadDescriptor& padDescriptor,
602 const char* name)
603{
604 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
605
606 std::vector<unsigned int> padList;
607 for (auto& p: padDescriptor.m_PadList)
608 {
609 padList.push_back(p.first);
610 padList.push_back(p.second);
611 }
612
613 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
David Monahan34757812019-06-19 11:47:21 +0100614 m_flatBufferBuilder.CreateVector(padList),
Aron Virginas-Tarf3569052019-07-05 16:01:08 +0100615 padDescriptor.m_PadValue);
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000616
617 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
618 flatBufferBaseLayer,
619 flatBufferPadDesc);
620
621 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
622}
623
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000624void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
625 const armnn::PermuteDescriptor& permuteDescriptor,
626 const char* name)
627{
628 // Create FlatBuffer BaseLayer
629 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
630
631 std::vector<unsigned int> dimMappings;
Matthew Jacksondba634f2019-08-15 15:14:18 +0100632 for (unsigned int i=0; i<permuteDescriptor.m_DimMappings.GetSize(); ++i)
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000633 {
Matthew Jacksondba634f2019-08-15 15:14:18 +0100634 dimMappings.push_back(permuteDescriptor.m_DimMappings[i]);
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000635 }
636
637 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
638 m_flatBufferBuilder.CreateVector(dimMappings));
639
640 // Create the FlatBuffer PermuteLayer
641 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
642 flatBufferPermuteBaseLayer,
643 flatBufferPermuteDesc);
644
645 // Add the AnyLayer to the FlatBufferLayers
646 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
647}
648
Saoirse Stewart263829c2019-02-19 15:54:14 +0000649// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000650void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000651 const armnn::ReshapeDescriptor& reshapeDescriptor,
652 const char* name)
653{
654 // Create FlatBuffer BaseLayer
655 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
656
657 std::vector<unsigned int> targetShape;
658 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
659 {
660 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
661 }
662
663 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
664 m_flatBufferBuilder.CreateVector(targetShape));
665
666 // Create the FlatBuffer ReshapeLayer
667 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
668 flatBufferReshapeDesc);
669
670 // Add the AnyLayer to the FlatBufferLayers
671 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
672}
673
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000674void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
675 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
676 const char* name)
677{
678 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
679
680 auto flatBufferDescriptor =
681 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
682 resizeDescriptor.m_TargetWidth,
683 resizeDescriptor.m_TargetHeight,
684 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
685
686 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
687 flatBufferBaseLayer,
688 flatBufferDescriptor);
689
690 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
691}
692
Teresa Charlina9075df2019-06-27 15:41:57 +0100693void SerializerVisitor::VisitResizeLayer(const armnn::IConnectableLayer* layer,
694 const armnn::ResizeDescriptor& resizeDescriptor,
695 const char* name)
696{
FinnWilliamsArm6fb339a2019-06-28 15:07:10 +0100697 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Resize);
698
699 auto flatBufferDescriptor =
700 CreateResizeDescriptor(m_flatBufferBuilder,
701 resizeDescriptor.m_TargetHeight,
702 resizeDescriptor.m_TargetWidth,
703 GetFlatBufferResizeMethod(resizeDescriptor.m_Method),
704 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
705
706 auto flatBufferLayer = serializer::CreateResizeLayer(m_flatBufferBuilder,
707 flatBufferBaseLayer,
708 flatBufferDescriptor);
709
710 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeLayer);
Teresa Charlina9075df2019-06-27 15:41:57 +0100711}
712
Sadik Armagan8b42a382019-03-01 14:24:49 +0000713void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
714{
715 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
716 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
717
718 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
719}
720
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000721// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000722void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
723 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000724 const char* name)
725{
726 // Create FlatBuffer BaseLayer
727 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
728
729 // Create the FlatBuffer SoftmaxDescriptor
730 auto flatBufferSoftmaxDesc =
731 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
732
733 // Create the FlatBuffer SoftmaxLayer
734 auto flatBufferSoftmaxLayer =
735 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
736 flatBufferSoftmaxBaseLayer,
737 flatBufferSoftmaxDesc);
738
739 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
740}
741
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000742void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
743 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000744 const char* name)
745{
746 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
747 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
748 m_flatBufferBuilder,
749 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
750 pooling2dDescriptor.m_PadLeft,
751 pooling2dDescriptor.m_PadRight,
752 pooling2dDescriptor.m_PadTop,
753 pooling2dDescriptor.m_PadBottom,
754 pooling2dDescriptor.m_PoolWidth,
755 pooling2dDescriptor.m_PoolHeight,
756 pooling2dDescriptor.m_StrideX,
757 pooling2dDescriptor.m_StrideY,
758 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
759 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
760 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
761
762 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
763 fbPooling2dBaseLayer,
764 fbPooling2dDescriptor);
765
766 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
767}
768
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100769void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
770 const char* name)
771{
Ellen Norris-Thompson51982472019-06-19 11:46:21 +0100772 // Create FlatBuffer BaseLayer
773 auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
774
775 // Create the FlatBuffer AdditionLayer
776 auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
777
778 // Add the AnyLayer to the FlatBufferLayers
779 CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100780}
781
Derek Lamberti87acb272019-03-27 16:51:31 +0000782void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
783{
784 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
785 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
786 fbQuantizeBaseLayer);
787 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
788}
789
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000790// Build FlatBuffer for FullyConnected Layer
791void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
792 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
793 const armnn::ConstTensor& weights,
794 const armnn::Optional<armnn::ConstTensor>& biases,
795 const char* name)
796{
797 // Create FlatBuffer BaseLayer
798 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
799
800 // Create FlatBuffer FullyConnectedDescriptor
801 auto flatBufferDescriptor =
802 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
803 fullyConnectedDescriptor.m_BiasEnabled,
804 fullyConnectedDescriptor.m_TransposeWeightMatrix);
805
806 // Create FlatBuffer weights data
807 auto flatBufferWeights = CreateConstTensorInfo(weights);
808
809 // Create FlatBuffer bias data
810 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
811 if (fullyConnectedDescriptor.m_BiasEnabled)
812 {
813 flatBufferBiases = CreateConstTensorInfo(biases.value());
814 }
815
816 // Create FlatBuffer FullyConnectedLayer
817 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
818 flatBufferBaseLayer,
819 flatBufferDescriptor,
820 flatBufferWeights,
821 flatBufferBiases);
822
823 // Add created FullyConnectedLayer to the FlatBufferLayers
824 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
825}
826
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000827// Build FlatBuffer for SpaceToBatchNd Layer
828void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
829 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
830 const char* name)
831{
832 // Create FlatBuffer BaseLayer
833 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
834
835 std::vector<unsigned int> padList;
836 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
837 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
838 {
839 padList.push_back(pad.first);
840 padList.push_back(pad.second);
841 }
842
843 auto flatBufferDescriptor =
844 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
845 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
846 m_flatBufferBuilder.CreateVector(padList),
847 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
848
849 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
850 flatBufferBaseLayer,
851 flatBufferDescriptor);
852
853 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
854}
855
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100856// Build FlatBuffer for SpaceToDepthLayer
857void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
858 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
859 const char* name)
860{
Aron Virginas-Taraa067142019-06-11 16:01:44 +0100861 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
862 auto flatBufferDescriptor =
863 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
864 spaceToDepthDescriptor.m_BlockSize,
865 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
866
867 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
868 flatBufferBaseLayer,
869 flatBufferDescriptor);
870
871 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100872}
873
Jim Flynn18ce3382019-03-08 11:08:30 +0000874// Build FlatBuffer for Splitter Layer
875void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
876 const armnn::ViewsDescriptor& viewsDescriptor,
877 const char* name)
878{
879 // Create FlatBuffer ViewOrigins
880 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
881 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
882
883 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
884 {
885 std::vector<uint32_t> viewOrigin;
886 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
887
888 // Copy vector
889 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
890 {
891 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
892 }
893
894 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
895 m_flatBufferBuilder.CreateVector(viewOrigin)));
896 }
897
898 // Create FlatBuffer OriginsDescriptor
899 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
900 viewsDescriptor.GetOrigins().GetConcatAxis(),
901 viewsDescriptor.GetOrigins().GetNumViews(),
902 viewsDescriptor.GetOrigins().GetNumDimensions(),
903 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
904
905 // Create FlatBuffer ViewOrigins
906 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
907 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
908
909 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
910 {
911 std::vector<uint32_t> viewSize;
912 viewSize.reserve(viewsDescriptor.GetNumDimensions());
913
914 // Copy vector
915 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
916 {
917 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
918 }
919
920 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
921 m_flatBufferBuilder.CreateVector(viewSize)));
922 }
923
924 // Create FlatBuffer ViewsDescriptor
925 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
926 flatBufferOriginDescriptor,
927 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
928
929 // Create FlatBuffer BaseLayer
930 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
931
932 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
933 flatBufferBaseLayer,
934 flatBufferViewsDescriptor);
935
936 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
937}
938
Nina Drozd57728782019-02-27 10:53:27 +0000939void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
940 const armnn::NormalizationDescriptor& descriptor,
941 const char* name)
942{
943 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
944
945 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
946 m_flatBufferBuilder,
947 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
948 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
949 descriptor.m_NormSize,
950 descriptor.m_Alpha,
951 descriptor.m_Beta,
952 descriptor.m_K,
953 GetFlatBufferDataLayout(descriptor.m_DataLayout));
954
955 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
956 fbNormalizationBaseLayer,
957 fbNormalizationDescriptor);
958
959 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
960}
961
Matthew Jackson2b8c1da2019-07-04 14:59:16 +0100962void SerializerVisitor::VisitStackLayer(const armnn::IConnectableLayer* layer,
963 const armnn::StackDescriptor& stackDescriptor,
964 const char* name)
965{
Matthew Jacksonb5433ee2019-07-11 15:54:20 +0100966 auto stackBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Stack);
967
968 std::vector<unsigned int> inputShape;
969 for (unsigned int i =0; i < stackDescriptor.m_InputShape.GetNumDimensions(); i++)
970 {
971 inputShape.push_back(stackDescriptor.m_InputShape[i]);
972 }
973
974 auto flatBufferStackDescriptor = CreateStackDescriptor(m_flatBufferBuilder,
975 stackDescriptor.m_Axis,
976 stackDescriptor.m_NumInputs,
977 m_flatBufferBuilder.CreateVector(inputShape));
978
979 auto stackLayer = serializer::CreateStackLayer(m_flatBufferBuilder, stackBaseLayer, flatBufferStackDescriptor);
980 CreateAnyLayer(stackLayer.o, serializer::Layer::Layer_StackLayer);
Matthew Jackson2b8c1da2019-07-04 14:59:16 +0100981}
982
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000983void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
984 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
985 const char* name)
986{
987 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
988
989 auto flatBufferDescriptor =
990 CreateStridedSliceDescriptor(m_flatBufferBuilder,
991 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
992 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
993 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
994 stridedSliceDescriptor.m_BeginMask,
995 stridedSliceDescriptor.m_EndMask,
996 stridedSliceDescriptor.m_ShrinkAxisMask,
997 stridedSliceDescriptor.m_EllipsisMask,
998 stridedSliceDescriptor.m_NewAxisMask,
999 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
1000
1001 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
1002 flatBufferBaseLayer,
1003 flatBufferDescriptor);
1004
1005 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
1006}
1007
Conor Kennedyda1f9752019-03-01 14:37:12 +00001008void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
1009{
1010 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
1011 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
1012
1013 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
1014}
1015
Sadik Armaganeff363d2019-04-05 15:25:46 +01001016void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
1017{
1018 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
1019 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
1020
1021 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
1022}
1023
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001024void SerializerVisitor::VisitTransposeConvolution2dLayer(
1025 const armnn::IConnectableLayer* layer,
1026 const armnn::TransposeConvolution2dDescriptor& descriptor,
1027 const armnn::ConstTensor& weights,
1028 const armnn::Optional<armnn::ConstTensor>& biases,
1029 const char* name)
1030{
Aron Virginas-Tarcb549302019-06-21 13:53:38 +01001031 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
1032 auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
1033 descriptor.m_PadLeft,
1034 descriptor.m_PadRight,
1035 descriptor.m_PadTop,
1036 descriptor.m_PadBottom,
1037 descriptor.m_StrideX,
1038 descriptor.m_StrideY,
1039 descriptor.m_BiasEnabled,
1040 GetFlatBufferDataLayout(descriptor.m_DataLayout));
1041
1042 // weights & biases
1043 auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
1044 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
1045 if (biases.has_value())
1046 {
1047 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
1048 }
1049
1050 auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
1051 fbBaseLayer,
1052 fbDescriptor,
1053 fbWeightsConstTensorInfo,
1054 fbBiasesConstTensorInfo);
1055
1056 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001057}
1058
James Conroyee18dc82019-07-17 11:27:46 +01001059void SerializerVisitor::VisitQuantizedLstmLayer(const armnn::IConnectableLayer* layer,
1060 const armnn::QuantizedLstmInputParams& params,
1061 const char* name)
1062{
Jan Eilers5b01a892019-07-23 09:47:43 +01001063 auto fbQuantizedLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_QuantizedLstm);
1064
1065 // Get input parameters
Francis Murtaghbb590b42019-08-14 09:51:36 +01001066 auto inputToInputWeights = CreateConstTensorInfo(params.GetInputToInputWeights());
1067 auto inputToForgetWeights = CreateConstTensorInfo(params.GetInputToForgetWeights());
1068 auto inputToCellWeights = CreateConstTensorInfo(params.GetInputToCellWeights());
1069 auto inputToOutputWeights = CreateConstTensorInfo(params.GetInputToOutputWeights());
Jan Eilers5b01a892019-07-23 09:47:43 +01001070
Francis Murtaghbb590b42019-08-14 09:51:36 +01001071 auto recurrentToInputWeights = CreateConstTensorInfo(params.GetRecurrentToInputWeights());
1072 auto recurrentToForgetWeights = CreateConstTensorInfo(params.GetRecurrentToForgetWeights());
1073 auto recurrentToCellWeights = CreateConstTensorInfo(params.GetRecurrentToCellWeights());
1074 auto recurrentToOutputWeights = CreateConstTensorInfo(params.GetRecurrentToOutputWeights());
Jan Eilers5b01a892019-07-23 09:47:43 +01001075
Francis Murtaghbb590b42019-08-14 09:51:36 +01001076 auto inputGateBias = CreateConstTensorInfo(params.GetInputGateBias());
1077 auto forgetGateBias = CreateConstTensorInfo(params.GetForgetGateBias());
1078 auto cellBias = CreateConstTensorInfo(params.GetCellBias());
1079 auto outputGateBias = CreateConstTensorInfo(params.GetOutputGateBias());
Jan Eilers5b01a892019-07-23 09:47:43 +01001080
1081 auto fbQuantizedLstmParams = serializer::CreateQuantizedLstmInputParams(
1082 m_flatBufferBuilder,
1083 inputToInputWeights,
1084 inputToForgetWeights,
1085 inputToCellWeights,
1086 inputToOutputWeights,
1087 recurrentToInputWeights,
1088 recurrentToForgetWeights,
1089 recurrentToCellWeights,
1090 recurrentToOutputWeights,
1091 inputGateBias,
1092 forgetGateBias,
1093 cellBias,
1094 outputGateBias);
1095
1096 auto fbQuantizedLstmLayer = serializer::CreateQuantizedLstmLayer(
1097 m_flatBufferBuilder,
1098 fbQuantizedLstmBaseLayer,
1099 fbQuantizedLstmParams);
1100
1101 CreateAnyLayer(fbQuantizedLstmLayer.o, serializer::Layer::Layer_QuantizedLstmLayer);
James Conroyee18dc82019-07-17 11:27:46 +01001102}
1103
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001104fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001105 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001106{
Sadik Armagandb059fd2019-03-20 12:28:32 +00001107 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
1108
Mike Kelly8c1701a2019-02-11 17:01:27 +00001109 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
1110 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
1111
1112 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +00001113 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +00001114 m_flatBufferBuilder.CreateString(layer->GetName()),
1115 layerType,
1116 m_flatBufferBuilder.CreateVector(inputSlots),
1117 m_flatBufferBuilder.CreateVector(outputSlots));
1118}
1119
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001120void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001121{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001122 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +00001123 m_serializedLayers.push_back(anyLayer);
1124}
1125
Mike Kellya0766c32019-02-19 17:22:07 +00001126template <typename T>
1127flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
1128{
1129 const T* buffer = reinterpret_cast<const T*>(memory);
1130 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
1131 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
1132 return fbVector;
1133}
1134
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001135flatbuffers::Offset<serializer::ConstTensor>
1136 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +00001137{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001138 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +00001139
1140 // Get the dimensions
1141 std::vector<unsigned int> shape;
1142
1143 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1144 {
1145 shape.push_back(tensorInfo.GetShape()[dim]);
1146 }
1147
1148 // Create FlatBuffer TensorInfo
1149 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1150 m_flatBufferBuilder.CreateVector(shape),
1151 GetFlatBufferDataType(tensorInfo.GetDataType()),
1152 tensorInfo.GetQuantizationScale(),
1153 tensorInfo.GetQuantizationOffset());
1154 flatbuffers::Offset<void> fbPayload;
1155
1156 switch (tensorInfo.GetDataType())
1157 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001158 case armnn::DataType::Float32:
1159 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +00001160 {
1161 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1162 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1163 m_flatBufferBuilder,
1164 fbVector);
1165 fbPayload = flatBuffersData.o;
1166 break;
1167 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001168 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +00001169 {
1170 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1171 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1172 m_flatBufferBuilder,
1173 fbVector);
1174 fbPayload = flatBuffersData.o;
1175 break;
1176 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001177 case armnn::DataType::QuantisedSymm16:
1178 {
1179 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1180 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1181 m_flatBufferBuilder,
1182 fbVector);
1183 fbPayload = flatBuffersData.o;
1184 break;
1185 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001186 case armnn::DataType::QuantisedAsymm8:
1187 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001188 default:
1189 {
1190 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1191 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1192 m_flatBufferBuilder,
1193 fbVector);
1194 fbPayload = flatBuffersData.o;
1195 }
1196 }
1197 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1198 m_flatBufferBuilder,
1199 flatBufferTensorInfo,
1200 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1201 fbPayload);
1202 return flatBufferConstTensor;
1203}
1204
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001205std::vector<fb::Offset<serializer::InputSlot>>
1206 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001207{
Mike Kellya0766c32019-02-19 17:22:07 +00001208 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001209
1210 // Get the InputSlots
1211 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1212 {
1213 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1214
1215 // Get the Connection for the InputSlot
1216 const IOutputSlot* connection = inputSlot.GetConnection();
1217
1218 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001219 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1220 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001221 // Create FlatBuffer InputSlot
1222 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1223 }
1224 return inputSlots;
1225}
1226
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001227std::vector<fb::Offset<serializer::OutputSlot>>
1228 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001229{
1230 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1231
1232 // Get the OutputSlots
1233 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1234 {
1235 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001236 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001237
1238 // Get the dimensions
1239 std::vector<unsigned int> shape;
1240 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1241 {
1242 shape.push_back(tensorInfo.GetShape()[dim]);
1243 }
1244
1245 // Create FlatBuffer TensorInfo
1246 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1247 m_flatBufferBuilder.CreateVector(shape),
1248 GetFlatBufferDataType(tensorInfo.GetDataType()),
1249 tensorInfo.GetQuantizationScale(),
1250 tensorInfo.GetQuantizationOffset());
1251
1252 // Create FlatBuffer Outputslot
1253 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1254 slotIndex,
1255 flatBufferTensorInfo));
1256 }
1257 return outputSlots;
1258}
1259
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001260
1261ISerializer* ISerializer::CreateRaw()
1262{
1263 return new Serializer();
1264}
1265
1266ISerializerPtr ISerializer::Create()
1267{
1268 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1269}
1270
1271void ISerializer::Destroy(ISerializer* serializer)
1272{
1273 delete serializer;
1274}
1275
1276void Serializer::Serialize(const INetwork& inNetwork)
1277{
1278 // Iterate through to network
1279 inNetwork.Accept(m_SerializerVisitor);
1280 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1281
1282 // Create FlatBuffer SerializedGraph
1283 auto serializedGraph = serializer::CreateSerializedGraph(
1284 fbBuilder,
1285 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1286 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1287 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1288
1289 // Serialize the graph
1290 fbBuilder.Finish(serializedGraph);
1291}
1292
1293bool Serializer::SaveSerializedToStream(std::ostream& stream)
1294{
1295 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1296
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001297 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1298 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001299 return !stream.bad();
1300}
1301
Matteo Martincighec333912019-02-13 15:12:39 +00001302} // namespace armnnSerializer