blob: a9f7b7d307a4e5f8f2d6451e5d8f4afbdc6cdda0 [file] [log] [blame]
Mike Kelly8c1701a2019-02-11 17:01:27 +00001//
Teresa Charlin52664732020-06-29 16:27:03 +01002// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
Mike Kelly8c1701a2019-02-11 17:01:27 +00003// SPDX-License-Identifier: MIT
4//
Mike Kelly8c1701a2019-02-11 17:01:27 +00005#include "Serializer.hpp"
Finn Williamsb454c5c2021-02-09 15:56:23 +00006#include "SerializerUtils.hpp"
Saoirse Stewart3166c3e2019-02-18 15:24:53 +00007
Matthew Benthamff130e22020-01-17 11:47:42 +00008#include <armnn/Descriptors.hpp>
9#include <armnn/LstmParams.hpp>
10#include <armnn/QuantizedLstmParams.hpp>
Jan Eilers8eb25602020-03-09 12:13:48 +000011#include <armnn/utility/IgnoreUnused.hpp>
Matthew Sloyan0663d662020-09-14 11:47:26 +010012#include <armnn/utility/NumericCast.hpp>
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000013
Finn Williamsb454c5c2021-02-09 15:56:23 +000014#include <fmt/format.h>
Mike Kelly8c1701a2019-02-11 17:01:27 +000015#include <iostream>
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000016
Mike Kelly8c1701a2019-02-11 17:01:27 +000017using namespace armnn;
18namespace fb = flatbuffers;
Derek Lamberti0028d1b2019-02-20 13:57:42 +000019namespace serializer = armnnSerializer;
Mike Kelly8c1701a2019-02-11 17:01:27 +000020
21namespace armnnSerializer
22{
23
Finn Williams85d36712021-01-26 22:30:06 +000024ISerializer::ISerializer() : pSerializerImpl(new SerializerImpl())
25{
26}
27
28ISerializer::~ISerializer() = default;
29
30ISerializer* ISerializer::CreateRaw()
31{
32 return new ISerializer();
33}
34
35ISerializerPtr ISerializer::Create()
36{
37 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
38}
39
40void ISerializer::Destroy(ISerializer* serializer)
41{
42 delete serializer;
43}
44
45void ISerializer::Serialize(const armnn::INetwork& inNetwork)
46{
47 pSerializerImpl->Serialize(inNetwork);
48}
49
50bool ISerializer::SaveSerializedToStream(std::ostream& stream)
51{
52 return pSerializerImpl->SaveSerializedToStream(stream);
53}
54
Mike Kellyaf484012019-02-20 16:53:11 +000055serializer::ActivationFunction GetFlatBufferActivationFunction(armnn::ActivationFunction function)
56{
57 switch (function)
58 {
59 case armnn::ActivationFunction::Sigmoid:
60 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
61 case armnn::ActivationFunction::TanH:
62 return serializer::ActivationFunction::ActivationFunction_TanH;
63 case armnn::ActivationFunction::Linear:
64 return serializer::ActivationFunction::ActivationFunction_Linear;
65 case armnn::ActivationFunction::ReLu:
66 return serializer::ActivationFunction::ActivationFunction_ReLu;
67 case armnn::ActivationFunction::BoundedReLu:
68 return serializer::ActivationFunction::ActivationFunction_BoundedReLu;
69 case armnn::ActivationFunction::LeakyReLu:
70 return serializer::ActivationFunction::ActivationFunction_LeakyReLu;
71 case armnn::ActivationFunction::Abs:
72 return serializer::ActivationFunction::ActivationFunction_Abs;
73 case armnn::ActivationFunction::Sqrt:
74 return serializer::ActivationFunction::ActivationFunction_Sqrt;
75 case armnn::ActivationFunction::Square:
76 return serializer::ActivationFunction::ActivationFunction_Square;
David Monahan3b3c3812020-02-25 09:03:29 +000077 case armnn::ActivationFunction::Elu:
78 return serializer::ActivationFunction::ActivationFunction_Elu;
Colm Donelan03fbeaf2020-02-26 15:39:23 +000079 case armnn::ActivationFunction::HardSwish:
80 return serializer::ActivationFunction::ActivationFunction_HardSwish;
Mike Kellyaf484012019-02-20 16:53:11 +000081 default:
82 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
83 }
84}
85
Narumol Prangnawarat0cfcf232019-09-09 17:16:24 +010086serializer::ArgMinMaxFunction GetFlatBufferArgMinMaxFunction(armnn::ArgMinMaxFunction function)
87{
88 switch (function)
89 {
90 case armnn::ArgMinMaxFunction::Max:
91 return serializer::ArgMinMaxFunction::ArgMinMaxFunction_Max;
92 case armnn::ArgMinMaxFunction::Min:
93 default:
94 return serializer::ArgMinMaxFunction::ArgMinMaxFunction_Min;
95 }
96}
97
Finn Williamsb454c5c2021-02-09 15:56:23 +000098uint32_t SerializerStrategy::GetSerializedId(armnn::LayerGuid guid)
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000099{
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000100 if (m_guidMap.empty())
101 {
janeil013fec1ea2019-11-07 09:47:20 +0000102 m_guidMap.insert(std::make_pair(guid, m_layerId));
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000103 }
104 else if (m_guidMap.find(guid) == m_guidMap.end())
105 {
janeil013fec1ea2019-11-07 09:47:20 +0000106 ++m_layerId;
107 m_guidMap.insert(std::make_pair(guid, m_layerId));
108
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000109 return m_layerId;
110 }
Saoirse Stewart30211042019-02-18 17:19:16 +0000111 return m_guidMap[guid];
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000112}
113
Mike Kelly8c1701a2019-02-11 17:01:27 +0000114// Build FlatBuffer for Input Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +0000115void SerializerStrategy::SerializeInputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000116{
Jan Eilers8eb25602020-03-09 12:13:48 +0000117 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000118
Mike Kelly8c1701a2019-02-11 17:01:27 +0000119 // Create FlatBuffer BaseLayer
120 auto flatBufferInputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Input);
121
122 // Create FlatBuffer BindableBaseLayer
123 auto flatBufferInputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
124 flatBufferInputBaseLayer,
125 id);
Tee Jungaa920c52019-11-05 10:48:25 +0000126 // Push layer binding id to outputIds.
127 m_inputIds.push_back(id);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000128
129 // Create the FlatBuffer InputLayer
130 auto flatBufferInputLayer = serializer::CreateInputLayer(m_flatBufferBuilder, flatBufferInputBindableBaseLayer);
131
132 // Add the AnyLayer to the FlatBufferLayers
133 CreateAnyLayer(flatBufferInputLayer.o, serializer::Layer::Layer_InputLayer);
134}
135
136// Build FlatBuffer for Output Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +0000137void SerializerStrategy::SerializeOutputLayer(const armnn::IConnectableLayer* layer,
138 LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000139{
Jan Eilers8eb25602020-03-09 12:13:48 +0000140 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000141
Mike Kelly8c1701a2019-02-11 17:01:27 +0000142 // Create FlatBuffer BaseLayer
143 auto flatBufferOutputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Output);
144
145 // Create FlatBuffer BindableBaseLayer
146 auto flatBufferOutputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
147 flatBufferOutputBaseLayer,
148 id);
Tee Jungaa920c52019-11-05 10:48:25 +0000149 // Push layer binding id to outputIds.
150 m_outputIds.push_back(id);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000151
152 // Create the FlatBuffer OutputLayer
153 auto flatBufferOutputLayer = serializer::CreateOutputLayer(m_flatBufferBuilder, flatBufferOutputBindableBaseLayer);
154 // Add the AnyLayer to the FlatBufferLayers
155 CreateAnyLayer(flatBufferOutputLayer.o, serializer::Layer::Layer_OutputLayer);
156}
157
Mike Kellyaf484012019-02-20 16:53:11 +0000158// Build FlatBuffer for Activation Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +0000159void SerializerStrategy::SerializeActivationLayer(const armnn::IConnectableLayer* layer,
160 const armnn::ActivationDescriptor& descriptor,
161 const char* name)
Mike Kellyaf484012019-02-20 16:53:11 +0000162{
Jan Eilers8eb25602020-03-09 12:13:48 +0000163 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000164
Mike Kellyaf484012019-02-20 16:53:11 +0000165 // Create FlatBuffer BaseLayer
166 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Activation);
167
168 // Create the FlatBuffer ActivationDescriptor
169 auto flatBufferDescriptor = CreateActivationDescriptor(m_flatBufferBuilder,
170 GetFlatBufferActivationFunction(descriptor.m_Function),
171 descriptor.m_A,
172 descriptor.m_B);
173
174 // Create the FlatBuffer ActivationLayer
175 auto flatBufferAdditionLayer = CreateActivationLayer(m_flatBufferBuilder,
176 flatBufferBaseLayer,
177 flatBufferDescriptor);
178
179 // Add the AnyLayer to the FlatBufferLayers
180 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_ActivationLayer);
181}
182
Mike Kelly8c1701a2019-02-11 17:01:27 +0000183// Build FlatBuffer for Addition Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +0000184void SerializerStrategy::SerializeAdditionLayer(const armnn::IConnectableLayer* layer, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000185{
Jan Eilers8eb25602020-03-09 12:13:48 +0000186 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000187
Mike Kelly8c1701a2019-02-11 17:01:27 +0000188 // Create FlatBuffer BaseLayer
189 auto flatBufferAdditionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Addition);
190
191 // Create the FlatBuffer AdditionLayer
192 auto flatBufferAdditionLayer = serializer::CreateAdditionLayer(m_flatBufferBuilder, flatBufferAdditionBaseLayer);
193
194 // Add the AnyLayer to the FlatBufferLayers
195 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_AdditionLayer);
196}
197
Nikhil Rajee391d52019-09-05 17:50:44 +0100198// Build FlatBuffer for ArgMinMax Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +0000199void SerializerStrategy::SerializeArgMinMaxLayer(const armnn::IConnectableLayer *layer,
200 const armnn::ArgMinMaxDescriptor& descriptor,
201 const char *name)
Nikhil Rajee391d52019-09-05 17:50:44 +0100202{
Jan Eilers8eb25602020-03-09 12:13:48 +0000203 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000204
Narumol Prangnawarat0cfcf232019-09-09 17:16:24 +0100205 // Create FlatBuffer BaseLayer
206 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ArgMinMax);
207
208 // Create FlatBuffer Descriptor
209 auto flatBufferDescriptor = CreateArgMinMaxDescriptor(m_flatBufferBuilder,
210 GetFlatBufferArgMinMaxFunction(descriptor.m_Function),
211 descriptor.m_Axis);
212
213 // Create FlatBuffer ArgMinMaxLayer
214 auto flatBufferLayer = CreateArgMinMaxLayer(m_flatBufferBuilder,
215 flatBufferBaseLayer,
216 flatBufferDescriptor);
217
218 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ArgMinMaxLayer);
Nikhil Rajee391d52019-09-05 17:50:44 +0100219}
220
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000221// Build FlatBuffer for BatchToSpaceNd Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +0000222void SerializerStrategy::SerializeBatchToSpaceNdLayer(const armnn::IConnectableLayer* layer,
223 const armnn::BatchToSpaceNdDescriptor& descriptor,
224 const char* name)
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000225{
Jan Eilers8eb25602020-03-09 12:13:48 +0000226 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000227
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000228 // Create FlatBuffer BaseLayer
229 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchToSpaceNd);
230
231 std::vector<unsigned int> crops;
232 crops.reserve(descriptor.m_Crops.size() * 2);
233 for (auto& crop : descriptor.m_Crops)
234 {
235 crops.push_back(crop.first);
236 crops.push_back(crop.second);
237 }
238
239 auto flatBufferDescriptor =
240 CreateBatchToSpaceNdDescriptor(m_flatBufferBuilder,
241 m_flatBufferBuilder.CreateVector(descriptor.m_BlockShape),
242 m_flatBufferBuilder.CreateVector(crops),
243 GetFlatBufferDataLayout(descriptor.m_DataLayout));
244
245 auto flatBufferLayer = serializer::CreateBatchToSpaceNdLayer(m_flatBufferBuilder,
246 flatBufferBaseLayer,
247 flatBufferDescriptor);
248
249 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_BatchToSpaceNdLayer);
250}
251
Finn Williamsb454c5c2021-02-09 15:56:23 +0000252void SerializerStrategy::SerializeBatchNormalizationLayer(
253 const armnn::IConnectableLayer* layer,
254 const armnn::BatchNormalizationDescriptor& batchNormDescriptor,
255 const std::vector<armnn::ConstTensor>& constants,
256 const char* name)
ruoyan018e7fa232019-02-28 15:09:07 +0000257{
Jan Eilers8eb25602020-03-09 12:13:48 +0000258 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000259
Finn Williamsb454c5c2021-02-09 15:56:23 +0000260 const armnn::ConstTensor& mean = constants[0];
261 const armnn::ConstTensor& variance = constants[1];
262 const armnn::ConstTensor& beta = constants[2];
263 const armnn::ConstTensor& gamma = constants[3];
264
ruoyan018e7fa232019-02-28 15:09:07 +0000265 auto fbBatchNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchNormalization);
266 auto fbBatchNormalizationDescriptor = serializer::CreateBatchNormalizationDescriptor(
267 m_flatBufferBuilder,
268 batchNormDescriptor.m_Eps,
269 GetFlatBufferDataLayout(batchNormDescriptor.m_DataLayout));
270
271 auto fbMeanConstTensorInfo = CreateConstTensorInfo(mean);
272 auto fbVarianceConstTensorInfo = CreateConstTensorInfo(variance);
273 auto fbBetaConstTensorInfo = CreateConstTensorInfo(beta);
274 auto fbGammaConstTensorInfo = CreateConstTensorInfo(gamma);
275 auto fbBatchNormalizationLayer = serializer::CreateBatchNormalizationLayer(m_flatBufferBuilder,
276 fbBatchNormalizationBaseLayer,
277 fbBatchNormalizationDescriptor,
278 fbMeanConstTensorInfo,
279 fbVarianceConstTensorInfo,
280 fbBetaConstTensorInfo,
281 fbGammaConstTensorInfo);
282
283 CreateAnyLayer(fbBatchNormalizationLayer.o, serializer::Layer::Layer_BatchNormalizationLayer);
284}
285
mathad01b392e982021-04-07 12:07:30 +0100286void SerializerStrategy::SerializeCastLayer(const armnn::IConnectableLayer* layer,
287 const char* name)
288{
289 IgnoreUnused(name);
290
291 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Cast);
292 auto fbCastLayer = serializer::CreateCastLayer(m_flatBufferBuilder, fbBaseLayer);
293 CreateAnyLayer(fbCastLayer.o, serializer::Layer::Layer_CastLayer);
294}
295
Simon Obute51f67772021-09-03 15:50:13 +0100296void SerializerStrategy::SerializeChannelShuffleLayer(const armnn::IConnectableLayer* layer,
297 const armnn::ChannelShuffleDescriptor& descriptor,
298 const char* name)
299{
300 IgnoreUnused(name);
301 auto fbDescriptor = CreateChannelShuffleDescriptor(m_flatBufferBuilder,
302 descriptor.m_Axis,
303 descriptor.m_NumGroups);
304 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ChannelShuffle);
305 auto fbChannelShuffleLayer = serializer::CreateChannelShuffleLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
306 CreateAnyLayer(fbChannelShuffleLayer.o, serializer::Layer::Layer_ChannelShuffleLayer);
307}
308
Finn Williamsb454c5c2021-02-09 15:56:23 +0000309void SerializerStrategy::SerializeComparisonLayer(const armnn::IConnectableLayer* layer,
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100310 const armnn::ComparisonDescriptor& descriptor,
311 const char* name)
312{
Jan Eilers8eb25602020-03-09 12:13:48 +0000313 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000314
Aron Virginas-Tare80ebd12019-10-17 16:11:54 +0100315 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Comparison);
316 auto fbDescriptor = serializer::CreateComparisonDescriptor(
317 m_flatBufferBuilder,
318 GetFlatBufferComparisonOperation(descriptor.m_Operation));
319
320 auto fbLayer = serializer::CreateComparisonLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
321 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_ComparisonLayer);
Aron Virginas-Tar77bfb5e2019-10-16 17:45:38 +0100322}
323
Conor Kennedy76277882019-02-26 08:29:54 +0000324// Build FlatBuffer for Constant Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +0000325void SerializerStrategy::SerializeConstantLayer(const armnn::IConnectableLayer* layer,
326 const std::vector<armnn::ConstTensor>& constants,
327 const char* name)
Conor Kennedy76277882019-02-26 08:29:54 +0000328{
Jan Eilers8eb25602020-03-09 12:13:48 +0000329 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000330
Finn Williamsb454c5c2021-02-09 15:56:23 +0000331 armnn::ConstTensor input = constants[0];
332
Conor Kennedy76277882019-02-26 08:29:54 +0000333 // Create FlatBuffer BaseLayer
334 auto flatBufferConstantBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Constant);
335
336 auto flatBufferConstTensorInfo = CreateConstTensorInfo(input);
337
338 // Create the FlatBuffer ConstantLayer
339 auto flatBufferLayer = CreateConstantLayer(m_flatBufferBuilder,
340 flatBufferConstantBaseLayer,
341 flatBufferConstTensorInfo);
342
343 // Add the AnyLayer to the FlatBufferLayers
344 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConstantLayer);
345}
346
Mike Kellya0766c32019-02-19 17:22:07 +0000347// Build FlatBuffer for Convolution2dLayer
Finn Williamsb454c5c2021-02-09 15:56:23 +0000348void SerializerStrategy::SerializeConvolution2dLayer(const armnn::IConnectableLayer* layer,
349 const armnn::Convolution2dDescriptor& descriptor,
350 const std::vector<armnn::ConstTensor>& constants,
351 const char* name)
Mike Kellya0766c32019-02-19 17:22:07 +0000352{
Jan Eilers8eb25602020-03-09 12:13:48 +0000353 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000354
Finn Williamsb454c5c2021-02-09 15:56:23 +0000355 const armnn::ConstTensor weights = constants[0];
356
Mike Kellya0766c32019-02-19 17:22:07 +0000357 // Create FlatBuffer BaseLayer
358 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
359
360 auto flatBufferDescriptor = CreateConvolution2dDescriptor(m_flatBufferBuilder,
361 descriptor.m_PadLeft,
362 descriptor.m_PadRight,
363 descriptor.m_PadTop,
364 descriptor.m_PadBottom,
365 descriptor.m_StrideX,
366 descriptor.m_StrideY,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100367 descriptor.m_DilationX,
368 descriptor.m_DilationY,
Mike Kellya0766c32019-02-19 17:22:07 +0000369 descriptor.m_BiasEnabled,
370 GetFlatBufferDataLayout(descriptor.m_DataLayout));
371 auto flatBufferWeightsConstTensorInfo = CreateConstTensorInfo(weights);
372 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiasesConstTensorInfo;
373
Finn Williamsb454c5c2021-02-09 15:56:23 +0000374 if (constants.size() > 1)
Mike Kellya0766c32019-02-19 17:22:07 +0000375 {
Finn Williamsb454c5c2021-02-09 15:56:23 +0000376 const armnn::ConstTensor biases = constants[1];
377 flatBufferBiasesConstTensorInfo = CreateConstTensorInfo(biases);
Mike Kellya0766c32019-02-19 17:22:07 +0000378 }
379
380 // Create the FlatBuffer Convolution2dLayer
381 auto flatBufferLayer = CreateConvolution2dLayer(m_flatBufferBuilder,
382 flatBufferBaseLayer,
383 flatBufferDescriptor,
384 flatBufferWeightsConstTensorInfo,
385 flatBufferBiasesConstTensorInfo);
386
387 // Add the AnyLayer to the FlatBufferLayers
388 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution2dLayer);
389}
390
Matthew Sloyan5d7b0a32021-10-18 13:07:49 +0100391// Build FlatBuffer for Convolution3dLayer
Matthew Sloyanb63a3112021-09-08 13:05:51 +0100392void SerializerStrategy::SerializeConvolution3dLayer(const armnn::IConnectableLayer* layer,
393 const armnn::Convolution3dDescriptor& descriptor,
Matthew Sloyanb63a3112021-09-08 13:05:51 +0100394 const char* name)
395{
396 IgnoreUnused(name);
397
Matthew Sloyanb63a3112021-09-08 13:05:51 +0100398 // Create FlatBuffer BaseLayer
Matthew Sloyan5d7b0a32021-10-18 13:07:49 +0100399 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution3d);
Matthew Sloyanb63a3112021-09-08 13:05:51 +0100400
401 auto flatBufferDescriptor = CreateConvolution3dDescriptor(m_flatBufferBuilder,
402 descriptor.m_PadLeft,
403 descriptor.m_PadRight,
404 descriptor.m_PadTop,
405 descriptor.m_PadBottom,
406 descriptor.m_PadFront,
407 descriptor.m_PadBack,
408 descriptor.m_StrideX,
409 descriptor.m_StrideY,
410 descriptor.m_StrideZ,
411 descriptor.m_DilationX,
412 descriptor.m_DilationY,
413 descriptor.m_DilationZ,
414 descriptor.m_BiasEnabled,
415 GetFlatBufferDataLayout(descriptor.m_DataLayout));
Matthew Sloyanb63a3112021-09-08 13:05:51 +0100416
Matthew Sloyan5d7b0a32021-10-18 13:07:49 +0100417 // Create the FlatBuffer Convolution3dLayer
Matthew Sloyanb63a3112021-09-08 13:05:51 +0100418 auto flatBufferLayer = CreateConvolution3dLayer(m_flatBufferBuilder,
419 flatBufferBaseLayer,
Matthew Sloyan5d7b0a32021-10-18 13:07:49 +0100420 flatBufferDescriptor);
Matthew Sloyanb63a3112021-09-08 13:05:51 +0100421
422 // Add the AnyLayer to the FlatBufferLayers
423 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution3dLayer);
424}
425
Finn Williamsb454c5c2021-02-09 15:56:23 +0000426void SerializerStrategy::SerializeDepthToSpaceLayer(const armnn::IConnectableLayer* layer,
Aron Virginas-Tardd6247f2019-09-19 14:31:17 +0100427 const armnn::DepthToSpaceDescriptor& descriptor,
428 const char* name)
429{
Jan Eilers8eb25602020-03-09 12:13:48 +0000430 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000431
Aron Virginas-Tarda9d2d32019-09-20 10:42:02 +0100432 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthToSpace);
433 auto fbDescriptor = CreateDepthToSpaceDescriptor(m_flatBufferBuilder,
434 descriptor.m_BlockSize,
435 GetFlatBufferDataLayout(descriptor.m_DataLayout));
436
437 auto fbLayer = serializer::CreateDepthToSpaceLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
438
439 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_DepthToSpaceLayer);
Aron Virginas-Tardd6247f2019-09-19 14:31:17 +0100440}
441
Finn Williamsb454c5c2021-02-09 15:56:23 +0000442void SerializerStrategy::SerializeDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
443 const armnn::DepthwiseConvolution2dDescriptor& descriptor,
444 const std::vector<armnn::ConstTensor>& constants,
445 const char* name)
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000446{
Jan Eilers8eb25602020-03-09 12:13:48 +0000447 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000448
Finn Williamsb454c5c2021-02-09 15:56:23 +0000449 const armnn::ConstTensor& weights = constants[0];
450
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000451 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthwiseConvolution2d);
452 auto fbDescriptor = CreateDepthwiseConvolution2dDescriptor(m_flatBufferBuilder,
453 descriptor.m_PadLeft,
454 descriptor.m_PadRight,
455 descriptor.m_PadTop,
456 descriptor.m_PadBottom,
457 descriptor.m_StrideX,
458 descriptor.m_StrideY,
Matthew Benthamacad04e2019-05-13 10:02:45 +0100459 descriptor.m_DilationX,
460 descriptor.m_DilationY,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000461 descriptor.m_BiasEnabled,
462 GetFlatBufferDataLayout(descriptor.m_DataLayout));
463
464 flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
465 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
Finn Williamsb454c5c2021-02-09 15:56:23 +0000466
467 if (constants.size() > 1)
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000468 {
Finn Williamsb454c5c2021-02-09 15:56:23 +0000469 const armnn::ConstTensor& biases = constants[1];
470 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases);
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000471 }
472
473 auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
474 fbBaseLayer,
475 fbDescriptor,
476 fbWeightsConstTensorInfo,
477 fbBiasesConstTensorInfo);
478
479 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
480}
481
Finn Williamsb454c5c2021-02-09 15:56:23 +0000482void SerializerStrategy::SerializeDequantizeLayer(const armnn::IConnectableLayer* layer,
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000483 const char* name)
484{
Jan Eilers8eb25602020-03-09 12:13:48 +0000485 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000486
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000487 auto fbDequantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Dequantize);
488 auto fbDequantizeLayer = serializer::CreateDequantizeLayer(m_flatBufferBuilder, fbDequantizeBaseLayer);
489
490 CreateAnyLayer(fbDequantizeLayer.o, serializer::Layer::Layer_DequantizeLayer);
491}
492
Finn Williamsb454c5c2021-02-09 15:56:23 +0000493void SerializerStrategy::SerializeDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
494 const armnn::DetectionPostProcessDescriptor& descriptor,
495 const std::vector<armnn::ConstTensor>& constants,
496 const char* name)
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000497{
Jan Eilers8eb25602020-03-09 12:13:48 +0000498 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000499
Finn Williamsb454c5c2021-02-09 15:56:23 +0000500 const armnn::ConstTensor& anchors = constants[0];
501
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000502 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
503 auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
504 descriptor.m_MaxDetections,
505 descriptor.m_MaxClassesPerDetection,
506 descriptor.m_DetectionsPerClass,
507 descriptor.m_NmsScoreThreshold,
508 descriptor.m_NmsIouThreshold,
509 descriptor.m_NumClasses,
510 descriptor.m_UseRegularNms,
511 descriptor.m_ScaleX,
512 descriptor.m_ScaleY,
513 descriptor.m_ScaleW,
514 descriptor.m_ScaleH);
515
516 flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);
517
518 auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
519 fbBaseLayer,
520 fbDescriptor,
521 fbAnchorsConstTensorInfo);
522
523 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
524}
525
Finn Williamsb454c5c2021-02-09 15:56:23 +0000526void SerializerStrategy::SerializeDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000527{
Jan Eilers8eb25602020-03-09 12:13:48 +0000528 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000529
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000530 auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
531 auto fbDivisionLayer = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000532
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000533 CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
534}
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000535
Finn Williamsb454c5c2021-02-09 15:56:23 +0000536void SerializerStrategy::SerializeElementwiseUnaryLayer(const armnn::IConnectableLayer* layer,
josh minor4a3c6102020-01-06 16:40:46 -0600537 const armnn::ElementwiseUnaryDescriptor& descriptor,
538 const char* name)
539{
Jan Eilers8eb25602020-03-09 12:13:48 +0000540 IgnoreUnused(name);
josh minor4a3c6102020-01-06 16:40:46 -0600541
542 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ElementwiseUnary);
543 auto fbDescriptor = serializer::CreateElementwiseUnaryDescriptor(
544 m_flatBufferBuilder,
545 GetFlatBufferUnaryOperation(descriptor.m_Operation));
546
547 auto fbLayer = serializer::CreateElementwiseUnaryLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
548 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_ElementwiseUnaryLayer);
549}
550
Finn Williamsb454c5c2021-02-09 15:56:23 +0000551void SerializerStrategy::SerializeFillLayer(const armnn::IConnectableLayer* layer,
Ryan OSheaec6c6802020-06-05 17:17:06 +0100552 const armnn::FillDescriptor& fillDescriptor,
553 const char* name)
554{
Ryan OSheaec6c6802020-06-05 17:17:06 +0100555 IgnoreUnused(name);
Keith Davis300ad562020-06-04 16:34:23 +0100556
557 auto fbFillBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Fill);
558
559 auto fbDescriptor = serializer::CreateFillDescriptor(m_flatBufferBuilder, fillDescriptor.m_Value);
560
561 auto fbFillLayer = serializer::CreateFillLayer(m_flatBufferBuilder, fbFillBaseLayer, fbDescriptor);
562
563 CreateAnyLayer(fbFillLayer.o, serializer::Layer::Layer_FillLayer);
Ryan OSheaec6c6802020-06-05 17:17:06 +0100564}
565
Finn Williamsb454c5c2021-02-09 15:56:23 +0000566void SerializerStrategy::SerializeFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000567{
Jan Eilers8eb25602020-03-09 12:13:48 +0000568 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000569
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000570 auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
571 auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);
572
573 CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
574}
575
Finn Williamsb454c5c2021-02-09 15:56:23 +0000576void SerializerStrategy::SerializeGatherLayer(const armnn::IConnectableLayer* layer,
Teresa Charlin52664732020-06-29 16:27:03 +0100577 const armnn::GatherDescriptor& gatherDescriptor,
578 const char* name)
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000579{
Jan Eilers8eb25602020-03-09 12:13:48 +0000580 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000581
Teresa Charlin52664732020-06-29 16:27:03 +0100582 auto fbGatherDescriptor = CreateGatherDescriptor(m_flatBufferBuilder,
583 gatherDescriptor.m_Axis);
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000584 auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
Teresa Charlin52664732020-06-29 16:27:03 +0100585 auto flatBufferLayer = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer, fbGatherDescriptor);
Saoirse Stewarta1ed73a2019-03-04 13:40:12 +0000586
587 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
588}
589
Finn Williamsb454c5c2021-02-09 15:56:23 +0000590void SerializerStrategy::SerializeInstanceNormalizationLayer(
Kevin Mayce5045a2019-10-02 14:07:47 +0100591 const armnn::IConnectableLayer* layer,
592 const armnn::InstanceNormalizationDescriptor& instanceNormalizationDescriptor,
593 const char* name)
594{
Jan Eilers8eb25602020-03-09 12:13:48 +0000595 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000596
Aron Virginas-Tar781ced92019-10-03 11:15:39 +0100597 auto fbDescriptor = serializer::CreateInstanceNormalizationDescriptor(
598 m_flatBufferBuilder,
599 instanceNormalizationDescriptor.m_Gamma,
600 instanceNormalizationDescriptor.m_Beta,
601 instanceNormalizationDescriptor.m_Eps,
602 GetFlatBufferDataLayout(instanceNormalizationDescriptor.m_DataLayout));
603
604 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_InstanceNormalization);
605 auto fbLayer = serializer::CreateInstanceNormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
606
607 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_InstanceNormalizationLayer);
Kevin Mayce5045a2019-10-02 14:07:47 +0100608}
609
Finn Williamsb454c5c2021-02-09 15:56:23 +0000610void SerializerStrategy::SerializeL2NormalizationLayer(const armnn::IConnectableLayer* layer,
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000611 const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
612 const char* name)
613{
Jan Eilers8eb25602020-03-09 12:13:48 +0000614 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000615
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000616 // Create FlatBuffer BaseLayer
617 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);
618
619 // Create the FlatBuffer L2Normalization Descriptor
620 auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100621 m_flatBufferBuilder,
622 GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout),
623 l2NormalizationDescriptor.m_Eps);
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000624
Ferran Balaguer0dcffec2019-06-18 16:25:06 +0100625 // Create FlatBuffer layer
Narumol Prangnawarat495701f2019-03-07 17:31:34 +0000626 auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
627
628 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
629}
630
Finn Williamsb454c5c2021-02-09 15:56:23 +0000631void SerializerStrategy::SerializeLogicalBinaryLayer(const armnn::IConnectableLayer* layer,
James Conroyaba90cd2020-11-06 16:28:18 +0000632 const armnn::LogicalBinaryDescriptor& descriptor,
633 const char* name)
634{
635 IgnoreUnused(name);
636
637 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_LogicalBinary);
638 auto fbDescriptor = serializer::CreateLogicalBinaryDescriptor(
639 m_flatBufferBuilder,
640 GetFlatBufferLogicalBinaryOperation(descriptor.m_Operation));
641
642 auto fbLayer = serializer::CreateLogicalBinaryLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
643 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_LogicalBinaryLayer);
644}
645
Finn Williamsb454c5c2021-02-09 15:56:23 +0000646void SerializerStrategy::SerializeLogSoftmaxLayer(const armnn::IConnectableLayer* layer,
Aron Virginas-Tarf982dea2019-10-11 14:07:53 +0100647 const armnn::LogSoftmaxDescriptor& logSoftmaxDescriptor,
648 const char* name)
649{
Jan Eilers8eb25602020-03-09 12:13:48 +0000650 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000651
Sadik Armagan26257852019-10-14 13:00:47 +0100652 // Create FlatBuffer BaseLayer
653 auto flatBufferLogSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_LogSoftmax);
654
655 // Create the FlatBuffer LogSoftmaxDescriptor
656 auto flatBufferLogSoftmaxDesc =
657 serializer::CreateLogSoftmaxDescriptor(m_flatBufferBuilder,
658 logSoftmaxDescriptor.m_Beta,
659 logSoftmaxDescriptor.m_Axis);
660
661 // Create the FlatBuffer LogSoftmaxLayer
662 auto flatBufferLogSoftmaxLayer =
663 serializer::CreateLogSoftmaxLayer(m_flatBufferBuilder,
664 flatBufferLogSoftmaxBaseLayer,
665 flatBufferLogSoftmaxDesc);
666
667 CreateAnyLayer(flatBufferLogSoftmaxLayer.o, serializer::Layer::Layer_LogSoftmaxLayer);
Aron Virginas-Tarf982dea2019-10-11 14:07:53 +0100668}
669
Finn Williamsb454c5c2021-02-09 15:56:23 +0000670void SerializerStrategy::SerializeLstmLayer(const armnn::IConnectableLayer* layer,
671 const armnn::LstmDescriptor& descriptor,
672 const std::vector<armnn::ConstTensor>& constants,
673 const char* name)
Jim Flynn11af3752019-03-19 17:22:29 +0000674{
Jan Eilers8eb25602020-03-09 12:13:48 +0000675 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000676
Jim Flynn11af3752019-03-19 17:22:29 +0000677 auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);
678
679 auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
680 m_flatBufferBuilder,
681 descriptor.m_ActivationFunc,
682 descriptor.m_ClippingThresCell,
683 descriptor.m_ClippingThresProj,
684 descriptor.m_CifgEnabled,
685 descriptor.m_PeepholeEnabled,
Jan Eilersf8c62972019-07-17 11:07:49 +0100686 descriptor.m_ProjectionEnabled,
687 descriptor.m_LayerNormEnabled);
Jim Flynn11af3752019-03-19 17:22:29 +0000688
Finn Williamsb454c5c2021-02-09 15:56:23 +0000689 // Index for constants vector
690 std::size_t i = 0;
691
692 // Get mandatory/basic input parameters
693 auto inputToForgetWeights = CreateConstTensorInfo(constants[i++]); //InputToForgetWeights
694 auto inputToCellWeights = CreateConstTensorInfo(constants[i++]); //InputToCellWeights
695 auto inputToOutputWeights = CreateConstTensorInfo(constants[i++]); //InputToOutputWeights
696 auto recurrentToForgetWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToForgetWeights
697 auto recurrentToCellWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToCellWeights
698 auto recurrentToOutputWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToOutputWeights
699 auto forgetGateBias = CreateConstTensorInfo(constants[i++]); //ForgetGateBias
700 auto cellBias = CreateConstTensorInfo(constants[i++]); //CellBias
701 auto outputGateBias = CreateConstTensorInfo(constants[i++]); //OutputGateBias
702
703
Jim Flynn11af3752019-03-19 17:22:29 +0000704
705 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
706 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
707 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
708 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
709 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
710 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
711 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
712 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
713 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
Jan Eilersf8c62972019-07-17 11:07:49 +0100714 flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
715 flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
716 flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
717 flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;
Jim Flynn11af3752019-03-19 17:22:29 +0000718
719 if (!descriptor.m_CifgEnabled)
720 {
Finn Williamsb454c5c2021-02-09 15:56:23 +0000721 inputToInputWeights = CreateConstTensorInfo(constants[i++]); //InputToInputWeights
722 recurrentToInputWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToInputWeights
723 inputGateBias = CreateConstTensorInfo(constants[i++]); //InputGateBias
Jim Flynn11af3752019-03-19 17:22:29 +0000724 }
725
726 if (descriptor.m_PeepholeEnabled)
727 {
Finn Williamsb454c5c2021-02-09 15:56:23 +0000728 if (!descriptor.m_CifgEnabled)
729 {
730 cellToInputWeights = CreateConstTensorInfo(constants[i++]); //CellToInputWeights
731 }
732 cellToForgetWeights = CreateConstTensorInfo(constants[i++]); //CellToForgetWeights
733 cellToOutputWeights = CreateConstTensorInfo(constants[i++]); //CellToOutputWeights
734 }
735
736 if (descriptor.m_ProjectionEnabled)
737 {
738 projectionWeights = CreateConstTensorInfo(constants[i++]); //ProjectionWeights
739 projectionBias = CreateConstTensorInfo(constants[i++]); //ProjectionBias
Jim Flynn11af3752019-03-19 17:22:29 +0000740 }
741
Jan Eilersf8c62972019-07-17 11:07:49 +0100742 if (descriptor.m_LayerNormEnabled)
743 {
744 if (!descriptor.m_CifgEnabled)
745 {
Finn Williamsb454c5c2021-02-09 15:56:23 +0000746 inputLayerNormWeights = CreateConstTensorInfo(constants[i++]); //InputLayerNormWeights
Jan Eilersf8c62972019-07-17 11:07:49 +0100747 }
Finn Williamsb454c5c2021-02-09 15:56:23 +0000748 forgetLayerNormWeights = CreateConstTensorInfo(constants[i++]); //ForgetLayerNormWeights
749 cellLayerNormWeights = CreateConstTensorInfo(constants[i++]); //CellLayerNormWeights
750 outputLayerNormWeights = CreateConstTensorInfo(constants[i++]); //OutputLayerNormWeights
Jan Eilersf8c62972019-07-17 11:07:49 +0100751 }
752
Jim Flynn11af3752019-03-19 17:22:29 +0000753 auto fbLstmParams = serializer::CreateLstmInputParams(
754 m_flatBufferBuilder,
755 inputToForgetWeights,
756 inputToCellWeights,
757 inputToOutputWeights,
758 recurrentToForgetWeights,
759 recurrentToCellWeights,
760 recurrentToOutputWeights,
761 forgetGateBias,
762 cellBias,
763 outputGateBias,
764 inputToInputWeights,
765 recurrentToInputWeights,
766 cellToInputWeights,
767 inputGateBias,
768 projectionWeights,
769 projectionBias,
770 cellToForgetWeights,
Jan Eilersf8c62972019-07-17 11:07:49 +0100771 cellToOutputWeights,
772 inputLayerNormWeights,
773 forgetLayerNormWeights,
774 cellLayerNormWeights,
775 outputLayerNormWeights);
Jim Flynn11af3752019-03-19 17:22:29 +0000776
777 auto fbLstmLayer = serializer::CreateLstmLayer(
778 m_flatBufferBuilder,
779 fbLstmBaseLayer,
780 fbLstmDescriptor,
781 fbLstmParams);
782
783 CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
784}
785
Finn Williamsb454c5c2021-02-09 15:56:23 +0000786void SerializerStrategy::SerializeMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000787{
Jan Eilers8eb25602020-03-09 12:13:48 +0000788 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000789
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000790 auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
791 auto fbMaximumLayer = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);
792
793 CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
794}
795
Finn Williamsb454c5c2021-02-09 15:56:23 +0000796void SerializerStrategy::SerializeMeanLayer(const armnn::IConnectableLayer* layer,
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000797 const armnn::MeanDescriptor& descriptor,
798 const char* name)
799{
Jan Eilers8eb25602020-03-09 12:13:48 +0000800 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000801
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000802 auto fbMeanBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
803 auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
804 m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
805 descriptor.m_KeepDims);
806
807 auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
808 fbMeanBaseLayer,
809 fbMeanDescriptor);
810
811 CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
812}
813
Finn Williamsb454c5c2021-02-09 15:56:23 +0000814void SerializerStrategy::SerializeMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000815{
Jan Eilers8eb25602020-03-09 12:13:48 +0000816 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000817
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000818 auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
819 auto fbMinimumLayer = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);
820
821 CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
822}
823
Finn Williamsb454c5c2021-02-09 15:56:23 +0000824void SerializerStrategy::SerializeMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100825{
Jan Eilers8eb25602020-03-09 12:13:48 +0000826 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000827
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +0100828 auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
829 auto fbMergeLayer = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);
830
831 CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
832}
833
Finn Williamsb454c5c2021-02-09 15:56:23 +0000834void SerializerStrategy::SerializeConcatLayer(const armnn::IConnectableLayer* layer,
Jim Flynne242f2d2019-05-22 14:24:13 +0100835 const armnn::ConcatDescriptor& concatDescriptor,
836 const char* name)
837{
Jan Eilers8eb25602020-03-09 12:13:48 +0000838 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000839
Jim Flynne242f2d2019-05-22 14:24:13 +0100840 auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000841
842 std::vector<flatbuffers::Offset<UintVector>> views;
Jim Flynne242f2d2019-05-22 14:24:13 +0100843 for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000844 {
Jim Flynne242f2d2019-05-22 14:24:13 +0100845 const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000846 std::vector<uint32_t> origins;
Jim Flynne242f2d2019-05-22 14:24:13 +0100847 for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
Jim Flynnac25a1b2019-02-28 10:40:49 +0000848 {
849 origins.push_back(origin[d]);
850 }
851 auto view = m_flatBufferBuilder.CreateVector(origins);
852 auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
853 views.push_back(uintVector);
854 }
855
Jim Flynne242f2d2019-05-22 14:24:13 +0100856 auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
857 concatDescriptor.GetConcatAxis(),
858 concatDescriptor.GetNumViews(),
859 concatDescriptor.GetNumDimensions(),
Jim Flynnac25a1b2019-02-28 10:40:49 +0000860 m_flatBufferBuilder.CreateVector(views));
861
Jim Flynne242f2d2019-05-22 14:24:13 +0100862 auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
863 flatBufferConcatBaseLayer,
864 flatBufferConcatDescriptor);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000865
Jim Flynne242f2d2019-05-22 14:24:13 +0100866 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
Jim Flynnac25a1b2019-02-28 10:40:49 +0000867}
868
Finn Williamsb454c5c2021-02-09 15:56:23 +0000869void SerializerStrategy::SerializeMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000870{
Jan Eilers8eb25602020-03-09 12:13:48 +0000871 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000872
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000873 auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
874 auto fbMultiplicationLayer = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
875 fbMultiplicationBaseLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000876
Sadik Armaganac97c8c2019-03-04 17:44:21 +0000877 CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
Sadik Armagan5f450272019-02-12 14:31:45 +0000878}
879
Finn Williamsb454c5c2021-02-09 15:56:23 +0000880void SerializerStrategy::SerializePadLayer(const armnn::IConnectableLayer* layer,
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000881 const armnn::PadDescriptor& padDescriptor,
882 const char* name)
883{
Jan Eilers8eb25602020-03-09 12:13:48 +0000884 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000885
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000886 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);
887
888 std::vector<unsigned int> padList;
889 for (auto& p: padDescriptor.m_PadList)
890 {
891 padList.push_back(p.first);
892 padList.push_back(p.second);
893 }
894
895 auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
David Monahan34757812019-06-19 11:47:21 +0100896 m_flatBufferBuilder.CreateVector(padList),
Matthew Sloyan2e5d0b22021-10-21 14:05:31 +0100897 padDescriptor.m_PadValue,
898 GetFlatBufferPaddingMode(padDescriptor.m_PaddingMode));
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +0000899
900 auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
901 flatBufferBaseLayer,
902 flatBufferPadDesc);
903
904 CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
905}
906
Finn Williamsb454c5c2021-02-09 15:56:23 +0000907void SerializerStrategy::SerializePermuteLayer(const armnn::IConnectableLayer* layer,
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000908 const armnn::PermuteDescriptor& permuteDescriptor,
909 const char* name)
910{
Jan Eilers8eb25602020-03-09 12:13:48 +0000911 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000912
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000913 // Create FlatBuffer BaseLayer
914 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
915
916 std::vector<unsigned int> dimMappings;
Matthew Jacksondba634f2019-08-15 15:14:18 +0100917 for (unsigned int i=0; i<permuteDescriptor.m_DimMappings.GetSize(); ++i)
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000918 {
Matthew Jacksondba634f2019-08-15 15:14:18 +0100919 dimMappings.push_back(permuteDescriptor.m_DimMappings[i]);
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000920 }
921
922 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
923 m_flatBufferBuilder.CreateVector(dimMappings));
924
925 // Create the FlatBuffer PermuteLayer
926 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
927 flatBufferPermuteBaseLayer,
928 flatBufferPermuteDesc);
929
930 // Add the AnyLayer to the FlatBufferLayers
931 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
932}
933
Finn Williams2605b232020-06-10 15:53:46 +0100934// Build FlatBuffer for Rank Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +0000935void SerializerStrategy::SerializeRankLayer(const armnn::IConnectableLayer* layer,
Finn Williams2605b232020-06-10 15:53:46 +0100936 const char* name)
937{
938 IgnoreUnused(name);
939 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rank);
940 auto flatBufferRankLayer = serializer::CreateRankLayer(m_flatBufferBuilder, flatBufferBaseLayer);
941
942 CreateAnyLayer(flatBufferRankLayer.o, serializer::Layer::Layer_RankLayer);
943}
Sadik Armagan0c3ea5b2021-02-03 09:29:30 +0000944
Finn Williamsb454c5c2021-02-09 15:56:23 +0000945void SerializerStrategy::SerializeReduceLayer(const armnn::IConnectableLayer* layer,
946 const armnn::ReduceDescriptor& reduceDescriptor,
947 const char*)
Sadik Armagan0c3ea5b2021-02-03 09:29:30 +0000948{
949 auto fbReduceBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reduce);
950 auto fbDescriptor = CreateReduceDescriptor(m_flatBufferBuilder,
Sadik Armagan0c3ea5b2021-02-03 09:29:30 +0000951 reduceDescriptor.m_KeepDims,
952 m_flatBufferBuilder.CreateVector(reduceDescriptor.m_vAxis),
953 GetFlatBufferReduceOperation(reduceDescriptor.m_ReduceOperation));
954 auto fbReduceLayer = serializer::CreateReduceLayer(m_flatBufferBuilder,
955 fbReduceBaseLayer,
956 fbDescriptor);
957
958 CreateAnyLayer(fbReduceLayer.o, serializer::Layer::Layer_ReduceLayer);
959}
960
Saoirse Stewart263829c2019-02-19 15:54:14 +0000961// Build FlatBuffer for Reshape Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +0000962void SerializerStrategy::SerializeReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000963 const armnn::ReshapeDescriptor& reshapeDescriptor,
964 const char* name)
965{
Jan Eilers8eb25602020-03-09 12:13:48 +0000966 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000967
Saoirse Stewart263829c2019-02-19 15:54:14 +0000968 // Create FlatBuffer BaseLayer
969 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
970
971 std::vector<unsigned int> targetShape;
972 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
973 {
974 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
975 }
976
977 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
978 m_flatBufferBuilder.CreateVector(targetShape));
979
980 // Create the FlatBuffer ReshapeLayer
981 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
982 flatBufferReshapeDesc);
983
984 // Add the AnyLayer to the FlatBufferLayers
985 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
986}
987
Finn Williamsb454c5c2021-02-09 15:56:23 +0000988void SerializerStrategy::SerializeResizeLayer(const armnn::IConnectableLayer* layer,
Teresa Charlina9075df2019-06-27 15:41:57 +0100989 const armnn::ResizeDescriptor& resizeDescriptor,
990 const char* name)
991{
Jan Eilers8eb25602020-03-09 12:13:48 +0000992 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +0000993
FinnWilliamsArm6fb339a2019-06-28 15:07:10 +0100994 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Resize);
995
996 auto flatBufferDescriptor =
997 CreateResizeDescriptor(m_flatBufferBuilder,
998 resizeDescriptor.m_TargetHeight,
999 resizeDescriptor.m_TargetWidth,
1000 GetFlatBufferResizeMethod(resizeDescriptor.m_Method),
David Monahan4a0c9b92020-05-30 09:48:39 +01001001 GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout),
1002 resizeDescriptor.m_AlignCorners,
1003 resizeDescriptor.m_HalfPixelCenters);
FinnWilliamsArm6fb339a2019-06-28 15:07:10 +01001004
1005 auto flatBufferLayer = serializer::CreateResizeLayer(m_flatBufferBuilder,
1006 flatBufferBaseLayer,
1007 flatBufferDescriptor);
1008
1009 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeLayer);
Teresa Charlina9075df2019-06-27 15:41:57 +01001010}
1011
Finn Williamsb454c5c2021-02-09 15:56:23 +00001012void SerializerStrategy::SerializeSliceLayer(const armnn::IConnectableLayer* layer,
Aron Virginas-Tar636ab402019-09-16 14:27:45 +01001013 const armnn::SliceDescriptor& sliceDescriptor,
1014 const char* name)
1015{
Jan Eilers8eb25602020-03-09 12:13:48 +00001016 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001017
Aron Virginas-Tar2fda80b2019-09-18 13:36:52 +01001018 auto fbSliceBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Slice);
1019 auto fbSliceDescriptor = CreateSliceDescriptor(m_flatBufferBuilder,
1020 m_flatBufferBuilder.CreateVector(sliceDescriptor.m_Begin),
1021 m_flatBufferBuilder.CreateVector(sliceDescriptor.m_Size));
1022
1023 auto fbSliceLayer = serializer::CreateSliceLayer(m_flatBufferBuilder, fbSliceBaseLayer, fbSliceDescriptor);
1024
1025 CreateAnyLayer(fbSliceLayer.o, serializer::Layer::Layer_SliceLayer);
Aron Virginas-Tar636ab402019-09-16 14:27:45 +01001026}
1027
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +00001028// Build FlatBuffer for Softmax Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +00001029void SerializerStrategy::SerializeSoftmaxLayer(const armnn::IConnectableLayer* layer,
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001030 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +00001031 const char* name)
1032{
Jan Eilers8eb25602020-03-09 12:13:48 +00001033 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001034
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +00001035 // Create FlatBuffer BaseLayer
1036 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
1037
1038 // Create the FlatBuffer SoftmaxDescriptor
1039 auto flatBufferSoftmaxDesc =
Sadik Armaganfd0cae32021-11-08 17:18:31 +00001040 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder,
1041 softmaxDescriptor.m_Beta,
1042 softmaxDescriptor.m_Axis);
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +00001043
1044 // Create the FlatBuffer SoftmaxLayer
1045 auto flatBufferSoftmaxLayer =
1046 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
1047 flatBufferSoftmaxBaseLayer,
1048 flatBufferSoftmaxDesc);
1049
1050 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
1051}
1052
Finn Williamsb454c5c2021-02-09 15:56:23 +00001053void SerializerStrategy::SerializePooling2dLayer(const armnn::IConnectableLayer* layer,
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001054 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +00001055 const char* name)
1056{
Jan Eilers8eb25602020-03-09 12:13:48 +00001057 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001058
Saoirse Stewart3166c3e2019-02-18 15:24:53 +00001059 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
1060 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
1061 m_flatBufferBuilder,
1062 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
1063 pooling2dDescriptor.m_PadLeft,
1064 pooling2dDescriptor.m_PadRight,
1065 pooling2dDescriptor.m_PadTop,
1066 pooling2dDescriptor.m_PadBottom,
1067 pooling2dDescriptor.m_PoolWidth,
1068 pooling2dDescriptor.m_PoolHeight,
1069 pooling2dDescriptor.m_StrideX,
1070 pooling2dDescriptor.m_StrideY,
1071 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
1072 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
1073 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
1074
1075 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
1076 fbPooling2dBaseLayer,
1077 fbPooling2dDescriptor);
1078
1079 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
1080}
1081
Finn Williamsb454c5c2021-02-09 15:56:23 +00001082void SerializerStrategy::SerializePreluLayer(const armnn::IConnectableLayer* layer,
Matteo Martincigh0e406ee2019-06-12 15:42:18 +01001083 const char* name)
1084{
Jan Eilers8eb25602020-03-09 12:13:48 +00001085 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001086
Ellen Norris-Thompson51982472019-06-19 11:46:21 +01001087 // Create FlatBuffer BaseLayer
1088 auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);
1089
1090 // Create the FlatBuffer AdditionLayer
1091 auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);
1092
1093 // Add the AnyLayer to the FlatBufferLayers
1094 CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
Matteo Martincigh0e406ee2019-06-12 15:42:18 +01001095}
1096
Finn Williamsb454c5c2021-02-09 15:56:23 +00001097void SerializerStrategy::SerializeQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
Derek Lamberti87acb272019-03-27 16:51:31 +00001098{
Jan Eilers8eb25602020-03-09 12:13:48 +00001099 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001100
Derek Lamberti87acb272019-03-27 16:51:31 +00001101 auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
1102 auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
1103 fbQuantizeBaseLayer);
1104 CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
1105}
1106
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001107// Build FlatBuffer for FullyConnected Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +00001108void SerializerStrategy::SerializeFullyConnectedLayer(const armnn::IConnectableLayer* layer,
1109 const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
Sadik Armaganf0a6dec2021-03-25 07:46:55 +00001110 const char*)
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001111{
1112 // Create FlatBuffer BaseLayer
1113 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);
1114
1115 // Create FlatBuffer FullyConnectedDescriptor
1116 auto flatBufferDescriptor =
1117 serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
1118 fullyConnectedDescriptor.m_BiasEnabled,
Sadik Armaganf0a6dec2021-03-25 07:46:55 +00001119 fullyConnectedDescriptor.m_TransposeWeightMatrix,
1120 fullyConnectedDescriptor.m_ConstantWeights);
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001121
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001122 // Create FlatBuffer FullyConnectedLayer
1123 auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
1124 flatBufferBaseLayer,
Matthew Sloyan81beae32021-07-13 19:46:11 +01001125 flatBufferDescriptor);
Sadik Armagandbb0c0c2019-02-21 09:01:41 +00001126
1127 // Add created FullyConnectedLayer to the FlatBufferLayers
1128 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
1129}
1130
Nattapat Chaimanowong45286992019-02-26 15:53:02 +00001131// Build FlatBuffer for SpaceToBatchNd Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +00001132void SerializerStrategy::SerializeSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
Nattapat Chaimanowong45286992019-02-26 15:53:02 +00001133 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
1134 const char* name)
1135{
Jan Eilers8eb25602020-03-09 12:13:48 +00001136 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001137
Nattapat Chaimanowong45286992019-02-26 15:53:02 +00001138 // Create FlatBuffer BaseLayer
1139 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);
1140
1141 std::vector<unsigned int> padList;
1142 padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
1143 for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
1144 {
1145 padList.push_back(pad.first);
1146 padList.push_back(pad.second);
1147 }
1148
1149 auto flatBufferDescriptor =
1150 CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
1151 m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
1152 m_flatBufferBuilder.CreateVector(padList),
1153 GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));
1154
1155 auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
1156 flatBufferBaseLayer,
1157 flatBufferDescriptor);
1158
1159 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
1160}
1161
Aron Virginas-Tar972af152019-06-11 14:14:03 +01001162// Build FlatBuffer for SpaceToDepthLayer
Finn Williamsb454c5c2021-02-09 15:56:23 +00001163void SerializerStrategy::SerializeSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
Aron Virginas-Tar972af152019-06-11 14:14:03 +01001164 const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
1165 const char* name)
1166{
Jan Eilers8eb25602020-03-09 12:13:48 +00001167 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001168
Aron Virginas-Taraa067142019-06-11 16:01:44 +01001169 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
1170 auto flatBufferDescriptor =
1171 CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
1172 spaceToDepthDescriptor.m_BlockSize,
1173 GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));
1174
1175 auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
1176 flatBufferBaseLayer,
1177 flatBufferDescriptor);
1178
1179 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
Aron Virginas-Tar972af152019-06-11 14:14:03 +01001180}
1181
Jim Flynn18ce3382019-03-08 11:08:30 +00001182// Build FlatBuffer for Splitter Layer
Finn Williamsb454c5c2021-02-09 15:56:23 +00001183void SerializerStrategy::SerializeSplitterLayer(const armnn::IConnectableLayer* layer,
Jim Flynn18ce3382019-03-08 11:08:30 +00001184 const armnn::ViewsDescriptor& viewsDescriptor,
1185 const char* name)
1186{
Jan Eilers8eb25602020-03-09 12:13:48 +00001187 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001188
Jim Flynn18ce3382019-03-08 11:08:30 +00001189 // Create FlatBuffer ViewOrigins
1190 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
1191 flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());
1192
1193 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
1194 {
1195 std::vector<uint32_t> viewOrigin;
1196 viewOrigin.reserve(viewsDescriptor.GetNumDimensions());
1197
1198 // Copy vector
1199 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
1200 {
1201 viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
1202 }
1203
1204 flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
1205 m_flatBufferBuilder.CreateVector(viewOrigin)));
1206 }
1207
1208 // Create FlatBuffer OriginsDescriptor
1209 auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
1210 viewsDescriptor.GetOrigins().GetConcatAxis(),
1211 viewsDescriptor.GetOrigins().GetNumViews(),
1212 viewsDescriptor.GetOrigins().GetNumDimensions(),
1213 m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));
1214
1215 // Create FlatBuffer ViewOrigins
1216 std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
1217 flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());
1218
1219 for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
1220 {
1221 std::vector<uint32_t> viewSize;
1222 viewSize.reserve(viewsDescriptor.GetNumDimensions());
1223
1224 // Copy vector
1225 for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
1226 {
1227 viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
1228 }
1229
1230 flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
1231 m_flatBufferBuilder.CreateVector(viewSize)));
1232 }
1233
1234 // Create FlatBuffer ViewsDescriptor
1235 auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
1236 flatBufferOriginDescriptor,
1237 m_flatBufferBuilder.CreateVector(flatBufferViewSizes));
1238
1239 // Create FlatBuffer BaseLayer
1240 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);
1241
1242 auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
1243 flatBufferBaseLayer,
1244 flatBufferViewsDescriptor);
1245
1246 CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
1247}
1248
Finn Williamsb454c5c2021-02-09 15:56:23 +00001249void SerializerStrategy::SerializeNormalizationLayer(const armnn::IConnectableLayer* layer,
Nina Drozd57728782019-02-27 10:53:27 +00001250 const armnn::NormalizationDescriptor& descriptor,
1251 const char* name)
1252{
Jan Eilers8eb25602020-03-09 12:13:48 +00001253 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001254
Nina Drozd57728782019-02-27 10:53:27 +00001255 auto fbNormalizationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);
1256
1257 auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
1258 m_flatBufferBuilder,
1259 GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
1260 GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
1261 descriptor.m_NormSize,
1262 descriptor.m_Alpha,
1263 descriptor.m_Beta,
1264 descriptor.m_K,
1265 GetFlatBufferDataLayout(descriptor.m_DataLayout));
1266
1267 auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
1268 fbNormalizationBaseLayer,
1269 fbNormalizationDescriptor);
1270
1271 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
1272}
1273
Keith Davis3ae3f972021-05-21 16:33:48 +01001274void SerializerStrategy::SerializeShapeLayer(const armnn::IConnectableLayer* layer,
1275 const char* name)
1276{
1277 IgnoreUnused(name);
1278
1279 auto shapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Shape);
1280 auto shapeLayer = serializer::CreateShapeLayer(m_flatBufferBuilder, shapeBaseLayer);
1281
1282 CreateAnyLayer(shapeLayer.o, serializer::Layer::Layer_ShapeLayer);
1283}
1284
Finn Williamsb454c5c2021-02-09 15:56:23 +00001285void SerializerStrategy::SerializeStackLayer(const armnn::IConnectableLayer* layer,
Matthew Jackson2b8c1da2019-07-04 14:59:16 +01001286 const armnn::StackDescriptor& stackDescriptor,
1287 const char* name)
1288{
Jan Eilers8eb25602020-03-09 12:13:48 +00001289 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001290
Matthew Jacksonb5433ee2019-07-11 15:54:20 +01001291 auto stackBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Stack);
1292
1293 std::vector<unsigned int> inputShape;
1294 for (unsigned int i =0; i < stackDescriptor.m_InputShape.GetNumDimensions(); i++)
1295 {
1296 inputShape.push_back(stackDescriptor.m_InputShape[i]);
1297 }
1298
1299 auto flatBufferStackDescriptor = CreateStackDescriptor(m_flatBufferBuilder,
1300 stackDescriptor.m_Axis,
1301 stackDescriptor.m_NumInputs,
1302 m_flatBufferBuilder.CreateVector(inputShape));
1303
1304 auto stackLayer = serializer::CreateStackLayer(m_flatBufferBuilder, stackBaseLayer, flatBufferStackDescriptor);
1305 CreateAnyLayer(stackLayer.o, serializer::Layer::Layer_StackLayer);
Matthew Jackson2b8c1da2019-07-04 14:59:16 +01001306}
1307
Finn Williamsb454c5c2021-02-09 15:56:23 +00001308void SerializerStrategy::SerializeStandInLayer(const armnn::IConnectableLayer *layer,
Derek Lamberti013c3902019-10-21 10:46:16 +01001309 const armnn::StandInDescriptor& standInDescriptor,
1310 const char *name)
1311{
Jan Eilers8eb25602020-03-09 12:13:48 +00001312 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001313
Aron Virginas-Tar85121a22019-10-23 10:41:35 +01001314 auto fbDescriptor = serializer::CreateStandInDescriptor(m_flatBufferBuilder,
1315 standInDescriptor.m_NumInputs,
1316 standInDescriptor.m_NumOutputs);
1317
1318 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StandIn);
1319 auto fbLayer = serializer::CreateStandInLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
1320
1321 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_StandInLayer);
Derek Lamberti013c3902019-10-21 10:46:16 +01001322}
1323
Finn Williamsb454c5c2021-02-09 15:56:23 +00001324void SerializerStrategy::SerializeStridedSliceLayer(const armnn::IConnectableLayer* layer,
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +00001325 const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
1326 const char* name)
1327{
Jan Eilers8eb25602020-03-09 12:13:48 +00001328 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001329
Nattapat Chaimanowongb3485212019-03-04 12:35:39 +00001330 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);
1331
1332 auto flatBufferDescriptor =
1333 CreateStridedSliceDescriptor(m_flatBufferBuilder,
1334 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
1335 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
1336 m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
1337 stridedSliceDescriptor.m_BeginMask,
1338 stridedSliceDescriptor.m_EndMask,
1339 stridedSliceDescriptor.m_ShrinkAxisMask,
1340 stridedSliceDescriptor.m_EllipsisMask,
1341 stridedSliceDescriptor.m_NewAxisMask,
1342 GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));
1343
1344 auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
1345 flatBufferBaseLayer,
1346 flatBufferDescriptor);
1347
1348 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
1349}
1350
Finn Williamsb454c5c2021-02-09 15:56:23 +00001351void SerializerStrategy::SerializeSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
Conor Kennedyda1f9752019-03-01 14:37:12 +00001352{
Jan Eilers8eb25602020-03-09 12:13:48 +00001353 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001354
Conor Kennedyda1f9752019-03-01 14:37:12 +00001355 auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
1356 auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);
1357
1358 CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
1359}
1360
Finn Williamsb454c5c2021-02-09 15:56:23 +00001361void SerializerStrategy::SerializeSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armaganeff363d2019-04-05 15:25:46 +01001362{
Jan Eilers8eb25602020-03-09 12:13:48 +00001363 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001364
Sadik Armaganeff363d2019-04-05 15:25:46 +01001365 auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
1366 auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);
1367
1368 CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
1369}
1370
Finn Williamsb454c5c2021-02-09 15:56:23 +00001371void SerializerStrategy::SerializeTransposeConvolution2dLayer(
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001372 const armnn::IConnectableLayer* layer,
1373 const armnn::TransposeConvolution2dDescriptor& descriptor,
Finn Williamsb454c5c2021-02-09 15:56:23 +00001374 const std::vector<armnn::ConstTensor>& constants,
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001375 const char* name)
1376{
Jan Eilers8eb25602020-03-09 12:13:48 +00001377 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001378
Finn Williamsb454c5c2021-02-09 15:56:23 +00001379 const armnn::ConstTensor& weights = constants.at(0);
1380
Aron Virginas-Tarcb549302019-06-21 13:53:38 +01001381 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
1382 auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
1383 descriptor.m_PadLeft,
1384 descriptor.m_PadRight,
1385 descriptor.m_PadTop,
1386 descriptor.m_PadBottom,
1387 descriptor.m_StrideX,
1388 descriptor.m_StrideY,
1389 descriptor.m_BiasEnabled,
1390 GetFlatBufferDataLayout(descriptor.m_DataLayout));
1391
1392 // weights & biases
1393 auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
1394 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
Finn Williamsb454c5c2021-02-09 15:56:23 +00001395 if (constants.size() > 1)
Aron Virginas-Tarcb549302019-06-21 13:53:38 +01001396 {
Finn Williamsb454c5c2021-02-09 15:56:23 +00001397 const armnn::ConstTensor& biases = constants.at(1);
1398 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases);
Aron Virginas-Tarcb549302019-06-21 13:53:38 +01001399 }
1400
1401 auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
1402 fbBaseLayer,
1403 fbDescriptor,
1404 fbWeightsConstTensorInfo,
1405 fbBiasesConstTensorInfo);
1406
1407 CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
Aron Virginas-Tar639fb042019-06-20 14:28:19 +01001408}
1409
Finn Williamsb454c5c2021-02-09 15:56:23 +00001410void SerializerStrategy::SerializeTransposeLayer(const armnn::IConnectableLayer* layer,
Mike Kellyc9ea45a2020-02-28 18:11:58 +00001411 const armnn::TransposeDescriptor& descriptor,
1412 const char* name)
1413{
Jan Eilers8eb25602020-03-09 12:13:48 +00001414 IgnoreUnused(name);
Mike Kellyc9ea45a2020-02-28 18:11:58 +00001415
1416 // Create FlatBuffer BaseLayer
1417 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Transpose);
1418
1419 std::vector<unsigned int> dimMappings;
1420 for (unsigned int i=0; i<descriptor.m_DimMappings.GetSize(); ++i)
1421 {
1422 dimMappings.push_back(descriptor.m_DimMappings[i]);
1423 }
1424
1425 auto flatBufferDesc = serializer::CreateTransposeDescriptor(m_flatBufferBuilder,
1426 m_flatBufferBuilder.CreateVector(dimMappings));
1427
1428 // Create the FlatBuffer TransposeLayer
1429 auto flatBufferLayer = serializer::CreateTransposeLayer(m_flatBufferBuilder,
1430 flatBufferBaseLayer,
1431 flatBufferDesc);
1432
1433 // Add the AnyLayer to the FlatBufferLayers
1434 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_TransposeLayer);
1435}
1436
Finn Williamsb454c5c2021-02-09 15:56:23 +00001437void SerializerStrategy::SerializeQLstmLayer(const armnn::IConnectableLayer* layer,
1438 const armnn::QLstmDescriptor& descriptor,
1439 const std::vector<armnn::ConstTensor>& constants,
1440 const char* name)
James Conroy586a9aa2020-03-20 08:49:33 +00001441{
James Conroy8d333182020-05-13 10:27:58 +01001442 IgnoreUnused(name);
James Conroy586a9aa2020-03-20 08:49:33 +00001443
James Conroy8d333182020-05-13 10:27:58 +01001444 auto fbQLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_QLstm);
1445
1446 auto fbQLstmDescriptor = serializer::CreateQLstmDescriptor(
1447 m_flatBufferBuilder,
1448 descriptor.m_CifgEnabled,
1449 descriptor.m_PeepholeEnabled,
1450 descriptor.m_ProjectionEnabled,
1451 descriptor.m_LayerNormEnabled,
1452 descriptor.m_CellClip,
1453 descriptor.m_ProjectionClip,
1454 descriptor.m_InputIntermediateScale,
1455 descriptor.m_ForgetIntermediateScale,
1456 descriptor.m_CellIntermediateScale,
1457 descriptor.m_OutputIntermediateScale,
1458 descriptor.m_HiddenStateZeroPoint,
1459 descriptor.m_HiddenStateScale
1460 );
1461
Finn Williamsb454c5c2021-02-09 15:56:23 +00001462 // Index for constants vector
1463 std::size_t i = 0;
1464
James Conroy8d333182020-05-13 10:27:58 +01001465 // Mandatory params
Finn Williamsb454c5c2021-02-09 15:56:23 +00001466 auto inputToForgetWeights = CreateConstTensorInfo(constants[i++]); //InputToForgetWeights
1467 auto inputToCellWeights = CreateConstTensorInfo(constants[i++]); //InputToCellWeights
1468 auto inputToOutputWeights = CreateConstTensorInfo(constants[i++]); //InputToOutputWeights
1469 auto recurrentToForgetWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToForgetWeights
1470 auto recurrentToCellWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToCellWeights
1471 auto recurrentToOutputWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToOutputWeights
1472 auto forgetGateBias = CreateConstTensorInfo(constants[i++]); //ForgetGateBias
1473 auto cellBias = CreateConstTensorInfo(constants[i++]); //CellBias
1474 auto outputGateBias = CreateConstTensorInfo(constants[i++]); //OutputGateBias
James Conroy8d333182020-05-13 10:27:58 +01001475
1476 // CIFG
1477 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
1478 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
1479 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
1480
1481 if (!descriptor.m_CifgEnabled)
1482 {
Finn Williamsb454c5c2021-02-09 15:56:23 +00001483 inputToInputWeights = CreateConstTensorInfo(constants[i++]); //InputToInputWeights
1484 recurrentToInputWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToInputWeights
1485 inputGateBias = CreateConstTensorInfo(constants[i++]); //InputGateBias
James Conroy8d333182020-05-13 10:27:58 +01001486 }
1487
1488 // Peephole
1489 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
1490 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
1491 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
1492
1493 if (descriptor.m_PeepholeEnabled)
1494 {
1495 if (!descriptor.m_CifgEnabled)
1496 {
Finn Williamsb454c5c2021-02-09 15:56:23 +00001497 cellToInputWeights = CreateConstTensorInfo(constants[i++]); //CellToInputWeights
James Conroy8d333182020-05-13 10:27:58 +01001498 }
Finn Williamsb454c5c2021-02-09 15:56:23 +00001499 cellToForgetWeights = CreateConstTensorInfo(constants[i++]); //CellToForgetWeights
1500 cellToOutputWeights = CreateConstTensorInfo(constants[i++]); //CellToOutputWeights
1501 }
James Conroy8d333182020-05-13 10:27:58 +01001502
Finn Williamsb454c5c2021-02-09 15:56:23 +00001503 // Projection
1504 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
1505 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
1506
1507 if (descriptor.m_ProjectionEnabled)
1508 {
1509 projectionWeights = CreateConstTensorInfo(constants[i++]); //ProjectionWeights
1510 projectionBias = CreateConstTensorInfo(constants[i++]); //ProjectionBias
James Conroy8d333182020-05-13 10:27:58 +01001511 }
1512
1513 // Layer norm
1514 flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
1515 flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
1516 flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
1517 flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;
1518
1519 if (descriptor.m_LayerNormEnabled)
1520 {
1521 if (!descriptor.m_CifgEnabled)
1522 {
Finn Williamsb454c5c2021-02-09 15:56:23 +00001523 inputLayerNormWeights = CreateConstTensorInfo(constants[i++]); //InputLayerNormWeights
James Conroy8d333182020-05-13 10:27:58 +01001524 }
Finn Williamsb454c5c2021-02-09 15:56:23 +00001525 forgetLayerNormWeights = CreateConstTensorInfo(constants[i++]); //ForgetLayerNormWeights
1526 cellLayerNormWeights = CreateConstTensorInfo(constants[i++]); //CellLayerNormWeights
1527 outputLayerNormWeights = CreateConstTensorInfo(constants[i++]); //OutputLayerNormWeights
James Conroy8d333182020-05-13 10:27:58 +01001528 }
1529
1530 auto fbQLstmParams = serializer::CreateQLstmInputParams(
1531 m_flatBufferBuilder,
1532 inputToForgetWeights,
1533 inputToCellWeights,
1534 inputToOutputWeights,
1535 recurrentToForgetWeights,
1536 recurrentToCellWeights,
1537 recurrentToOutputWeights,
1538 forgetGateBias,
1539 cellBias,
1540 outputGateBias,
1541 inputToInputWeights,
1542 recurrentToInputWeights,
1543 inputGateBias,
1544 projectionWeights,
1545 projectionBias,
1546 cellToInputWeights,
1547 cellToForgetWeights,
1548 cellToOutputWeights,
1549 inputLayerNormWeights,
1550 forgetLayerNormWeights,
1551 cellLayerNormWeights,
1552 outputLayerNormWeights);
1553
1554 auto fbQLstmLayer = serializer::CreateQLstmLayer(
1555 m_flatBufferBuilder,
1556 fbQLstmBaseLayer,
1557 fbQLstmDescriptor,
1558 fbQLstmParams);
1559
1560 CreateAnyLayer(fbQLstmLayer.o, serializer::Layer::Layer_QLstmLayer);
James Conroy586a9aa2020-03-20 08:49:33 +00001561}
1562
Finn Williamsb454c5c2021-02-09 15:56:23 +00001563void SerializerStrategy::SerializeQuantizedLstmLayer(const armnn::IConnectableLayer* layer,
1564 const std::vector<armnn::ConstTensor>& constants,
1565 const char* name)
James Conroyee18dc82019-07-17 11:27:46 +01001566{
Jan Eilers8eb25602020-03-09 12:13:48 +00001567 IgnoreUnused(name);
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001568
Jan Eilers5b01a892019-07-23 09:47:43 +01001569 auto fbQuantizedLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_QuantizedLstm);
1570
Finn Williamsb454c5c2021-02-09 15:56:23 +00001571 // index for constants vector
1572 size_t i = 0;
1573
Jan Eilers5b01a892019-07-23 09:47:43 +01001574 // Get input parameters
Finn Williamsb454c5c2021-02-09 15:56:23 +00001575 auto inputToInputWeights = CreateConstTensorInfo(constants[i++]);
1576 auto inputToForgetWeights = CreateConstTensorInfo(constants[i++]);
1577 auto inputToCellWeights = CreateConstTensorInfo(constants[i++]);
1578 auto inputToOutputWeights = CreateConstTensorInfo(constants[i++]);
Jan Eilers5b01a892019-07-23 09:47:43 +01001579
Finn Williamsb454c5c2021-02-09 15:56:23 +00001580 auto recurrentToInputWeights = CreateConstTensorInfo(constants[i++]);
1581 auto recurrentToForgetWeights = CreateConstTensorInfo(constants[i++]);
1582 auto recurrentToCellWeights = CreateConstTensorInfo(constants[i++]);
1583 auto recurrentToOutputWeights = CreateConstTensorInfo(constants[i++]);
Jan Eilers5b01a892019-07-23 09:47:43 +01001584
Finn Williamsb454c5c2021-02-09 15:56:23 +00001585 auto inputGateBias = CreateConstTensorInfo(constants[i++]);
1586 auto forgetGateBias = CreateConstTensorInfo(constants[i++]);
1587 auto cellBias = CreateConstTensorInfo(constants[i++]);
1588 auto outputGateBias = CreateConstTensorInfo(constants[i++]);
Jan Eilers5b01a892019-07-23 09:47:43 +01001589
1590 auto fbQuantizedLstmParams = serializer::CreateQuantizedLstmInputParams(
1591 m_flatBufferBuilder,
1592 inputToInputWeights,
1593 inputToForgetWeights,
1594 inputToCellWeights,
1595 inputToOutputWeights,
1596 recurrentToInputWeights,
1597 recurrentToForgetWeights,
1598 recurrentToCellWeights,
1599 recurrentToOutputWeights,
1600 inputGateBias,
1601 forgetGateBias,
1602 cellBias,
1603 outputGateBias);
1604
1605 auto fbQuantizedLstmLayer = serializer::CreateQuantizedLstmLayer(
1606 m_flatBufferBuilder,
1607 fbQuantizedLstmBaseLayer,
1608 fbQuantizedLstmParams);
1609
1610 CreateAnyLayer(fbQuantizedLstmLayer.o, serializer::Layer::Layer_QuantizedLstmLayer);
James Conroyee18dc82019-07-17 11:27:46 +01001611}
1612
Narumol Prangnawarata0162e12021-07-23 14:47:49 +01001613void SerializerStrategy::SerializeUnidirectionalSequenceLstmLayer(
1614 const armnn::IConnectableLayer* layer,
1615 const armnn::UnidirectionalSequenceLstmDescriptor& descriptor,
1616 const std::vector<armnn::ConstTensor>& constants,
1617 const char* name)
1618{
1619 IgnoreUnused(name);
1620
1621 auto fbUnidirectionalSequenceLstmBaseLayer =
1622 CreateLayerBase(layer, serializer::LayerType::LayerType_UnidirectionalSequenceLstm);
1623
1624 auto fbUnidirectionalSequenceLstmDescriptor = serializer::CreateUnidirectionalSequenceLstmDescriptor(
1625 m_flatBufferBuilder,
1626 descriptor.m_ActivationFunc,
1627 descriptor.m_ClippingThresCell,
1628 descriptor.m_ClippingThresProj,
1629 descriptor.m_CifgEnabled,
1630 descriptor.m_PeepholeEnabled,
1631 descriptor.m_ProjectionEnabled,
1632 descriptor.m_LayerNormEnabled,
1633 descriptor.m_TimeMajor);
1634
1635 // Index for constants vector
1636 std::size_t i = 0;
1637
1638 // Get mandatory/basic input parameters
1639 auto inputToForgetWeights = CreateConstTensorInfo(constants[i++]); //InputToForgetWeights
1640 auto inputToCellWeights = CreateConstTensorInfo(constants[i++]); //InputToCellWeights
1641 auto inputToOutputWeights = CreateConstTensorInfo(constants[i++]); //InputToOutputWeights
1642 auto recurrentToForgetWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToForgetWeights
1643 auto recurrentToCellWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToCellWeights
1644 auto recurrentToOutputWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToOutputWeights
1645 auto forgetGateBias = CreateConstTensorInfo(constants[i++]); //ForgetGateBias
1646 auto cellBias = CreateConstTensorInfo(constants[i++]); //CellBias
1647 auto outputGateBias = CreateConstTensorInfo(constants[i++]); //OutputGateBias
1648
1649 //Define optional parameters, these will be set depending on configuration in Lstm descriptor
1650 flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
1651 flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
1652 flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
1653 flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
1654 flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
1655 flatbuffers::Offset<serializer::ConstTensor> projectionBias;
1656 flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
1657 flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
1658 flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
1659 flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
1660 flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
1661 flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;
1662
1663 if (!descriptor.m_CifgEnabled)
1664 {
1665 inputToInputWeights = CreateConstTensorInfo(constants[i++]); //InputToInputWeights
1666 recurrentToInputWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToInputWeights
1667 inputGateBias = CreateConstTensorInfo(constants[i++]); //InputGateBias
1668 }
1669
1670 if (descriptor.m_PeepholeEnabled)
1671 {
1672 if (!descriptor.m_CifgEnabled)
1673 {
1674 cellToInputWeights = CreateConstTensorInfo(constants[i++]); //CellToInputWeights
1675 }
1676 cellToForgetWeights = CreateConstTensorInfo(constants[i++]); //CellToForgetWeights
1677 cellToOutputWeights = CreateConstTensorInfo(constants[i++]); //CellToOutputWeights
1678 }
1679
1680 if (descriptor.m_ProjectionEnabled)
1681 {
1682 projectionWeights = CreateConstTensorInfo(constants[i++]); //ProjectionWeights
1683 projectionBias = CreateConstTensorInfo(constants[i++]); //ProjectionBias
1684 }
1685
1686 if (descriptor.m_LayerNormEnabled)
1687 {
1688 if (!descriptor.m_CifgEnabled)
1689 {
1690 inputLayerNormWeights = CreateConstTensorInfo(constants[i++]); //InputLayerNormWeights
1691 }
1692 forgetLayerNormWeights = CreateConstTensorInfo(constants[i++]); //ForgetLayerNormWeights
1693 cellLayerNormWeights = CreateConstTensorInfo(constants[i++]); //CellLayerNormWeights
1694 outputLayerNormWeights = CreateConstTensorInfo(constants[i++]); //OutputLayerNormWeights
1695 }
1696
1697 auto fbUnidirectionalSequenceLstmParams = serializer::CreateLstmInputParams(
1698 m_flatBufferBuilder,
1699 inputToForgetWeights,
1700 inputToCellWeights,
1701 inputToOutputWeights,
1702 recurrentToForgetWeights,
1703 recurrentToCellWeights,
1704 recurrentToOutputWeights,
1705 forgetGateBias,
1706 cellBias,
1707 outputGateBias,
1708 inputToInputWeights,
1709 recurrentToInputWeights,
1710 cellToInputWeights,
1711 inputGateBias,
1712 projectionWeights,
1713 projectionBias,
1714 cellToForgetWeights,
1715 cellToOutputWeights,
1716 inputLayerNormWeights,
1717 forgetLayerNormWeights,
1718 cellLayerNormWeights,
1719 outputLayerNormWeights);
1720
1721 auto fbUnidirectionalSequenceLstmLayer = serializer::CreateUnidirectionalSequenceLstmLayer(
1722 m_flatBufferBuilder,
1723 fbUnidirectionalSequenceLstmBaseLayer,
1724 fbUnidirectionalSequenceLstmDescriptor,
1725 fbUnidirectionalSequenceLstmParams);
1726
1727 CreateAnyLayer(fbUnidirectionalSequenceLstmLayer.o, serializer::Layer::Layer_UnidirectionalSequenceLstmLayer);
1728}
1729
Finn Williamsb454c5c2021-02-09 15:56:23 +00001730fb::Offset<serializer::LayerBase> SerializerStrategy::CreateLayerBase(const IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00001731 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001732{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001733
Sadik Armagandb059fd2019-03-20 12:28:32 +00001734 uint32_t fbIndex = GetSerializedId(layer->GetGuid());
1735
Mike Kelly8c1701a2019-02-11 17:01:27 +00001736 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
1737 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
1738
1739 return serializer::CreateLayerBase(m_flatBufferBuilder,
Sadik Armagandb059fd2019-03-20 12:28:32 +00001740 fbIndex,
Mike Kelly8c1701a2019-02-11 17:01:27 +00001741 m_flatBufferBuilder.CreateString(layer->GetName()),
1742 layerType,
1743 m_flatBufferBuilder.CreateVector(inputSlots),
1744 m_flatBufferBuilder.CreateVector(outputSlots));
1745}
1746
Finn Williamsb454c5c2021-02-09 15:56:23 +00001747void SerializerStrategy::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001748{
Derek Lamberti859f9ce2019-12-10 22:05:21 +00001749
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001750 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +00001751 m_serializedLayers.push_back(anyLayer);
1752}
1753
Mike Kellya0766c32019-02-19 17:22:07 +00001754template <typename T>
Finn Williamsb454c5c2021-02-09 15:56:23 +00001755flatbuffers::Offset<flatbuffers::Vector<T>> SerializerStrategy::CreateDataVector(const void* memory, unsigned int size)
Mike Kellya0766c32019-02-19 17:22:07 +00001756{
1757 const T* buffer = reinterpret_cast<const T*>(memory);
1758 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
1759 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
1760 return fbVector;
1761}
1762
Finn Williamsb454c5c2021-02-09 15:56:23 +00001763flatbuffers::Offset<TensorInfo> SerializerStrategy::CreateTensorInfo(const armnn::TensorInfo& tensorInfo)
Mike Kellya0766c32019-02-19 17:22:07 +00001764{
Mike Kellya0766c32019-02-19 17:22:07 +00001765 // Get the dimensions
1766 std::vector<unsigned int> shape;
Colm Donelan800b2812021-02-12 12:43:35 +00001767 std::vector<bool> specificity;
1768 // This assumes that the TensorShape constructors have ensured that the size of m_DimensionsSpecificity
1769 // matches the size of dimensions.
1770 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
1771 {
1772 specificity.push_back(tensorInfo.GetShape().GetDimensionSpecificity(dim));
Mike Kellydf258592021-04-26 23:53:31 +01001773
1774 if (tensorInfo.GetShape().GetDimensionSpecificity(dim))
1775 {
1776 shape.push_back(tensorInfo.GetShape()[dim]);
1777 }
1778 else
1779 {
1780 shape.push_back(0);
1781 }
Colm Donelan800b2812021-02-12 12:43:35 +00001782 }
1783
Sadik Armagan1a84fe32020-03-27 15:56:57 +00001784 if (tensorInfo.HasPerAxisQuantization())
1785 {
1786 // Create FlatBuffer TensorInfo
1787 auto flatBufferTensorInfo =
1788 serializer::CreateTensorInfo(m_flatBufferBuilder,
1789 m_flatBufferBuilder.CreateVector(shape),
1790 GetFlatBufferDataType(tensorInfo.GetDataType()),
1791 tensorInfo.GetQuantizationScales()[0],
1792 tensorInfo.GetQuantizationOffset(),
1793 m_flatBufferBuilder.CreateVector(tensorInfo.GetQuantizationScales()),
Finn Williams2605b232020-06-10 15:53:46 +01001794 tensorInfo.GetQuantizationDim().value(),
1795 static_cast<unsigned int>
Colm Donelan800b2812021-02-12 12:43:35 +00001796 (tensorInfo.GetShape().GetDimensionality()),
1797 m_flatBufferBuilder.CreateVector(specificity));
Sadik Armagan1a84fe32020-03-27 15:56:57 +00001798 return flatBufferTensorInfo;
1799 }
1800
Mike Kellya0766c32019-02-19 17:22:07 +00001801 // Create FlatBuffer TensorInfo
1802 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
1803 m_flatBufferBuilder.CreateVector(shape),
1804 GetFlatBufferDataType(tensorInfo.GetDataType()),
1805 tensorInfo.GetQuantizationScale(),
Finn Williams2605b232020-06-10 15:53:46 +01001806 tensorInfo.GetQuantizationOffset(),
1807 0,
1808 0,
1809 static_cast<unsigned int>
Colm Donelan800b2812021-02-12 12:43:35 +00001810 (tensorInfo.GetShape().GetDimensionality()),
1811 m_flatBufferBuilder.CreateVector(specificity));
Sadik Armagan1a84fe32020-03-27 15:56:57 +00001812 return flatBufferTensorInfo;
1813}
1814
1815flatbuffers::Offset<serializer::ConstTensor>
Finn Williamsb454c5c2021-02-09 15:56:23 +00001816 SerializerStrategy::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Sadik Armagan1a84fe32020-03-27 15:56:57 +00001817{
1818 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
1819
Mike Kellya0766c32019-02-19 17:22:07 +00001820 flatbuffers::Offset<void> fbPayload;
1821
1822 switch (tensorInfo.GetDataType())
1823 {
Mike Kelly1f140f72021-04-06 12:25:55 +01001824 case armnn::DataType::Signed64:
1825 {
1826 auto fbVector = CreateDataVector<int64_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1827 flatbuffers::Offset<serializer::LongData> flatBuffersData = serializer::CreateLongData(
1828 m_flatBufferBuilder,
1829 fbVector);
1830 fbPayload = flatBuffersData.o;
1831 break;
1832 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001833 case armnn::DataType::Float32:
1834 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +00001835 {
1836 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1837 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
1838 m_flatBufferBuilder,
1839 fbVector);
1840 fbPayload = flatBuffersData.o;
1841 break;
1842 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001843 case armnn::DataType::Float16:
Mike Kellyae42f012020-04-24 15:44:01 +01001844 case armnn::DataType::BFloat16:
Derek Lambertif90c56d2020-01-10 17:14:08 +00001845 case armnn::DataType::QSymmS16:
Nattapat Chaimanowongcd5ac232019-03-19 12:26:36 +00001846 {
1847 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1848 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
1849 m_flatBufferBuilder,
1850 fbVector);
1851 fbPayload = flatBuffersData.o;
1852 break;
1853 }
Sadik Armagan1a84fe32020-03-27 15:56:57 +00001854 case armnn::DataType::QSymmS8:
Mike Kellyae42f012020-04-24 15:44:01 +01001855 case armnn::DataType::QAsymmS8:
Derek Lambertif90c56d2020-01-10 17:14:08 +00001856 case armnn::DataType::QAsymmU8:
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001857 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +00001858 default:
1859 {
1860 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
1861 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
1862 m_flatBufferBuilder,
1863 fbVector);
1864 fbPayload = flatBuffersData.o;
1865 }
1866 }
1867 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
1868 m_flatBufferBuilder,
Sadik Armagan1a84fe32020-03-27 15:56:57 +00001869 CreateTensorInfo(tensorInfo),
Mike Kellya0766c32019-02-19 17:22:07 +00001870 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
1871 fbPayload);
1872 return flatBufferConstTensor;
1873}
1874
Finn Williamsb454c5c2021-02-09 15:56:23 +00001875flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> SerializerStrategy::GetVersionTable()
Tee Jungaa920c52019-11-05 10:48:25 +00001876{
1877 flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> versionsTable =
1878 serializer::CreateFeatureCompatibilityVersions(
1879 m_flatBufferBuilder,
Jan Eilers53ef7952021-06-02 12:01:25 +01001880 1, // Binding ids scheme version
Matthew Sloyan81beae32021-07-13 19:46:11 +01001881 1, // Weights layout scheme version
1882 1 // Constant tensors as inputs version
Tee Jungaa920c52019-11-05 10:48:25 +00001883 );
1884 return versionsTable;
1885}
1886
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001887std::vector<fb::Offset<serializer::InputSlot>>
Finn Williamsb454c5c2021-02-09 15:56:23 +00001888 SerializerStrategy::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001889{
Mike Kellya0766c32019-02-19 17:22:07 +00001890 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +00001891
1892 // Get the InputSlots
1893 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
1894 {
1895 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
1896
1897 // Get the Connection for the InputSlot
1898 const IOutputSlot* connection = inputSlot.GetConnection();
1899
1900 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +00001901 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
1902 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +00001903 // Create FlatBuffer InputSlot
1904 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
1905 }
1906 return inputSlots;
1907}
1908
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001909std::vector<fb::Offset<serializer::OutputSlot>>
Finn Williamsb454c5c2021-02-09 15:56:23 +00001910 SerializerStrategy::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +00001911{
1912 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
1913
1914 // Get the OutputSlots
1915 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
1916 {
1917 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +00001918 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +00001919
Mike Kelly8c1701a2019-02-11 17:01:27 +00001920 // Create FlatBuffer Outputslot
1921 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
1922 slotIndex,
Sadik Armagan1a84fe32020-03-27 15:56:57 +00001923 CreateTensorInfo(tensorInfo)));
Mike Kelly8c1701a2019-02-11 17:01:27 +00001924 }
1925 return outputSlots;
1926}
1927
Finn Williamsb454c5c2021-02-09 15:56:23 +00001928void SerializerStrategy::ExecuteStrategy(const armnn::IConnectableLayer* layer,
1929 const BaseDescriptor& descriptor,
1930 const std::vector<armnn::ConstTensor>& constants,
1931 const char* name,
1932 const armnn::LayerBindingId id)
1933{
1934 IgnoreUnused(constants);
1935
1936 switch (layer->GetType())
1937 {
1938 case armnn::LayerType::Activation :
1939 {
1940 const armnn::ActivationDescriptor& layerDescriptor =
1941 static_cast<const armnn::ActivationDescriptor&>(descriptor);
1942 SerializeActivationLayer(layer, layerDescriptor, name);
1943 break;
1944 }
1945 case armnn::LayerType::Addition :
1946 {
1947 SerializeAdditionLayer(layer, name);
1948 break;
1949 }
1950 case armnn::LayerType::ArgMinMax :
1951 {
1952 const armnn::ArgMinMaxDescriptor& layerDescriptor =
1953 static_cast<const armnn::ArgMinMaxDescriptor&>(descriptor);
1954 SerializeArgMinMaxLayer(layer, layerDescriptor, name);
1955 break;
1956 }
1957 case armnn::LayerType::BatchNormalization :
1958 {
1959 const armnn::BatchNormalizationDescriptor& layerDescriptor =
1960 static_cast<const armnn::BatchNormalizationDescriptor&>(descriptor);
1961 SerializeBatchNormalizationLayer(layer,
1962 layerDescriptor,
1963 constants,
1964 name);
1965 break;
1966 }
1967 case armnn::LayerType::BatchToSpaceNd :
1968 {
1969 const armnn::BatchToSpaceNdDescriptor& layerDescriptor =
1970 static_cast<const armnn::BatchToSpaceNdDescriptor&>(descriptor);
1971 SerializeBatchToSpaceNdLayer(layer,
1972 layerDescriptor,
1973 name);
1974 break;
1975 }
mathad01b392e982021-04-07 12:07:30 +01001976 case armnn::LayerType::Cast :
1977 {
1978 SerializeCastLayer(layer, name);
1979 break;
1980 }
Simon Obute51f67772021-09-03 15:50:13 +01001981 case armnn::LayerType::ChannelShuffle :
1982 {
1983 const armnn::ChannelShuffleDescriptor& layerDescriptor =
1984 static_cast<const armnn::ChannelShuffleDescriptor&>(descriptor);
1985 SerializeChannelShuffleLayer(layer,
1986 layerDescriptor,
1987 name);
1988 break;
1989 }
Finn Williamsb454c5c2021-02-09 15:56:23 +00001990 case armnn::LayerType::Comparison :
1991 {
1992 const armnn::ComparisonDescriptor& layerDescriptor =
1993 static_cast<const armnn::ComparisonDescriptor&>(descriptor);
1994 SerializeComparisonLayer(layer,
1995 layerDescriptor,
1996 name);
1997 break;
1998 }
1999 case armnn::LayerType::Concat :
2000 {
2001 const armnn::ConcatDescriptor& layerDescriptor =
2002 static_cast<const armnn::ConcatDescriptor&>(descriptor);
2003 SerializeConcatLayer(layer,
2004 layerDescriptor,
2005 name);
2006 break;
2007 }
2008 case armnn::LayerType::Constant :
2009 {
2010 SerializeConstantLayer(layer,
2011 constants,
2012 name);
2013 break;
2014 }
2015 case armnn::LayerType::Convolution2d :
2016 {
2017 const armnn::Convolution2dDescriptor& layerDescriptor =
2018 static_cast<const armnn::Convolution2dDescriptor&>(descriptor);
2019 SerializeConvolution2dLayer(layer,
2020 layerDescriptor,
2021 constants,
2022 name);
2023 break;
2024 }
Matthew Sloyanb63a3112021-09-08 13:05:51 +01002025 case armnn::LayerType::Convolution3d :
2026 {
2027 const armnn::Convolution3dDescriptor& layerDescriptor =
2028 static_cast<const armnn::Convolution3dDescriptor&>(descriptor);
2029 SerializeConvolution3dLayer(layer,
2030 layerDescriptor,
Matthew Sloyanb63a3112021-09-08 13:05:51 +01002031 name);
2032 break;
2033 }
Finn Williamsb454c5c2021-02-09 15:56:23 +00002034 case armnn::LayerType::DepthToSpace :
2035 {
2036 const armnn::DepthToSpaceDescriptor& layerDescriptor =
2037 static_cast<const armnn::DepthToSpaceDescriptor&>(descriptor);
2038 SerializeDepthToSpaceLayer(layer,
2039 layerDescriptor,
2040 name);
2041 break;
2042 }
2043 case armnn::LayerType::DepthwiseConvolution2d :
2044 {
2045 const armnn::DepthwiseConvolution2dDescriptor& layerDescriptor =
2046 static_cast<const armnn::DepthwiseConvolution2dDescriptor&>(descriptor);
2047 SerializeDepthwiseConvolution2dLayer(layer,
2048 layerDescriptor,
2049 constants,
2050 name);
2051 break;
2052 }
2053 case armnn::LayerType::Dequantize :
2054 {
2055 SerializeDequantizeLayer(layer,
2056 name);
2057 break;
2058 }
2059 case armnn::LayerType::DetectionPostProcess :
2060 {
2061 const armnn::DetectionPostProcessDescriptor& layerDescriptor =
2062 static_cast<const armnn::DetectionPostProcessDescriptor&>(descriptor);
2063 SerializeDetectionPostProcessLayer(layer, layerDescriptor, constants, name);
2064 break;
2065 }
2066 case armnn::LayerType::Division :
2067 {
2068 SerializeDivisionLayer(layer, name);
2069 break;
2070 }
2071 case armnn::LayerType::ElementwiseUnary :
2072 {
2073 const armnn::ElementwiseUnaryDescriptor& layerDescriptor =
2074 static_cast<const armnn::ElementwiseUnaryDescriptor&>(descriptor);
2075 SerializeElementwiseUnaryLayer(layer, layerDescriptor, name);
2076 break;
2077 }
2078 case armnn::LayerType::Fill :
2079 {
2080 const armnn::FillDescriptor& layerDescriptor =
2081 static_cast<const armnn::FillDescriptor&>(descriptor);
2082 SerializeFillLayer(layer, layerDescriptor, name);
2083 break;
2084 }
2085 case armnn::LayerType::Floor :
2086 {
2087 SerializeFloorLayer(layer, name);
2088 break;
2089 }
2090 case armnn::LayerType::FullyConnected :
2091 {
2092 const armnn::FullyConnectedDescriptor& layerDescriptor =
2093 static_cast<const armnn::FullyConnectedDescriptor&>(descriptor);
Matthew Sloyan81beae32021-07-13 19:46:11 +01002094 SerializeFullyConnectedLayer(layer, layerDescriptor, name);
Finn Williamsb454c5c2021-02-09 15:56:23 +00002095 break;
2096 }
2097 case armnn::LayerType::Gather :
2098 {
2099 const armnn::GatherDescriptor& layerDescriptor =
2100 static_cast<const armnn::GatherDescriptor&>(descriptor);
2101 SerializeGatherLayer(layer, layerDescriptor, name);
2102 break;
2103 }
2104 case armnn::LayerType::Input:
2105 {
2106 SerializeInputLayer(layer, id, name);
2107 break;
2108 }
2109 case armnn::LayerType::InstanceNormalization :
2110 {
2111 const armnn::InstanceNormalizationDescriptor& layerDescriptor =
2112 static_cast<const armnn::InstanceNormalizationDescriptor&>(descriptor);
2113 SerializeInstanceNormalizationLayer(layer, layerDescriptor, name);
2114 break;
2115 }
2116 case armnn::LayerType::L2Normalization :
2117 {
2118 const armnn::L2NormalizationDescriptor& layerDescriptor =
2119 static_cast<const armnn::L2NormalizationDescriptor&>(descriptor);
2120 SerializeL2NormalizationLayer(layer, layerDescriptor, name);
2121 break;
2122 }
2123 case armnn::LayerType::LogicalBinary :
2124 {
2125 const armnn::LogicalBinaryDescriptor& layerDescriptor =
2126 static_cast<const armnn::LogicalBinaryDescriptor&>(descriptor);
2127 SerializeLogicalBinaryLayer(layer, layerDescriptor, name);
2128 break;
2129 }
2130 case armnn::LayerType::LogSoftmax :
2131 {
2132 const armnn::LogSoftmaxDescriptor& layerDescriptor =
2133 static_cast<const armnn::LogSoftmaxDescriptor&>(descriptor);
2134 SerializeLogSoftmaxLayer(layer, layerDescriptor, name);
2135 break;
2136 }
2137 case armnn::LayerType::Lstm :
2138 {
2139 const armnn::LstmDescriptor& layerDescriptor =
2140 static_cast<const armnn::LstmDescriptor&>(descriptor);
2141 SerializeLstmLayer(layer, layerDescriptor, constants, name);
2142 break;
2143 }
2144 case armnn::LayerType::QLstm :
2145 {
2146 const armnn::QLstmDescriptor& layerDescriptor =
2147 static_cast<const armnn::QLstmDescriptor&>(descriptor);
2148 SerializeQLstmLayer(layer, layerDescriptor, constants, name);
2149 break;
2150 }
2151 case armnn::LayerType::Maximum :
2152 {
2153 SerializeMaximumLayer(layer, name);
2154 break;
2155 }
2156 case armnn::LayerType::Mean :
2157 {
2158 const armnn::MeanDescriptor& layerDescriptor =
2159 static_cast<const armnn::MeanDescriptor&>(descriptor);
2160 SerializeMeanLayer(layer, layerDescriptor, name);
2161 break;
2162 }
2163 case armnn::LayerType::Merge :
2164 {
2165 SerializeMergeLayer(layer, name);
2166 break;
2167 }
2168 case armnn::LayerType::Minimum :
2169 {
2170 SerializeMinimumLayer(layer, name);
2171 break;
2172 }
2173 case armnn::LayerType::Multiplication :
2174 {
2175 SerializeMultiplicationLayer(layer, name);
2176 break;
2177 }
2178 case armnn::LayerType::Normalization :
2179 {
2180 const armnn::NormalizationDescriptor& layerDescriptor =
2181 static_cast<const armnn::NormalizationDescriptor&>(descriptor);
2182 SerializeNormalizationLayer(layer, layerDescriptor, name);
2183 break;
2184 }
2185 case armnn::LayerType::Output:
2186 {
2187 SerializeOutputLayer(layer, id, name);
2188 break;
2189 }
2190 case armnn::LayerType::Pad :
2191 {
2192 const armnn::PadDescriptor& layerDescriptor =
2193 static_cast<const armnn::PadDescriptor&>(descriptor);
2194 SerializePadLayer(layer, layerDescriptor, name);
2195 break;
2196 }
2197 case armnn::LayerType::Permute :
2198 {
2199 const armnn::PermuteDescriptor& layerDescriptor =
2200 static_cast<const armnn::PermuteDescriptor&>(descriptor);
2201 SerializePermuteLayer(layer, layerDescriptor, name);
2202 break;
2203 }
2204 case armnn::LayerType::Pooling2d :
2205 {
2206 const armnn::Pooling2dDescriptor& layerDescriptor =
2207 static_cast<const armnn::Pooling2dDescriptor&>(descriptor);
2208 SerializePooling2dLayer(layer, layerDescriptor, name);
2209 break;
2210 }
2211 case armnn::LayerType::Prelu :
2212 {
2213 SerializePreluLayer(layer, name);
2214 break;
2215 }
2216 case armnn::LayerType::Quantize :
2217 {
2218 SerializeQuantizeLayer(layer, name);
2219 break;
2220 }
2221 case armnn::LayerType::QuantizedLstm:
2222 SerializeQuantizedLstmLayer(layer, constants, name);
2223 break;
2224 case armnn::LayerType::Reshape:
2225 {
2226 const armnn::ReshapeDescriptor &layerDescriptor =
2227 static_cast<const armnn::ReshapeDescriptor &>(descriptor);
2228 SerializeReshapeLayer(layer, layerDescriptor, name);
2229 break;
2230 }
2231 case armnn::LayerType::Rank:
2232 {
2233 SerializeRankLayer(layer, name);
2234 break;
2235 }
2236 case armnn::LayerType::Reduce:
2237 {
2238 const armnn::ReduceDescriptor& layerDescriptor =
2239 static_cast<const armnn::ReduceDescriptor&>(descriptor);
2240 SerializeReduceLayer(layer, layerDescriptor, name);
2241 break;
2242 }
2243 case armnn::LayerType::Resize:
2244 {
2245 const armnn::ResizeDescriptor& layerDescriptor =
2246 static_cast<const armnn::ResizeDescriptor&>(descriptor);
2247 SerializeResizeLayer(layer, layerDescriptor, name);
2248 break;
2249 }
Keith Davis3ae3f972021-05-21 16:33:48 +01002250 case armnn::LayerType::Shape:
2251 {
2252 SerializeShapeLayer(layer, name);
2253 break;
2254 }
Finn Williamsb454c5c2021-02-09 15:56:23 +00002255 case armnn::LayerType::Slice:
2256 {
2257 const armnn::SliceDescriptor& layerDescriptor =
2258 static_cast<const armnn::SliceDescriptor&>(descriptor);
2259 SerializeSliceLayer(layer, layerDescriptor, name);
2260 break;
2261 }
2262 case armnn::LayerType::Softmax:
2263 {
2264 const armnn::SoftmaxDescriptor& layerDescriptor =
2265 static_cast<const armnn::SoftmaxDescriptor&>(descriptor);
2266 SerializeSoftmaxLayer(layer, layerDescriptor, name);
2267 break;
2268 }
2269 case armnn::LayerType::SpaceToBatchNd:
2270 {
2271 const armnn::SpaceToBatchNdDescriptor& layerDescriptor =
2272 static_cast<const armnn::SpaceToBatchNdDescriptor&>(descriptor);
2273 SerializeSpaceToBatchNdLayer(layer, layerDescriptor, name);
2274 break;
2275 }
2276 case armnn::LayerType::SpaceToDepth:
2277 {
2278 const armnn::SpaceToDepthDescriptor& layerDescriptor =
2279 static_cast<const armnn::SpaceToDepthDescriptor&>(descriptor);
2280 SerializeSpaceToDepthLayer(layer, layerDescriptor, name);
2281 break;
2282 }
2283 case armnn::LayerType::Splitter:
2284 {
2285 const armnn::SplitterDescriptor& layerDescriptor =
2286 static_cast<const armnn::SplitterDescriptor&>(descriptor);
2287 SerializeSplitterLayer(layer, layerDescriptor, name);
2288 break;
2289 }
2290 case armnn::LayerType::Stack:
2291 {
2292 const armnn::StackDescriptor& layerDescriptor =
2293 static_cast<const armnn::StackDescriptor&>(descriptor);
2294 SerializeStackLayer(layer, layerDescriptor, name);
2295 break;
2296 }
2297 case armnn::LayerType::StandIn:
2298 {
2299 const armnn::StandInDescriptor& layerDescriptor =
2300 static_cast<const armnn::StandInDescriptor&>(descriptor);
2301 SerializeStandInLayer(layer, layerDescriptor, name);
2302 break;
2303 }
2304 case armnn::LayerType::StridedSlice:
2305 {
2306 const armnn::StridedSliceDescriptor& layerDescriptor =
2307 static_cast<const armnn::StridedSliceDescriptor&>(descriptor);
2308 SerializeStridedSliceLayer(layer, layerDescriptor, name);
2309 break;
2310 }
2311 case armnn::LayerType::Subtraction:
2312 {
2313 SerializeSubtractionLayer(layer, name);
2314 break;
2315 }
2316 case armnn::LayerType::Switch:
2317 {
2318 SerializeSwitchLayer(layer, name);
2319 break;
2320 }
2321 case armnn::LayerType::Transpose:
2322 {
2323 const armnn::TransposeDescriptor& layerDescriptor =
2324 static_cast<const armnn::TransposeDescriptor&>(descriptor);
2325 SerializeTransposeLayer(layer, layerDescriptor, name);
2326 break;
2327 }
2328 case armnn::LayerType::TransposeConvolution2d:
2329 {
2330 const armnn::TransposeConvolution2dDescriptor& layerDescriptor =
2331 static_cast<const armnn::TransposeConvolution2dDescriptor&>(descriptor);
2332 SerializeTransposeConvolution2dLayer(layer, layerDescriptor, constants, name);
2333 break;
2334 }
Narumol Prangnawarata0162e12021-07-23 14:47:49 +01002335 case armnn::LayerType::UnidirectionalSequenceLstm :
2336 {
2337 const armnn::UnidirectionalSequenceLstmDescriptor& layerDescriptor =
2338 static_cast<const armnn::UnidirectionalSequenceLstmDescriptor&>(descriptor);
2339 SerializeUnidirectionalSequenceLstmLayer(layer, layerDescriptor, constants, name);
2340 break;
2341 }
Finn Williamsb454c5c2021-02-09 15:56:23 +00002342 default:
2343 {
2344 throw InvalidArgumentException(
2345 fmt::format("A layer of unknown type was given to the serializer. Layer name: {}; Layer Id: {}",
2346 layer->GetName(),
2347 id));
2348 }
2349 }
2350}
2351
Finn Williams85d36712021-01-26 22:30:06 +00002352void ISerializer::SerializerImpl::Serialize(const INetwork& inNetwork)
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00002353{
2354 // Iterate through to network
Finn Williamsb454c5c2021-02-09 15:56:23 +00002355 inNetwork.ExecuteStrategy(m_SerializerStrategy);
2356 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerStrategy.GetFlatBufferBuilder();
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00002357
2358 // Create FlatBuffer SerializedGraph
2359 auto serializedGraph = serializer::CreateSerializedGraph(
Finn Williamsb454c5c2021-02-09 15:56:23 +00002360 fbBuilder,
2361 fbBuilder.CreateVector(m_SerializerStrategy.GetSerializedLayers()),
2362 fbBuilder.CreateVector(m_SerializerStrategy.GetInputIds()),
2363 fbBuilder.CreateVector(m_SerializerStrategy.GetOutputIds()),
2364 m_SerializerStrategy.GetVersionTable());
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00002365
2366 // Serialize the graph
2367 fbBuilder.Finish(serializedGraph);
2368}
2369
Finn Williamsb454c5c2021-02-09 15:56:23 +00002370
Finn Williams85d36712021-01-26 22:30:06 +00002371bool ISerializer::SerializerImpl::SaveSerializedToStream(std::ostream& stream)
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00002372{
Finn Williamsb454c5c2021-02-09 15:56:23 +00002373 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerStrategy.GetFlatBufferBuilder();
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00002374
Matthew Sloyan0663d662020-09-14 11:47:26 +01002375 auto bytesToWrite = armnn::numeric_cast<std::streamsize>(fbBuilder.GetSize());
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +00002376 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +00002377 return !stream.bad();
2378}
2379
Finn Williams2605b232020-06-10 15:53:46 +01002380} // namespace armnnSerializer