blob: 57228c406ec4e68a747aadece822a8b426720d18 [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;
20namespace serializer = armnn::armnnSerializer;
21
22namespace armnnSerializer
23{
24
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000025uint32_t SerializerVisitor::GetSerializedId(unsigned int guid)
26{
27 std::pair<unsigned int, uint32_t> guidPair(guid, m_layerId);
28
29 if (m_guidMap.empty())
30 {
31 m_guidMap.insert(guidPair);
32 }
33 else if (m_guidMap.find(guid) == m_guidMap.end())
34 {
35 guidPair.second = ++m_layerId;
36 m_guidMap.insert(guidPair);
37 return m_layerId;
38 }
39 return m_layerId;
40}
41
Mike Kelly8c1701a2019-02-11 17:01:27 +000042// Build FlatBuffer for Input Layer
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +000043void SerializerVisitor::VisitInputLayer(const IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000044{
45 // Create FlatBuffer BaseLayer
46 auto flatBufferInputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Input);
47
48 // Create FlatBuffer BindableBaseLayer
49 auto flatBufferInputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
50 flatBufferInputBaseLayer,
51 id);
52
53 // Push layer Guid to outputIds.
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000054 m_inputIds.push_back(GetSerializedId(layer->GetGuid()));
Mike Kelly8c1701a2019-02-11 17:01:27 +000055
56 // Create the FlatBuffer InputLayer
57 auto flatBufferInputLayer = serializer::CreateInputLayer(m_flatBufferBuilder, flatBufferInputBindableBaseLayer);
58
59 // Add the AnyLayer to the FlatBufferLayers
60 CreateAnyLayer(flatBufferInputLayer.o, serializer::Layer::Layer_InputLayer);
61}
62
63// Build FlatBuffer for Output Layer
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +000064void SerializerVisitor::VisitOutputLayer(const IConnectableLayer* layer, LayerBindingId id, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000065{
66 // Create FlatBuffer BaseLayer
67 auto flatBufferOutputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Output);
68
69 // Create FlatBuffer BindableBaseLayer
70 auto flatBufferOutputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
71 flatBufferOutputBaseLayer,
72 id);
73 // Push layer Guid to outputIds.
Saoirse Stewartcb8a3212019-02-14 15:46:10 +000074 m_outputIds.push_back(GetSerializedId(layer->GetGuid()));
Mike Kelly8c1701a2019-02-11 17:01:27 +000075
76 // Create the FlatBuffer OutputLayer
77 auto flatBufferOutputLayer = serializer::CreateOutputLayer(m_flatBufferBuilder, flatBufferOutputBindableBaseLayer);
78 // Add the AnyLayer to the FlatBufferLayers
79 CreateAnyLayer(flatBufferOutputLayer.o, serializer::Layer::Layer_OutputLayer);
80}
81
82// Build FlatBuffer for Addition Layer
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +000083void SerializerVisitor::VisitAdditionLayer(const IConnectableLayer* layer, const char* name)
Mike Kelly8c1701a2019-02-11 17:01:27 +000084{
85 // Create FlatBuffer BaseLayer
86 auto flatBufferAdditionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Addition);
87
88 // Create the FlatBuffer AdditionLayer
89 auto flatBufferAdditionLayer = serializer::CreateAdditionLayer(m_flatBufferBuilder, flatBufferAdditionBaseLayer);
90
91 // Add the AnyLayer to the FlatBufferLayers
92 CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_AdditionLayer);
93}
94
Sadik Armagan5f450272019-02-12 14:31:45 +000095// Build FlatBuffer for Multiplication Layer
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +000096void SerializerVisitor::VisitMultiplicationLayer(const IConnectableLayer* layer, const char* name)
Sadik Armagan5f450272019-02-12 14:31:45 +000097{
98 // Create FlatBuffer BaseLayer
99 auto flatBufferMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
100
101 // Create the FlatBuffer MultiplicationLayer
102 auto flatBufferMultiplicationLayer =
103 serializer::CreateMultiplicationLayer(m_flatBufferBuilder, flatBufferMultiplicationBaseLayer);
104
105 // Add the AnyLayer to the FlatBufferLayers
106 CreateAnyLayer(flatBufferMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
107}
108
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000109// Build FlatBuffer for Softmax Layer
110void SerializerVisitor::VisitSoftmaxLayer(const IConnectableLayer* layer,
111 const SoftmaxDescriptor& softmaxDescriptor,
112 const char* name)
113{
114 // Create FlatBuffer BaseLayer
115 auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);
116
117 // Create the FlatBuffer SoftmaxDescriptor
118 auto flatBufferSoftmaxDesc =
119 serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);
120
121 // Create the FlatBuffer SoftmaxLayer
122 auto flatBufferSoftmaxLayer =
123 serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
124 flatBufferSoftmaxBaseLayer,
125 flatBufferSoftmaxDesc);
126
127 CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
128}
129
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000130void SerializerVisitor::VisitPooling2dLayer(const IConnectableLayer* layer,
131 const Pooling2dDescriptor& pooling2dDescriptor,
132 const char* name)
133{
134 auto fbPooling2dBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
135 auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
136 m_flatBufferBuilder,
137 GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
138 pooling2dDescriptor.m_PadLeft,
139 pooling2dDescriptor.m_PadRight,
140 pooling2dDescriptor.m_PadTop,
141 pooling2dDescriptor.m_PadBottom,
142 pooling2dDescriptor.m_PoolWidth,
143 pooling2dDescriptor.m_PoolHeight,
144 pooling2dDescriptor.m_StrideX,
145 pooling2dDescriptor.m_StrideY,
146 GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
147 GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
148 GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));
149
150 auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
151 fbPooling2dBaseLayer,
152 fbPooling2dDescriptor);
153
154 CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
155}
156
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000157fb::Offset<serializer::LayerBase> SerializerVisitor::CreateLayerBase(const IConnectableLayer* layer,
158 const serializer::LayerType layerType)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000159{
160 std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
161 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);
162
163 return serializer::CreateLayerBase(m_flatBufferBuilder,
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000164 GetSerializedId(layer->GetGuid()),
Mike Kelly8c1701a2019-02-11 17:01:27 +0000165 m_flatBufferBuilder.CreateString(layer->GetName()),
166 layerType,
167 m_flatBufferBuilder.CreateVector(inputSlots),
168 m_flatBufferBuilder.CreateVector(outputSlots));
169}
170
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000171void SerializerVisitor::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000172{
173 auto anyLayer = armnn::armnnSerializer::CreateAnyLayer(m_flatBufferBuilder,
174 serializerLayer,
175 layer);
176 m_serializedLayers.push_back(anyLayer);
177}
178
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000179std::vector<fb::Offset<serializer::InputSlot>> SerializerVisitor::CreateInputSlots(const IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000180{
181 std::vector<fb::Offset <serializer::InputSlot>> inputSlots;
182
183 // Get the InputSlots
184 for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
185 {
186 const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);
187
188 // Get the Connection for the InputSlot
189 const IOutputSlot* connection = inputSlot.GetConnection();
190
191 // Create FlatBuffer Connection
Saoirse Stewartcb8a3212019-02-14 15:46:10 +0000192 serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
193 connection->CalculateIndexOnOwner());
Mike Kelly8c1701a2019-02-11 17:01:27 +0000194 // Create FlatBuffer InputSlot
195 inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
196 }
197 return inputSlots;
198}
199
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000200std::vector<fb::Offset<serializer::OutputSlot>> SerializerVisitor::CreateOutputSlots(const IConnectableLayer* layer)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000201{
202 std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;
203
204 // Get the OutputSlots
205 for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
206 {
207 const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
208 const TensorInfo& tensorInfo = outputSlot.GetTensorInfo();
209
210 // Get the dimensions
211 std::vector<unsigned int> shape;
212 for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
213 {
214 shape.push_back(tensorInfo.GetShape()[dim]);
215 }
216
217 // Create FlatBuffer TensorInfo
218 auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
219 m_flatBufferBuilder.CreateVector(shape),
220 GetFlatBufferDataType(tensorInfo.GetDataType()),
221 tensorInfo.GetQuantizationScale(),
222 tensorInfo.GetQuantizationOffset());
223
224 // Create FlatBuffer Outputslot
225 outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
226 slotIndex,
227 flatBufferTensorInfo));
228 }
229 return outputSlots;
230}
231
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000232
233ISerializer* ISerializer::CreateRaw()
234{
235 return new Serializer();
236}
237
238ISerializerPtr ISerializer::Create()
239{
240 return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
241}
242
243void ISerializer::Destroy(ISerializer* serializer)
244{
245 delete serializer;
246}
247
248void Serializer::Serialize(const INetwork& inNetwork)
249{
250 // Iterate through to network
251 inNetwork.Accept(m_SerializerVisitor);
252 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
253
254 // Create FlatBuffer SerializedGraph
255 auto serializedGraph = serializer::CreateSerializedGraph(
256 fbBuilder,
257 fbBuilder.CreateVector(m_SerializerVisitor.GetSerializedLayers()),
258 fbBuilder.CreateVector(m_SerializerVisitor.GetInputIds()),
259 fbBuilder.CreateVector(m_SerializerVisitor.GetOutputIds()));
260
261 // Serialize the graph
262 fbBuilder.Finish(serializedGraph);
263}
264
265bool Serializer::SaveSerializedToStream(std::ostream& stream)
266{
267 flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerVisitor.GetFlatBufferBuilder();
268
Nattapat Chaimanowong7b53b692019-02-12 14:38:31 +0000269 auto bytesToWrite = boost::numeric_cast<std::streamsize>(fbBuilder.GetSize());
270 stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
Nattapat Chaimanowongac9cadc2019-02-13 15:52:41 +0000271 return !stream.bad();
272}
273
Matteo Martincighec333912019-02-13 15:12:39 +0000274} // namespace armnnSerializer