blob: 5f1745bda52279f95b3483bb9b174296721405da [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
511BOOST_AUTO_TEST_CASE(SerializeDeserializeReshape)
512{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000513 class VerifyReshapeName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
514 {
515 public:
516 void VisitReshapeLayer(const armnn::IConnectableLayer*, const armnn::ReshapeDescriptor&, const char* name)
517 {
518 BOOST_TEST(name == "reshape");
519 }
520 };
521
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000522 unsigned int inputShape[] = { 1, 9 };
523 unsigned int outputShape[] = { 3, 3 };
Saoirse Stewart263829c2019-02-19 15:54:14 +0000524
525 auto inputTensorInfo = armnn::TensorInfo(2, inputShape, armnn::DataType::Float32);
526 auto outputTensorInfo = armnn::TensorInfo(2, outputShape, armnn::DataType::Float32);
527 auto reshapeOutputTensorInfo = armnn::TensorInfo(2, outputShape, armnn::DataType::Float32);
528
529 armnn::ReshapeDescriptor reshapeDescriptor;
530 reshapeDescriptor.m_TargetShape = reshapeOutputTensorInfo.GetShape();
531
532 armnn::INetworkPtr network = armnn::INetwork::Create();
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000533 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
534 armnn::IConnectableLayer* const reshapeLayer = network->AddReshapeLayer(reshapeDescriptor, "reshape");
535 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
Saoirse Stewart263829c2019-02-19 15:54:14 +0000536
537 inputLayer->GetOutputSlot(0).Connect(reshapeLayer->GetInputSlot(0));
538 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
539 reshapeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
540 reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
541
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000542 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
543 BOOST_CHECK(deserializedNetwork);
Saoirse Stewart263829c2019-02-19 15:54:14 +0000544
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000545 VerifyReshapeName nameChecker;
546 deserializedNetwork->Accept(nameChecker);
547
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000548 CheckDeserializedNetworkAgainstOriginal(*network,
549 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000550 {inputTensorInfo.GetShape()},
551 {outputTensorInfo.GetShape()});
Saoirse Stewart263829c2019-02-19 15:54:14 +0000552}
553
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000554BOOST_AUTO_TEST_CASE(SerializeDeserializeDepthwiseConvolution2d)
555{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000556 class VerifyDepthwiseConvolution2dName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
557 {
558 public:
559 void VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer*,
560 const armnn::DepthwiseConvolution2dDescriptor&,
561 const armnn::ConstTensor&,
562 const armnn::Optional<armnn::ConstTensor>&,
563 const char* name) override
564 {
565 BOOST_TEST(name == "depthwise_convolution");
566 }
567 };
568
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000569 armnn::TensorInfo inputInfo ({ 1, 5, 5, 3 }, armnn::DataType::Float32);
570 armnn::TensorInfo outputInfo({ 1, 3, 3, 3 }, armnn::DataType::Float32);
571
572 armnn::TensorInfo weightsInfo({ 1, 3, 3, 3 }, armnn::DataType::Float32);
573 armnn::TensorInfo biasesInfo ({ 3 }, armnn::DataType::Float32);
574
575 armnn::DepthwiseConvolution2dDescriptor descriptor;
576 descriptor.m_StrideX = 1;
577 descriptor.m_StrideY = 1;
578 descriptor.m_BiasEnabled = true;
579 descriptor.m_DataLayout = armnn::DataLayout::NHWC;
580
581 std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
582 armnn::ConstTensor weights(weightsInfo, weightsData);
583
584 std::vector<int32_t> biasesData = GenerateRandomData<int32_t>(biasesInfo.GetNumElements());
585 armnn::ConstTensor biases(biasesInfo, biasesData);
586
587 armnn::INetworkPtr network = armnn::INetwork::Create();
588 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
589 armnn::IConnectableLayer* const depthwiseConvLayer =
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000590 network->AddDepthwiseConvolution2dLayer(descriptor, weights, biases, "depthwise_convolution");
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000591 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
592
593 inputLayer->GetOutputSlot(0).Connect(depthwiseConvLayer->GetInputSlot(0));
594 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
595 depthwiseConvLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
596 depthwiseConvLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
597
598 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
599 BOOST_CHECK(deserializedNetwork);
600
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000601 VerifyDepthwiseConvolution2dName nameChecker;
602 deserializedNetwork->Accept(nameChecker);
603
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000604 CheckDeserializedNetworkAgainstOriginal(*network,
605 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000606 {inputInfo.GetShape()},
607 {outputInfo.GetShape()});
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000608}
609
610BOOST_AUTO_TEST_CASE(SerializeDeserializeSoftmax)
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000611{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000612 class VerifySoftmaxName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
613 {
614 public:
615 void VisitSoftmaxLayer(const armnn::IConnectableLayer*, const armnn::SoftmaxDescriptor&, const char* name)
616 {
617 BOOST_TEST(name == "softmax");
618 }
619 };
620
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000621 armnn::TensorInfo tensorInfo({1, 10}, armnn::DataType::Float32);
622
623 armnn::SoftmaxDescriptor descriptor;
624 descriptor.m_Beta = 1.0f;
625
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000626 armnn::INetworkPtr network = armnn::INetwork::Create();
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000627 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
628 armnn::IConnectableLayer* const softmaxLayer = network->AddSoftmaxLayer(descriptor, "softmax");
629 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000630
631 inputLayer->GetOutputSlot(0).Connect(softmaxLayer->GetInputSlot(0));
632 inputLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
633 softmaxLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
634 softmaxLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
635
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000636 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000637 BOOST_CHECK(deserializedNetwork);
638
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000639 VerifySoftmaxName nameChecker;
640 deserializedNetwork->Accept(nameChecker);
641
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000642 CheckDeserializedNetworkAgainstOriginal(*network,
643 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000644 {tensorInfo.GetShape()},
645 {tensorInfo.GetShape()});
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000646}
647
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000648BOOST_AUTO_TEST_CASE(SerializeDeserializePooling2d)
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000649{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000650 class VerifyPooling2dName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
651 {
652 void VisitPooling2dLayer(const armnn::IConnectableLayer*, const armnn::Pooling2dDescriptor&, const char* name)
653 {
654 BOOST_TEST(name == "pooling2d");
655 }
656 };
657
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000658 unsigned int inputShape[] = {1, 2, 2, 1};
659 unsigned int outputShape[] = {1, 1, 1, 1};
660
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000661 auto inputInfo = armnn::TensorInfo(4, inputShape, armnn::DataType::Float32);
662 auto outputInfo = armnn::TensorInfo(4, outputShape, armnn::DataType::Float32);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000663
664 armnn::Pooling2dDescriptor desc;
665 desc.m_DataLayout = armnn::DataLayout::NHWC;
666 desc.m_PadTop = 0;
667 desc.m_PadBottom = 0;
668 desc.m_PadLeft = 0;
669 desc.m_PadRight = 0;
670 desc.m_PoolType = armnn::PoolingAlgorithm::Average;
671 desc.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
672 desc.m_PaddingMethod = armnn::PaddingMethod::Exclude;
673 desc.m_PoolHeight = 2;
674 desc.m_PoolWidth = 2;
675 desc.m_StrideX = 2;
676 desc.m_StrideY = 2;
677
678 armnn::INetworkPtr network = armnn::INetwork::Create();
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000679 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
680 armnn::IConnectableLayer* const pooling2dLayer = network->AddPooling2dLayer(desc, "pooling2d");
681 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000682
683 inputLayer->GetOutputSlot(0).Connect(pooling2dLayer->GetInputSlot(0));
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000684 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000685 pooling2dLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000686 pooling2dLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000687
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000688 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
689 BOOST_CHECK(deserializedNetwork);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000690
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000691 VerifyPooling2dName nameChecker;
692 deserializedNetwork->Accept(nameChecker);
693
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000694 CheckDeserializedNetworkAgainstOriginal(*network,
695 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000696 {inputInfo.GetShape()},
697 {outputInfo.GetShape()});
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000698}
699
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000700BOOST_AUTO_TEST_CASE(SerializeDeserializePermute)
701{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000702 class VerifyPermuteName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
703 {
704 public:
705 void VisitPermuteLayer(const armnn::IConnectableLayer*, const armnn::PermuteDescriptor&, const char* name)
706 {
707 BOOST_TEST(name == "permute");
708 }
709 };
710
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000711 unsigned int inputShape[] = { 4, 3, 2, 1 };
712 unsigned int outputShape[] = { 1, 2, 3, 4 };
713 unsigned int dimsMapping[] = { 3, 2, 1, 0 };
714
715 auto inputTensorInfo = armnn::TensorInfo(4, inputShape, armnn::DataType::Float32);
716 auto outputTensorInfo = armnn::TensorInfo(4, outputShape, armnn::DataType::Float32);
717
718 armnn::PermuteDescriptor permuteDescriptor(armnn::PermutationVector(dimsMapping, 4));
719
720 armnn::INetworkPtr network = armnn::INetwork::Create();
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000721 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
722 armnn::IConnectableLayer* const permuteLayer = network->AddPermuteLayer(permuteDescriptor, "permute");
723 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000724
725 inputLayer->GetOutputSlot(0).Connect(permuteLayer->GetInputSlot(0));
726 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
727 permuteLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
728 permuteLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
729
730 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
731 BOOST_CHECK(deserializedNetwork);
732
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000733 VerifyPermuteName nameChecker;
734 deserializedNetwork->Accept(nameChecker);
735
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000736 CheckDeserializedNetworkAgainstOriginal(*network,
737 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000738 {inputTensorInfo.GetShape()},
739 {outputTensorInfo.GetShape()});
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +0000740}
741
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000742BOOST_AUTO_TEST_CASE(SerializeDeserializeFullyConnected)
743{
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000744 class VerifyFullyConnectedName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
745 {
746 public:
747 void VisitFullyConnectedLayer(const armnn::IConnectableLayer*,
748 const armnn::FullyConnectedDescriptor&,
749 const armnn::ConstTensor&,
750 const armnn::Optional<armnn::ConstTensor>&,
751 const char* name) override
752 {
753 BOOST_TEST(name == "fully_connected");
754 }
755 };
756
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000757 armnn::TensorInfo inputInfo ({ 2, 5, 1, 1 }, armnn::DataType::Float32);
758 armnn::TensorInfo outputInfo({ 2, 3 }, armnn::DataType::Float32);
759
760 armnn::TensorInfo weightsInfo({ 5, 3 }, armnn::DataType::Float32);
761 armnn::TensorInfo biasesInfo ({ 3 }, armnn::DataType::Float32);
762
763 armnn::FullyConnectedDescriptor descriptor;
764 descriptor.m_BiasEnabled = true;
765 descriptor.m_TransposeWeightMatrix = false;
766
767 std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
768 std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
769
770 armnn::ConstTensor weights(weightsInfo, weightsData);
771 armnn::ConstTensor biases(biasesInfo, biasesData);
772
773 armnn::INetworkPtr network = armnn::INetwork::Create();
774 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0, "input");
775 armnn::IConnectableLayer* const fullyConnectedLayer = network->AddFullyConnectedLayer(descriptor,
776 weights,
777 biases,
778 "fully_connected");
779 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0, "output");
780
781 inputLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(0));
782 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
783
784 fullyConnectedLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
785 fullyConnectedLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
786
787 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
788 BOOST_CHECK(deserializedNetwork);
789
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000790 VerifyFullyConnectedName nameChecker;
791 deserializedNetwork->Accept(nameChecker);
792
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000793 CheckDeserializedNetworkAgainstOriginal(*network,
794 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000795 {inputInfo.GetShape()},
796 {outputInfo.GetShape()});
Sadik Armagandbb0c0c2019-02-21 09:01:41 +0000797}
798
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000799BOOST_AUTO_TEST_CASE(SerializeDeserializeSpaceToBatchNd)
800{
801 class VerifySpaceToBatchNdName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
802 {
803 public:
804 void VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer*,
805 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
806 const char* name) override
807 {
808 BOOST_TEST(name == "SpaceToBatchNdLayer");
809 }
810 };
811
812 unsigned int inputShape[] = {2, 1, 2, 4};
813 unsigned int outputShape[] = {8, 1, 1, 3};
814
815 armnn::SpaceToBatchNdDescriptor desc;
816 desc.m_DataLayout = armnn::DataLayout::NCHW;
817 desc.m_BlockShape = {2, 2};
818 desc.m_PadList = {{0, 0}, {2, 0}};
819
820 auto inputTensorInfo = armnn::TensorInfo(4, inputShape, armnn::DataType::Float32);
821 auto outputTensorInfo = armnn::TensorInfo(4, outputShape, armnn::DataType::Float32);
822
823 armnn::INetworkPtr network = armnn::INetwork::Create();
824 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
825 armnn::IConnectableLayer* const spaceToBatchNdLayer = network->AddSpaceToBatchNdLayer(desc, "SpaceToBatchNdLayer");
826 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
827
828 inputLayer->GetOutputSlot(0).Connect(spaceToBatchNdLayer->GetInputSlot(0));
829 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
830 spaceToBatchNdLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
831 spaceToBatchNdLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
832
833 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
834 BOOST_CHECK(deserializedNetwork);
835
836 VerifySpaceToBatchNdName nameChecker;
837 deserializedNetwork->Accept(nameChecker);
838
839 CheckDeserializedNetworkAgainstOriginal(*network,
840 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000841 {inputTensorInfo.GetShape()},
842 {outputTensorInfo.GetShape()});
Nattapat Chaimanowong45286992019-02-26 15:53:02 +0000843}
844
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000845BOOST_AUTO_TEST_CASE(SerializeDeserializeBatchToSpaceNd)
846{
847 class VerifyBatchToSpaceNdName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
848 {
849 public:
850 void VisitBatchToSpaceNdLayer(const armnn::IConnectableLayer*,
851 const armnn::BatchToSpaceNdDescriptor& descriptor,
852 const char* name) override
853 {
854 BOOST_TEST(name == "BatchToSpaceNdLayer");
855 }
856 };
857
858 unsigned int inputShape[] = {4, 1, 2, 2};
859 unsigned int outputShape[] = {1, 1, 4, 4};
860
861 armnn::BatchToSpaceNdDescriptor desc;
862 desc.m_DataLayout = armnn::DataLayout::NCHW;
863 desc.m_BlockShape = {2, 2};
864 desc.m_Crops = {{0, 0}, {0, 0}};
865
866 auto inputTensorInfo = armnn::TensorInfo(4, inputShape, armnn::DataType::Float32);
867 auto outputTensorInfo = armnn::TensorInfo(4, outputShape, armnn::DataType::Float32);
868
869 armnn::INetworkPtr network = armnn::INetwork::Create();
870 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
871 armnn::IConnectableLayer* const batchToSpaceNdLayer = network->AddBatchToSpaceNdLayer(desc, "BatchToSpaceNdLayer");
872 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
873
874 inputLayer->GetOutputSlot(0).Connect(batchToSpaceNdLayer->GetInputSlot(0));
875 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
876 batchToSpaceNdLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
877 batchToSpaceNdLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
878
879 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
880 BOOST_CHECK(deserializedNetwork);
881
882 VerifyBatchToSpaceNdName nameChecker;
883 deserializedNetwork->Accept(nameChecker);
884
885 CheckDeserializedNetworkAgainstOriginal(*network,
886 *deserializedNetwork,
Nattapat Chaimanowong8d69bbc2019-02-27 16:52:29 +0000887 {inputTensorInfo.GetShape()},
888 {outputTensorInfo.GetShape()});
Nattapat Chaimanowong6b4ed982019-02-26 17:24:13 +0000889}
890
Éanna Ó Catháin58885892019-02-27 16:16:39 +0000891BOOST_AUTO_TEST_CASE(SerializeDivision)
892{
893 class VerifyDivisionName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
894 {
895 public:
896 void VisitDivisionLayer(const armnn::IConnectableLayer*, const char* name) override
897 {
898 BOOST_TEST(name == "division");
899 }
900 };
901
902 const armnn::TensorInfo info({ 1, 5, 2, 3 }, armnn::DataType::Float32);
903
904 armnn::INetworkPtr network = armnn::INetwork::Create();
905 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
906 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
907
908 const char* divLayerName = "division";
909
910 armnn::IConnectableLayer* const divisionLayer = network->AddDivisionLayer(divLayerName);
911 inputLayer0->GetOutputSlot(0).Connect(divisionLayer->GetInputSlot(0));
912 inputLayer1->GetOutputSlot(0).Connect(divisionLayer->GetInputSlot(1));
913
914 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
915 divisionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
916
917 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
918 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
919 divisionLayer->GetOutputSlot(0).SetTensorInfo(info);
920
921 armnnSerializer::Serializer serializer;
922 serializer.Serialize(*network);
923
924 std::stringstream stream;
925 serializer.SaveSerializedToStream(stream);
926 BOOST_TEST(stream.str().length() > 0);
927 BOOST_TEST(stream.str().find(divLayerName) != stream.str().npos);
928
929 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(stream.str());
930 BOOST_CHECK(deserializedNetwork);
931
932 VerifyDivisionName nameChecker;
933 deserializedNetwork->Accept(nameChecker);
934}
935
Nina Drozd57728782019-02-27 10:53:27 +0000936BOOST_AUTO_TEST_CASE(SerializeDeserializeNormalization)
937{
938 class VerifyNormalizationName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
939 {
940 public:
941 void VisitNormalizationLayer(const armnn::IConnectableLayer*,
942 const armnn::NormalizationDescriptor& normalizationDescriptor,
943 const char* name) override
944 {
945 BOOST_TEST(name == "NormalizationLayer");
946 }
947 };
948
949 unsigned int inputShape[] = {2, 1, 2, 2};
950 unsigned int outputShape[] = {2, 1, 2, 2};
951
952 armnn::NormalizationDescriptor desc;
953 desc.m_DataLayout = armnn::DataLayout::NCHW;
954 desc.m_NormSize = 3;
955 desc.m_Alpha = 1;
956 desc.m_Beta = 1;
957 desc.m_K = 1;
958
959 auto inputTensorInfo = armnn::TensorInfo(4, inputShape, armnn::DataType::Float32);
960 auto outputTensorInfo = armnn::TensorInfo(4, outputShape, armnn::DataType::Float32);
961
962 armnn::INetworkPtr network = armnn::INetwork::Create();
963 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
964 armnn::IConnectableLayer* const normalizationLayer = network->AddNormalizationLayer(desc, "NormalizationLayer");
965 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
966
967 inputLayer->GetOutputSlot(0).Connect(normalizationLayer->GetInputSlot(0));
968 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
969 normalizationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
970 normalizationLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
971
972 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
973 BOOST_CHECK(deserializedNetwork);
974
975 VerifyNormalizationName nameChecker;
976 deserializedNetwork->Accept(nameChecker);
977
978 CheckDeserializedNetworkAgainstOriginal(*network,
979 *deserializedNetwork,
980 {inputTensorInfo.GetShape()},
981 {outputTensorInfo.GetShape()});
982}
983
Nattapat Chaimanowong235cea52019-02-28 16:27:30 +0000984BOOST_AUTO_TEST_CASE(SerializeDeserializeEqual)
985{
986 class VerifyEqualName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
987 {
988 public:
989 void VisitEqualLayer(const armnn::IConnectableLayer*,
990 const char* name) override
991 {
992 BOOST_TEST(name == "EqualLayer");
993 }
994 };
995
996 const armnn::TensorInfo inputTensorInfo1 = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Float32);
997 const armnn::TensorInfo inputTensorInfo2 = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Float32);
998 const armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Boolean);
999
1000 armnn::INetworkPtr network = armnn::INetwork::Create();
1001 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(0);
1002 armnn::IConnectableLayer* const inputLayer2 = network->AddInputLayer(1);
1003 armnn::IConnectableLayer* const equalLayer = network->AddEqualLayer("EqualLayer");
1004 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1005
1006 inputLayer1->GetOutputSlot(0).Connect(equalLayer->GetInputSlot(0));
1007 inputLayer1->GetOutputSlot(0).SetTensorInfo(inputTensorInfo1);
1008 inputLayer2->GetOutputSlot(0).Connect(equalLayer->GetInputSlot(1));
1009 inputLayer2->GetOutputSlot(0).SetTensorInfo(inputTensorInfo2);
1010 equalLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1011 equalLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1012
1013 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1014 BOOST_CHECK(deserializedNetwork);
1015
1016 VerifyEqualName nameChecker;
1017 deserializedNetwork->Accept(nameChecker);
1018
1019 CheckDeserializedNetworkAgainstOriginal(*network,
1020 *deserializedNetwork,
1021 {inputTensorInfo1.GetShape(), inputTensorInfo2.GetShape()},
1022 {outputTensorInfo.GetShape()},
1023 {0, 1});
1024}
Nattapat Chaimanowongebb0f9c2019-03-01 12:14:06 +00001025
1026BOOST_AUTO_TEST_CASE(SerializeDeserializePad)
1027{
1028 class VerifyPadName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
1029 {
1030 public:
1031 void VisitPadLayer(const armnn::IConnectableLayer*,
1032 const armnn::PadDescriptor& descriptor,
1033 const char* name) override
1034 {
1035 BOOST_TEST(name == "PadLayer");
1036 }
1037 };
1038
1039 armnn::PadDescriptor desc({{0, 0}, {1, 0}, {1, 1}, {1, 2}});
1040
1041 const armnn::TensorInfo inputTensorInfo = armnn::TensorInfo({1, 2, 3, 4}, armnn::DataType::Float32);
1042 const armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({1, 3, 5, 7}, armnn::DataType::Float32);
1043
1044 armnn::INetworkPtr network = armnn::INetwork::Create();
1045 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1046 armnn::IConnectableLayer* const padLayer = network->AddPadLayer(desc, "PadLayer");
1047 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1048
1049 inputLayer->GetOutputSlot(0).Connect(padLayer->GetInputSlot(0));
1050 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
1051 padLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1052 padLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1053
1054 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1055 BOOST_CHECK(deserializedNetwork);
1056
1057 VerifyPadName nameChecker;
1058 deserializedNetwork->Accept(nameChecker);
1059
1060 CheckDeserializedNetworkAgainstOriginal(*network,
1061 *deserializedNetwork,
1062 {inputTensorInfo.GetShape()},
1063 {outputTensorInfo.GetShape()});
1064}
1065
Sadik Armagan8b42a382019-03-01 14:24:49 +00001066BOOST_AUTO_TEST_CASE(SerializeRsqrt)
1067{
1068 class VerifyRsqrtName : public armnn::LayerVisitorBase<armnn::VisitorNoThrowPolicy>
1069 {
1070 public:
1071 void VisitRsqrtLayer(const armnn::IConnectableLayer*, const char* name) override
1072 {
1073 BOOST_TEST(name == "rsqrt");
1074 }
1075 };
1076
1077 const armnn::TensorInfo tensorInfo({ 3, 1, 2 }, armnn::DataType::Float32);
1078
1079 armnn::INetworkPtr network = armnn::INetwork::Create();
1080 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1081 armnn::IConnectableLayer* const rsqrtLayer = network->AddRsqrtLayer("rsqrt");
1082 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1083
1084 inputLayer->GetOutputSlot(0).Connect(rsqrtLayer->GetInputSlot(0));
1085 rsqrtLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1086
1087 inputLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1088 rsqrtLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1089
1090 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1091 BOOST_CHECK(deserializedNetwork);
1092
1093 VerifyRsqrtName nameChecker;
1094 deserializedNetwork->Accept(nameChecker);
1095
1096 CheckDeserializedNetworkAgainstOriginal(*network,
1097 *deserializedNetwork,
1098 {tensorInfo.GetShape()},
1099 {tensorInfo.GetShape()});
1100}
1101
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +00001102BOOST_AUTO_TEST_SUITE_END()