blob: ad6676edc7185dcea815d5f9d0c5040212b83bb3 [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 <armnn/ArmNN.hpp>
7#include <armnn/INetwork.hpp>
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +00008
Mike Kelly8c1701a2019-02-11 17:01:27 +00009#include "../Serializer.hpp"
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +000010
Derek Lamberti0028d1b2019-02-20 13:57:42 +000011#include <armnnDeserializer/IDeserializer.hpp>
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +000012
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +000013#include <random>
Mike Kelly8c1701a2019-02-11 17:01:27 +000014#include <sstream>
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +000015#include <vector>
16
Mike Kelly8c1701a2019-02-11 17:01:27 +000017#include <boost/test/unit_test.hpp>
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +000018#include <flatbuffers/idl.h>
19
Derek Lamberti0028d1b2019-02-20 13:57:42 +000020using armnnDeserializer::IDeserializer;
Mike Kelly8c1701a2019-02-11 17:01:27 +000021
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000022namespace
23{
24
25armnn::INetworkPtr DeserializeNetwork(const std::string& serializerString)
26{
27 std::vector<std::uint8_t> const serializerVector{serializerString.begin(), serializerString.end()};
Derek Lamberti0028d1b2019-02-20 13:57:42 +000028 return IDeserializer::Create()->CreateNetworkFromBinary(serializerVector);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000029}
30
31std::string SerializeNetwork(const armnn::INetwork& network)
32{
33 armnnSerializer::Serializer serializer;
34 serializer.Serialize(network);
35
36 std::stringstream stream;
37 serializer.SaveSerializedToStream(stream);
38
39 std::string serializerString{stream.str()};
40 return serializerString;
41}
42
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +000043template<typename DataType>
44static std::vector<DataType> GenerateRandomData(size_t size)
45{
46 constexpr bool isIntegerType = std::is_integral<DataType>::value;
47 using Distribution =
48 typename std::conditional<isIntegerType,
49 std::uniform_int_distribution<DataType>,
50 std::uniform_real_distribution<DataType>>::type;
51
52 static constexpr DataType lowerLimit = std::numeric_limits<DataType>::min();
53 static constexpr DataType upperLimit = std::numeric_limits<DataType>::max();
54
55 static Distribution distribution(lowerLimit, upperLimit);
56 static std::default_random_engine generator;
57
58 std::vector<DataType> randomData(size);
59 std::generate(randomData.begin(), randomData.end(), []() { return distribution(generator); });
60
61 return randomData;
62}
63
64void CheckDeserializedNetworkAgainstOriginal(const armnn::INetwork& deserializedNetwork,
65 const armnn::INetwork& originalNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +000066 const std::vector<armnn::TensorShape>& inputShapes,
67 const std::vector<armnn::TensorShape>& outputShapes,
68 const std::vector<armnn::LayerBindingId>& inputBindingIds = {0},
69 const std::vector<armnn::LayerBindingId>& outputBindingIds = {0})
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +000070{
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +000071 BOOST_CHECK(inputShapes.size() == inputBindingIds.size());
72 BOOST_CHECK(outputShapes.size() == outputBindingIds.size());
73
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +000074 armnn::IRuntime::CreationOptions options;
75 armnn::IRuntimePtr runtime = armnn::IRuntime::Create(options);
76
77 std::vector<armnn::BackendId> preferredBackends = { armnn::BackendId("CpuRef") };
78
79 // Optimize original network
80 armnn::IOptimizedNetworkPtr optimizedOriginalNetwork =
81 armnn::Optimize(originalNetwork, preferredBackends, runtime->GetDeviceSpec());
82 BOOST_CHECK(optimizedOriginalNetwork);
83
84 // Optimize deserialized network
85 armnn::IOptimizedNetworkPtr optimizedDeserializedNetwork =
86 armnn::Optimize(deserializedNetwork, preferredBackends, runtime->GetDeviceSpec());
87 BOOST_CHECK(optimizedDeserializedNetwork);
88
89 armnn::NetworkId networkId1;
90 armnn::NetworkId networkId2;
91
92 // Load original and deserialized network
93 armnn::Status status1 = runtime->LoadNetwork(networkId1, std::move(optimizedOriginalNetwork));
94 BOOST_CHECK(status1 == armnn::Status::Success);
95
96 armnn::Status status2 = runtime->LoadNetwork(networkId2, std::move(optimizedDeserializedNetwork));
97 BOOST_CHECK(status2 == armnn::Status::Success);
98
99 // Generate some input data
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000100 armnn::InputTensors inputTensors1;
101 armnn::InputTensors inputTensors2;
102 std::vector<std::vector<float>> inputData;
103 inputData.reserve(inputShapes.size());
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000104
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000105 for (unsigned int i = 0; i < inputShapes.size(); i++)
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000106 {
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000107 inputData.push_back(GenerateRandomData<float>(inputShapes[i].GetNumElements()));
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000108
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000109 inputTensors1.emplace_back(
110 i, armnn::ConstTensor(runtime->GetInputTensorInfo(networkId1, inputBindingIds[i]), inputData[i].data()));
111
112 inputTensors2.emplace_back(
113 i, armnn::ConstTensor(runtime->GetInputTensorInfo(networkId2, inputBindingIds[i]), inputData[i].data()));
114 }
115
116 armnn::OutputTensors outputTensors1;
117 armnn::OutputTensors outputTensors2;
118 std::vector<std::vector<float>> outputData1;
119 std::vector<std::vector<float>> outputData2;
120 outputData1.reserve(outputShapes.size());
121 outputData2.reserve(outputShapes.size());
122
123 for (unsigned int i = 0; i < outputShapes.size(); i++)
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000124 {
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000125 outputData1.emplace_back(outputShapes[i].GetNumElements());
126 outputData2.emplace_back(outputShapes[i].GetNumElements());
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000127
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000128 outputTensors1.emplace_back(
129 i, armnn::Tensor(runtime->GetOutputTensorInfo(networkId1, outputBindingIds[i]), outputData1[i].data()));
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000130
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000131 outputTensors2.emplace_back(
132 i, armnn::Tensor(runtime->GetOutputTensorInfo(networkId2, outputBindingIds[i]), outputData2[i].data()));
133 }
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000134
135 // Run original and deserialized network
136 runtime->EnqueueWorkload(networkId1, inputTensors1, outputTensors1);
137 runtime->EnqueueWorkload(networkId2, inputTensors2, outputTensors2);
138
139 // Compare output data
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000140 for (unsigned int i = 0; i < outputShapes.size(); i++)
141 {
142 BOOST_CHECK_EQUAL_COLLECTIONS(
143 outputData1[i].begin(), outputData1[i].end(), outputData2[i].begin(), outputData2[i].end());
144 }
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000145}
146
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000147} // anonymous namespace
148
149BOOST_AUTO_TEST_SUITE(SerializerTests)
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000150
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000151BOOST_AUTO_TEST_CASE(SerializeAddition)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000152{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000153 class VerifyAdditionName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
154 {
155 public:
156 void VisitAdditionLayer(const armnn::IConnectableLayer*, const char* name) override
157 {
158 BOOST_TEST(name == "addition");
159 }
160 };
161
Mike Kelly8c1701a2019-02-11 17:01:27 +0000162 armnn::INetworkPtr network = armnn::INetwork::Create();
163 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
164 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
165
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000166 armnn::IConnectableLayer* const additionLayer = network->AddAdditionLayer("addition");
167 inputLayer0->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(0));
168 inputLayer1->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(1));
Mike Kelly8c1701a2019-02-11 17:01:27 +0000169
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000170 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
171 additionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
Mike Kelly8c1701a2019-02-11 17:01:27 +0000172
Jim Flynn3091b062019-02-15 14:45:04 +0000173 armnn::TensorShape shape{1U};
174 armnn::TensorInfo info(shape, armnn::DataType::Float32);
175 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
176 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000177 additionLayer->GetOutputSlot(0).SetTensorInfo(info);
Jim Flynn3091b062019-02-15 14:45:04 +0000178
Mike Kelly8c1701a2019-02-11 17:01:27 +0000179 armnnSerializer::Serializer serializer;
180 serializer.Serialize(*network);
181
182 std::stringstream stream;
183 serializer.SaveSerializedToStream(stream);
184 BOOST_TEST(stream.str().length() > 0);
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000185
186 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(stream.str());
187 BOOST_CHECK(deserializedNetwork);
188
189 VerifyAdditionName nameChecker;
190 deserializedNetwork->Accept(nameChecker);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000191}
192
Conor Kennedy76277882019-02-26 08:29:54 +0000193BOOST_AUTO_TEST_CASE(SerializeConstant)
194{
195 armnn::INetworkPtr network = armnn::INetwork::Create();
196
197 armnn::ConstTensor inputTensor;
198
199 armnn::IConnectableLayer* const inputLayer0 = network->AddConstantLayer(inputTensor, "constant");
200 armnn::IConnectableLayer* const outputLayer0 = network->AddOutputLayer(0);
201
202 inputLayer0->GetOutputSlot(0).Connect(outputLayer0->GetInputSlot(0));
203
204 armnnSerializer::Serializer serializer;
205 serializer.Serialize(*network);
206
207 std::stringstream stream;
208 serializer.SaveSerializedToStream(stream);
209 BOOST_TEST(stream.str().length() > 0);
210 BOOST_TEST(stream.str().find("constant") != stream.str().npos);
211}
212
213BOOST_AUTO_TEST_CASE(SerializeDeserializeConstant)
214{
215 class VerifyConstantName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
216 {
217 public:
218 void VisitConstantLayer(const armnn::IConnectableLayer*, const armnn::ConstTensor&, const char* name) override
219 {
220 BOOST_TEST(name == "constant");
221 }
222 };
223
224 armnn::TensorInfo commonTensorInfo({ 2, 3 }, armnn::DataType::Float32);
225
226 std::vector<float> constantData = GenerateRandomData<float>(commonTensorInfo.GetNumElements());
227 armnn::ConstTensor constTensor(commonTensorInfo, constantData);
228
229 // Builds up the structure of the network.
230 armnn::INetworkPtr net(armnn::INetwork::Create());
231
232 armnn::IConnectableLayer* input = net->AddInputLayer(0);
233 armnn::IConnectableLayer* constant = net->AddConstantLayer(constTensor, "constant");
234 armnn::IConnectableLayer* add = net->AddAdditionLayer();
235 armnn::IConnectableLayer* output = net->AddOutputLayer(0);
236
237 input->GetOutputSlot(0).Connect(add->GetInputSlot(0));
238 constant->GetOutputSlot(0).Connect(add->GetInputSlot(1));
239 add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
240
241 // Sets the tensors in the network.
242 input->GetOutputSlot(0).SetTensorInfo(commonTensorInfo);
243 constant->GetOutputSlot(0).SetTensorInfo(commonTensorInfo);
244 add->GetOutputSlot(0).SetTensorInfo(commonTensorInfo);
245
246 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*net));
247 BOOST_CHECK(deserializedNetwork);
248
249 VerifyConstantName nameChecker;
250 deserializedNetwork->Accept(nameChecker);
251
252 CheckDeserializedNetworkAgainstOriginal(*net,
253 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000254 {commonTensorInfo.GetShape()},
255 {commonTensorInfo.GetShape()});
Conor Kennedy76277882019-02-26 08:29:54 +0000256}
257
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000258BOOST_AUTO_TEST_CASE(SerializeFloor)
259{
260 class VerifyFloorName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
261 {
262 public:
263 void VisitMultiplicationLayer(const armnn::IConnectableLayer*, const char* name) override
264 {
265 BOOST_TEST(name == "floor");
266 }
267 };
268
269 const armnn::TensorInfo info({4,4}, armnn::DataType::Float32);
270
271 armnn::INetworkPtr network = armnn::INetwork::Create();
272 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(1);
273
274 const char* floorLayerName = "floor";
275
276 armnn::IConnectableLayer* const floorLayer = network->AddFloorLayer(floorLayerName);
277 inputLayer->GetOutputSlot(0).Connect(floorLayer->GetInputSlot(0));
278
279 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
280 floorLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
281
282 inputLayer->GetOutputSlot(0).SetTensorInfo(info);
283 floorLayer->GetOutputSlot(0).SetTensorInfo(info);
284
285 armnnSerializer::Serializer serializer;
286 serializer.Serialize(*network);
287
288 std::stringstream stream;
289 serializer.SaveSerializedToStream(stream);
290 BOOST_TEST(stream.str().length() > 0);
291 BOOST_TEST(stream.str().find(floorLayerName) != stream.str().npos);
292
293 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(stream.str());
294 BOOST_CHECK(deserializedNetwork);
295
296 VerifyFloorName nameChecker;
297 deserializedNetwork->Accept(nameChecker);
298}
299
Aron Virginas-Tar0fe32452019-02-28 13:12:47 +0000300BOOST_AUTO_TEST_CASE(SerializeMinimum)
301{
302 class VerifyMinimumName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
303 {
304 public:
305 explicit VerifyMinimumName(const std::string& expectedMinimumLayerName)
306 : m_ExpectedMinimumLayerName(expectedMinimumLayerName) {}
307
308 void VisitMinimumLayer(const armnn::IConnectableLayer*, const char* name) override
309 {
310 BOOST_TEST(name == m_ExpectedMinimumLayerName.c_str());
311 }
312
313 private:
314 std::string m_ExpectedMinimumLayerName;
315 };
316
317 const armnn::TensorInfo info({ 1, 2, 2, 3 }, armnn::DataType::Float32);
318
319 armnn::INetworkPtr network = armnn::INetwork::Create();
320 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
321 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
322
323 const std::string minimumLayerName("minimum");
324
325 armnn::IConnectableLayer* const minimumLayer = network->AddMinimumLayer(minimumLayerName.c_str());
326 inputLayer0->GetOutputSlot(0).Connect(minimumLayer->GetInputSlot(0));
327 inputLayer1->GetOutputSlot(0).Connect(minimumLayer->GetInputSlot(1));
328
329 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
330 minimumLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
331
332 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
333 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
334 minimumLayer->GetOutputSlot(0).SetTensorInfo(info);
335
336 armnnSerializer::Serializer serializer;
337 serializer.Serialize(*network);
338
339 std::stringstream stream;
340 serializer.SaveSerializedToStream(stream);
341 BOOST_TEST(stream.str().length() > 0);
342 BOOST_TEST(stream.str().find(minimumLayerName) != stream.str().npos);
343
344 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(stream.str());
345 BOOST_CHECK(deserializedNetwork);
346
347 VerifyMinimumName nameChecker(minimumLayerName);
348 deserializedNetwork->Accept(nameChecker);
349}
350
Aron Virginas-Tar377351e2019-02-27 14:42:31 +0000351BOOST_AUTO_TEST_CASE(SerializeMaximum)
352{
353 class VerifyMaximumName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
354 {
355 public:
356 explicit VerifyMaximumName(const std::string& expectedMaximumLayerName)
357 : m_ExpectedMaximumLayerName(expectedMaximumLayerName) {}
358
359 void VisitMaximumLayer(const armnn::IConnectableLayer*, const char* name) override
360 {
361 BOOST_TEST(name == m_ExpectedMaximumLayerName.c_str());
362 }
363
364 private:
365 std::string m_ExpectedMaximumLayerName;
366 };
367
368 const armnn::TensorInfo info({ 1, 2, 2, 3 }, armnn::DataType::Float32);
369
370 armnn::INetworkPtr network = armnn::INetwork::Create();
371 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
372 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
373
374 const std::string maximumLayerName("maximum");
375
376 armnn::IConnectableLayer* const maximumLayer = network->AddMaximumLayer(maximumLayerName.c_str());
377 inputLayer0->GetOutputSlot(0).Connect(maximumLayer->GetInputSlot(0));
378 inputLayer1->GetOutputSlot(0).Connect(maximumLayer->GetInputSlot(1));
379
380 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
381 maximumLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
382
383 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
384 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
385 maximumLayer->GetOutputSlot(0).SetTensorInfo(info);
386
387 armnnSerializer::Serializer serializer;
388 serializer.Serialize(*network);
389
390 std::stringstream stream;
391 serializer.SaveSerializedToStream(stream);
392 BOOST_TEST(stream.str().length() > 0);
393 BOOST_TEST(stream.str().find(maximumLayerName) != stream.str().npos);
394
395 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(stream.str());
396 BOOST_CHECK(deserializedNetwork);
397
398 VerifyMaximumName nameChecker(maximumLayerName);
399 deserializedNetwork->Accept(nameChecker);
400}
401
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000402BOOST_AUTO_TEST_CASE(SerializeMultiplication)
Sadik Armagan5f450272019-02-12 14:31:45 +0000403{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000404 class VerifyMultiplicationName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
405 {
406 public:
407 void VisitMultiplicationLayer(const armnn::IConnectableLayer*, const char* name) override
408 {
409 BOOST_TEST(name == "multiplication");
410 }
411 };
412
Sadik Armagan5f450272019-02-12 14:31:45 +0000413 const armnn::TensorInfo info({ 1, 5, 2, 3 }, armnn::DataType::Float32);
414
415 armnn::INetworkPtr network = armnn::INetwork::Create();
416 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
417 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
418
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000419 const char* multLayerName = "multiplication";
Sadik Armagan5f450272019-02-12 14:31:45 +0000420
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000421 armnn::IConnectableLayer* const multiplicationLayer = network->AddMultiplicationLayer(multLayerName);
422 inputLayer0->GetOutputSlot(0).Connect(multiplicationLayer->GetInputSlot(0));
423 inputLayer1->GetOutputSlot(0).Connect(multiplicationLayer->GetInputSlot(1));
Sadik Armagan5f450272019-02-12 14:31:45 +0000424
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000425 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
426 multiplicationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
Sadik Armagan5f450272019-02-12 14:31:45 +0000427
Jim Flynn3091b062019-02-15 14:45:04 +0000428 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
429 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000430 multiplicationLayer->GetOutputSlot(0).SetTensorInfo(info);
Jim Flynn3091b062019-02-15 14:45:04 +0000431
Sadik Armagan5f450272019-02-12 14:31:45 +0000432 armnnSerializer::Serializer serializer;
433 serializer.Serialize(*network);
434
435 std::stringstream stream;
436 serializer.SaveSerializedToStream(stream);
437 BOOST_TEST(stream.str().length() > 0);
438 BOOST_TEST(stream.str().find(multLayerName) != stream.str().npos);
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000439
440 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(stream.str());
441 BOOST_CHECK(deserializedNetwork);
442
443 VerifyMultiplicationName nameChecker;
444 deserializedNetwork->Accept(nameChecker);
Sadik Armagan5f450272019-02-12 14:31:45 +0000445}
446
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000447BOOST_AUTO_TEST_CASE(SerializeDeserializeConvolution2d)
Saoirse Stewart263829c2019-02-19 15:54:14 +0000448{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000449
450 class VerifyConvolution2dName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
451 {
452 public:
453 void VisitConvolution2dLayer(const armnn::IConnectableLayer*,
454 const armnn::Convolution2dDescriptor&,
455 const armnn::ConstTensor&,
456 const armnn::Optional<armnn::ConstTensor>&,
457 const char* name) override
458 {
459 BOOST_TEST(name == "convolution");
460 }
461 };
462
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000463 armnn::TensorInfo inputInfo ({ 1, 5, 5, 1 }, armnn::DataType::Float32);
464 armnn::TensorInfo outputInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
Saoirse Stewart263829c2019-02-19 15:54:14 +0000465
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000466 armnn::TensorInfo weightsInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
467 armnn::TensorInfo biasesInfo ({ 1 }, armnn::DataType::Float32);
468
469 // Construct network
470 armnn::INetworkPtr network = armnn::INetwork::Create();
471
472 armnn::Convolution2dDescriptor descriptor;
473 descriptor.m_PadLeft = 1;
474 descriptor.m_PadRight = 1;
475 descriptor.m_PadTop = 1;
476 descriptor.m_PadBottom = 1;
477 descriptor.m_StrideX = 2;
478 descriptor.m_StrideY = 2;
479 descriptor.m_BiasEnabled = true;
480 descriptor.m_DataLayout = armnn::DataLayout::NHWC;
481
482 std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
483 armnn::ConstTensor weights(weightsInfo, weightsData);
484
485 std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
486 armnn::ConstTensor biases(biasesInfo, biasesData);
487
488 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0, "input");
489 armnn::IConnectableLayer* const convLayer =
490 network->AddConvolution2dLayer(descriptor, weights, biases, "convolution");
491 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0, "output");
492
493 inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
494 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
495
496 convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
497 convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
498
499 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
500 BOOST_CHECK(deserializedNetwork);
501
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000502 VerifyConvolution2dName nameChecker;
503 deserializedNetwork->Accept(nameChecker);
504
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000505 CheckDeserializedNetworkAgainstOriginal(*network,
506 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000507 {inputInfo.GetShape()},
508 {outputInfo.GetShape()});
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000509}
510
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000511BOOST_AUTO_TEST_CASE(SerializeDeserializeGreater)
512{
513 class VerifyGreaterName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
514 {
515 public:
516 void VisitGreaterLayer(const armnn::IConnectableLayer*, const char* name) override
517 {
518 BOOST_TEST(name == "greater");
519 }
520 };
521
522 const armnn::TensorInfo inputTensorInfo1({ 1, 2, 2, 2 }, armnn::DataType::Float32);
523 const armnn::TensorInfo inputTensorInfo2({ 1, 2, 2, 2 }, armnn::DataType::Float32);
524 const armnn::TensorInfo outputTensorInfo({ 1, 2, 2, 2 }, armnn::DataType::Boolean);
525
526 armnn::INetworkPtr network = armnn::INetwork::Create();
527 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(0);
528 armnn::IConnectableLayer* const inputLayer2 = network->AddInputLayer(1);
529 armnn::IConnectableLayer* const greaterLayer = network->AddGreaterLayer("greater");
530 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
531
532 inputLayer1->GetOutputSlot(0).Connect(greaterLayer->GetInputSlot(0));
533 inputLayer1->GetOutputSlot(0).SetTensorInfo(inputTensorInfo1);
534 inputLayer2->GetOutputSlot(0).Connect(greaterLayer->GetInputSlot(1));
535 inputLayer2->GetOutputSlot(0).SetTensorInfo(inputTensorInfo2);
536 greaterLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
537 greaterLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
538
539 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
540 BOOST_CHECK(deserializedNetwork);
541
542 VerifyGreaterName nameChecker;
543 deserializedNetwork->Accept(nameChecker);
544
545 CheckDeserializedNetworkAgainstOriginal(*network,
546 *deserializedNetwork,
547 {inputTensorInfo1.GetShape(), inputTensorInfo2.GetShape()},
548 {outputTensorInfo.GetShape()},
549 {0, 1});
550}
551
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000552BOOST_AUTO_TEST_CASE(SerializeDeserializeReshape)
553{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000554 class VerifyReshapeName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
555 {
556 public:
557 void VisitReshapeLayer(const armnn::IConnectableLayer*, const armnn::ReshapeDescriptor&, const char* name)
558 {
559 BOOST_TEST(name == "reshape");
560 }
561 };
562
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000563 unsigned int inputShape[] = { 1, 9 };
564 unsigned int outputShape[] = { 3, 3 };
Saoirse Stewart263829c2019-02-19 15:54:14 +0000565
566 auto inputTensorInfo = armnn::TensorInfo(2, inputShape, armnn::DataType::Float32);
567 auto outputTensorInfo = armnn::TensorInfo(2, outputShape, armnn::DataType::Float32);
568 auto reshapeOutputTensorInfo = armnn::TensorInfo(2, outputShape, armnn::DataType::Float32);
569
570 armnn::ReshapeDescriptor reshapeDescriptor;
571 reshapeDescriptor.m_TargetShape = reshapeOutputTensorInfo.GetShape();
572
573 armnn::INetworkPtr network = armnn::INetwork::Create();
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000574 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
575 armnn::IConnectableLayer* const reshapeLayer = network->AddReshapeLayer(reshapeDescriptor, "reshape");
576 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
Saoirse Stewart263829c2019-02-19 15:54:14 +0000577
578 inputLayer->GetOutputSlot(0).Connect(reshapeLayer->GetInputSlot(0));
579 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
580 reshapeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
581 reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
582
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000583 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
584 BOOST_CHECK(deserializedNetwork);
Saoirse Stewart263829c2019-02-19 15:54:14 +0000585
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000586 VerifyReshapeName nameChecker;
587 deserializedNetwork->Accept(nameChecker);
588
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000589 CheckDeserializedNetworkAgainstOriginal(*network,
590 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000591 {inputTensorInfo.GetShape()},
592 {outputTensorInfo.GetShape()});
Saoirse Stewart263829c2019-02-19 15:54:14 +0000593}
594
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000595BOOST_AUTO_TEST_CASE(SerializeDeserializeDepthwiseConvolution2d)
596{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000597 class VerifyDepthwiseConvolution2dName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
598 {
599 public:
600 void VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer*,
601 const armnn::DepthwiseConvolution2dDescriptor&,
602 const armnn::ConstTensor&,
603 const armnn::Optional<armnn::ConstTensor>&,
604 const char* name) override
605 {
606 BOOST_TEST(name == "depthwise_convolution");
607 }
608 };
609
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000610 armnn::TensorInfo inputInfo ({ 1, 5, 5, 3 }, armnn::DataType::Float32);
611 armnn::TensorInfo outputInfo({ 1, 3, 3, 3 }, armnn::DataType::Float32);
612
613 armnn::TensorInfo weightsInfo({ 1, 3, 3, 3 }, armnn::DataType::Float32);
614 armnn::TensorInfo biasesInfo ({ 3 }, armnn::DataType::Float32);
615
616 armnn::DepthwiseConvolution2dDescriptor descriptor;
617 descriptor.m_StrideX = 1;
618 descriptor.m_StrideY = 1;
619 descriptor.m_BiasEnabled = true;
620 descriptor.m_DataLayout = armnn::DataLayout::NHWC;
621
622 std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
623 armnn::ConstTensor weights(weightsInfo, weightsData);
624
625 std::vector<int32_t> biasesData = GenerateRandomData<int32_t>(biasesInfo.GetNumElements());
626 armnn::ConstTensor biases(biasesInfo, biasesData);
627
628 armnn::INetworkPtr network = armnn::INetwork::Create();
629 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
630 armnn::IConnectableLayer* const depthwiseConvLayer =
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000631 network->AddDepthwiseConvolution2dLayer(descriptor, weights, biases, "depthwise_convolution");
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000632 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
633
634 inputLayer->GetOutputSlot(0).Connect(depthwiseConvLayer->GetInputSlot(0));
635 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
636 depthwiseConvLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
637 depthwiseConvLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
638
639 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
640 BOOST_CHECK(deserializedNetwork);
641
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000642 VerifyDepthwiseConvolution2dName nameChecker;
643 deserializedNetwork->Accept(nameChecker);
644
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000645 CheckDeserializedNetworkAgainstOriginal(*network,
646 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000647 {inputInfo.GetShape()},
648 {outputInfo.GetShape()});
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000649}
650
651BOOST_AUTO_TEST_CASE(SerializeDeserializeSoftmax)
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000652{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000653 class VerifySoftmaxName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
654 {
655 public:
656 void VisitSoftmaxLayer(const armnn::IConnectableLayer*, const armnn::SoftmaxDescriptor&, const char* name)
657 {
658 BOOST_TEST(name == "softmax");
659 }
660 };
661
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000662 armnn::TensorInfo tensorInfo({1, 10}, armnn::DataType::Float32);
663
664 armnn::SoftmaxDescriptor descriptor;
665 descriptor.m_Beta = 1.0f;
666
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000667 armnn::INetworkPtr network = armnn::INetwork::Create();
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000668 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
669 armnn::IConnectableLayer* const softmaxLayer = network->AddSoftmaxLayer(descriptor, "softmax");
670 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000671
672 inputLayer->GetOutputSlot(0).Connect(softmaxLayer->GetInputSlot(0));
673 inputLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
674 softmaxLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
675 softmaxLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
676
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000677 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000678 BOOST_CHECK(deserializedNetwork);
679
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000680 VerifySoftmaxName nameChecker;
681 deserializedNetwork->Accept(nameChecker);
682
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000683 CheckDeserializedNetworkAgainstOriginal(*network,
684 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000685 {tensorInfo.GetShape()},
686 {tensorInfo.GetShape()});
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000687}
688
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000689BOOST_AUTO_TEST_CASE(SerializeDeserializePooling2d)
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000690{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000691 class VerifyPooling2dName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
692 {
693 void VisitPooling2dLayer(const armnn::IConnectableLayer*, const armnn::Pooling2dDescriptor&, const char* name)
694 {
695 BOOST_TEST(name == "pooling2d");
696 }
697 };
698
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000699 unsigned int inputShape[] = {1, 2, 2, 1};
700 unsigned int outputShape[] = {1, 1, 1, 1};
701
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000702 auto inputInfo = armnn::TensorInfo(4, inputShape, armnn::DataType::Float32);
703 auto outputInfo = armnn::TensorInfo(4, outputShape, armnn::DataType::Float32);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000704
705 armnn::Pooling2dDescriptor desc;
706 desc.m_DataLayout = armnn::DataLayout::NHWC;
707 desc.m_PadTop = 0;
708 desc.m_PadBottom = 0;
709 desc.m_PadLeft = 0;
710 desc.m_PadRight = 0;
711 desc.m_PoolType = armnn::PoolingAlgorithm::Average;
712 desc.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
713 desc.m_PaddingMethod = armnn::PaddingMethod::Exclude;
714 desc.m_PoolHeight = 2;
715 desc.m_PoolWidth = 2;
716 desc.m_StrideX = 2;
717 desc.m_StrideY = 2;
718
719 armnn::INetworkPtr network = armnn::INetwork::Create();
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000720 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
721 armnn::IConnectableLayer* const pooling2dLayer = network->AddPooling2dLayer(desc, "pooling2d");
722 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000723
724 inputLayer->GetOutputSlot(0).Connect(pooling2dLayer->GetInputSlot(0));
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000725 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000726 pooling2dLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000727 pooling2dLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000728
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000729 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
730 BOOST_CHECK(deserializedNetwork);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000731
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000732 VerifyPooling2dName nameChecker;
733 deserializedNetwork->Accept(nameChecker);
734
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000735 CheckDeserializedNetworkAgainstOriginal(*network,
736 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000737 {inputInfo.GetShape()},
738 {outputInfo.GetShape()});
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000739}
740
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000741BOOST_AUTO_TEST_CASE(SerializeDeserializePermute)
742{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000743 class VerifyPermuteName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
744 {
745 public:
746 void VisitPermuteLayer(const armnn::IConnectableLayer*, const armnn::PermuteDescriptor&, const char* name)
747 {
748 BOOST_TEST(name == "permute");
749 }
750 };
751
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000752 unsigned int inputShape[] = { 4, 3, 2, 1 };
753 unsigned int outputShape[] = { 1, 2, 3, 4 };
754 unsigned int dimsMapping[] = { 3, 2, 1, 0 };
755
756 auto inputTensorInfo = armnn::TensorInfo(4, inputShape, armnn::DataType::Float32);
757 auto outputTensorInfo = armnn::TensorInfo(4, outputShape, armnn::DataType::Float32);
758
759 armnn::PermuteDescriptor permuteDescriptor(armnn::PermutationVector(dimsMapping, 4));
760
761 armnn::INetworkPtr network = armnn::INetwork::Create();
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000762 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
763 armnn::IConnectableLayer* const permuteLayer = network->AddPermuteLayer(permuteDescriptor, "permute");
764 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000765
766 inputLayer->GetOutputSlot(0).Connect(permuteLayer->GetInputSlot(0));
767 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
768 permuteLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
769 permuteLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
770
771 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
772 BOOST_CHECK(deserializedNetwork);
773
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000774 VerifyPermuteName nameChecker;
775 deserializedNetwork->Accept(nameChecker);
776
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000777 CheckDeserializedNetworkAgainstOriginal(*network,
778 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000779 {inputTensorInfo.GetShape()},
780 {outputTensorInfo.GetShape()});
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000781}
782
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000783BOOST_AUTO_TEST_CASE(SerializeDeserializeFullyConnected)
784{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000785 class VerifyFullyConnectedName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
786 {
787 public:
788 void VisitFullyConnectedLayer(const armnn::IConnectableLayer*,
789 const armnn::FullyConnectedDescriptor&,
790 const armnn::ConstTensor&,
791 const armnn::Optional<armnn::ConstTensor>&,
792 const char* name) override
793 {
794 BOOST_TEST(name == "fully_connected");
795 }
796 };
797
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000798 armnn::TensorInfo inputInfo ({ 2, 5, 1, 1 }, armnn::DataType::Float32);
799 armnn::TensorInfo outputInfo({ 2, 3 }, armnn::DataType::Float32);
800
801 armnn::TensorInfo weightsInfo({ 5, 3 }, armnn::DataType::Float32);
802 armnn::TensorInfo biasesInfo ({ 3 }, armnn::DataType::Float32);
803
804 armnn::FullyConnectedDescriptor descriptor;
805 descriptor.m_BiasEnabled = true;
806 descriptor.m_TransposeWeightMatrix = false;
807
808 std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
809 std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
810
811 armnn::ConstTensor weights(weightsInfo, weightsData);
812 armnn::ConstTensor biases(biasesInfo, biasesData);
813
814 armnn::INetworkPtr network = armnn::INetwork::Create();
815 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0, "input");
816 armnn::IConnectableLayer* const fullyConnectedLayer = network->AddFullyConnectedLayer(descriptor,
817 weights,
818 biases,
819 "fully_connected");
820 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0, "output");
821
822 inputLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(0));
823 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
824
825 fullyConnectedLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
826 fullyConnectedLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
827
828 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
829 BOOST_CHECK(deserializedNetwork);
830
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000831 VerifyFullyConnectedName nameChecker;
832 deserializedNetwork->Accept(nameChecker);
833
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000834 CheckDeserializedNetworkAgainstOriginal(*network,
835 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000836 {inputInfo.GetShape()},
837 {outputInfo.GetShape()});
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000838}
839
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000840BOOST_AUTO_TEST_CASE(SerializeDeserializeSpaceToBatchNd)
841{
842 class VerifySpaceToBatchNdName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
843 {
844 public:
845 void VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer*,
846 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
847 const char* name) override
848 {
849 BOOST_TEST(name == "SpaceToBatchNdLayer");
850 }
851 };
852
853 unsigned int inputShape[] = {2, 1, 2, 4};
854 unsigned int outputShape[] = {8, 1, 1, 3};
855
856 armnn::SpaceToBatchNdDescriptor desc;
857 desc.m_DataLayout = armnn::DataLayout::NCHW;
858 desc.m_BlockShape = {2, 2};
859 desc.m_PadList = {{0, 0}, {2, 0}};
860
861 auto inputTensorInfo = armnn::TensorInfo(4, inputShape, armnn::DataType::Float32);
862 auto outputTensorInfo = armnn::TensorInfo(4, outputShape, armnn::DataType::Float32);
863
864 armnn::INetworkPtr network = armnn::INetwork::Create();
865 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
866 armnn::IConnectableLayer* const spaceToBatchNdLayer = network->AddSpaceToBatchNdLayer(desc, "SpaceToBatchNdLayer");
867 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
868
869 inputLayer->GetOutputSlot(0).Connect(spaceToBatchNdLayer->GetInputSlot(0));
870 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
871 spaceToBatchNdLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
872 spaceToBatchNdLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
873
874 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
875 BOOST_CHECK(deserializedNetwork);
876
877 VerifySpaceToBatchNdName nameChecker;
878 deserializedNetwork->Accept(nameChecker);
879
880 CheckDeserializedNetworkAgainstOriginal(*network,
881 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000882 {inputTensorInfo.GetShape()},
883 {outputTensorInfo.GetShape()});
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000884}
885
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000886BOOST_AUTO_TEST_CASE(SerializeDeserializeBatchToSpaceNd)
887{
888 class VerifyBatchToSpaceNdName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
889 {
890 public:
891 void VisitBatchToSpaceNdLayer(const armnn::IConnectableLayer*,
892 const armnn::BatchToSpaceNdDescriptor& descriptor,
893 const char* name) override
894 {
895 BOOST_TEST(name == "BatchToSpaceNdLayer");
896 }
897 };
898
899 unsigned int inputShape[] = {4, 1, 2, 2};
900 unsigned int outputShape[] = {1, 1, 4, 4};
901
902 armnn::BatchToSpaceNdDescriptor desc;
903 desc.m_DataLayout = armnn::DataLayout::NCHW;
904 desc.m_BlockShape = {2, 2};
905 desc.m_Crops = {{0, 0}, {0, 0}};
906
907 auto inputTensorInfo = armnn::TensorInfo(4, inputShape, armnn::DataType::Float32);
908 auto outputTensorInfo = armnn::TensorInfo(4, outputShape, armnn::DataType::Float32);
909
910 armnn::INetworkPtr network = armnn::INetwork::Create();
911 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
912 armnn::IConnectableLayer* const batchToSpaceNdLayer = network->AddBatchToSpaceNdLayer(desc, "BatchToSpaceNdLayer");
913 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
914
915 inputLayer->GetOutputSlot(0).Connect(batchToSpaceNdLayer->GetInputSlot(0));
916 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
917 batchToSpaceNdLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
918 batchToSpaceNdLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
919
920 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
921 BOOST_CHECK(deserializedNetwork);
922
923 VerifyBatchToSpaceNdName nameChecker;
924 deserializedNetwork->Accept(nameChecker);
925
926 CheckDeserializedNetworkAgainstOriginal(*network,
927 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000928 {inputTensorInfo.GetShape()},
929 {outputTensorInfo.GetShape()});
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000930}
931
ruoyan018e7fa232019-02-28 15:09:07 +0000932BOOST_AUTO_TEST_CASE(SerializeDeserializeBatchNormalization)
933{
934 class VerifyBatchNormalizationName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
935 {
936 public:
937 void VisitBatchNormalizationLayer(const armnn::IConnectableLayer*,
938 const armnn::BatchNormalizationDescriptor&,
939 const armnn::ConstTensor&,
940 const armnn::ConstTensor&,
941 const armnn::ConstTensor&,
942 const armnn::ConstTensor&,
943 const char* name) override
944 {
945 BOOST_TEST(name == "BatchNormalization:1");
946 }
947 };
948
949 armnn::TensorInfo inputInfo ({ 1, 3, 3, 1 }, armnn::DataType::Float32);
950 armnn::TensorInfo outputInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
951
952 armnn::TensorInfo meanInfo({1}, armnn::DataType::Float32);
953 armnn::TensorInfo varianceInfo({1}, armnn::DataType::Float32);
954 armnn::TensorInfo scaleInfo({1}, armnn::DataType::Float32);
955 armnn::TensorInfo offsetInfo({1}, armnn::DataType::Float32);
956
957 armnn::BatchNormalizationDescriptor descriptor;
958 descriptor.m_Eps = 0.0010000000475f;
959 descriptor.m_DataLayout = armnn::DataLayout::NHWC;
960
961 std::vector<float> meanData({5.0});
962 std::vector<float> varianceData({2.0});
963 std::vector<float> scaleData({1.0});
964 std::vector<float> offsetData({0.0});
965
966 armnn::ConstTensor mean(meanInfo, meanData);
967 armnn::ConstTensor variance(varianceInfo, varianceData);
968 armnn::ConstTensor scale(scaleInfo, scaleData);
969 armnn::ConstTensor offset(offsetInfo, offsetData);
970
971 armnn::INetworkPtr network = armnn::INetwork::Create();
972 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
973 armnn::IConnectableLayer* const batchNormalizationLayer = network->AddBatchNormalizationLayer(
974 descriptor,
975 mean,
976 variance,
977 scale,
978 offset,
979 "BatchNormalizationLayer");
980 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
981
982 inputLayer->GetOutputSlot(0).Connect(batchNormalizationLayer->GetInputSlot(0));
983 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
984
985 batchNormalizationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
986 batchNormalizationLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
987
988 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
989 BOOST_CHECK(deserializedNetwork);
990
991 VerifyBatchNormalizationName nameChecker;
992 deserializedNetwork->Accept(nameChecker);
993
994 CheckDeserializedNetworkAgainstOriginal(*network,
995 *deserializedNetwork,
996 {inputInfo.GetShape()},
997 {outputInfo.GetShape()});
998}
999
Éanna Ó Catháin58885892019-02-27 16:16:39 +00001000BOOST_AUTO_TEST_CASE(SerializeDivision)
1001{
1002 class VerifyDivisionName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
1003 {
1004 public:
1005 void VisitDivisionLayer(const armnn::IConnectableLayer*, const char* name) override
1006 {
1007 BOOST_TEST(name == "division");
1008 }
1009 };
1010
1011 const armnn::TensorInfo info({ 1, 5, 2, 3 }, armnn::DataType::Float32);
1012
1013 armnn::INetworkPtr network = armnn::INetwork::Create();
1014 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1015 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
1016
1017 const char* divLayerName = "division";
1018
1019 armnn::IConnectableLayer* const divisionLayer = network->AddDivisionLayer(divLayerName);
1020 inputLayer0->GetOutputSlot(0).Connect(divisionLayer->GetInputSlot(0));
1021 inputLayer1->GetOutputSlot(0).Connect(divisionLayer->GetInputSlot(1));
1022
1023 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1024 divisionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1025
1026 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1027 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
1028 divisionLayer->GetOutputSlot(0).SetTensorInfo(info);
1029
1030 armnnSerializer::Serializer serializer;
1031 serializer.Serialize(*network);
1032
1033 std::stringstream stream;
1034 serializer.SaveSerializedToStream(stream);
1035 BOOST_TEST(stream.str().length() > 0);
1036 BOOST_TEST(stream.str().find(divLayerName) != stream.str().npos);
1037
1038 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(stream.str());
1039 BOOST_CHECK(deserializedNetwork);
1040
1041 VerifyDivisionName nameChecker;
1042 deserializedNetwork->Accept(nameChecker);
1043}
1044
Nina Drozd57728782019-02-27 10:53:27 +00001045BOOST_AUTO_TEST_CASE(SerializeDeserializeNormalization)
1046{
1047 class VerifyNormalizationName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
1048 {
1049 public:
1050 void VisitNormalizationLayer(const armnn::IConnectableLayer*,
1051 const armnn::NormalizationDescriptor& normalizationDescriptor,
1052 const char* name) override
1053 {
1054 BOOST_TEST(name == "NormalizationLayer");
1055 }
1056 };
1057
1058 unsigned int inputShape[] = {2, 1, 2, 2};
1059 unsigned int outputShape[] = {2, 1, 2, 2};
1060
1061 armnn::NormalizationDescriptor desc;
1062 desc.m_DataLayout = armnn::DataLayout::NCHW;
1063 desc.m_NormSize = 3;
1064 desc.m_Alpha = 1;
1065 desc.m_Beta = 1;
1066 desc.m_K = 1;
1067
1068 auto inputTensorInfo = armnn::TensorInfo(4, inputShape, armnn::DataType::Float32);
1069 auto outputTensorInfo = armnn::TensorInfo(4, outputShape, armnn::DataType::Float32);
1070
1071 armnn::INetworkPtr network = armnn::INetwork::Create();
1072 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1073 armnn::IConnectableLayer* const normalizationLayer = network->AddNormalizationLayer(desc, "NormalizationLayer");
1074 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1075
1076 inputLayer->GetOutputSlot(0).Connect(normalizationLayer->GetInputSlot(0));
1077 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
1078 normalizationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1079 normalizationLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1080
1081 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1082 BOOST_CHECK(deserializedNetwork);
1083
1084 VerifyNormalizationName nameChecker;
1085 deserializedNetwork->Accept(nameChecker);
1086
1087 CheckDeserializedNetworkAgainstOriginal(*network,
1088 *deserializedNetwork,
1089 {inputTensorInfo.GetShape()},
1090 {outputTensorInfo.GetShape()});
1091}
1092
Nattapat Chaimanowong235cea52019-02-28 16:27:30 +00001093BOOST_AUTO_TEST_CASE(SerializeDeserializeEqual)
1094{
1095 class VerifyEqualName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
1096 {
1097 public:
1098 void VisitEqualLayer(const armnn::IConnectableLayer*,
1099 const char* name) override
1100 {
1101 BOOST_TEST(name == "EqualLayer");
1102 }
1103 };
1104
1105 const armnn::TensorInfo inputTensorInfo1 = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Float32);
1106 const armnn::TensorInfo inputTensorInfo2 = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Float32);
1107 const armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Boolean);
1108
1109 armnn::INetworkPtr network = armnn::INetwork::Create();
1110 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(0);
1111 armnn::IConnectableLayer* const inputLayer2 = network->AddInputLayer(1);
1112 armnn::IConnectableLayer* const equalLayer = network->AddEqualLayer("EqualLayer");
1113 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1114
1115 inputLayer1->GetOutputSlot(0).Connect(equalLayer->GetInputSlot(0));
1116 inputLayer1->GetOutputSlot(0).SetTensorInfo(inputTensorInfo1);
1117 inputLayer2->GetOutputSlot(0).Connect(equalLayer->GetInputSlot(1));
1118 inputLayer2->GetOutputSlot(0).SetTensorInfo(inputTensorInfo2);
1119 equalLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1120 equalLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1121
1122 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1123 BOOST_CHECK(deserializedNetwork);
1124
1125 VerifyEqualName nameChecker;
1126 deserializedNetwork->Accept(nameChecker);
1127
1128 CheckDeserializedNetworkAgainstOriginal(*network,
1129 *deserializedNetwork,
1130 {inputTensorInfo1.GetShape(), inputTensorInfo2.GetShape()},
1131 {outputTensorInfo.GetShape()},
1132 {0, 1});
1133}
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +00001134
1135BOOST_AUTO_TEST_CASE(SerializeDeserializePad)
1136{
1137 class VerifyPadName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
1138 {
1139 public:
1140 void VisitPadLayer(const armnn::IConnectableLayer*,
1141 const armnn::PadDescriptor& descriptor,
1142 const char* name) override
1143 {
1144 BOOST_TEST(name == "PadLayer");
1145 }
1146 };
1147
1148 armnn::PadDescriptor desc({{0, 0}, {1, 0}, {1, 1}, {1, 2}});
1149
1150 const armnn::TensorInfo inputTensorInfo = armnn::TensorInfo({1, 2, 3, 4}, armnn::DataType::Float32);
1151 const armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({1, 3, 5, 7}, armnn::DataType::Float32);
1152
1153 armnn::INetworkPtr network = armnn::INetwork::Create();
1154 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1155 armnn::IConnectableLayer* const padLayer = network->AddPadLayer(desc, "PadLayer");
1156 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1157
1158 inputLayer->GetOutputSlot(0).Connect(padLayer->GetInputSlot(0));
1159 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
1160 padLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1161 padLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1162
1163 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1164 BOOST_CHECK(deserializedNetwork);
1165
1166 VerifyPadName nameChecker;
1167 deserializedNetwork->Accept(nameChecker);
1168
1169 CheckDeserializedNetworkAgainstOriginal(*network,
1170 *deserializedNetwork,
1171 {inputTensorInfo.GetShape()},
1172 {outputTensorInfo.GetShape()});
1173}
1174
Sadik Armagan8b42a382019-03-01 14:24:49 +00001175BOOST_AUTO_TEST_CASE(SerializeRsqrt)
1176{
1177 class VerifyRsqrtName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
1178 {
1179 public:
1180 void VisitRsqrtLayer(const armnn::IConnectableLayer*, const char* name) override
1181 {
1182 BOOST_TEST(name == "rsqrt");
1183 }
1184 };
1185
1186 const armnn::TensorInfo tensorInfo({ 3, 1, 2 }, armnn::DataType::Float32);
1187
1188 armnn::INetworkPtr network = armnn::INetwork::Create();
1189 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1190 armnn::IConnectableLayer* const rsqrtLayer = network->AddRsqrtLayer("rsqrt");
1191 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1192
1193 inputLayer->GetOutputSlot(0).Connect(rsqrtLayer->GetInputSlot(0));
1194 rsqrtLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1195
1196 inputLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1197 rsqrtLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1198
1199 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1200 BOOST_CHECK(deserializedNetwork);
1201
1202 VerifyRsqrtName nameChecker;
1203 deserializedNetwork->Accept(nameChecker);
1204
1205 CheckDeserializedNetworkAgainstOriginal(*network,
1206 *deserializedNetwork,
1207 {tensorInfo.GetShape()},
1208 {tensorInfo.GetShape()});
1209}
1210
Nattapat Chaimanowong6522cdc2019-03-01 16:14:13 +00001211BOOST_AUTO_TEST_CASE(SerializeDeserializeResizeBilinear)
1212{
1213 class VerifyResizeBilinearName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
1214 {
1215 public:
1216 void VisitResizeBilinearLayer(const armnn::IConnectableLayer*,
1217 const armnn::ResizeBilinearDescriptor& descriptor,
1218 const char* name) override
1219 {
1220 BOOST_TEST(name == "ResizeBilinearLayer");
1221 }
1222 };
1223
1224 armnn::ResizeBilinearDescriptor desc;
1225 desc.m_TargetWidth = 4;
1226 desc.m_TargetHeight = 2;
1227
1228 const armnn::TensorInfo inputTensorInfo = armnn::TensorInfo({1, 3, 5, 5}, armnn::DataType::Float32);
1229 const armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({1, 3, 2, 4}, armnn::DataType::Float32);
1230
1231 armnn::INetworkPtr network = armnn::INetwork::Create();
1232 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1233 armnn::IConnectableLayer* const resizeLayer = network->AddResizeBilinearLayer(desc, "ResizeBilinearLayer");
1234 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1235
1236 inputLayer->GetOutputSlot(0).Connect(resizeLayer->GetInputSlot(0));
1237 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
1238 resizeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1239 resizeLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1240
1241 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1242 BOOST_CHECK(deserializedNetwork);
1243
1244 VerifyResizeBilinearName nameChecker;
1245 deserializedNetwork->Accept(nameChecker);
1246
1247 CheckDeserializedNetworkAgainstOriginal(*network,
1248 *deserializedNetwork,
1249 {inputTensorInfo.GetShape()},
1250 {outputTensorInfo.GetShape()});
1251}
1252
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +00001253BOOST_AUTO_TEST_SUITE_END()