blob: e1d22ec406e79663a6ae9999ba717012cb3daccf [file] [log] [blame]
Mike Kelly8c1701a2019-02-11 17:01:27 +00001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include "Serializer.hpp"
Saoirse Stewart3166c3e2019-02-18 15:24:53 +00007
8#include "SerializerUtils.hpp"
9
Mike Kelly8c1701a2019-02-11 17:01:27 +000010#include <armnn/ArmNN.hpp>
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000011
Mike Kelly8c1701a2019-02-11 17:01:27 +000012#include <iostream>
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000013
Mike Kelly8c1701a2019-02-11 17:01:27 +000014#include <Schema_generated.h>
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000015
Mike Kelly8c1701a2019-02-11 17:01:27 +000016#include <flatbuffers/util.h>
17
18using namespace armnn;
19namespace fb = flatbuffers;
Derek Lamberti0028d1b2019-02-20 13:57:42 +000020namespace serializer = armnnSerializer;
Mike Kelly8c1701a2019-02-11 17:01:27 +000021
22namespace armnnSerializer
23{
24
Mike Kellyaf484012019-02-20 16:53:11 +000025serializer::ActivationFunction GetFlatBufferActivationFunction(armnn::ActivationFunction function)
26{
27 switch (function)
28 {
29 case armnn::ActivationFunction::Sigmoid:
30 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
31 case armnn::ActivationFunction::TanH:
32 return serializer::ActivationFunction::ActivationFunction_TanH;
33 case armnn::ActivationFunction::Linear:
34 return serializer::ActivationFunction::ActivationFunction_Linear;
35 case armnn::ActivationFunction::ReLu:
36 return serializer::ActivationFunction::ActivationFunction_ReLu;
37 case armnn::ActivationFunction::BoundedReLu:
38 return serializer::ActivationFunction::ActivationFunction_BoundedReLu;
39 case armnn::ActivationFunction::LeakyReLu:
40 return serializer::ActivationFunction::ActivationFunction_LeakyReLu;
41 case armnn::ActivationFunction::Abs:
42 return serializer::ActivationFunction::ActivationFunction_Abs;
43 case armnn::ActivationFunction::Sqrt:
44 return serializer::ActivationFunction::ActivationFunction_Sqrt;
45 case armnn::ActivationFunction::Square:
46 return serializer::ActivationFunction::ActivationFunction_Square;
47 default:
48 return serializer::ActivationFunction::ActivationFunction_Sigmoid;
49 }
50}
51
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000052uint32_t SerializerVisitor::GetSerializedId(unsigned int guid)
53{
54 std::pair<unsigned int, uint32_t> guidPair(guid, m_layerId);
55
56 if (m_guidMap.empty())
57 {
58 m_guidMap.insert(guidPair);
59 }
60 else if (m_guidMap.find(guid) == m_guidMap.end())
61 {
62 guidPair.second = ++m_layerId;
63 m_guidMap.insert(guidPair);
64 return m_layerId;
65 }
Saoirse Stewart30211042019-02-18 17:19:16 +000066 return m_guidMap[guid];
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000067}
68
Mike Kelly8c1701a2019-02-11 17:01:27 +000069// Build FlatBuffer for Input Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +000070void SerializerVisitor::VisitInputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000071{
72 // Create FlatBuffer BaseLayer
73 auto flatBufferInputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Input);
74
75 // Create FlatBuffer BindableBaseLayer
76 auto flatBufferInputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
77 flatBufferInputBaseLayer,
78 id);
Mike Kelly8c1701a2019-02-11 17:01:27 +000079 // Push layer Guid to outputIds.
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000080 m_inputIds.push_back(GetSerializedId(layer->GetGuid()));
Mike Kelly8c1701a2019-02-11 17:01:27 +000081
82 // Create the FlatBuffer InputLayer
83 auto flatBufferInputLayer = serializer::CreateInputLayer(m_flatBufferBuilder, flatBufferInputBindableBaseLayer);
84
85 // Add the AnyLayer to the FlatBufferLayers
86 CreateAnyLayer(flatBufferInputLayer.o, serializer::Layer::Layer_InputLayer);
87}
88
89// Build FlatBuffer for Output Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +000090void SerializerVisitor::VisitOutputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000091{
92 // Create FlatBuffer BaseLayer
93 auto flatBufferOutputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Output);
94
95 // Create FlatBuffer BindableBaseLayer
96 auto flatBufferOutputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
97 flatBufferOutputBaseLayer,
98 id);
99 // Push layer Guid to outputIds.
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000100 m_outputIds.push_back(GetSerializedId(layer->GetGuid()));
Mike Kelly8c1701a2019-02-11 17:01:27 +0000101
102 // Create the FlatBuffer OutputLayer
103 auto flatBufferOutputLayer = serializer::CreateOutputLayer(m_flatBufferBuilder, flatBufferOutputBindableBaseLayer);
104 // Add the AnyLayer to the FlatBufferLayers
105 CreateAnyLayer(flatBufferOutputLayer.o, serializer::Layer::Layer_OutputLayer);
106}
107
Mike Kellyaf484012019-02-20 16:53:11 +0000108// Build FlatBuffer for Activation Layer
109void SerializerVisitor::VisitActivationLayer(const armnn::IConnectableLayer* layer,
110 const armnn::ActivationDescriptor& descriptor,
111 const char* name)
112{
113 // Create FlatBuffer BaseLayer
114 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Activation);
115
116 // Create the FlatBuffer ActivationDescriptor
117 auto flatBufferDescriptor = CreateActivationDescriptor(m_flatBufferBuilder,
118 GetFlatBufferActivationFunction(descriptor.m_Function),
119 descriptor.m_A,
120 descriptor.m_B);
121
122 // Create the FlatBuffer ActivationLayer
123 auto flatBufferAdditionLayer = CreateActivationLayer(m_flatBufferBuilder,
124 flatBufferBaseLayer,
125 flatBufferDescriptor);
126
127 // Add the AnyLayer to the FlatBufferLayers
128 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_ActivationLayer);
129}
130
Mike Kelly8c1701a2019-02-11 17:01:27 +0000131// Build FlatBuffer for Addition Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000132void SerializerVisitor::VisitAdditionLayer(const armnn::IConnectableLayer* layer, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000133{
134 // Create FlatBuffer BaseLayer
135 auto flatBufferAdditionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Addition);
136
137 // Create the FlatBuffer AdditionLayer
138 auto flatBufferAdditionLayer = serializer::CreateAdditionLayer(m_flatBufferBuilder, flatBufferAdditionBaseLayer);
139
140 // Add the AnyLayer to the FlatBufferLayers
141 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_AdditionLayer);
142}
143
Mike Kellya0766c32019-02-19 17:22:07 +0000144// Build FlatBuffer for Convolution2dLayer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000145void SerializerVisitor::VisitConvolution2dLayer(const armnn::IConnectableLayer* layer,
146 const armnn::Convolution2dDescriptor& descriptor,
147 const armnn::ConstTensor& weights,
148 const armnn::Optional<armnn::ConstTensor>& biases,
Mike Kellya0766c32019-02-19 17:22:07 +0000149 const char* name)
150{
151 // Create FlatBuffer BaseLayer
152 auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
153
154 auto flatBufferDescriptor = CreateConvolution2dDescriptor(m_flatBufferBuilder,
155 descriptor.m_PadLeft,
156 descriptor.m_PadRight,
157 descriptor.m_PadTop,
158 descriptor.m_PadBottom,
159 descriptor.m_StrideX,
160 descriptor.m_StrideY,
161 descriptor.m_BiasEnabled,
162 GetFlatBufferDataLayout(descriptor.m_DataLayout));
163 auto flatBufferWeightsConstTensorInfo = CreateConstTensorInfo(weights);
164 flatbuffers::Offset<serializer::ConstTensor> flatBufferBiasesConstTensorInfo;
165
166 if (biases.has_value())
167 {
168 flatBufferBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
169 }
170
171 // Create the FlatBuffer Convolution2dLayer
172 auto flatBufferLayer = CreateConvolution2dLayer(m_flatBufferBuilder,
173 flatBufferBaseLayer,
174 flatBufferDescriptor,
175 flatBufferWeightsConstTensorInfo,
176 flatBufferBiasesConstTensorInfo);
177
178 // Add the AnyLayer to the FlatBufferLayers
179 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution2dLayer);
180}
181
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000182void SerializerVisitor::VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
183 const armnn::DepthwiseConvolution2dDescriptor& descriptor,
184 const armnn::ConstTensor& weights,
185 const armnn::Optional<armnn::ConstTensor>& biases,
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000186 const char* name)
187{
188 auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthwiseConvolution2d);
189 auto fbDescriptor = CreateDepthwiseConvolution2dDescriptor(m_flatBufferBuilder,
190 descriptor.m_PadLeft,
191 descriptor.m_PadRight,
192 descriptor.m_PadTop,
193 descriptor.m_PadBottom,
194 descriptor.m_StrideX,
195 descriptor.m_StrideY,
196 descriptor.m_BiasEnabled,
197 GetFlatBufferDataLayout(descriptor.m_DataLayout));
198
199 flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
200 flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
201 if (biases.has_value())
202 {
203 fbBiasesConstTensorInfo = CreateConstTensorInfo(biases.value());
204 }
205
206 auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
207 fbBaseLayer,
208 fbDescriptor,
209 fbWeightsConstTensorInfo,
210 fbBiasesConstTensorInfo);
211
212 CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
213}
214
Sadik Armagan5f450272019-02-12 14:31:45 +0000215// Build FlatBuffer for Multiplication Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000216void SerializerVisitor::VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +0000217{
218 // Create FlatBuffer BaseLayer
219 auto flatBufferMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
220
221 // Create the FlatBuffer MultiplicationLayer
222 auto flatBufferMultiplicationLayer =
223 serializer::CreateMultiplicationLayer(m_flatBufferBuilder, flatBufferMultiplicationBaseLayer);
224
225 // Add the AnyLayer to the FlatBufferLayers
226 CreateAnyLayer(flatBufferMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
227}
228
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000229void SerializerVisitor::VisitPermuteLayer(const armnn::IConnectableLayer* layer,
230 const armnn::PermuteDescriptor& permuteDescriptor,
231 const char* name)
232{
233 // Create FlatBuffer BaseLayer
234 auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);
235
236 std::vector<unsigned int> dimMappings;
237 for (auto& v: permuteDescriptor.m_DimMappings)
238 {
239 dimMappings.push_back(v);
240 }
241
242 auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
243 m_flatBufferBuilder.CreateVector(dimMappings));
244
245 // Create the FlatBuffer PermuteLayer
246 auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
247 flatBufferPermuteBaseLayer,
248 flatBufferPermuteDesc);
249
250 // Add the AnyLayer to the FlatBufferLayers
251 CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
252}
253
Saoirse Stewart263829c2019-02-19 15:54:14 +0000254// Build FlatBuffer for Reshape Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000255void SerializerVisitor::VisitReshapeLayer(const armnn::IConnectableLayer* layer,
Saoirse Stewart263829c2019-02-19 15:54:14 +0000256 const armnn::ReshapeDescriptor& reshapeDescriptor,
257 const char* name)
258{
259 // Create FlatBuffer BaseLayer
260 auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);
261
262 std::vector<unsigned int> targetShape;
263 for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
264 {
265 targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
266 }
267
268 auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
269 m_flatBufferBuilder.CreateVector(targetShape));
270
271 // Create the FlatBuffer ReshapeLayer
272 auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
273 flatBufferReshapeDesc);
274
275 // Add the AnyLayer to the FlatBufferLayers
276 CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
277}
278
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000279// Build FlatBuffer for Softmax Layer
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000280void SerializerVisitor::VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
281 const armnn::SoftmaxDescriptor& softmaxDescriptor,
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000282 const char* name)
283{
284 // Create FlatBuffer BaseLayer
285 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
286
287 // Create the FlatBuffer SoftmaxDescriptor
288 auto flatBufferSoftmaxDesc =
289 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
290
291 // Create the FlatBuffer SoftmaxLayer
292 auto flatBufferSoftmaxLayer =
293 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
294 flatBufferSoftmaxBaseLayer,
295 flatBufferSoftmaxDesc);
296
297 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
298}
299
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000300void SerializerVisitor::VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
301 const armnn::Pooling2dDescriptor& pooling2dDescriptor,
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000302 const char* name)
303{
304 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
305 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
306 m_flatBufferBuilder,
307 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
308 pooling2dDescriptor.m_PadLeft,
309 pooling2dDescriptor.m_PadRight,
310 pooling2dDescriptor.m_PadTop,
311 pooling2dDescriptor.m_PadBottom,
312 pooling2dDescriptor.m_PoolWidth,
313 pooling2dDescriptor.m_PoolHeight,
314 pooling2dDescriptor.m_StrideX,
315 pooling2dDescriptor.m_StrideY,
316 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
317 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
318 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
319
320 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
321 fbPooling2dBaseLayer,
322 fbPooling2dDescriptor);
323
324 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
325}
326
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000327fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const armnn::IConnectableLayer* layer,
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000328 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000329{
330 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
331 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
332
333 return serializer::CreateLayerBase(m_flatBufferBuilder,
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000334 GetSerializedId(layer->GetGuid()),
Mike Kelly8c1701a2019-02-11 17:01:27 +0000335 m_flatBufferBuilder.CreateString(layer->GetName()),
336 layerType,
337 m_flatBufferBuilder.CreateVector(inputSlots),
338 m_flatBufferBuilder.CreateVector(outputSlots));
339}
340
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000341void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000342{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000343 auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000344 m_serializedLayers.push_back(anyLayer);
345}
346
Mike Kellya0766c32019-02-19 17:22:07 +0000347template <typename T>
348flatbuffers::Offset<flatbuffers::Vector<T>> SerializerVisitor::CreateDataVector(const void* memory, unsigned int size)
349{
350 const T* buffer = reinterpret_cast<const T*>(memory);
351 std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
352 auto fbVector = m_flatBufferBuilder.CreateVector(vector);
353 return fbVector;
354}
355
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000356flatbuffers::Offset<serializer::ConstTensor>
357 SerializerVisitor::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
Mike Kellya0766c32019-02-19 17:22:07 +0000358{
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000359 armnn::TensorInfo tensorInfo = constTensor.GetInfo();
Mike Kellya0766c32019-02-19 17:22:07 +0000360
361 // Get the dimensions
362 std::vector<unsigned int> shape;
363
364 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
365 {
366 shape.push_back(tensorInfo.GetShape()[dim]);
367 }
368
369 // Create FlatBuffer TensorInfo
370 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
371 m_flatBufferBuilder.CreateVector(shape),
372 GetFlatBufferDataType(tensorInfo.GetDataType()),
373 tensorInfo.GetQuantizationScale(),
374 tensorInfo.GetQuantizationOffset());
375 flatbuffers::Offset<void> fbPayload;
376
377 switch (tensorInfo.GetDataType())
378 {
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000379 case armnn::DataType::Float32:
380 case armnn::DataType::Signed32:
Mike Kellya0766c32019-02-19 17:22:07 +0000381 {
382 auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
383 flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
384 m_flatBufferBuilder,
385 fbVector);
386 fbPayload = flatBuffersData.o;
387 break;
388 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000389 case armnn::DataType::Float16:
Mike Kellya0766c32019-02-19 17:22:07 +0000390 {
391 auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
392 flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
393 m_flatBufferBuilder,
394 fbVector);
395 fbPayload = flatBuffersData.o;
396 break;
397 }
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000398 case armnn::DataType::QuantisedAsymm8:
399 case armnn::DataType::Boolean:
Mike Kellya0766c32019-02-19 17:22:07 +0000400 default:
401 {
402 auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
403 flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
404 m_flatBufferBuilder,
405 fbVector);
406 fbPayload = flatBuffersData.o;
407 }
408 }
409 flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
410 m_flatBufferBuilder,
411 flatBufferTensorInfo,
412 GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
413 fbPayload);
414 return flatBufferConstTensor;
415}
416
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000417std::vector<fb::Offset<serializer::InputSlot>>
418 SerializerVisitor::CreateInputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000419{
Mike Kellya0766c32019-02-19 17:22:07 +0000420 std::vector<fb::Offset<serializer::InputSlot>> inputSlots;
Mike Kelly8c1701a2019-02-11 17:01:27 +0000421
422 // Get the InputSlots
423 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
424 {
425 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
426
427 // Get the Connection for the InputSlot
428 const IOutputSlot* connection = inputSlot.GetConnection();
429
430 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000431 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
432 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +0000433 // Create FlatBuffer InputSlot
434 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
435 }
436 return inputSlots;
437}
438
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000439std::vector<fb::Offset<serializer::OutputSlot>>
440 SerializerVisitor::CreateOutputSlots(const armnn::IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000441{
442 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
443
444 // Get the OutputSlots
445 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
446 {
447 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000448 const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
Mike Kelly8c1701a2019-02-11 17:01:27 +0000449
450 // Get the dimensions
451 std::vector<unsigned int> shape;
452 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
453 {
454 shape.push_back(tensorInfo.GetShape()[dim]);
455 }
456
457 // Create FlatBuffer TensorInfo
458 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
459 m_flatBufferBuilder.CreateVector(shape),
460 GetFlatBufferDataType(tensorInfo.GetDataType()),
461 tensorInfo.GetQuantizationScale(),
462 tensorInfo.GetQuantizationOffset());
463
464 // Create FlatBuffer Outputslot
465 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
466 slotIndex,
467 flatBufferTensorInfo));
468 }
469 return outputSlots;
470}
471
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000472
473ISerializer* ISerializer::CreateRaw()
474{
475 return new Serializer();
476}
477
478ISerializerPtr ISerializer::Create()
479{
480 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
481}
482
483void ISerializer::Destroy(ISerializer* serializer)
484{
485 delete serializer;
486}
487
488void Serializer::Serialize(const INetwork& inNetwork)
489{
490 // Iterate through to network
491 inNetwork.Accept(m_SerializerVisitor);
492 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
493
494 // Create FlatBuffer SerializedGraph
495 auto serializedGraph = serializer::CreateSerializedGraph(
496 fbBuilder,
497 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
498 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
499 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
500
501 // Serialize the graph
502 fbBuilder.Finish(serializedGraph);
503}
504
505bool Serializer::SaveSerializedToStream(std::ostream& stream)
506{
507 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
508
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +0000509 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
510 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000511 return !stream.bad();
512}
513
Matteo Martincighec333912019-02-13 15:12:39 +0000514} // namespace armnnSerializer