blob: 595573c41779a9270d82ceb060d36062e8c877c0 [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{
FinnWilliamsArm4ffcc8f2019-09-05 14:34:20 +0100110 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Abs);
111 auto flatBufferAbsLayer = serializer::CreateAbsLayer(m_flatBufferBuilder, flatBufferBaseLayer);
112
113 CreateAnyLayer(flatBufferAbsLayer.o, serializer::Layer::Layer_AbsLayer);
Kevin May868eb142019-09-04 17:29:31 +0100114}
115
Mike Kellyaf484012019-02-20 16:53:11 +0000116// Build FlatBuffer for Activation Layer
117void SerializerVisitor::VisitActivationLayer(const armnn::IConnectableLayer* layer,
118 const armnn::ActivationDescriptor& descriptor,
119 const char* name)
120{
121 // Create FlatBuffer BaseLayer
122 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Activation);
123
124 // Create the FlatBuffer ActivationDescriptor
125 auto flatBufferDescriptor = CreateActivationDescriptor(m_flatBufferBuilder,
126 GetFlatBufferActivationFunction(descriptor.m_Function),
127 descriptor.m_A,
128 descriptor.m_B);
129
130 // Create the FlatBuffer ActivationLayer
131 auto flatBufferAdditionLayer = CreateActivationLayer(m_flatBufferBuilder,
132 flatBufferBaseLayer,
133 flatBufferDescriptor);
134
135 // Add the AnyLayer to the FlatBufferLayers
136 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_ActivationLayer);
137}
138
Mike Kelly8c1701a2019-02-11 17:01:27 +0000139// Build FlatBuffer for Addition Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000140void SerializerVisitor::VisitAdditionLayer(const armnn::IConnectableLayer* layer, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000141{
142 // Create FlatBuffer BaseLayer
143 auto flatBufferAdditionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Addition);
144
145 // Create the FlatBuffer AdditionLayer
146 auto flatBufferAdditionLayer = serializer::CreateAdditionLayer(m_flatBufferBuilder, flatBufferAdditionBaseLayer);
147
148 // Add the AnyLayer to the FlatBufferLayers
149 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_AdditionLayer);
150}
151
Nikhil Rajee391d52019-09-05 17:50:44 +0100152// Build FlatBuffer for ArgMinMax Layer
153void SerializerVisitor::VisitArgMinMaxLayer(const armnn::IConnectableLayer *layer,
154 const armnn::ArgMinMaxDescriptor& descriptor,
155 const char *name)
156{
157 // This will be implemented in IVGCVSW-3724
158 throw UnimplementedException("SerializerVisitor::VisitArgMinMaxLayer is not implemented");
159}
160
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000161// Build FlatBuffer for BatchToSpaceNd Layer
162void SerializerVisitor::VisitBatchToSpaceNdLayer(const armnn::IConnectableLayer* layer,
163 const armnn::BatchToSpaceNdDescriptor& descriptor,
164 const char* name)
165{
166 // Create FlatBuffer BaseLayer
167 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchToSpaceNd);
168
169 std::vector<unsigned int> crops;
170 crops.reserve(descriptor.m_Crops.size() * 2);
171 for (auto& crop : descriptor.m_Crops)
172 {
173 crops.push_back(crop.first);
174 crops.push_back(crop.second);
175 }
176
177 auto flatBufferDescriptor =
178 CreateBatchToSpaceNdDescriptor(m_flatBufferBuilder,
179 m_flatBufferBuilder.CreateVector(descriptor.m_BlockShape),
180 m_flatBufferBuilder.CreateVector(crops),
181 GetFlatBufferDataLayout(descriptor.m_DataLayout));
182
183 auto flatBufferLayer = serializer::CreateBatchToSpaceNdLayer(m_flatBufferBuilder,
184 flatBufferBaseLayer,
185 flatBufferDescriptor);
186
187 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_BatchToSpaceNdLayer);
188}
189
ruoyan018e7fa232019-02-28 15:09:07 +0000190void SerializerVisitor::VisitBatchNormalizationLayer(const armnn::IConnectableLayer* layer,
191 const armnn::BatchNormalizationDescriptor& batchNormDescriptor,
192 const armnn::ConstTensor& mean,
193 const armnn::ConstTensor& variance,
194 const armnn::ConstTensor& beta,
195 const armnn::ConstTensor& gamma,
196 const char* name)
197{
198 auto fbBatchNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchNormalization);
199 auto fbBatchNormalizationDescriptor = serializer::CreateBatchNormalizationDescriptor(
200 m_flatBufferBuilder,
201 batchNormDescriptor.m_Eps,
202 GetFlatBufferDataLayout(batchNormDescriptor.m_DataLayout));
203
204 auto fbMeanConstTensorInfo = CreateConstTensorInfo(mean);
205 auto fbVarianceConstTensorInfo = CreateConstTensorInfo(variance);
206 auto fbBetaConstTensorInfo = CreateConstTensorInfo(beta);
207 auto fbGammaConstTensorInfo = CreateConstTensorInfo(gamma);
208 auto fbBatchNormalizationLayer = serializer::CreateBatchNormalizationLayer(m_flatBufferBuilder,
209 fbBatchNormalizationBaseLayer,
210 fbBatchNormalizationDescriptor,
211 fbMeanConstTensorInfo,
212 fbVarianceConstTensorInfo,
213 fbBetaConstTensorInfo,
214 fbGammaConstTensorInfo);
215
216 CreateAnyLayer(fbBatchNormalizationLayer.o, serializer::Layer::Layer_BatchNormalizationLayer);
217}
218
Conor Kennedy76277882019-02-26 08:29:54 +0000219// Build FlatBuffer for Constant Layer
220void SerializerVisitor::VisitConstantLayer(const armnn::IConnectableLayer* layer,
221 const armnn::ConstTensor& input,
222 const char* name)
223{
224 // Create FlatBuffer BaseLayer
225 auto flatBufferConstantBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Constant);
226
227 auto flatBufferConstTensorInfo = CreateConstTensorInfo(input);
228
229 // Create the FlatBuffer ConstantLayer
230 auto flatBufferLayer = CreateConstantLayer(m_flatBufferBuilder,
231 flatBufferConstantBaseLayer,
232 flatBufferConstTensorInfo);
233
234 // Add the AnyLayer to the FlatBufferLayers
235 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConstantLayer);
236}
237
Mike Kellya0766c32019-02-19 17:22:07 +0000238// Build FlatBuffer for Convolution2dLayer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000239void SerializerVisitor::VisitConvolution2dLayer(const armnn::IConnectableLayer* layer,
240 const armnn::Convolution2dDescriptor& descriptor,
241 const armnn::ConstTensor& weights,
242 const armnn::Optional<armnn::ConstTensor>& biases,
Mike Kellya0766c32019-02-19 17:22:07 +0000243 const char* name)
244{
245 // Create FlatBuffer BaseLayer
246 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
247
248 auto flatBufferDescriptor = CreateConvolution2dDescriptor(m_flatBufferBuilder,
249 descriptor.m_PadLeft,
250 descriptor.m_PadRight,
251 descriptor.m_PadTop,
252 descriptor.m_PadBottom,
253 descriptor.m_StrideX,
254 descriptor.m_StrideY,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100255 descriptor.m_DilationX,
256 descriptor.m_DilationY,
Mike Kellya0766c32019-02-19 17:22:07 +0000257 descriptor.m_BiasEnabled,
258 GetFlatBufferDataLayout(descriptor.m_DataLayout));
259 auto flatBufferWeightsConstTensorInfo = CreateConstTensorInfo(weights);
260 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiasesConstTensorInfo;
261
262 if (biases.has_value())
263 {
264 flatBufferBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
265 }
266
267 // Create the FlatBuffer Convolution2dLayer
268 auto flatBufferLayer = CreateConvolution2dLayer(m_flatBufferBuilder,
269 flatBufferBaseLayer,
270 flatBufferDescriptor,
271 flatBufferWeightsConstTensorInfo,
272 flatBufferBiasesConstTensorInfo);
273
274 // Add the AnyLayer to the FlatBufferLayers
275 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution2dLayer);
276}
277
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000278void SerializerVisitor::VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
279 const armnn::DepthwiseConvolution2dDescriptor& descriptor,
280 const armnn::ConstTensor& weights,
281 const armnn::Optional<armnn::ConstTensor>& biases,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000282 const char* name)
283{
284 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthwiseConvolution2d);
285 auto fbDescriptor = CreateDepthwiseConvolution2dDescriptor(m_flatBufferBuilder,
286 descriptor.m_PadLeft,
287 descriptor.m_PadRight,
288 descriptor.m_PadTop,
289 descriptor.m_PadBottom,
290 descriptor.m_StrideX,
291 descriptor.m_StrideY,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100292 descriptor.m_DilationX,
293 descriptor.m_DilationY,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000294 descriptor.m_BiasEnabled,
295 GetFlatBufferDataLayout(descriptor.m_DataLayout));
296
297 flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
298 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
299 if (biases.has_value())
300 {
301 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
302 }
303
304 auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
305 fbBaseLayer,
306 fbDescriptor,
307 fbWeightsConstTensorInfo,
308 fbBiasesConstTensorInfo);
309
310 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
311}
312
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000313void SerializerVisitor::VisitDequantizeLayer(const armnn::IConnectableLayer* layer,
314 const char* name)
315{
316 auto fbDequantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Dequantize);
317 auto fbDequantizeLayer = serializer::CreateDequantizeLayer(m_flatBufferBuilder, fbDequantizeBaseLayer);
318
319 CreateAnyLayer(fbDequantizeLayer.o, serializer::Layer::Layer_DequantizeLayer);
320}
321
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000322void SerializerVisitor::VisitDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
323 const armnn::DetectionPostProcessDescriptor& descriptor,
324 const armnn::ConstTensor& anchors,
325 const char* name)
326{
327 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
328 auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
329 descriptor.m_MaxDetections,
330 descriptor.m_MaxClassesPerDetection,
331 descriptor.m_DetectionsPerClass,
332 descriptor.m_NmsScoreThreshold,
333 descriptor.m_NmsIouThreshold,
334 descriptor.m_NumClasses,
335 descriptor.m_UseRegularNms,
336 descriptor.m_ScaleX,
337 descriptor.m_ScaleY,
338 descriptor.m_ScaleW,
339 descriptor.m_ScaleH);
340
341 flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);
342
343 auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
344 fbBaseLayer,
345 fbDescriptor,
346 fbAnchorsConstTensorInfo);
347
348 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
349}
350
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000351void SerializerVisitor::VisitDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
352{
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000353 auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
354 auto fbDivisionLayer = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000355
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000356 CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
357}
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000358
Aron Virginas-Tar377351e2019-02-27 14:42:31 +0000359void SerializerVisitor::VisitEqualLayer(const armnn::IConnectableLayer* layer, const char* name)
360{
361 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Equal);
362 auto fbEqualLayer = serializer::CreateEqualLayer(m_flatBufferBuilder, fbBaseLayer);
363
364 CreateAnyLayer(fbEqualLayer.o, serializer::Layer::Layer_EqualLayer);
365}
366
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000367void SerializerVisitor::VisitFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
368{
369 auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
370 auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);
371
372 CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
373}
374
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000375void SerializerVisitor::VisitGatherLayer(const armnn::IConnectableLayer* layer, const char* name)
376{
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000377 auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
378 auto flatBufferLayer = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer);
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000379
380 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
381}
382
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000383void SerializerVisitor::VisitGreaterLayer(const armnn::IConnectableLayer* layer, const char* name)
384{
385 auto fbGreaterBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Greater);
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000386 auto fbGreaterLayer = serializer::CreateGreaterLayer(m_flatBufferBuilder, fbGreaterBaseLayer);
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000387
388 CreateAnyLayer(fbGreaterLayer.o, serializer::Layer::Layer_GreaterLayer);
389}
390
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000391void SerializerVisitor::VisitL2NormalizationLayer(const armnn::IConnectableLayer* layer,
392 const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
393 const char* name)
394{
395 // Create FlatBuffer BaseLayer
396 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);
397
398 // Create the FlatBuffer L2Normalization Descriptor
399 auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100400 m_flatBufferBuilder,
401 GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout),
402 l2NormalizationDescriptor.m_Eps);
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000403
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100404 // Create FlatBuffer layer
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000405 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
406
407 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
408}
409
Jim Flynn11af3752019-03-19 17:22:29 +0000410void SerializerVisitor::VisitLstmLayer(const armnn::IConnectableLayer* layer, const armnn::LstmDescriptor& descriptor,
411 const armnn::LstmInputParams& params, const char* name)
412{
413 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
414
415 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
416 m_flatBufferBuilder,
417 descriptor.m_ActivationFunc,
418 descriptor.m_ClippingThresCell,
419 descriptor.m_ClippingThresProj,
420 descriptor.m_CifgEnabled,
421 descriptor.m_PeepholeEnabled,
Jan Eilersf8c62972019-07-17 11:07:49 +0100422 descriptor.m_ProjectionEnabled,
423 descriptor.m_LayerNormEnabled);
Jim Flynn11af3752019-03-19 17:22:29 +0000424
425 // Get mandatory input parameters
426 auto inputToForgetWeights = CreateConstTensorInfo(*params.m_InputToForgetWeights);
427 auto inputToCellWeights = CreateConstTensorInfo(*params.m_InputToCellWeights);
428 auto inputToOutputWeights = CreateConstTensorInfo(*params.m_InputToOutputWeights);
429 auto recurrentToForgetWeights = CreateConstTensorInfo(*params.m_RecurrentToForgetWeights);
430 auto recurrentToCellWeights = CreateConstTensorInfo(*params.m_RecurrentToCellWeights);
431 auto recurrentToOutputWeights = CreateConstTensorInfo(*params.m_RecurrentToOutputWeights);
432 auto forgetGateBias = CreateConstTensorInfo(*params.m_ForgetGateBias);
433 auto cellBias = CreateConstTensorInfo(*params.m_CellBias);
434 auto outputGateBias = CreateConstTensorInfo(*params.m_OutputGateBias);
435
436 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
437 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
438 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
439 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
440 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
441 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
442 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
443 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
444 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
Jan Eilersf8c62972019-07-17 11:07:49 +0100445 flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
446 flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
447 flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
448 flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;
Jim Flynn11af3752019-03-19 17:22:29 +0000449
450 if (!descriptor.m_CifgEnabled)
451 {
452 inputToInputWeights = CreateConstTensorInfo(*params.m_InputToInputWeights);
453 recurrentToInputWeights = CreateConstTensorInfo(*params.m_RecurrentToInputWeights);
454 cellToInputWeights = CreateConstTensorInfo(*params.m_CellToInputWeights);
455 inputGateBias = CreateConstTensorInfo(*params.m_InputGateBias);
456 }
457
458 if (descriptor.m_ProjectionEnabled)
459 {
460 projectionWeights = CreateConstTensorInfo(*params.m_ProjectionWeights);
461 projectionBias = CreateConstTensorInfo(*params.m_ProjectionBias);
462 }
463
464 if (descriptor.m_PeepholeEnabled)
465 {
466 cellToForgetWeights = CreateConstTensorInfo(*params.m_CellToForgetWeights);
467 cellToOutputWeights = CreateConstTensorInfo(*params.m_CellToOutputWeights);
468 }
469
Jan Eilersf8c62972019-07-17 11:07:49 +0100470 if (descriptor.m_LayerNormEnabled)
471 {
472 if (!descriptor.m_CifgEnabled)
473 {
474 inputLayerNormWeights = CreateConstTensorInfo((*params.m_InputLayerNormWeights));
475 }
476 forgetLayerNormWeights = CreateConstTensorInfo(*params.m_ForgetLayerNormWeights);
477 cellLayerNormWeights = CreateConstTensorInfo(*params.m_CellLayerNormWeights);
478 outputLayerNormWeights = CreateConstTensorInfo(*params.m_OutputLayerNormWeights);
479 }
480
Jim Flynn11af3752019-03-19 17:22:29 +0000481 auto fbLstmParams = serializer::CreateLstmInputParams(
482 m_flatBufferBuilder,
483 inputToForgetWeights,
484 inputToCellWeights,
485 inputToOutputWeights,
486 recurrentToForgetWeights,
487 recurrentToCellWeights,
488 recurrentToOutputWeights,
489 forgetGateBias,
490 cellBias,
491 outputGateBias,
492 inputToInputWeights,
493 recurrentToInputWeights,
494 cellToInputWeights,
495 inputGateBias,
496 projectionWeights,
497 projectionBias,
498 cellToForgetWeights,
Jan Eilersf8c62972019-07-17 11:07:49 +0100499 cellToOutputWeights,
500 inputLayerNormWeights,
501 forgetLayerNormWeights,
502 cellLayerNormWeights,
503 outputLayerNormWeights);
Jim Flynn11af3752019-03-19 17:22:29 +0000504
505 auto fbLstmLayer = serializer::CreateLstmLayer(
506 m_flatBufferBuilder,
507 fbLstmBaseLayer,
508 fbLstmDescriptor,
509 fbLstmParams);
510
511 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
512}
513
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000514void SerializerVisitor::VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
515{
516 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
517 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
518
519 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
520}
521
522void SerializerVisitor::VisitMeanLayer(const armnn::IConnectableLayer* layer,
523 const armnn::MeanDescriptor& descriptor,
524 const char* name)
525{
526 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
527 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
528 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
529 descriptor.m_KeepDims);
530
531 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
532 fbMeanBaseLayer,
533 fbMeanDescriptor);
534
535 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
536}
537
538void SerializerVisitor::VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
539{
540 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
541 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
542
543 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
544}
545
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100546void SerializerVisitor::VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
547{
548 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
549 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
550
551 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
552}
553
Jim Flynnac25a1b2019-02-28 10:40:49 +0000554void SerializerVisitor::VisitMergerLayer(const armnn::IConnectableLayer* layer,
Jim Flynne242f2d2019-05-22 14:24:13 +0100555 const armnn::MergerDescriptor& mergerDescriptor,
Jim Flynnac25a1b2019-02-28 10:40:49 +0000556 const char* name)
557{
Jim Flynne242f2d2019-05-22 14:24:13 +0100558 VisitConcatLayer(layer, mergerDescriptor, name);
559}
560
561void SerializerVisitor::VisitConcatLayer(const armnn::IConnectableLayer* layer,
562 const armnn::ConcatDescriptor& concatDescriptor,
563 const char* name)
564{
565 auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000566
567 std::vector<flatbuffers::Offset<UintVector>> views;
Jim Flynne242f2d2019-05-22 14:24:13 +0100568 for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000569 {
Jim Flynne242f2d2019-05-22 14:24:13 +0100570 const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000571 std::vector<uint32_t> origins;
Jim Flynne242f2d2019-05-22 14:24:13 +0100572 for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000573 {
574 origins.push_back(origin[d]);
575 }
576 auto view = m_flatBufferBuilder.CreateVector(origins);
577 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
578 views.push_back(uintVector);
579 }
580
Jim Flynne242f2d2019-05-22 14:24:13 +0100581 auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
582 concatDescriptor.GetConcatAxis(),
583 concatDescriptor.GetNumViews(),
584 concatDescriptor.GetNumDimensions(),
Jim Flynnac25a1b2019-02-28 10:40:49 +0000585 m_flatBufferBuilder.CreateVector(views));
586
Jim Flynne242f2d2019-05-22 14:24:13 +0100587 auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
588 flatBufferConcatBaseLayer,
589 flatBufferConcatDescriptor);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000590
Jim Flynne242f2d2019-05-22 14:24:13 +0100591 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000592}
593
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000594void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000595{
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000596 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
597 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
598 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000599
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000600 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000601}
602
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000603void SerializerVisitor::VisitPadLayer(const armnn::IConnectableLayer* layer,
604 const armnn::PadDescriptor& padDescriptor,
605 const char* name)
606{
607 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
608
609 std::vector<unsigned int> padList;
610 for (auto& p: padDescriptor.m_PadList)
611 {
612 padList.push_back(p.first);
613 padList.push_back(p.second);
614 }
615
616 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
David Monahan34757812019-06-19 11:47:21 +0100617 m_flatBufferBuilder.CreateVector(padList),
Aron Virginas-Tarf3569052019-07-05 16:01:08 +0100618 padDescriptor.m_PadValue);
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000619
620 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
621 flatBufferBaseLayer,
622 flatBufferPadDesc);
623
624 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
625}
626
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000627void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
628 const armnn::PermuteDescriptor& permuteDescriptor,
629 const char* name)
630{
631 // Create FlatBuffer BaseLayer
632 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
633
634 std::vector<unsigned int> dimMappings;
Matthew Jacksondba634f2019-08-15 15:14:18 +0100635 for (unsigned int i=0; i<permuteDescriptor.m_DimMappings.GetSize(); ++i)
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000636 {
Matthew Jacksondba634f2019-08-15 15:14:18 +0100637 dimMappings.push_back(permuteDescriptor.m_DimMappings[i]);
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000638 }
639
640 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
641 m_flatBufferBuilder.CreateVector(dimMappings));
642
643 // Create the FlatBuffer PermuteLayer
644 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
645 flatBufferPermuteBaseLayer,
646 flatBufferPermuteDesc);
647
648 // Add the AnyLayer to the FlatBufferLayers
649 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
650}
651
Saoirse Stewart263829c2019-02-19 15:54:14 +0000652// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000653void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000654 const armnn::ReshapeDescriptor& reshapeDescriptor,
655 const char* name)
656{
657 // Create FlatBuffer BaseLayer
658 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
659
660 std::vector<unsigned int> targetShape;
661 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
662 {
663 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
664 }
665
666 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
667 m_flatBufferBuilder.CreateVector(targetShape));
668
669 // Create the FlatBuffer ReshapeLayer
670 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
671 flatBufferReshapeDesc);
672
673 // Add the AnyLayer to the FlatBufferLayers
674 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
675}
676
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +0000677void SerializerVisitor::VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
678 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
679 const char* name)
680{
681 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);
682
683 auto flatBufferDescriptor =
684 CreateResizeBilinearDescriptor(m_flatBufferBuilder,
685 resizeDescriptor.m_TargetWidth,
686 resizeDescriptor.m_TargetHeight,
687 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
688
689 auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
690 flatBufferBaseLayer,
691 flatBufferDescriptor);
692
693 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
694}
695
Teresa Charlina9075df2019-06-27 15:41:57 +0100696void SerializerVisitor::VisitResizeLayer(const armnn::IConnectableLayer* layer,
697 const armnn::ResizeDescriptor& resizeDescriptor,
698 const char* name)
699{
FinnWilliamsArm6fb339a2019-06-28 15:07:10 +0100700 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Resize);
701
702 auto flatBufferDescriptor =
703 CreateResizeDescriptor(m_flatBufferBuilder,
704 resizeDescriptor.m_TargetHeight,
705 resizeDescriptor.m_TargetWidth,
706 GetFlatBufferResizeMethod(resizeDescriptor.m_Method),
707 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout));
708
709 auto flatBufferLayer = serializer::CreateResizeLayer(m_flatBufferBuilder,
710 flatBufferBaseLayer,
711 flatBufferDescriptor);
712
713 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeLayer);
Teresa Charlina9075df2019-06-27 15:41:57 +0100714}
715
Sadik Armagan8b42a382019-03-01 14:24:49 +0000716void SerializerVisitor::VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
717{
718 auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
719 auto fbRsqrtLayer = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);
720
721 CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
722}
723
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000724// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000725void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
726 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000727 const char* name)
728{
729 // Create FlatBuffer BaseLayer
730 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
731
732 // Create the FlatBuffer SoftmaxDescriptor
733 auto flatBufferSoftmaxDesc =
734 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
735
736 // Create the FlatBuffer SoftmaxLayer
737 auto flatBufferSoftmaxLayer =
738 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
739 flatBufferSoftmaxBaseLayer,
740 flatBufferSoftmaxDesc);
741
742 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
743}
744
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000745void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
746 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000747 const char* name)
748{
749 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
750 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
751 m_flatBufferBuilder,
752 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
753 pooling2dDescriptor.m_PadLeft,
754 pooling2dDescriptor.m_PadRight,
755 pooling2dDescriptor.m_PadTop,
756 pooling2dDescriptor.m_PadBottom,
757 pooling2dDescriptor.m_PoolWidth,
758 pooling2dDescriptor.m_PoolHeight,
759 pooling2dDescriptor.m_StrideX,
760 pooling2dDescriptor.m_StrideY,
761 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
762 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
763 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
764
765 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
766 fbPooling2dBaseLayer,
767 fbPooling2dDescriptor);
768
769 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
770}
771
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100772void SerializerVisitor::VisitPreluLayer(const armnn::IConnectableLayer* layer,
773 const char* name)
774{
Ellen Norris-Thompson51982472019-06-19 11:46:21 +0100775 // Create FlatBuffer BaseLayer
776 auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
777
778 // Create the FlatBuffer AdditionLayer
779 auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
780
781 // Add the AnyLayer to the FlatBufferLayers
782 CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
Matteo Martincigh0e406ee2019-06-12 15:42:18 +0100783}
784
Derek Lamberti87acb272019-03-27 16:51:31 +0000785void SerializerVisitor::VisitQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
786{
787 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
788 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
789 fbQuantizeBaseLayer);
790 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
791}
792
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000793// Build FlatBuffer for FullyConnected Layer
794void SerializerVisitor::VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
795 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
796 const armnn::ConstTensor& weights,
797 const armnn::Optional<armnn::ConstTensor>& biases,
798 const char* name)
799{
800 // Create FlatBuffer BaseLayer
801 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
802
803 // Create FlatBuffer FullyConnectedDescriptor
804 auto flatBufferDescriptor =
805 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
806 fullyConnectedDescriptor.m_BiasEnabled,
807 fullyConnectedDescriptor.m_TransposeWeightMatrix);
808
809 // Create FlatBuffer weights data
810 auto flatBufferWeights = CreateConstTensorInfo(weights);
811
812 // Create FlatBuffer bias data
813 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
814 if (fullyConnectedDescriptor.m_BiasEnabled)
815 {
816 flatBufferBiases = CreateConstTensorInfo(biases.value());
817 }
818
819 // Create FlatBuffer FullyConnectedLayer
820 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
821 flatBufferBaseLayer,
822 flatBufferDescriptor,
823 flatBufferWeights,
824 flatBufferBiases);
825
826 // Add created FullyConnectedLayer to the FlatBufferLayers
827 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
828}
829
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000830// Build FlatBuffer for SpaceToBatchNd Layer
831void SerializerVisitor::VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
832 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
833 const char* name)
834{
835 // Create FlatBuffer BaseLayer
836 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
837
838 std::vector<unsigned int> padList;
839 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
840 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
841 {
842 padList.push_back(pad.first);
843 padList.push_back(pad.second);
844 }
845
846 auto flatBufferDescriptor =
847 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
848 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
849 m_flatBufferBuilder.CreateVector(padList),
850 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
851
852 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
853 flatBufferBaseLayer,
854 flatBufferDescriptor);
855
856 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
857}
858
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100859// Build FlatBuffer for SpaceToDepthLayer
860void SerializerVisitor::VisitSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
861 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
862 const char* name)
863{
Aron Virginas-Taraa067142019-06-11 16:01:44 +0100864 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
865 auto flatBufferDescriptor =
866 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
867 spaceToDepthDescriptor.m_BlockSize,
868 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
869
870 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
871 flatBufferBaseLayer,
872 flatBufferDescriptor);
873
874 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +0100875}
876
Jim Flynn18ce3382019-03-08 11:08:30 +0000877// Build FlatBuffer for Splitter Layer
878void SerializerVisitor::VisitSplitterLayer(const armnn::IConnectableLayer* layer,
879 const armnn::ViewsDescriptor& viewsDescriptor,
880 const char* name)
881{
882 // Create FlatBuffer ViewOrigins
883 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
884 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
885
886 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
887 {
888 std::vector<uint32_t> viewOrigin;
889 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
890
891 // Copy vector
892 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
893 {
894 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
895 }
896
897 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
898 m_flatBufferBuilder.CreateVector(viewOrigin)));
899 }
900
901 // Create FlatBuffer OriginsDescriptor
902 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
903 viewsDescriptor.GetOrigins().GetConcatAxis(),
904 viewsDescriptor.GetOrigins().GetNumViews(),
905 viewsDescriptor.GetOrigins().GetNumDimensions(),
906 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
907
908 // Create FlatBuffer ViewOrigins
909 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
910 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
911
912 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
913 {
914 std::vector<uint32_t> viewSize;
915 viewSize.reserve(viewsDescriptor.GetNumDimensions());
916
917 // Copy vector
918 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
919 {
920 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
921 }
922
923 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
924 m_flatBufferBuilder.CreateVector(viewSize)));
925 }
926
927 // Create FlatBuffer ViewsDescriptor
928 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
929 flatBufferOriginDescriptor,
930 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
931
932 // Create FlatBuffer BaseLayer
933 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
934
935 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
936 flatBufferBaseLayer,
937 flatBufferViewsDescriptor);
938
939 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
940}
941
Nina Drozd57728782019-02-27 10:53:27 +0000942void SerializerVisitor::VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
943 const armnn::NormalizationDescriptor& descriptor,
944 const char* name)
945{
946 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
947
948 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
949 m_flatBufferBuilder,
950 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
951 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
952 descriptor.m_NormSize,
953 descriptor.m_Alpha,
954 descriptor.m_Beta,
955 descriptor.m_K,
956 GetFlatBufferDataLayout(descriptor.m_DataLayout));
957
958 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
959 fbNormalizationBaseLayer,
960 fbNormalizationDescriptor);
961
962 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
963}
964
Matthew Jackson2b8c1da2019-07-04 14:59:16 +0100965void SerializerVisitor::VisitStackLayer(const armnn::IConnectableLayer* layer,
966 const armnn::StackDescriptor& stackDescriptor,
967 const char* name)
968{
Matthew Jacksonb5433ee2019-07-11 15:54:20 +0100969 auto stackBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Stack);
970
971 std::vector<unsigned int> inputShape;
972 for (unsigned int i =0; i < stackDescriptor.m_InputShape.GetNumDimensions(); i++)
973 {
974 inputShape.push_back(stackDescriptor.m_InputShape[i]);
975 }
976
977 auto flatBufferStackDescriptor = CreateStackDescriptor(m_flatBufferBuilder,
978 stackDescriptor.m_Axis,
979 stackDescriptor.m_NumInputs,
980 m_flatBufferBuilder.CreateVector(inputShape));
981
982 auto stackLayer = serializer::CreateStackLayer(m_flatBufferBuilder, stackBaseLayer, flatBufferStackDescriptor);
983 CreateAnyLayer(stackLayer.o, serializer::Layer::Layer_StackLayer);
Matthew Jackson2b8c1da2019-07-04 14:59:16 +0100984}
985
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +0000986void SerializerVisitor::VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
987 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
988 const char* name)
989{
990 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
991
992 auto flatBufferDescriptor =
993 CreateStridedSliceDescriptor(m_flatBufferBuilder,
994 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
995 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
996 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
997 stridedSliceDescriptor.m_BeginMask,
998 stridedSliceDescriptor.m_EndMask,
999 stridedSliceDescriptor.m_ShrinkAxisMask,
1000 stridedSliceDescriptor.m_EllipsisMask,
1001 stridedSliceDescriptor.m_NewAxisMask,
1002 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
1003
1004 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
1005 flatBufferBaseLayer,
1006 flatBufferDescriptor);
1007
1008 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
1009}
1010
Conor Kennedyda1f9752019-03-01 14:37:12 +00001011void SerializerVisitor::VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
1012{
1013 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
1014 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
1015
1016 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
1017}
1018
Sadik Armaganeff363d2019-04-05 15:25:46 +01001019void SerializerVisitor::VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
1020{
1021 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
1022 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
1023
1024 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
1025}
1026
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001027void SerializerVisitor::VisitTransposeConvolution2dLayer(
1028 const armnn::IConnectableLayer* layer,
1029 const armnn::TransposeConvolution2dDescriptor& descriptor,
1030 const armnn::ConstTensor& weights,
1031 const armnn::Optional<armnn::ConstTensor>& biases,
1032 const char* name)
1033{
Aron Virginas-Tarcb549302019-06-21 13:53:38 +01001034 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
1035 auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
1036 descriptor.m_PadLeft,
1037 descriptor.m_PadRight,
1038 descriptor.m_PadTop,
1039 descriptor.m_PadBottom,
1040 descriptor.m_StrideX,
1041 descriptor.m_StrideY,
1042 descriptor.m_BiasEnabled,
1043 GetFlatBufferDataLayout(descriptor.m_DataLayout));
1044
1045 // weights & biases
1046 auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
1047 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
1048 if (biases.has_value())
1049 {
1050 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
1051 }
1052
1053 auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
1054 fbBaseLayer,
1055 fbDescriptor,
1056 fbWeightsConstTensorInfo,
1057 fbBiasesConstTensorInfo);
1058
1059 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001060}
1061
James Conroyee18dc82019-07-17 11:27:46 +01001062void SerializerVisitor::VisitQuantizedLstmLayer(const armnn::IConnectableLayer* layer,
1063 const armnn::QuantizedLstmInputParams& params,
1064 const char* name)
1065{
Jan Eilers5b01a892019-07-23 09:47:43 +01001066 auto fbQuantizedLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_QuantizedLstm);
1067
1068 // Get input parameters
Francis Murtaghbb590b42019-08-14 09:51:36 +01001069 auto inputToInputWeights = CreateConstTensorInfo(params.GetInputToInputWeights());
1070 auto inputToForgetWeights = CreateConstTensorInfo(params.GetInputToForgetWeights());
1071 auto inputToCellWeights = CreateConstTensorInfo(params.GetInputToCellWeights());
1072 auto inputToOutputWeights = CreateConstTensorInfo(params.GetInputToOutputWeights());
Jan Eilers5b01a892019-07-23 09:47:43 +01001073
Francis Murtaghbb590b42019-08-14 09:51:36 +01001074 auto recurrentToInputWeights = CreateConstTensorInfo(params.GetRecurrentToInputWeights());
1075 auto recurrentToForgetWeights = CreateConstTensorInfo(params.GetRecurrentToForgetWeights());
1076 auto recurrentToCellWeights = CreateConstTensorInfo(params.GetRecurrentToCellWeights());
1077 auto recurrentToOutputWeights = CreateConstTensorInfo(params.GetRecurrentToOutputWeights());
Jan Eilers5b01a892019-07-23 09:47:43 +01001078
Francis Murtaghbb590b42019-08-14 09:51:36 +01001079 auto inputGateBias = CreateConstTensorInfo(params.GetInputGateBias());
1080 auto forgetGateBias = CreateConstTensorInfo(params.GetForgetGateBias());
1081 auto cellBias = CreateConstTensorInfo(params.GetCellBias());
1082 auto outputGateBias = CreateConstTensorInfo(params.GetOutputGateBias());
Jan Eilers5b01a892019-07-23 09:47:43 +01001083
1084 auto fbQuantizedLstmParams = serializer::CreateQuantizedLstmInputParams(
1085 m_flatBufferBuilder,
1086 inputToInputWeights,
1087 inputToForgetWeights,
1088 inputToCellWeights,
1089 inputToOutputWeights,
1090 recurrentToInputWeights,
1091 recurrentToForgetWeights,
1092 recurrentToCellWeights,
1093 recurrentToOutputWeights,
1094 inputGateBias,
1095 forgetGateBias,
1096 cellBias,
1097 outputGateBias);
1098
1099 auto fbQuantizedLstmLayer = serializer::CreateQuantizedLstmLayer(
1100 m_flatBufferBuilder,
1101 fbQuantizedLstmBaseLayer,
1102 fbQuantizedLstmParams);
1103
1104 CreateAnyLayer(fbQuantizedLstmLayer.o, serializer::Layer::Layer_QuantizedLstmLayer);
James Conroyee18dc82019-07-17 11:27:46 +01001105}
1106
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001107fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001108 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001109{
Sadik Armagandb059fd2019-03-20 12:28:32 +00001110 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
1111
Mike Kelly8c1701a2019-02-11 17:01:27 +00001112 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
1113 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
1114
1115 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +00001116 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +00001117 m_flatBufferBuilder.CreateString(layer->GetName()),
1118 layerType,
1119 m_flatBufferBuilder.CreateVector(inputSlots),
1120 m_flatBufferBuilder.CreateVector(outputSlots));
1121}
1122
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001123void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001124{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001125 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +00001126 m_serializedLayers.push_back(anyLayer);
1127}
1128
Mike Kellya0766c32019-02-19 17:22:07 +00001129template <typename T>
1130flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
1131{
1132 const T* buffer = reinterpret_cast<const T*>(memory);
1133 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
1134 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
1135 return fbVector;
1136}
1137
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001138flatbuffers::Offset<serializer::ConstTensor>
1139 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +00001140{
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001141 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +00001142
1143 // Get the dimensions
1144 std::vector<unsigned int> shape;
1145
1146 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1147 {
1148 shape.push_back(tensorInfo.GetShape()[dim]);
1149 }
1150
1151 // Create FlatBuffer TensorInfo
1152 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1153 m_flatBufferBuilder.CreateVector(shape),
1154 GetFlatBufferDataType(tensorInfo.GetDataType()),
1155 tensorInfo.GetQuantizationScale(),
1156 tensorInfo.GetQuantizationOffset());
1157 flatbuffers::Offset<void> fbPayload;
1158
1159 switch (tensorInfo.GetDataType())
1160 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001161 case armnn::DataType::Float32:
1162 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +00001163 {
1164 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1165 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1166 m_flatBufferBuilder,
1167 fbVector);
1168 fbPayload = flatBuffersData.o;
1169 break;
1170 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001171 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +00001172 {
1173 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1174 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1175 m_flatBufferBuilder,
1176 fbVector);
1177 fbPayload = flatBuffersData.o;
1178 break;
1179 }
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001180 case armnn::DataType::QuantisedSymm16:
1181 {
1182 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1183 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1184 m_flatBufferBuilder,
1185 fbVector);
1186 fbPayload = flatBuffersData.o;
1187 break;
1188 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001189 case armnn::DataType::QuantisedAsymm8:
1190 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001191 default:
1192 {
1193 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1194 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1195 m_flatBufferBuilder,
1196 fbVector);
1197 fbPayload = flatBuffersData.o;
1198 }
1199 }
1200 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1201 m_flatBufferBuilder,
1202 flatBufferTensorInfo,
1203 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1204 fbPayload);
1205 return flatBufferConstTensor;
1206}
1207
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001208std::vector<fb::Offset<serializer::InputSlot>>
1209 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001210{
Mike Kellya0766c32019-02-19 17:22:07 +00001211 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001212
1213 // Get the InputSlots
1214 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1215 {
1216 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1217
1218 // Get the Connection for the InputSlot
1219 const IOutputSlot* connection = inputSlot.GetConnection();
1220
1221 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001222 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1223 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001224 // Create FlatBuffer InputSlot
1225 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1226 }
1227 return inputSlots;
1228}
1229
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001230std::vector<fb::Offset<serializer::OutputSlot>>
1231 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001232{
1233 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1234
1235 // Get the OutputSlots
1236 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1237 {
1238 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001239 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001240
1241 // Get the dimensions
1242 std::vector<unsigned int> shape;
1243 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1244 {
1245 shape.push_back(tensorInfo.GetShape()[dim]);
1246 }
1247
1248 // Create FlatBuffer TensorInfo
1249 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1250 m_flatBufferBuilder.CreateVector(shape),
1251 GetFlatBufferDataType(tensorInfo.GetDataType()),
1252 tensorInfo.GetQuantizationScale(),
1253 tensorInfo.GetQuantizationOffset());
1254
1255 // Create FlatBuffer Outputslot
1256 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1257 slotIndex,
1258 flatBufferTensorInfo));
1259 }
1260 return outputSlots;
1261}
1262
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001263
1264ISerializer* ISerializer::CreateRaw()
1265{
1266 return new Serializer();
1267}
1268
1269ISerializerPtr ISerializer::Create()
1270{
1271 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
1272}
1273
1274void ISerializer::Destroy(ISerializer* serializer)
1275{
1276 delete serializer;
1277}
1278
1279void Serializer::Serialize(const INetwork& inNetwork)
1280{
1281 // Iterate through to network
1282 inNetwork.Accept(m_SerializerVisitor);
1283 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1284
1285 // Create FlatBuffer SerializedGraph
1286 auto serializedGraph = serializer::CreateSerializedGraph(
1287 fbBuilder,
1288 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
1289 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
1290 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
1291
1292 // Serialize the graph
1293 fbBuilder.Finish(serializedGraph);
1294}
1295
1296bool Serializer::SaveSerializedToStream(std::ostream& stream)
1297{
1298 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
1299
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00001300 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
1301 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001302 return !stream.bad();
1303}
1304
Matteo Martincighec333912019-02-13 15:12:39 +00001305} // namespace armnnSerializer