blob: 2724ba4d353ec36b5e5014190a04feefe16e6b55 [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
Mike Kelly8c1701a2019-02-11 17:01:27 +00006#include "../Serializer.hpp"
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +00007
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +00008#include <armnn/ArmNN.hpp>
9#include <armnn/INetwork.hpp>
Derek Lamberti0028d1b2019-02-20 13:57:42 +000010#include <armnnDeserializer/IDeserializer.hpp>
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +000011
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +000012#include <random>
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +000013#include <vector>
14
Mike Kelly8c1701a2019-02-11 17:01:27 +000015#include <boost/test/unit_test.hpp>
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +000016
Derek Lamberti0028d1b2019-02-20 13:57:42 +000017using armnnDeserializer::IDeserializer;
Mike Kelly8c1701a2019-02-11 17:01:27 +000018
Saoirse Stewart3166c3e2019-02-18 15:24:53 +000019namespace
20{
21
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +000022struct DefaultLayerVerifierPolicy
23{
24 static void Apply()
25 {
26 BOOST_TEST_MESSAGE("Unexpected layer found in network");
27 BOOST_TEST(false);
28 }
29};
30
31class LayerVerifierBase : public armnn::LayerVisitorBase<DefaultLayerVerifierPolicy>
32{
33public:
34 LayerVerifierBase(const std::string& layerName,
35 const std::vector<armnn::TensorInfo>& inputInfos,
36 const std::vector<armnn::TensorInfo>& outputInfos)
37 : m_LayerName(layerName)
38 , m_InputTensorInfos(inputInfos)
39 , m_OutputTensorInfos(outputInfos) {}
40
41 void VisitInputLayer(const armnn::IConnectableLayer*, armnn::LayerBindingId, const char*) override {}
42
43 void VisitOutputLayer(const armnn::IConnectableLayer*, armnn::LayerBindingId id, const char*) override {}
44
45protected:
46 void VerifyNameAndConnections(const armnn::IConnectableLayer* layer, const char* name)
47 {
48 BOOST_TEST(name == m_LayerName.c_str());
49
50 BOOST_TEST(layer->GetNumInputSlots() == m_InputTensorInfos.size());
51 BOOST_TEST(layer->GetNumOutputSlots() == m_OutputTensorInfos.size());
52
53 for (unsigned int i = 0; i < m_InputTensorInfos.size(); i++)
54 {
55 const armnn::IOutputSlot* connectedOutput = layer->GetInputSlot(i).GetConnection();
56 BOOST_CHECK(connectedOutput);
57
58 const armnn::TensorInfo& connectedInfo = connectedOutput->GetTensorInfo();
59 BOOST_TEST(connectedInfo.GetShape() == m_InputTensorInfos[i].GetShape());
60 BOOST_TEST(
61 GetDataTypeName(connectedInfo.GetDataType()) == GetDataTypeName(m_InputTensorInfos[i].GetDataType()));
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +000062
63 BOOST_TEST(connectedInfo.GetQuantizationScale() == m_InputTensorInfos[i].GetQuantizationScale());
64 BOOST_TEST(connectedInfo.GetQuantizationOffset() == m_InputTensorInfos[i].GetQuantizationOffset());
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +000065 }
66
67 for (unsigned int i = 0; i < m_OutputTensorInfos.size(); i++)
68 {
69 const armnn::TensorInfo& outputInfo = layer->GetOutputSlot(i).GetTensorInfo();
70 BOOST_TEST(outputInfo.GetShape() == m_OutputTensorInfos[i].GetShape());
71 BOOST_TEST(
72 GetDataTypeName(outputInfo.GetDataType()) == GetDataTypeName(m_OutputTensorInfos[i].GetDataType()));
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +000073
74 BOOST_TEST(outputInfo.GetQuantizationScale() == m_OutputTensorInfos[i].GetQuantizationScale());
75 BOOST_TEST(outputInfo.GetQuantizationOffset() == m_OutputTensorInfos[i].GetQuantizationOffset());
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +000076 }
77 }
78
79private:
80 std::string m_LayerName;
81 std::vector<armnn::TensorInfo> m_InputTensorInfos;
82 std::vector<armnn::TensorInfo> m_OutputTensorInfos;
83};
84
85template<typename T>
86void CompareConstTensorData(const void* data1, const void* data2, unsigned int numElements)
87{
88 T typedData1 = static_cast<T>(data1);
89 T typedData2 = static_cast<T>(data2);
90 BOOST_CHECK(typedData1);
91 BOOST_CHECK(typedData2);
92
93 for (unsigned int i = 0; i < numElements; i++)
94 {
95 BOOST_TEST(typedData1[i] == typedData2[i]);
96 }
97}
98
99void CompareConstTensor(const armnn::ConstTensor& tensor1, const armnn::ConstTensor& tensor2)
100{
101 BOOST_TEST(tensor1.GetShape() == tensor2.GetShape());
102 BOOST_TEST(GetDataTypeName(tensor1.GetDataType()) == GetDataTypeName(tensor2.GetDataType()));
103
104 switch (tensor1.GetDataType())
105 {
106 case armnn::DataType::Float32:
107 CompareConstTensorData<const float*>(
108 tensor1.GetMemoryArea(), tensor2.GetMemoryArea(), tensor1.GetNumElements());
109 break;
110 case armnn::DataType::QuantisedAsymm8:
111 case armnn::DataType::Boolean:
112 CompareConstTensorData<const uint8_t*>(
113 tensor1.GetMemoryArea(), tensor2.GetMemoryArea(), tensor1.GetNumElements());
114 break;
115 case armnn::DataType::Signed32:
116 CompareConstTensorData<const int32_t*>(
117 tensor1.GetMemoryArea(), tensor2.GetMemoryArea(), tensor1.GetNumElements());
118 break;
119 default:
120 // Note that Float16 is not yet implemented
121 BOOST_TEST_MESSAGE("Unexpected datatype");
122 BOOST_TEST(false);
123 }
124}
125
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000126armnn::INetworkPtr DeserializeNetwork(const std::string& serializerString)
127{
128 std::vector<std::uint8_t> const serializerVector{serializerString.begin(), serializerString.end()};
Derek Lamberti0028d1b2019-02-20 13:57:42 +0000129 return IDeserializer::Create()->CreateNetworkFromBinary(serializerVector);
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000130}
131
132std::string SerializeNetwork(const armnn::INetwork& network)
133{
134 armnnSerializer::Serializer serializer;
135 serializer.Serialize(network);
136
137 std::stringstream stream;
138 serializer.SaveSerializedToStream(stream);
139
140 std::string serializerString{stream.str()};
141 return serializerString;
142}
143
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000144template<typename DataType>
145static std::vector<DataType> GenerateRandomData(size_t size)
146{
147 constexpr bool isIntegerType = std::is_integral<DataType>::value;
148 using Distribution =
149 typename std::conditional<isIntegerType,
150 std::uniform_int_distribution<DataType>,
151 std::uniform_real_distribution<DataType>>::type;
152
153 static constexpr DataType lowerLimit = std::numeric_limits<DataType>::min();
154 static constexpr DataType upperLimit = std::numeric_limits<DataType>::max();
155
156 static Distribution distribution(lowerLimit, upperLimit);
157 static std::default_random_engine generator;
158
159 std::vector<DataType> randomData(size);
160 std::generate(randomData.begin(), randomData.end(), []() { return distribution(generator); });
161
162 return randomData;
163}
164
Saoirse Stewart3166c3e2019-02-18 15:24:53 +0000165} // anonymous namespace
166
167BOOST_AUTO_TEST_SUITE(SerializerTests)
Aron Virginas-Tarfc413c02019-02-13 15:41:52 +0000168
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000169BOOST_AUTO_TEST_CASE(SerializeAddition)
Mike Kelly8c1701a2019-02-11 17:01:27 +0000170{
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000171 class AdditionLayerVerifier : public LayerVerifierBase
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000172 {
173 public:
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000174 AdditionLayerVerifier(const std::string& layerName,
175 const std::vector<armnn::TensorInfo>& inputInfos,
176 const std::vector<armnn::TensorInfo>& outputInfos)
177 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
178
179 void VisitAdditionLayer(const armnn::IConnectableLayer* layer, const char* name) override
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000180 {
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000181 VerifyNameAndConnections(layer, name);
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000182 }
183 };
184
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000185 const std::string layerName("addition");
186 const armnn::TensorInfo tensorInfo({1, 2, 3}, armnn::DataType::Float32);
187
Mike Kelly8c1701a2019-02-11 17:01:27 +0000188 armnn::INetworkPtr network = armnn::INetwork::Create();
189 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
190 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000191 armnn::IConnectableLayer* const additionLayer = network->AddAdditionLayer(layerName.c_str());
192 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000193
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000194 inputLayer0->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(0));
195 inputLayer1->GetOutputSlot(0).Connect(additionLayer->GetInputSlot(1));
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000196 additionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
Mike Kelly8c1701a2019-02-11 17:01:27 +0000197
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000198 inputLayer0->GetOutputSlot(0).SetTensorInfo(tensorInfo);
199 inputLayer1->GetOutputSlot(0).SetTensorInfo(tensorInfo);
200 additionLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
Jim Flynn3091b062019-02-15 14:45:04 +0000201
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000202 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000203 BOOST_CHECK(deserializedNetwork);
204
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000205 AdditionLayerVerifier verifier(layerName, {tensorInfo, tensorInfo}, {tensorInfo});
206 deserializedNetwork->Accept(verifier);
207}
Jim Flynnac25a1b2019-02-28 10:40:49 +0000208
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000209BOOST_AUTO_TEST_CASE(SerializeBatchNormalization)
210{
211 class BatchNormalizationLayerVerifier : public LayerVerifierBase
212 {
213 public:
214 BatchNormalizationLayerVerifier(const std::string& layerName,
215 const std::vector<armnn::TensorInfo>& inputInfos,
216 const std::vector<armnn::TensorInfo>& outputInfos,
217 const armnn::BatchNormalizationDescriptor& descriptor,
218 const armnn::ConstTensor& mean,
219 const armnn::ConstTensor& variance,
220 const armnn::ConstTensor& beta,
221 const armnn::ConstTensor& gamma)
222 : LayerVerifierBase(layerName, inputInfos, outputInfos)
223 , m_Descriptor(descriptor)
224 , m_Mean(mean)
225 , m_Variance(variance)
226 , m_Beta(beta)
227 , m_Gamma(gamma) {}
228
229 void VisitBatchNormalizationLayer(const armnn::IConnectableLayer* layer,
230 const armnn::BatchNormalizationDescriptor& descriptor,
231 const armnn::ConstTensor& mean,
232 const armnn::ConstTensor& variance,
233 const armnn::ConstTensor& beta,
234 const armnn::ConstTensor& gamma,
235 const char* name) override
236 {
237 VerifyNameAndConnections(layer, name);
238 VerifyDescriptor(descriptor);
239
240 CompareConstTensor(mean, m_Mean);
241 CompareConstTensor(variance, m_Variance);
242 CompareConstTensor(beta, m_Beta);
243 CompareConstTensor(gamma, m_Gamma);
244 }
245
246 private:
247 void VerifyDescriptor(const armnn::BatchNormalizationDescriptor& descriptor)
248 {
249 BOOST_TEST(descriptor.m_Eps == m_Descriptor.m_Eps);
250 BOOST_TEST(static_cast<int>(descriptor.m_DataLayout) == static_cast<int>(m_Descriptor.m_DataLayout));
251 }
252
253 armnn::BatchNormalizationDescriptor m_Descriptor;
254 armnn::ConstTensor m_Mean;
255 armnn::ConstTensor m_Variance;
256 armnn::ConstTensor m_Beta;
257 armnn::ConstTensor m_Gamma;
258 };
259
260 const std::string layerName("batchNormalization");
261 const armnn::TensorInfo inputInfo ({ 1, 3, 3, 1 }, armnn::DataType::Float32);
262 const armnn::TensorInfo outputInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
263
264 const armnn::TensorInfo meanInfo({1}, armnn::DataType::Float32);
265 const armnn::TensorInfo varianceInfo({1}, armnn::DataType::Float32);
266 const armnn::TensorInfo betaInfo({1}, armnn::DataType::Float32);
267 const armnn::TensorInfo gammaInfo({1}, armnn::DataType::Float32);
268
269 armnn::BatchNormalizationDescriptor descriptor;
270 descriptor.m_Eps = 0.0010000000475f;
271 descriptor.m_DataLayout = armnn::DataLayout::NHWC;
272
273 std::vector<float> meanData({5.0});
274 std::vector<float> varianceData({2.0});
275 std::vector<float> betaData({1.0});
276 std::vector<float> gammaData({0.0});
277
278 armnn::ConstTensor mean(meanInfo, meanData);
279 armnn::ConstTensor variance(varianceInfo, varianceData);
280 armnn::ConstTensor beta(betaInfo, betaData);
281 armnn::ConstTensor gamma(gammaInfo, gammaData);
282
283 armnn::INetworkPtr network = armnn::INetwork::Create();
284 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
285 armnn::IConnectableLayer* const batchNormalizationLayer =
286 network->AddBatchNormalizationLayer(descriptor, mean, variance, beta, gamma, layerName.c_str());
287 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
288
289 inputLayer->GetOutputSlot(0).Connect(batchNormalizationLayer->GetInputSlot(0));
290 batchNormalizationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
291
292 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
293 batchNormalizationLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
294
295 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
296 BOOST_CHECK(deserializedNetwork);
297
298 BatchNormalizationLayerVerifier verifier(
299 layerName, {inputInfo}, {outputInfo}, descriptor, mean, variance, beta, gamma);
300 deserializedNetwork->Accept(verifier);
301}
302
303BOOST_AUTO_TEST_CASE(SerializeBatchToSpaceNd)
304{
305 class BatchToSpaceNdLayerVerifier : public LayerVerifierBase
306 {
307 public:
308 BatchToSpaceNdLayerVerifier(const std::string& layerName,
309 const std::vector<armnn::TensorInfo>& inputInfos,
310 const std::vector<armnn::TensorInfo>& outputInfos,
311 const armnn::BatchToSpaceNdDescriptor& descriptor)
312 : LayerVerifierBase(layerName, inputInfos, outputInfos)
313 , m_Descriptor(descriptor) {}
314
315 void VisitBatchToSpaceNdLayer(const armnn::IConnectableLayer* layer,
316 const armnn::BatchToSpaceNdDescriptor& descriptor,
317 const char* name) override
318 {
319 VerifyNameAndConnections(layer, name);
320 VerifyDescriptor(descriptor);
321 }
322
323 private:
324 void VerifyDescriptor(const armnn::BatchToSpaceNdDescriptor& descriptor)
325 {
326 BOOST_TEST(descriptor.m_Crops == m_Descriptor.m_Crops);
327 BOOST_TEST(descriptor.m_BlockShape == m_Descriptor.m_BlockShape);
328 BOOST_TEST(GetDataLayoutName(descriptor.m_DataLayout) == GetDataLayoutName(m_Descriptor.m_DataLayout));
329 }
330
331 armnn::BatchToSpaceNdDescriptor m_Descriptor;
332 };
333
334 const std::string layerName("spaceToBatchNd");
335 const armnn::TensorInfo inputInfo({4, 1, 2, 2}, armnn::DataType::Float32);
336 const armnn::TensorInfo outputInfo({1, 1, 4, 4}, armnn::DataType::Float32);
337
338 armnn::BatchToSpaceNdDescriptor desc;
339 desc.m_DataLayout = armnn::DataLayout::NCHW;
340 desc.m_BlockShape = {2, 2};
341 desc.m_Crops = {{0, 0}, {0, 0}};
342
343 armnn::INetworkPtr network = armnn::INetwork::Create();
344 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
345 armnn::IConnectableLayer* const batchToSpaceNdLayer = network->AddBatchToSpaceNdLayer(desc, layerName.c_str());
346 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
347
348 inputLayer->GetOutputSlot(0).Connect(batchToSpaceNdLayer->GetInputSlot(0));
349 batchToSpaceNdLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
350
351 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
352 batchToSpaceNdLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
353
354 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
355 BOOST_CHECK(deserializedNetwork);
356
357 BatchToSpaceNdLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, desc);
358 deserializedNetwork->Accept(verifier);
Mike Kelly8c1701a2019-02-11 17:01:27 +0000359}
360
Conor Kennedy76277882019-02-26 08:29:54 +0000361BOOST_AUTO_TEST_CASE(SerializeConstant)
362{
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000363 class ConstantLayerVerifier : public LayerVerifierBase
Conor Kennedy76277882019-02-26 08:29:54 +0000364 {
365 public:
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000366 ConstantLayerVerifier(const std::string& layerName,
367 const std::vector<armnn::TensorInfo>& inputInfos,
368 const std::vector<armnn::TensorInfo>& outputInfos,
369 const armnn::ConstTensor& layerInput)
370 : LayerVerifierBase(layerName, inputInfos, outputInfos)
371 , m_LayerInput(layerInput) {}
372
373 void VisitConstantLayer(const armnn::IConnectableLayer* layer,
374 const armnn::ConstTensor& input,
375 const char* name) override
Conor Kennedy76277882019-02-26 08:29:54 +0000376 {
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000377 VerifyNameAndConnections(layer, name);
378
379 CompareConstTensor(input, m_LayerInput);
Conor Kennedy76277882019-02-26 08:29:54 +0000380 }
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000381
382 void VisitAdditionLayer(const armnn::IConnectableLayer* layer, const char* name = nullptr) override {}
383
384 private:
385 armnn::ConstTensor m_LayerInput;
Conor Kennedy76277882019-02-26 08:29:54 +0000386 };
387
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000388 const std::string layerName("constant");
389 const armnn::TensorInfo info({ 2, 3 }, armnn::DataType::Float32);
Conor Kennedy76277882019-02-26 08:29:54 +0000390
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000391 std::vector<float> constantData = GenerateRandomData<float>(info.GetNumElements());
392 armnn::ConstTensor constTensor(info, constantData);
Conor Kennedy76277882019-02-26 08:29:54 +0000393
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000394 armnn::INetworkPtr network(armnn::INetwork::Create());
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000395 armnn::IConnectableLayer* input = network->AddInputLayer(0);
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000396 armnn::IConnectableLayer* constant = network->AddConstantLayer(constTensor, layerName.c_str());
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000397 armnn::IConnectableLayer* add = network->AddAdditionLayer();
398 armnn::IConnectableLayer* output = network->AddOutputLayer(0);
Conor Kennedy76277882019-02-26 08:29:54 +0000399
400 input->GetOutputSlot(0).Connect(add->GetInputSlot(0));
401 constant->GetOutputSlot(0).Connect(add->GetInputSlot(1));
402 add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
403
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000404 input->GetOutputSlot(0).SetTensorInfo(info);
405 constant->GetOutputSlot(0).SetTensorInfo(info);
406 add->GetOutputSlot(0).SetTensorInfo(info);
Conor Kennedy76277882019-02-26 08:29:54 +0000407
Matteo Martincighf81edaa2019-03-04 14:34:30 +0000408 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
Conor Kennedy76277882019-02-26 08:29:54 +0000409 BOOST_CHECK(deserializedNetwork);
410
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000411 ConstantLayerVerifier verifier(layerName, {}, {info}, constTensor);
412 deserializedNetwork->Accept(verifier);
Conor Kennedy76277882019-02-26 08:29:54 +0000413}
414
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000415BOOST_AUTO_TEST_CASE(SerializeConvolution2d)
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000416{
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000417 class Convolution2dLayerVerifier : public LayerVerifierBase
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000418 {
419 public:
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000420 Convolution2dLayerVerifier(const std::string& layerName,
421 const std::vector<armnn::TensorInfo>& inputInfos,
422 const std::vector<armnn::TensorInfo>& outputInfos,
423 const armnn::Convolution2dDescriptor& descriptor,
424 const armnn::ConstTensor& weight,
425 const armnn::Optional<armnn::ConstTensor>& bias)
426 : LayerVerifierBase(layerName, inputInfos, outputInfos)
427 , m_Descriptor(descriptor)
428 , m_Weight(weight)
429 , m_Bias(bias) {}
Finn Williamsdd2ba7e2019-03-01 11:51:52 +0000430
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000431 void VisitConvolution2dLayer(const armnn::IConnectableLayer* layer,
432 const armnn::Convolution2dDescriptor& descriptor,
433 const armnn::ConstTensor& weight,
434 const armnn::Optional<armnn::ConstTensor>& bias,
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000435 const char* name) override
436 {
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000437 VerifyNameAndConnections(layer, name);
438 VerifyDescriptor(descriptor);
439
440 CompareConstTensor(weight, m_Weight);
441
442 BOOST_TEST(bias.has_value() == m_Bias.has_value());
443 if (bias.has_value() && m_Bias.has_value())
444 {
445 CompareConstTensor(bias.value(), m_Bias.value());
446 }
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000447 }
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000448
449 private:
450 void VerifyDescriptor(const armnn::Convolution2dDescriptor& descriptor)
451 {
452 BOOST_TEST(descriptor.m_PadLeft == m_Descriptor.m_PadLeft);
453 BOOST_TEST(descriptor.m_PadRight == m_Descriptor.m_PadRight);
454 BOOST_TEST(descriptor.m_PadTop == m_Descriptor.m_PadTop);
455 BOOST_TEST(descriptor.m_PadBottom == m_Descriptor.m_PadBottom);
456 BOOST_TEST(descriptor.m_StrideX == m_Descriptor.m_StrideX);
457 BOOST_TEST(descriptor.m_StrideY == m_Descriptor.m_StrideY);
458 BOOST_TEST(descriptor.m_BiasEnabled == m_Descriptor.m_BiasEnabled);
459 BOOST_TEST(GetDataLayoutName(descriptor.m_DataLayout) == GetDataLayoutName(m_Descriptor.m_DataLayout));
460 }
461
462 armnn::Convolution2dDescriptor m_Descriptor;
463 armnn::ConstTensor m_Weight;
464 armnn::Optional<armnn::ConstTensor> m_Bias;
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000465 };
466
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000467 const std::string layerName("convolution2d");
468 const armnn::TensorInfo inputInfo ({ 1, 5, 5, 1 }, armnn::DataType::Float32);
469 const armnn::TensorInfo outputInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
Saoirse Stewart263829c2019-02-19 15:54:14 +0000470
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000471 const armnn::TensorInfo weightsInfo({ 1, 3, 3, 1 }, armnn::DataType::Float32);
472 const armnn::TensorInfo biasesInfo ({ 1 }, armnn::DataType::Float32);
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000473
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000474 std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
475 armnn::ConstTensor weights(weightsInfo, weightsData);
476
477 std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
478 armnn::ConstTensor biases(biasesInfo, biasesData);
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000479
480 armnn::Convolution2dDescriptor descriptor;
481 descriptor.m_PadLeft = 1;
482 descriptor.m_PadRight = 1;
483 descriptor.m_PadTop = 1;
484 descriptor.m_PadBottom = 1;
485 descriptor.m_StrideX = 2;
486 descriptor.m_StrideY = 2;
487 descriptor.m_BiasEnabled = true;
488 descriptor.m_DataLayout = armnn::DataLayout::NHWC;
489
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000490 armnn::INetworkPtr network = armnn::INetwork::Create();
491 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000492 armnn::IConnectableLayer* const convLayer =
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000493 network->AddConvolution2dLayer(descriptor, weights, biases, layerName.c_str());
494 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000495
496 inputLayer->GetOutputSlot(0).Connect(convLayer->GetInputSlot(0));
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000497 convLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000498
499 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000500 convLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
501
502 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
503 BOOST_CHECK(deserializedNetwork);
504
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000505 Convolution2dLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, descriptor, weights, biases);
506 deserializedNetwork->Accept(verifier);
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000507}
508
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000509BOOST_AUTO_TEST_CASE(SerializeDepthwiseConvolution2d)
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000510{
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000511 class DepthwiseConvolution2dLayerVerifier : public LayerVerifierBase
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000512 {
513 public:
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000514 DepthwiseConvolution2dLayerVerifier(const std::string& layerName,
515 const std::vector<armnn::TensorInfo>& inputInfos,
516 const std::vector<armnn::TensorInfo>& outputInfos,
517 const armnn::DepthwiseConvolution2dDescriptor& descriptor,
518 const armnn::ConstTensor& weight,
519 const armnn::Optional<armnn::ConstTensor>& bias)
520 : LayerVerifierBase(layerName, inputInfos, outputInfos)
521 , m_Descriptor(descriptor)
522 , m_Weight(weight)
523 , m_Bias(bias) {}
Conor Kennedy79ffdf52019-03-01 14:24:54 +0000524
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000525 void VisitDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
526 const armnn::DepthwiseConvolution2dDescriptor& descriptor,
527 const armnn::ConstTensor& weight,
528 const armnn::Optional<armnn::ConstTensor>& bias,
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000529 const char* name) override
530 {
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000531 VerifyNameAndConnections(layer, name);
532 VerifyDescriptor(descriptor);
533
534 CompareConstTensor(weight, m_Weight);
535
536 BOOST_TEST(bias.has_value() == m_Bias.has_value());
537 if (bias.has_value() && m_Bias.has_value())
538 {
539 CompareConstTensor(bias.value(), m_Bias.value());
540 }
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000541 }
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000542
543 private:
544 void VerifyDescriptor(const armnn::DepthwiseConvolution2dDescriptor& descriptor)
545 {
546 BOOST_TEST(descriptor.m_PadLeft == m_Descriptor.m_PadLeft);
547 BOOST_TEST(descriptor.m_PadRight == m_Descriptor.m_PadRight);
548 BOOST_TEST(descriptor.m_PadTop == m_Descriptor.m_PadTop);
549 BOOST_TEST(descriptor.m_PadBottom == m_Descriptor.m_PadBottom);
550 BOOST_TEST(descriptor.m_StrideX == m_Descriptor.m_StrideX);
551 BOOST_TEST(descriptor.m_StrideY == m_Descriptor.m_StrideY);
552 BOOST_TEST(descriptor.m_BiasEnabled == m_Descriptor.m_BiasEnabled);
553 BOOST_TEST(GetDataLayoutName(descriptor.m_DataLayout) == GetDataLayoutName(m_Descriptor.m_DataLayout));
554 }
555
556 armnn::DepthwiseConvolution2dDescriptor m_Descriptor;
557 armnn::ConstTensor m_Weight;
558 armnn::Optional<armnn::ConstTensor> m_Bias;
Éanna Ó Catháin633f8592019-02-25 16:26:29 +0000559 };
560
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000561 const std::string layerName("depwiseConvolution2d");
562 const armnn::TensorInfo inputInfo ({ 1, 5, 5, 3 }, armnn::DataType::Float32);
563 const armnn::TensorInfo outputInfo({ 1, 3, 3, 3 }, armnn::DataType::Float32);
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000564
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000565 const armnn::TensorInfo weightsInfo({ 1, 3, 3, 3 }, armnn::DataType::Float32);
566 const armnn::TensorInfo biasesInfo ({ 3 }, armnn::DataType::Float32);
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000567
568 std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
569 armnn::ConstTensor weights(weightsInfo, weightsData);
570
571 std::vector<int32_t> biasesData = GenerateRandomData<int32_t>(biasesInfo.GetNumElements());
572 armnn::ConstTensor biases(biasesInfo, biasesData);
573
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000574 armnn::DepthwiseConvolution2dDescriptor descriptor;
575 descriptor.m_StrideX = 1;
576 descriptor.m_StrideY = 1;
577 descriptor.m_BiasEnabled = true;
578 descriptor.m_DataLayout = armnn::DataLayout::NHWC;
579
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000580 armnn::INetworkPtr network = armnn::INetwork::Create();
581 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
582 armnn::IConnectableLayer* const depthwiseConvLayer =
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000583 network->AddDepthwiseConvolution2dLayer(descriptor, weights, biases, layerName.c_str());
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000584 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
585
586 inputLayer->GetOutputSlot(0).Connect(depthwiseConvLayer->GetInputSlot(0));
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000587 depthwiseConvLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000588
589 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
Aron Virginas-Tarc04125f2019-02-19 16:31:08 +0000590 depthwiseConvLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
591
592 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
593 BOOST_CHECK(deserializedNetwork);
594
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000595 DepthwiseConvolution2dLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, descriptor, weights, biases);
596 deserializedNetwork->Accept(verifier);
Jim Flynn18ce3382019-03-08 11:08:30 +0000597}
598
Nattapat Chaimanowonge4294fd2019-03-28 09:56:53 +0000599BOOST_AUTO_TEST_CASE(SerializeDequantize)
600{
601 class DequantizeLayerVerifier : public LayerVerifierBase
602 {
603 public:
604 DequantizeLayerVerifier(const std::string& layerName,
605 const std::vector<armnn::TensorInfo>& inputInfos,
606 const std::vector<armnn::TensorInfo>& outputInfos)
607 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
608
609 void VisitDequantizeLayer(const armnn::IConnectableLayer* layer, const char* name) override
610 {
611 VerifyNameAndConnections(layer, name);
612 }
613 };
614
615 const std::string layerName("dequantize");
616 const armnn::TensorInfo inputInfo({ 1, 5, 2, 3 }, armnn::DataType::QuantisedAsymm8, 0.5f, 1);
617 const armnn::TensorInfo outputInfo({ 1, 5, 2, 3 }, armnn::DataType::Float32);
618
619 armnn::INetworkPtr network = armnn::INetwork::Create();
620 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
621 armnn::IConnectableLayer* const dequantizeLayer = network->AddDequantizeLayer(layerName.c_str());
622 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
623
624 inputLayer->GetOutputSlot(0).Connect(dequantizeLayer->GetInputSlot(0));
625 dequantizeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
626
627 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
628 dequantizeLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
629
630 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
631 BOOST_CHECK(deserializedNetwork);
632
633 DequantizeLayerVerifier verifier(layerName, {inputInfo}, {outputInfo});
634 deserializedNetwork->Accept(verifier);
635}
636
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000637BOOST_AUTO_TEST_CASE(SerializeDeserializeDetectionPostProcess)
638{
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000639 class DetectionPostProcessLayerVerifier : public LayerVerifierBase
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000640 {
641 public:
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000642 DetectionPostProcessLayerVerifier(const std::string& layerName,
643 const std::vector<armnn::TensorInfo>& inputInfos,
644 const std::vector<armnn::TensorInfo>& outputInfos,
645 const armnn::DetectionPostProcessDescriptor& descriptor,
646 const armnn::ConstTensor& anchors)
647 : LayerVerifierBase(layerName, inputInfos, outputInfos)
648 , m_Descriptor(descriptor)
649 , m_Anchors(anchors) {}
650
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000651 void VisitDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
652 const armnn::DetectionPostProcessDescriptor& descriptor,
653 const armnn::ConstTensor& anchors,
654 const char* name) override
655 {
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000656 VerifyNameAndConnections(layer, name);
657 VerifyDescriptor(descriptor);
658
659 CompareConstTensor(anchors, m_Anchors);
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000660 }
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000661
662 private:
663 void VerifyDescriptor(const armnn::DetectionPostProcessDescriptor& descriptor)
664 {
665 BOOST_TEST(descriptor.m_UseRegularNms == m_Descriptor.m_UseRegularNms);
666 BOOST_TEST(descriptor.m_MaxDetections == m_Descriptor.m_MaxDetections);
667 BOOST_TEST(descriptor.m_MaxClassesPerDetection == m_Descriptor.m_MaxClassesPerDetection);
668 BOOST_TEST(descriptor.m_DetectionsPerClass == m_Descriptor.m_DetectionsPerClass);
669 BOOST_TEST(descriptor.m_NmsScoreThreshold == m_Descriptor.m_NmsScoreThreshold);
670 BOOST_TEST(descriptor.m_NmsIouThreshold == m_Descriptor.m_NmsIouThreshold);
671 BOOST_TEST(descriptor.m_NumClasses == m_Descriptor.m_NumClasses);
672 BOOST_TEST(descriptor.m_ScaleY == m_Descriptor.m_ScaleY);
673 BOOST_TEST(descriptor.m_ScaleX == m_Descriptor.m_ScaleX);
674 BOOST_TEST(descriptor.m_ScaleH == m_Descriptor.m_ScaleH);
675 BOOST_TEST(descriptor.m_ScaleW == m_Descriptor.m_ScaleW);
676 }
677
678 armnn::DetectionPostProcessDescriptor m_Descriptor;
679 armnn::ConstTensor m_Anchors;
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000680 };
681
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000682 const std::string layerName("detectionPostProcess");
683
684 const std::vector<armnn::TensorInfo> inputInfos({
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000685 armnn::TensorInfo({ 1, 6, 4 }, armnn::DataType::Float32),
686 armnn::TensorInfo({ 1, 6, 3}, armnn::DataType::Float32)
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000687 });
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000688
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000689 const std::vector<armnn::TensorInfo> outputInfos({
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000690 armnn::TensorInfo({ 1, 3, 4 }, armnn::DataType::Float32),
691 armnn::TensorInfo({ 1, 3 }, armnn::DataType::Float32),
692 armnn::TensorInfo({ 1, 3 }, armnn::DataType::Float32),
693 armnn::TensorInfo({ 1 }, armnn::DataType::Float32)
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000694 });
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000695
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000696 armnn::DetectionPostProcessDescriptor descriptor;
697 descriptor.m_UseRegularNms = true;
698 descriptor.m_MaxDetections = 3;
699 descriptor.m_MaxClassesPerDetection = 1;
700 descriptor.m_DetectionsPerClass =1;
701 descriptor.m_NmsScoreThreshold = 0.0;
702 descriptor.m_NmsIouThreshold = 0.5;
703 descriptor.m_NumClasses = 2;
704 descriptor.m_ScaleY = 10.0;
705 descriptor.m_ScaleX = 10.0;
706 descriptor.m_ScaleH = 5.0;
707 descriptor.m_ScaleW = 5.0;
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000708
709 const armnn::TensorInfo anchorsInfo({ 6, 4 }, armnn::DataType::Float32);
710 const std::vector<float> anchorsData({
711 0.5f, 0.5f, 1.0f, 1.0f,
712 0.5f, 0.5f, 1.0f, 1.0f,
713 0.5f, 0.5f, 1.0f, 1.0f,
714 0.5f, 10.5f, 1.0f, 1.0f,
715 0.5f, 10.5f, 1.0f, 1.0f,
716 0.5f, 100.5f, 1.0f, 1.0f
717 });
718 armnn::ConstTensor anchors(anchorsInfo, anchorsData);
719
720 armnn::INetworkPtr network = armnn::INetwork::Create();
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000721 armnn::IConnectableLayer* const detectionLayer =
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000722 network->AddDetectionPostProcessLayer(descriptor, anchors, layerName.c_str());
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000723
724 for (unsigned int i = 0; i < 2; i++)
725 {
726 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(static_cast<int>(i));
727 inputLayer->GetOutputSlot(0).Connect(detectionLayer->GetInputSlot(i));
728 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfos[i]);
729 }
730
731 for (unsigned int i = 0; i < 4; i++)
732 {
733 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(static_cast<int>(i));
734 detectionLayer->GetOutputSlot(i).Connect(outputLayer->GetInputSlot(0));
735 detectionLayer->GetOutputSlot(i).SetTensorInfo(outputInfos[i]);
736 }
737
738 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
739 BOOST_CHECK(deserializedNetwork);
740
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000741 DetectionPostProcessLayerVerifier verifier(layerName, inputInfos, outputInfos, descriptor, anchors);
742 deserializedNetwork->Accept(verifier);
743}
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +0000744
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +0000745BOOST_AUTO_TEST_CASE(SerializeDivision)
746{
747 class DivisionLayerVerifier : public LayerVerifierBase
748 {
749 public:
750 DivisionLayerVerifier(const std::string& layerName,
751 const std::vector<armnn::TensorInfo>& inputInfos,
752 const std::vector<armnn::TensorInfo>& outputInfos)
753 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
754
755 void VisitDivisionLayer(const armnn::IConnectableLayer* layer, const char* name) override
756 {
757 VerifyNameAndConnections(layer, name);
758 }
759 };
760
761 const std::string layerName("division");
762 const armnn::TensorInfo info({ 1, 5, 2, 3 }, armnn::DataType::Float32);
763
764 armnn::INetworkPtr network = armnn::INetwork::Create();
765 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
766 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
767 armnn::IConnectableLayer* const divisionLayer = network->AddDivisionLayer(layerName.c_str());
768 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
769
770 inputLayer0->GetOutputSlot(0).Connect(divisionLayer->GetInputSlot(0));
771 inputLayer1->GetOutputSlot(0).Connect(divisionLayer->GetInputSlot(1));
772 divisionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
773
774 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
775 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
776 divisionLayer->GetOutputSlot(0).SetTensorInfo(info);
777
778 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
779 BOOST_CHECK(deserializedNetwork);
780
781 DivisionLayerVerifier verifier(layerName, {info, info}, {info});
782 deserializedNetwork->Accept(verifier);
783}
784
785BOOST_AUTO_TEST_CASE(SerializeEqual)
786{
787 class EqualLayerVerifier : public LayerVerifierBase
788 {
789 public:
790 EqualLayerVerifier(const std::string& layerName,
791 const std::vector<armnn::TensorInfo>& inputInfos,
792 const std::vector<armnn::TensorInfo>& outputInfos)
793 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
794
795 void VisitEqualLayer(const armnn::IConnectableLayer* layer, const char* name) override
796 {
797 VerifyNameAndConnections(layer, name);
798 }
799 };
800
801 const std::string layerName("equal");
802 const armnn::TensorInfo inputTensorInfo1 = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Float32);
803 const armnn::TensorInfo inputTensorInfo2 = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Float32);
804 const armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({2, 1, 2, 4}, armnn::DataType::Boolean);
805
806 armnn::INetworkPtr network = armnn::INetwork::Create();
807 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(0);
808 armnn::IConnectableLayer* const inputLayer2 = network->AddInputLayer(1);
809 armnn::IConnectableLayer* const equalLayer = network->AddEqualLayer(layerName.c_str());
810 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
811
812 inputLayer1->GetOutputSlot(0).Connect(equalLayer->GetInputSlot(0));
813 inputLayer2->GetOutputSlot(0).Connect(equalLayer->GetInputSlot(1));
814 equalLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
815
816 inputLayer1->GetOutputSlot(0).SetTensorInfo(inputTensorInfo1);
817 inputLayer2->GetOutputSlot(0).SetTensorInfo(inputTensorInfo2);
818 equalLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
819
820 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
821 BOOST_CHECK(deserializedNetwork);
822
823 EqualLayerVerifier verifier(layerName, {inputTensorInfo1, inputTensorInfo2}, {outputTensorInfo});
824 deserializedNetwork->Accept(verifier);
825}
826
827BOOST_AUTO_TEST_CASE(SerializeFloor)
828{
829 class FloorLayerVerifier : public LayerVerifierBase
830 {
831 public:
832 FloorLayerVerifier(const std::string& layerName,
833 const std::vector<armnn::TensorInfo>& inputInfos,
834 const std::vector<armnn::TensorInfo>& outputInfos)
835 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
836
837 void VisitFloorLayer(const armnn::IConnectableLayer* layer, const char* name) override
838 {
839 VerifyNameAndConnections(layer, name);
840 }
841 };
842
843 const std::string layerName("floor");
844 const armnn::TensorInfo info({4,4}, armnn::DataType::Float32);
845
846 armnn::INetworkPtr network = armnn::INetwork::Create();
847 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
848 armnn::IConnectableLayer* const floorLayer = network->AddFloorLayer(layerName.c_str());
849 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
850
851 inputLayer->GetOutputSlot(0).Connect(floorLayer->GetInputSlot(0));
852 floorLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
853
854 inputLayer->GetOutputSlot(0).SetTensorInfo(info);
855 floorLayer->GetOutputSlot(0).SetTensorInfo(info);
856
857 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
858 BOOST_CHECK(deserializedNetwork);
859
860 FloorLayerVerifier verifier(layerName, {info}, {info});
861 deserializedNetwork->Accept(verifier);
862}
863
864BOOST_AUTO_TEST_CASE(SerializeFullyConnected)
865{
866 class FullyConnectedLayerVerifier : public LayerVerifierBase
867 {
868 public:
869 FullyConnectedLayerVerifier(const std::string& layerName,
870 const std::vector<armnn::TensorInfo>& inputInfos,
871 const std::vector<armnn::TensorInfo>& outputInfos,
872 const armnn::FullyConnectedDescriptor& descriptor,
873 const armnn::ConstTensor& weight,
874 const armnn::Optional<armnn::ConstTensor>& bias)
875 : LayerVerifierBase(layerName, inputInfos, outputInfos)
876 , m_Descriptor(descriptor)
877 , m_Weight(weight)
878 , m_Bias(bias) {}
879
880 void VisitFullyConnectedLayer(const armnn::IConnectableLayer* layer,
881 const armnn::FullyConnectedDescriptor& descriptor,
882 const armnn::ConstTensor& weight,
883 const armnn::Optional<armnn::ConstTensor>& bias,
884 const char* name) override
885 {
886 VerifyNameAndConnections(layer, name);
887 VerifyDescriptor(descriptor);
888
889 CompareConstTensor(weight, m_Weight);
890
891 BOOST_TEST(bias.has_value() == m_Bias.has_value());
892 if (bias.has_value() && m_Bias.has_value())
893 {
894 CompareConstTensor(bias.value(), m_Bias.value());
895 }
896 }
897
898 private:
899 void VerifyDescriptor(const armnn::FullyConnectedDescriptor& descriptor)
900 {
901 BOOST_TEST(descriptor.m_BiasEnabled == m_Descriptor.m_BiasEnabled);
902 BOOST_TEST(descriptor.m_TransposeWeightMatrix == m_Descriptor.m_TransposeWeightMatrix);
903 }
904
905 armnn::FullyConnectedDescriptor m_Descriptor;
906 armnn::ConstTensor m_Weight;
907 armnn::Optional<armnn::ConstTensor> m_Bias;
908 };
909
910 const std::string layerName("fullyConnected");
911 const armnn::TensorInfo inputInfo ({ 2, 5, 1, 1 }, armnn::DataType::Float32);
912 const armnn::TensorInfo outputInfo({ 2, 3 }, armnn::DataType::Float32);
913
914 const armnn::TensorInfo weightsInfo({ 5, 3 }, armnn::DataType::Float32);
915 const armnn::TensorInfo biasesInfo ({ 3 }, armnn::DataType::Float32);
916 std::vector<float> weightsData = GenerateRandomData<float>(weightsInfo.GetNumElements());
917 std::vector<float> biasesData = GenerateRandomData<float>(biasesInfo.GetNumElements());
918 armnn::ConstTensor weights(weightsInfo, weightsData);
919 armnn::ConstTensor biases(biasesInfo, biasesData);
920
921 armnn::FullyConnectedDescriptor descriptor;
922 descriptor.m_BiasEnabled = true;
923 descriptor.m_TransposeWeightMatrix = false;
924
925 armnn::INetworkPtr network = armnn::INetwork::Create();
926 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
927 armnn::IConnectableLayer* const fullyConnectedLayer =
928 network->AddFullyConnectedLayer(descriptor, weights, biases, layerName.c_str());
929 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
930
931 inputLayer->GetOutputSlot(0).Connect(fullyConnectedLayer->GetInputSlot(0));
932 fullyConnectedLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
933
934 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
935 fullyConnectedLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
936
937 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
938 BOOST_CHECK(deserializedNetwork);
939
940 FullyConnectedLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, descriptor, weights, biases);
941 deserializedNetwork->Accept(verifier);
942}
943
944BOOST_AUTO_TEST_CASE(SerializeGather)
945{
946 class GatherLayerVerifier : public LayerVerifierBase
947 {
948 public:
949 GatherLayerVerifier(const std::string& layerName,
950 const std::vector<armnn::TensorInfo>& inputInfos,
951 const std::vector<armnn::TensorInfo>& outputInfos)
952 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
953
954 void VisitGatherLayer(const armnn::IConnectableLayer* layer, const char *name) override
955 {
956 VerifyNameAndConnections(layer, name);
957 }
958
959 void VisitConstantLayer(const armnn::IConnectableLayer* layer,
960 const armnn::ConstTensor& input,
961 const char *name) override {}
962 };
963
964 const std::string layerName("gather");
965 armnn::TensorInfo paramsInfo({ 8 }, armnn::DataType::QuantisedAsymm8);
966 armnn::TensorInfo outputInfo({ 3 }, armnn::DataType::QuantisedAsymm8);
967 const armnn::TensorInfo indicesInfo({ 3 }, armnn::DataType::Signed32);
968
969 paramsInfo.SetQuantizationScale(1.0f);
970 paramsInfo.SetQuantizationOffset(0);
971 outputInfo.SetQuantizationScale(1.0f);
972 outputInfo.SetQuantizationOffset(0);
973
974 const std::vector<int32_t>& indicesData = {7, 6, 5};
975
976 armnn::INetworkPtr network = armnn::INetwork::Create();
977 armnn::IConnectableLayer *const inputLayer = network->AddInputLayer(0);
978 armnn::IConnectableLayer *const constantLayer =
979 network->AddConstantLayer(armnn::ConstTensor(indicesInfo, indicesData));
980 armnn::IConnectableLayer *const gatherLayer = network->AddGatherLayer(layerName.c_str());
981 armnn::IConnectableLayer *const outputLayer = network->AddOutputLayer(0);
982
983 inputLayer->GetOutputSlot(0).Connect(gatherLayer->GetInputSlot(0));
984 constantLayer->GetOutputSlot(0).Connect(gatherLayer->GetInputSlot(1));
985 gatherLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
986
987 inputLayer->GetOutputSlot(0).SetTensorInfo(paramsInfo);
988 constantLayer->GetOutputSlot(0).SetTensorInfo(indicesInfo);
989 gatherLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
990
991 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
992 BOOST_CHECK(deserializedNetwork);
993
994 GatherLayerVerifier verifier(layerName, {paramsInfo, indicesInfo}, {outputInfo});
995 deserializedNetwork->Accept(verifier);
996}
997
998BOOST_AUTO_TEST_CASE(SerializeGreater)
999{
1000 class GreaterLayerVerifier : public LayerVerifierBase
1001 {
1002 public:
1003 GreaterLayerVerifier(const std::string& layerName,
1004 const std::vector<armnn::TensorInfo>& inputInfos,
1005 const std::vector<armnn::TensorInfo>& outputInfos)
1006 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
1007
1008 void VisitGreaterLayer(const armnn::IConnectableLayer* layer, const char* name) override
1009 {
1010 VerifyNameAndConnections(layer, name);
1011 }
1012 };
1013
1014 const std::string layerName("greater");
1015 const armnn::TensorInfo inputTensorInfo1({ 1, 2, 2, 2 }, armnn::DataType::Float32);
1016 const armnn::TensorInfo inputTensorInfo2({ 1, 2, 2, 2 }, armnn::DataType::Float32);
1017 const armnn::TensorInfo outputTensorInfo({ 1, 2, 2, 2 }, armnn::DataType::Boolean);
1018
1019 armnn::INetworkPtr network = armnn::INetwork::Create();
1020 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(0);
1021 armnn::IConnectableLayer* const inputLayer2 = network->AddInputLayer(1);
1022 armnn::IConnectableLayer* const greaterLayer = network->AddGreaterLayer(layerName.c_str());
1023 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1024
1025 inputLayer1->GetOutputSlot(0).Connect(greaterLayer->GetInputSlot(0));
1026 inputLayer2->GetOutputSlot(0).Connect(greaterLayer->GetInputSlot(1));
1027 greaterLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1028
1029 inputLayer1->GetOutputSlot(0).SetTensorInfo(inputTensorInfo1);
1030 inputLayer2->GetOutputSlot(0).SetTensorInfo(inputTensorInfo2);
1031 greaterLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1032
1033 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1034 BOOST_CHECK(deserializedNetwork);
1035
1036 GreaterLayerVerifier verifier(layerName, {inputTensorInfo1, inputTensorInfo2}, {outputTensorInfo});
1037 deserializedNetwork->Accept(verifier);
1038}
1039
1040BOOST_AUTO_TEST_CASE(SerializeL2Normalization)
1041{
1042 class L2NormalizationLayerVerifier : public LayerVerifierBase
1043 {
1044 public:
1045 L2NormalizationLayerVerifier(const std::string& layerName,
1046 const std::vector<armnn::TensorInfo>& inputInfos,
1047 const std::vector<armnn::TensorInfo>& outputInfos,
1048 const armnn::L2NormalizationDescriptor& descriptor)
1049 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1050 , m_Descriptor(descriptor) {}
1051
1052 void VisitL2NormalizationLayer(const armnn::IConnectableLayer* layer,
1053 const armnn::L2NormalizationDescriptor& descriptor,
1054 const char* name) override
1055 {
1056 VerifyNameAndConnections(layer, name);
1057 VerifyDescriptor(descriptor);
1058 }
1059 private:
1060 void VerifyDescriptor(const armnn::L2NormalizationDescriptor& descriptor)
1061 {
1062 BOOST_TEST(GetDataLayoutName(descriptor.m_DataLayout) == GetDataLayoutName(m_Descriptor.m_DataLayout));
1063 }
1064
1065 armnn::L2NormalizationDescriptor m_Descriptor;
1066 };
1067
1068 const std::string l2NormLayerName("l2Normalization");
1069 const armnn::TensorInfo info({1, 2, 1, 5}, armnn::DataType::Float32);
1070
1071 armnn::L2NormalizationDescriptor desc;
1072 desc.m_DataLayout = armnn::DataLayout::NCHW;
1073
1074 armnn::INetworkPtr network = armnn::INetwork::Create();
1075 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1076 armnn::IConnectableLayer* const l2NormLayer = network->AddL2NormalizationLayer(desc, l2NormLayerName.c_str());
1077 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1078
1079 inputLayer0->GetOutputSlot(0).Connect(l2NormLayer->GetInputSlot(0));
1080 l2NormLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1081
1082 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1083 l2NormLayer->GetOutputSlot(0).SetTensorInfo(info);
1084
1085 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1086 BOOST_CHECK(deserializedNetwork);
1087
1088 L2NormalizationLayerVerifier verifier(l2NormLayerName, {info}, {info}, desc);
1089 deserializedNetwork->Accept(verifier);
1090}
1091
1092BOOST_AUTO_TEST_CASE(SerializeMaximum)
1093{
1094 class MaximumLayerVerifier : public LayerVerifierBase
1095 {
1096 public:
1097 MaximumLayerVerifier(const std::string& layerName,
1098 const std::vector<armnn::TensorInfo>& inputInfos,
1099 const std::vector<armnn::TensorInfo>& outputInfos)
1100 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
1101
1102 void VisitMaximumLayer(const armnn::IConnectableLayer* layer, const char* name) override
1103 {
1104 VerifyNameAndConnections(layer, name);
1105 }
1106 };
1107
1108 const std::string layerName("maximum");
1109 const armnn::TensorInfo info({ 1, 2, 2, 3 }, armnn::DataType::Float32);
1110
1111 armnn::INetworkPtr network = armnn::INetwork::Create();
1112 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1113 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
1114 armnn::IConnectableLayer* const maximumLayer = network->AddMaximumLayer(layerName.c_str());
1115 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1116
1117 inputLayer0->GetOutputSlot(0).Connect(maximumLayer->GetInputSlot(0));
1118 inputLayer1->GetOutputSlot(0).Connect(maximumLayer->GetInputSlot(1));
1119 maximumLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1120
1121 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1122 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
1123 maximumLayer->GetOutputSlot(0).SetTensorInfo(info);
1124
1125 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1126 BOOST_CHECK(deserializedNetwork);
1127
1128 MaximumLayerVerifier verifier(layerName, {info, info}, {info});
1129 deserializedNetwork->Accept(verifier);
1130}
1131
1132BOOST_AUTO_TEST_CASE(SerializeMean)
1133{
1134 class MeanLayerVerifier : public LayerVerifierBase
1135 {
1136 public:
1137 MeanLayerVerifier(const std::string& layerName,
1138 const std::vector<armnn::TensorInfo>& inputInfos,
1139 const std::vector<armnn::TensorInfo>& outputInfos,
1140 const armnn::MeanDescriptor& descriptor)
1141 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1142 , m_Descriptor(descriptor) {}
1143
1144 void VisitMeanLayer(const armnn::IConnectableLayer* layer,
1145 const armnn::MeanDescriptor& descriptor,
1146 const char* name) override
1147 {
1148 VerifyNameAndConnections(layer, name);
1149 VerifyDescriptor(descriptor);
1150 }
1151
1152 private:
1153 void VerifyDescriptor(const armnn::MeanDescriptor& descriptor)
1154 {
1155 BOOST_TEST(descriptor.m_Axis == m_Descriptor.m_Axis);
1156 BOOST_TEST(descriptor.m_KeepDims == m_Descriptor.m_KeepDims);
1157 }
1158
1159 armnn::MeanDescriptor m_Descriptor;
1160 };
1161
1162 const std::string layerName("mean");
1163 const armnn::TensorInfo inputInfo({1, 1, 3, 2}, armnn::DataType::Float32);
1164 const armnn::TensorInfo outputInfo({1, 1, 1, 2}, armnn::DataType::Float32);
1165
1166 armnn::MeanDescriptor descriptor;
1167 descriptor.m_Axis = { 2 };
1168 descriptor.m_KeepDims = true;
1169
1170 armnn::INetworkPtr network = armnn::INetwork::Create();
1171 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1172 armnn::IConnectableLayer* const meanLayer = network->AddMeanLayer(descriptor, layerName.c_str());
1173 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1174
1175 inputLayer->GetOutputSlot(0).Connect(meanLayer->GetInputSlot(0));
1176 meanLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1177
1178 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1179 meanLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1180
1181 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1182 BOOST_CHECK(deserializedNetwork);
1183
1184 MeanLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, descriptor);
1185 deserializedNetwork->Accept(verifier);
1186}
1187
Nattapat Chaimanowong1f886302019-04-05 13:37:19 +01001188BOOST_AUTO_TEST_CASE(SerializeMerge)
1189{
1190 class MergeLayerVerifier : public LayerVerifierBase
1191 {
1192 public:
1193 MergeLayerVerifier(const std::string& layerName,
1194 const std::vector<armnn::TensorInfo>& inputInfos,
1195 const std::vector<armnn::TensorInfo>& outputInfos)
1196 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
1197
1198 void VisitMergeLayer(const armnn::IConnectableLayer* layer, const char* name) override
1199 {
1200 VerifyNameAndConnections(layer, name);
1201 }
1202 };
1203
1204 const std::string layerName("merge");
1205 const armnn::TensorInfo info({ 1, 2, 2, 3 }, armnn::DataType::Float32);
1206
1207 armnn::INetworkPtr network = armnn::INetwork::Create();
1208 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1209 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
1210 armnn::IConnectableLayer* const mergeLayer = network->AddMergeLayer(layerName.c_str());
1211 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1212
1213 inputLayer0->GetOutputSlot(0).Connect(mergeLayer->GetInputSlot(0));
1214 inputLayer1->GetOutputSlot(0).Connect(mergeLayer->GetInputSlot(1));
1215 mergeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1216
1217 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1218 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
1219 mergeLayer->GetOutputSlot(0).SetTensorInfo(info);
1220
1221 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1222 BOOST_CHECK(deserializedNetwork);
1223
1224 MergeLayerVerifier verifier(layerName, {info, info}, {info});
1225 deserializedNetwork->Accept(verifier);
1226}
1227
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +00001228BOOST_AUTO_TEST_CASE(SerializeMerger)
1229{
1230 class MergerLayerVerifier : public LayerVerifierBase
1231 {
1232 public:
1233 MergerLayerVerifier(const std::string& layerName,
1234 const std::vector<armnn::TensorInfo>& inputInfos,
1235 const std::vector<armnn::TensorInfo>& outputInfos,
1236 const armnn::OriginsDescriptor& descriptor)
1237 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1238 , m_Descriptor(descriptor) {}
1239
1240 void VisitMergerLayer(const armnn::IConnectableLayer* layer,
1241 const armnn::OriginsDescriptor& descriptor,
1242 const char* name) override
1243 {
1244 VerifyNameAndConnections(layer, name);
1245 VerifyDescriptor(descriptor);
1246 }
1247
1248 private:
1249 void VerifyDescriptor(const armnn::OriginsDescriptor& descriptor)
1250 {
1251 BOOST_TEST(descriptor.GetConcatAxis() == m_Descriptor.GetConcatAxis());
1252 BOOST_TEST(descriptor.GetNumViews() == m_Descriptor.GetNumViews());
1253 BOOST_TEST(descriptor.GetNumDimensions() == m_Descriptor.GetNumDimensions());
1254
1255 for (uint32_t i = 0; i < descriptor.GetNumViews(); i++)
1256 {
1257 for (uint32_t j = 0; j < descriptor.GetNumDimensions(); j++)
1258 {
1259 BOOST_TEST(descriptor.GetViewOrigin(i)[j] == m_Descriptor.GetViewOrigin(i)[j]);
1260 }
1261 }
1262 }
1263
1264 armnn::OriginsDescriptor m_Descriptor;
1265 };
1266
1267 const std::string layerName("merger");
1268 const armnn::TensorInfo inputInfo = armnn::TensorInfo({2, 3, 2, 2}, armnn::DataType::Float32);
1269 const armnn::TensorInfo outputInfo = armnn::TensorInfo({4, 3, 2, 2}, armnn::DataType::Float32);
1270
1271 const std::vector<armnn::TensorShape> shapes({inputInfo.GetShape(), inputInfo.GetShape()});
1272
1273 armnn::OriginsDescriptor descriptor =
1274 armnn::CreateMergerDescriptorForConcatenation(shapes.begin(), shapes.end(), 0);
1275
1276 armnn::INetworkPtr network = armnn::INetwork::Create();
1277 armnn::IConnectableLayer* const inputLayerOne = network->AddInputLayer(0);
1278 armnn::IConnectableLayer* const inputLayerTwo = network->AddInputLayer(1);
1279 armnn::IConnectableLayer* const mergerLayer = network->AddMergerLayer(descriptor, layerName.c_str());
1280 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1281
1282 inputLayerOne->GetOutputSlot(0).Connect(mergerLayer->GetInputSlot(0));
1283 inputLayerTwo->GetOutputSlot(0).Connect(mergerLayer->GetInputSlot(1));
1284 mergerLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1285
1286 inputLayerOne->GetOutputSlot(0).SetTensorInfo(inputInfo);
1287 inputLayerTwo->GetOutputSlot(0).SetTensorInfo(inputInfo);
1288 mergerLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1289
1290 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1291 BOOST_CHECK(deserializedNetwork);
1292
1293 MergerLayerVerifier verifier(layerName, {inputInfo, inputInfo}, {outputInfo}, descriptor);
1294 deserializedNetwork->Accept(verifier);
1295}
1296
1297BOOST_AUTO_TEST_CASE(SerializeMinimum)
1298{
1299 class MinimumLayerVerifier : public LayerVerifierBase
1300 {
1301 public:
1302 MinimumLayerVerifier(const std::string& layerName,
1303 const std::vector<armnn::TensorInfo>& inputInfos,
1304 const std::vector<armnn::TensorInfo>& outputInfos)
1305 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
1306
1307 void VisitMinimumLayer(const armnn::IConnectableLayer* layer, const char* name) override
1308 {
1309 VerifyNameAndConnections(layer, name);
1310 }
1311 };
1312
1313 const std::string layerName("minimum");
1314 const armnn::TensorInfo info({ 1, 2, 2, 3 }, armnn::DataType::Float32);
1315
1316 armnn::INetworkPtr network = armnn::INetwork::Create();
1317 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1318 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
1319 armnn::IConnectableLayer* const minimumLayer = network->AddMinimumLayer(layerName.c_str());
1320 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1321
1322 inputLayer0->GetOutputSlot(0).Connect(minimumLayer->GetInputSlot(0));
1323 inputLayer1->GetOutputSlot(0).Connect(minimumLayer->GetInputSlot(1));
1324 minimumLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1325
1326 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1327 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
1328 minimumLayer->GetOutputSlot(0).SetTensorInfo(info);
1329
1330 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1331 BOOST_CHECK(deserializedNetwork);
1332
1333 MinimumLayerVerifier verifier(layerName, {info, info}, {info});
1334 deserializedNetwork->Accept(verifier);
1335}
1336
1337BOOST_AUTO_TEST_CASE(SerializeMultiplication)
1338{
1339 class MultiplicationLayerVerifier : public LayerVerifierBase
1340 {
1341 public:
1342 MultiplicationLayerVerifier(const std::string& layerName,
1343 const std::vector<armnn::TensorInfo>& inputInfos,
1344 const std::vector<armnn::TensorInfo>& outputInfos)
1345 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
1346
1347 void VisitMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name) override
1348 {
1349 VerifyNameAndConnections(layer, name);
1350 }
1351 };
1352
1353 const std::string layerName("multiplication");
1354 const armnn::TensorInfo info({ 1, 5, 2, 3 }, armnn::DataType::Float32);
1355
1356 armnn::INetworkPtr network = armnn::INetwork::Create();
1357 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
1358 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
1359 armnn::IConnectableLayer* const multiplicationLayer = network->AddMultiplicationLayer(layerName.c_str());
1360 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1361
1362 inputLayer0->GetOutputSlot(0).Connect(multiplicationLayer->GetInputSlot(0));
1363 inputLayer1->GetOutputSlot(0).Connect(multiplicationLayer->GetInputSlot(1));
1364 multiplicationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1365
1366 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
1367 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
1368 multiplicationLayer->GetOutputSlot(0).SetTensorInfo(info);
1369
1370 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1371 BOOST_CHECK(deserializedNetwork);
1372
1373 MultiplicationLayerVerifier verifier(layerName, {info, info}, {info});
1374 deserializedNetwork->Accept(verifier);
1375}
1376
1377BOOST_AUTO_TEST_CASE(SerializeNormalization)
1378{
1379 class NormalizationLayerVerifier : public LayerVerifierBase
1380 {
1381 public:
1382 NormalizationLayerVerifier(const std::string& layerName,
1383 const std::vector<armnn::TensorInfo>& inputInfos,
1384 const std::vector<armnn::TensorInfo>& outputInfos,
1385 const armnn::NormalizationDescriptor& descriptor)
1386 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1387 , m_Descriptor(descriptor) {}
1388
1389 void VisitNormalizationLayer(const armnn::IConnectableLayer* layer,
1390 const armnn::NormalizationDescriptor& descriptor,
1391 const char* name) override
1392 {
1393 VerifyNameAndConnections(layer, name);
1394 VerifyDescriptor(descriptor);
1395 }
1396
1397 private:
1398 void VerifyDescriptor(const armnn::NormalizationDescriptor& descriptor)
1399 {
1400 BOOST_TEST(GetDataLayoutName(descriptor.m_DataLayout) == GetDataLayoutName(m_Descriptor.m_DataLayout));
1401 BOOST_TEST(descriptor.m_NormSize == m_Descriptor.m_NormSize);
1402 BOOST_TEST(descriptor.m_Alpha == m_Descriptor.m_Alpha);
1403 BOOST_TEST(descriptor.m_Beta == m_Descriptor.m_Beta);
1404 BOOST_TEST(descriptor.m_K == m_Descriptor.m_K);
1405 BOOST_TEST(
1406 static_cast<int>(descriptor.m_NormChannelType) == static_cast<int>(m_Descriptor.m_NormChannelType));
1407 BOOST_TEST(
1408 static_cast<int>(descriptor.m_NormMethodType) == static_cast<int>(m_Descriptor.m_NormMethodType));
1409 }
1410
1411 armnn::NormalizationDescriptor m_Descriptor;
1412 };
1413
1414 const std::string layerName("normalization");
1415 const armnn::TensorInfo info({2, 1, 2, 2}, armnn::DataType::Float32);
1416
1417 armnn::NormalizationDescriptor desc;
1418 desc.m_DataLayout = armnn::DataLayout::NCHW;
1419 desc.m_NormSize = 3;
1420 desc.m_Alpha = 1;
1421 desc.m_Beta = 1;
1422 desc.m_K = 1;
1423
1424 armnn::INetworkPtr network = armnn::INetwork::Create();
1425 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1426 armnn::IConnectableLayer* const normalizationLayer = network->AddNormalizationLayer(desc, layerName.c_str());
1427 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1428
1429 inputLayer->GetOutputSlot(0).Connect(normalizationLayer->GetInputSlot(0));
1430 normalizationLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1431
1432 inputLayer->GetOutputSlot(0).SetTensorInfo(info);
1433 normalizationLayer->GetOutputSlot(0).SetTensorInfo(info);
1434
1435 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1436 BOOST_CHECK(deserializedNetwork);
1437
1438 NormalizationLayerVerifier verifier(layerName, {info}, {info}, desc);
1439 deserializedNetwork->Accept(verifier);
1440}
1441
1442BOOST_AUTO_TEST_CASE(SerializePad)
1443{
1444 class PadLayerVerifier : public LayerVerifierBase
1445 {
1446 public:
1447 PadLayerVerifier(const std::string& layerName,
1448 const std::vector<armnn::TensorInfo>& inputInfos,
1449 const std::vector<armnn::TensorInfo>& outputInfos,
1450 const armnn::PadDescriptor& descriptor)
1451 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1452 , m_Descriptor(descriptor) {}
1453
1454 void VisitPadLayer(const armnn::IConnectableLayer* layer,
1455 const armnn::PadDescriptor& descriptor,
1456 const char* name) override
1457 {
1458 VerifyNameAndConnections(layer, name);
1459 VerifyDescriptor(descriptor);
1460 }
1461
1462 private:
1463 void VerifyDescriptor(const armnn::PadDescriptor& descriptor)
1464 {
1465 BOOST_TEST(descriptor.m_PadList == m_Descriptor.m_PadList);
1466 }
1467
1468 armnn::PadDescriptor m_Descriptor;
1469 };
1470
1471 const std::string layerName("pad");
1472 const armnn::TensorInfo inputTensorInfo = armnn::TensorInfo({1, 2, 3, 4}, armnn::DataType::Float32);
1473 const armnn::TensorInfo outputTensorInfo = armnn::TensorInfo({1, 3, 5, 7}, armnn::DataType::Float32);
1474
1475 armnn::PadDescriptor desc({{0, 0}, {1, 0}, {1, 1}, {1, 2}});
1476
1477 armnn::INetworkPtr network = armnn::INetwork::Create();
1478 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1479 armnn::IConnectableLayer* const padLayer = network->AddPadLayer(desc, layerName.c_str());
1480 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1481
1482 inputLayer->GetOutputSlot(0).Connect(padLayer->GetInputSlot(0));
1483 padLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1484
1485 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
1486 padLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1487
1488 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1489 BOOST_CHECK(deserializedNetwork);
1490
1491 PadLayerVerifier verifier(layerName, {inputTensorInfo}, {outputTensorInfo}, desc);
1492 deserializedNetwork->Accept(verifier);
1493}
1494
1495BOOST_AUTO_TEST_CASE(SerializePermute)
1496{
1497 class PermuteLayerVerifier : public LayerVerifierBase
1498 {
1499 public:
1500 PermuteLayerVerifier(const std::string& layerName,
1501 const std::vector<armnn::TensorInfo>& inputInfos,
1502 const std::vector<armnn::TensorInfo>& outputInfos,
1503 const armnn::PermuteDescriptor& descriptor)
1504 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1505 , m_Descriptor(descriptor) {}
1506
1507 void VisitPermuteLayer(const armnn::IConnectableLayer* layer,
1508 const armnn::PermuteDescriptor& descriptor,
1509 const char* name) override
1510 {
1511 VerifyNameAndConnections(layer, name);
1512 VerifyDescriptor(descriptor);
1513 }
1514
1515 private:
1516 void VerifyDescriptor(const armnn::PermuteDescriptor& descriptor)
1517 {
1518 BOOST_TEST(descriptor.m_DimMappings.IsEqual(m_Descriptor.m_DimMappings));
1519 }
1520
1521 armnn::PermuteDescriptor m_Descriptor;
1522 };
1523
1524 const std::string layerName("permute");
1525 const armnn::TensorInfo inputTensorInfo({4, 3, 2, 1}, armnn::DataType::Float32);
1526 const armnn::TensorInfo outputTensorInfo({1, 2, 3, 4}, armnn::DataType::Float32);
1527
1528 armnn::PermuteDescriptor descriptor(armnn::PermutationVector({3, 2, 1, 0}));
1529
1530 armnn::INetworkPtr network = armnn::INetwork::Create();
1531 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1532 armnn::IConnectableLayer* const permuteLayer = network->AddPermuteLayer(descriptor, layerName.c_str());
1533 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1534
1535 inputLayer->GetOutputSlot(0).Connect(permuteLayer->GetInputSlot(0));
1536 permuteLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1537
1538 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
1539 permuteLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
1540
1541 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1542 BOOST_CHECK(deserializedNetwork);
1543
1544 PermuteLayerVerifier verifier(layerName, {inputTensorInfo}, {outputTensorInfo}, descriptor);
1545 deserializedNetwork->Accept(verifier);
1546}
1547
1548BOOST_AUTO_TEST_CASE(SerializePooling2d)
1549{
1550 class Pooling2dLayerVerifier : public LayerVerifierBase
1551 {
1552 public:
1553 Pooling2dLayerVerifier(const std::string& layerName,
1554 const std::vector<armnn::TensorInfo>& inputInfos,
1555 const std::vector<armnn::TensorInfo>& outputInfos,
1556 const armnn::Pooling2dDescriptor& descriptor)
1557 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1558 , m_Descriptor(descriptor) {}
1559
1560 void VisitPooling2dLayer(const armnn::IConnectableLayer* layer,
1561 const armnn::Pooling2dDescriptor& descriptor,
1562 const char* name) override
1563 {
1564 VerifyNameAndConnections(layer, name);
1565 VerifyDescriptor(descriptor);
1566 }
1567
1568 private:
1569 void VerifyDescriptor(const armnn::Pooling2dDescriptor& descriptor)
1570 {
1571 BOOST_TEST(GetDataLayoutName(descriptor.m_DataLayout) == GetDataLayoutName(m_Descriptor.m_DataLayout));
1572 BOOST_TEST(descriptor.m_PadLeft == m_Descriptor.m_PadLeft);
1573 BOOST_TEST(descriptor.m_PadRight == m_Descriptor.m_PadRight);
1574 BOOST_TEST(descriptor.m_PadTop == m_Descriptor.m_PadTop);
1575 BOOST_TEST(descriptor.m_PadBottom == m_Descriptor.m_PadBottom);
1576 BOOST_TEST(descriptor.m_PoolWidth == m_Descriptor.m_PoolWidth);
1577 BOOST_TEST(descriptor.m_PoolHeight == m_Descriptor.m_PoolHeight);
1578 BOOST_TEST(descriptor.m_StrideX == m_Descriptor.m_StrideX);
1579 BOOST_TEST(descriptor.m_StrideY == m_Descriptor.m_StrideY);
1580
1581 BOOST_TEST(
1582 static_cast<int>(descriptor.m_PaddingMethod) == static_cast<int>(m_Descriptor.m_PaddingMethod));
1583 BOOST_TEST(
1584 static_cast<int>(descriptor.m_PoolType) == static_cast<int>(m_Descriptor.m_PoolType));
1585 BOOST_TEST(
1586 static_cast<int>(descriptor.m_OutputShapeRounding) ==
1587 static_cast<int>(m_Descriptor.m_OutputShapeRounding));
1588 }
1589
1590 armnn::Pooling2dDescriptor m_Descriptor;
1591 };
1592
1593 const std::string layerName("pooling2d");
1594 const armnn::TensorInfo inputInfo({1, 2, 2, 1}, armnn::DataType::Float32);
1595 const armnn::TensorInfo outputInfo({1, 1, 1, 1}, armnn::DataType::Float32);
1596
1597 armnn::Pooling2dDescriptor desc;
1598 desc.m_DataLayout = armnn::DataLayout::NHWC;
1599 desc.m_PadTop = 0;
1600 desc.m_PadBottom = 0;
1601 desc.m_PadLeft = 0;
1602 desc.m_PadRight = 0;
1603 desc.m_PoolType = armnn::PoolingAlgorithm::Average;
1604 desc.m_OutputShapeRounding = armnn::OutputShapeRounding::Floor;
1605 desc.m_PaddingMethod = armnn::PaddingMethod::Exclude;
1606 desc.m_PoolHeight = 2;
1607 desc.m_PoolWidth = 2;
1608 desc.m_StrideX = 2;
1609 desc.m_StrideY = 2;
1610
1611 armnn::INetworkPtr network = armnn::INetwork::Create();
1612 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1613 armnn::IConnectableLayer* const pooling2dLayer = network->AddPooling2dLayer(desc, layerName.c_str());
1614 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1615
1616 inputLayer->GetOutputSlot(0).Connect(pooling2dLayer->GetInputSlot(0));
1617 pooling2dLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1618
1619 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1620 pooling2dLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1621
1622 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1623 BOOST_CHECK(deserializedNetwork);
1624
1625 Pooling2dLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, desc);
1626 deserializedNetwork->Accept(verifier);
1627}
1628
Derek Lamberti87acb272019-03-27 16:51:31 +00001629BOOST_AUTO_TEST_CASE(SerializeQuantize)
1630{
1631 class QuantizeLayerVerifier : public LayerVerifierBase
1632 {
1633 public:
1634 QuantizeLayerVerifier(const std::string& layerName,
1635 const std::vector<armnn::TensorInfo>& inputInfos,
1636 const std::vector<armnn::TensorInfo>& outputInfos)
1637 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
1638
1639 void VisitQuantizeLayer(const armnn::IConnectableLayer* layer, const char* name) override
1640 {
1641 VerifyNameAndConnections(layer, name);
1642 }
1643 };
1644
1645 const std::string layerName("quantize");
1646 const armnn::TensorInfo info({ 1, 2, 2, 3 }, armnn::DataType::Float32);
1647
1648 armnn::INetworkPtr network = armnn::INetwork::Create();
1649 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1650 armnn::IConnectableLayer* const quantizeLayer = network->AddQuantizeLayer(layerName.c_str());
1651 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1652
1653 inputLayer->GetOutputSlot(0).Connect(quantizeLayer->GetInputSlot(0));
1654 quantizeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1655
1656 inputLayer->GetOutputSlot(0).SetTensorInfo(info);
1657 quantizeLayer->GetOutputSlot(0).SetTensorInfo(info);
1658
1659 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1660 BOOST_CHECK(deserializedNetwork);
1661
1662 QuantizeLayerVerifier verifier(layerName, {info}, {info});
1663 deserializedNetwork->Accept(verifier);
1664}
Nattapat Chaimanowong03acd682019-03-20 11:19:52 +00001665BOOST_AUTO_TEST_CASE(SerializeReshape)
1666{
1667 class ReshapeLayerVerifier : public LayerVerifierBase
1668 {
1669 public:
1670 ReshapeLayerVerifier(const std::string& layerName,
1671 const std::vector<armnn::TensorInfo>& inputInfos,
1672 const std::vector<armnn::TensorInfo>& outputInfos,
1673 const armnn::ReshapeDescriptor& descriptor)
1674 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1675 , m_Descriptor(descriptor) {}
1676
1677 void VisitReshapeLayer(const armnn::IConnectableLayer* layer,
1678 const armnn::ReshapeDescriptor& descriptor,
1679 const char* name) override
1680 {
1681 VerifyNameAndConnections(layer, name);
1682 VerifyDescriptor(descriptor);
1683 }
1684
1685 private:
1686 void VerifyDescriptor(const armnn::ReshapeDescriptor& descriptor)
1687 {
1688 BOOST_TEST(descriptor.m_TargetShape == m_Descriptor.m_TargetShape);
1689 }
1690
1691 armnn::ReshapeDescriptor m_Descriptor;
1692 };
1693
1694 const std::string layerName("reshape");
1695 const armnn::TensorInfo inputInfo({1, 9}, armnn::DataType::Float32);
1696 const armnn::TensorInfo outputInfo({3, 3}, armnn::DataType::Float32);
1697
1698 armnn::ReshapeDescriptor descriptor({3, 3});
1699
1700 armnn::INetworkPtr network = armnn::INetwork::Create();
1701 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1702 armnn::IConnectableLayer* const reshapeLayer = network->AddReshapeLayer(descriptor, layerName.c_str());
1703 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1704
1705 inputLayer->GetOutputSlot(0).Connect(reshapeLayer->GetInputSlot(0));
1706 reshapeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1707
1708 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1709 reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1710
1711 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1712 BOOST_CHECK(deserializedNetwork);
1713
1714 ReshapeLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, descriptor);
1715 deserializedNetwork->Accept(verifier);
1716}
1717
1718BOOST_AUTO_TEST_CASE(SerializeResizeBilinear)
1719{
1720 class ResizeBilinearLayerVerifier : public LayerVerifierBase
1721 {
1722 public:
1723 ResizeBilinearLayerVerifier(const std::string& layerName,
1724 const std::vector<armnn::TensorInfo>& inputInfos,
1725 const std::vector<armnn::TensorInfo>& outputInfos,
1726 const armnn::ResizeBilinearDescriptor& descriptor)
1727 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1728 , m_Descriptor(descriptor) {}
1729
1730 void VisitResizeBilinearLayer(const armnn::IConnectableLayer* layer,
1731 const armnn::ResizeBilinearDescriptor& descriptor,
1732 const char* name) override
1733 {
1734 VerifyNameAndConnections(layer, name);
1735 VerifyDescriptor(descriptor);
1736 }
1737
1738 private:
1739 void VerifyDescriptor(const armnn::ResizeBilinearDescriptor& descriptor)
1740 {
1741 BOOST_TEST(GetDataLayoutName(descriptor.m_DataLayout) == GetDataLayoutName(m_Descriptor.m_DataLayout));
1742 BOOST_TEST(descriptor.m_TargetWidth == m_Descriptor.m_TargetWidth);
1743 BOOST_TEST(descriptor.m_TargetHeight == m_Descriptor.m_TargetHeight);
1744 }
1745
1746 armnn::ResizeBilinearDescriptor m_Descriptor;
1747 };
1748
1749 const std::string layerName("resizeBilinear");
1750 const armnn::TensorInfo inputInfo = armnn::TensorInfo({1, 3, 5, 5}, armnn::DataType::Float32);
1751 const armnn::TensorInfo outputInfo = armnn::TensorInfo({1, 3, 2, 4}, armnn::DataType::Float32);
1752
1753 armnn::ResizeBilinearDescriptor desc;
1754 desc.m_TargetWidth = 4;
1755 desc.m_TargetHeight = 2;
1756
1757 armnn::INetworkPtr network = armnn::INetwork::Create();
1758 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1759 armnn::IConnectableLayer* const resizeLayer = network->AddResizeBilinearLayer(desc, layerName.c_str());
1760 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1761
1762 inputLayer->GetOutputSlot(0).Connect(resizeLayer->GetInputSlot(0));
1763 resizeLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1764
1765 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1766 resizeLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1767
1768 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1769 BOOST_CHECK(deserializedNetwork);
1770
1771 ResizeBilinearLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, desc);
1772 deserializedNetwork->Accept(verifier);
1773}
1774
1775BOOST_AUTO_TEST_CASE(SerializeRsqrt)
1776{
1777 class RsqrtLayerVerifier : public LayerVerifierBase
1778 {
1779 public:
1780 RsqrtLayerVerifier(const std::string& layerName,
1781 const std::vector<armnn::TensorInfo>& inputInfos,
1782 const std::vector<armnn::TensorInfo>& outputInfos)
1783 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
1784
1785 void VisitRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name) override
1786 {
1787 VerifyNameAndConnections(layer, name);
1788 }
1789 };
1790
1791 const std::string layerName("rsqrt");
1792 const armnn::TensorInfo tensorInfo({ 3, 1, 2 }, armnn::DataType::Float32);
1793
1794 armnn::INetworkPtr network = armnn::INetwork::Create();
1795 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1796 armnn::IConnectableLayer* const rsqrtLayer = network->AddRsqrtLayer(layerName.c_str());
1797 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1798
1799 inputLayer->GetOutputSlot(0).Connect(rsqrtLayer->GetInputSlot(0));
1800 rsqrtLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1801
1802 inputLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1803 rsqrtLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
1804
1805 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1806 BOOST_CHECK(deserializedNetwork);
1807
1808 RsqrtLayerVerifier verifier(layerName, {tensorInfo}, {tensorInfo});
1809 deserializedNetwork->Accept(verifier);
1810}
1811
1812BOOST_AUTO_TEST_CASE(SerializeSoftmax)
1813{
1814 class SoftmaxLayerVerifier : public LayerVerifierBase
1815 {
1816 public:
1817 SoftmaxLayerVerifier(const std::string& layerName,
1818 const std::vector<armnn::TensorInfo>& inputInfos,
1819 const std::vector<armnn::TensorInfo>& outputInfos,
1820 const armnn::SoftmaxDescriptor& descriptor)
1821 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1822 , m_Descriptor(descriptor) {}
1823
1824 void VisitSoftmaxLayer(const armnn::IConnectableLayer* layer,
1825 const armnn::SoftmaxDescriptor& descriptor,
1826 const char* name) override
1827 {
1828 VerifyNameAndConnections(layer, name);
1829 VerifyDescriptor(descriptor);
1830 }
1831
1832 private:
1833 void VerifyDescriptor(const armnn::SoftmaxDescriptor& descriptor)
1834 {
1835 BOOST_TEST(descriptor.m_Beta == m_Descriptor.m_Beta);
1836 }
1837
1838 armnn::SoftmaxDescriptor m_Descriptor;
1839 };
1840
1841 const std::string layerName("softmax");
1842 const armnn::TensorInfo info({1, 10}, armnn::DataType::Float32);
1843
1844 armnn::SoftmaxDescriptor descriptor;
1845 descriptor.m_Beta = 1.0f;
1846
1847 armnn::INetworkPtr network = armnn::INetwork::Create();
1848 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1849 armnn::IConnectableLayer* const softmaxLayer = network->AddSoftmaxLayer(descriptor, layerName.c_str());
1850 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1851
1852 inputLayer->GetOutputSlot(0).Connect(softmaxLayer->GetInputSlot(0));
1853 softmaxLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1854
1855 inputLayer->GetOutputSlot(0).SetTensorInfo(info);
1856 softmaxLayer->GetOutputSlot(0).SetTensorInfo(info);
1857
1858 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1859 BOOST_CHECK(deserializedNetwork);
1860
1861 SoftmaxLayerVerifier verifier(layerName, {info}, {info}, descriptor);
1862 deserializedNetwork->Accept(verifier);
1863}
1864
1865BOOST_AUTO_TEST_CASE(SerializeSpaceToBatchNd)
1866{
1867 class SpaceToBatchNdLayerVerifier : public LayerVerifierBase
1868 {
1869 public:
1870 SpaceToBatchNdLayerVerifier(const std::string& layerName,
1871 const std::vector<armnn::TensorInfo>& inputInfos,
1872 const std::vector<armnn::TensorInfo>& outputInfos,
1873 const armnn::SpaceToBatchNdDescriptor& descriptor)
1874 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1875 , m_Descriptor(descriptor) {}
1876
1877 void VisitSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
1878 const armnn::SpaceToBatchNdDescriptor& descriptor,
1879 const char* name) override
1880 {
1881 VerifyNameAndConnections(layer, name);
1882 VerifyDescriptor(descriptor);
1883 }
1884
1885 private:
1886 void VerifyDescriptor(const armnn::SpaceToBatchNdDescriptor& descriptor)
1887 {
1888 BOOST_TEST(descriptor.m_PadList == m_Descriptor.m_PadList);
1889 BOOST_TEST(descriptor.m_BlockShape == m_Descriptor.m_BlockShape);
1890 BOOST_TEST(GetDataLayoutName(descriptor.m_DataLayout) == GetDataLayoutName(m_Descriptor.m_DataLayout));
1891 }
1892
1893 armnn::SpaceToBatchNdDescriptor m_Descriptor;
1894 };
1895
1896 const std::string layerName("spaceToBatchNd");
1897 const armnn::TensorInfo inputInfo({2, 1, 2, 4}, armnn::DataType::Float32);
1898 const armnn::TensorInfo outputInfo({8, 1, 1, 3}, armnn::DataType::Float32);
1899
1900 armnn::SpaceToBatchNdDescriptor desc;
1901 desc.m_DataLayout = armnn::DataLayout::NCHW;
1902 desc.m_BlockShape = {2, 2};
1903 desc.m_PadList = {{0, 0}, {2, 0}};
1904
1905 armnn::INetworkPtr network = armnn::INetwork::Create();
1906 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1907 armnn::IConnectableLayer* const spaceToBatchNdLayer = network->AddSpaceToBatchNdLayer(desc, layerName.c_str());
1908 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
1909
1910 inputLayer->GetOutputSlot(0).Connect(spaceToBatchNdLayer->GetInputSlot(0));
1911 spaceToBatchNdLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
1912
1913 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
1914 spaceToBatchNdLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
1915
1916 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
1917 BOOST_CHECK(deserializedNetwork);
1918
1919 SpaceToBatchNdLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, desc);
1920 deserializedNetwork->Accept(verifier);
1921}
1922
1923BOOST_AUTO_TEST_CASE(SerializeSplitter)
1924{
1925 class SplitterLayerVerifier : public LayerVerifierBase
1926 {
1927 public:
1928 SplitterLayerVerifier(const std::string& layerName,
1929 const std::vector<armnn::TensorInfo>& inputInfos,
1930 const std::vector<armnn::TensorInfo>& outputInfos,
1931 const armnn::ViewsDescriptor& descriptor)
1932 : LayerVerifierBase(layerName, inputInfos, outputInfos)
1933 , m_Descriptor(descriptor) {}
1934
1935 void VisitSplitterLayer(const armnn::IConnectableLayer* layer,
1936 const armnn::ViewsDescriptor& descriptor,
1937 const char* name) override
1938 {
1939 VerifyNameAndConnections(layer, name);
1940 VerifyDescriptor(descriptor);
1941 }
1942
1943 private:
1944 void VerifyDescriptor(const armnn::ViewsDescriptor& descriptor)
1945 {
1946 BOOST_TEST(descriptor.GetNumViews() == m_Descriptor.GetNumViews());
1947 BOOST_TEST(descriptor.GetNumDimensions() == m_Descriptor.GetNumDimensions());
1948
1949 for (uint32_t i = 0; i < descriptor.GetNumViews(); i++)
1950 {
1951 for (uint32_t j = 0; j < descriptor.GetNumDimensions(); j++)
1952 {
1953 BOOST_TEST(descriptor.GetViewOrigin(i)[j] == m_Descriptor.GetViewOrigin(i)[j]);
1954 BOOST_TEST(descriptor.GetViewSizes(i)[j] == m_Descriptor.GetViewSizes(i)[j]);
1955 }
1956 }
1957 }
1958
1959 armnn::ViewsDescriptor m_Descriptor;
1960 };
1961
1962 const unsigned int numViews = 3;
1963 const unsigned int numDimensions = 4;
1964 const unsigned int inputShape[] = {1, 18, 4, 4};
1965 const unsigned int outputShape[] = {1, 6, 4, 4};
1966
1967 // This is modelled on how the caffe parser sets up a splitter layer to partition an input along dimension one.
1968 unsigned int splitterDimSizes[4] = {static_cast<unsigned int>(inputShape[0]),
1969 static_cast<unsigned int>(inputShape[1]),
1970 static_cast<unsigned int>(inputShape[2]),
1971 static_cast<unsigned int>(inputShape[3])};
1972 splitterDimSizes[1] /= numViews;
1973 armnn::ViewsDescriptor desc(numViews, numDimensions);
1974
1975 for (unsigned int g = 0; g < numViews; ++g)
1976 {
1977 desc.SetViewOriginCoord(g, 1, splitterDimSizes[1] * g);
1978
1979 for (unsigned int dimIdx=0; dimIdx < 4; dimIdx++)
1980 {
1981 desc.SetViewSize(g, dimIdx, splitterDimSizes[dimIdx]);
1982 }
1983 }
1984
1985 const std::string layerName("splitter");
1986 const armnn::TensorInfo inputInfo(numDimensions, inputShape, armnn::DataType::Float32);
1987 const armnn::TensorInfo outputInfo(numDimensions, outputShape, armnn::DataType::Float32);
1988
1989 armnn::INetworkPtr network = armnn::INetwork::Create();
1990 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
1991 armnn::IConnectableLayer* const splitterLayer = network->AddSplitterLayer(desc, layerName.c_str());
1992 armnn::IConnectableLayer* const outputLayer0 = network->AddOutputLayer(0);
1993 armnn::IConnectableLayer* const outputLayer1 = network->AddOutputLayer(1);
1994 armnn::IConnectableLayer* const outputLayer2 = network->AddOutputLayer(2);
1995
1996 inputLayer->GetOutputSlot(0).Connect(splitterLayer->GetInputSlot(0));
1997 splitterLayer->GetOutputSlot(0).Connect(outputLayer0->GetInputSlot(0));
1998 splitterLayer->GetOutputSlot(1).Connect(outputLayer1->GetInputSlot(0));
1999 splitterLayer->GetOutputSlot(2).Connect(outputLayer2->GetInputSlot(0));
2000
2001 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
2002 splitterLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2003 splitterLayer->GetOutputSlot(1).SetTensorInfo(outputInfo);
2004 splitterLayer->GetOutputSlot(2).SetTensorInfo(outputInfo);
2005
2006 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2007 BOOST_CHECK(deserializedNetwork);
2008
2009 SplitterLayerVerifier verifier(layerName, {inputInfo}, {outputInfo, outputInfo, outputInfo}, desc);
2010 deserializedNetwork->Accept(verifier);
2011}
2012
2013BOOST_AUTO_TEST_CASE(SerializeStridedSlice)
2014{
2015 class StridedSliceLayerVerifier : public LayerVerifierBase
2016 {
2017 public:
2018 StridedSliceLayerVerifier(const std::string& layerName,
2019 const std::vector<armnn::TensorInfo>& inputInfos,
2020 const std::vector<armnn::TensorInfo>& outputInfos,
2021 const armnn::StridedSliceDescriptor& descriptor)
2022 : LayerVerifierBase(layerName, inputInfos, outputInfos)
2023 , m_Descriptor(descriptor) {}
2024
2025 void VisitStridedSliceLayer(const armnn::IConnectableLayer* layer,
2026 const armnn::StridedSliceDescriptor& descriptor,
2027 const char* name) override
2028 {
2029 VerifyNameAndConnections(layer, name);
2030 VerifyDescriptor(descriptor);
2031 }
2032
2033 private:
2034 void VerifyDescriptor(const armnn::StridedSliceDescriptor& descriptor)
2035 {
2036 BOOST_TEST(descriptor.m_Begin == m_Descriptor.m_Begin);
2037 BOOST_TEST(descriptor.m_End == m_Descriptor.m_End);
2038 BOOST_TEST(descriptor.m_Stride == m_Descriptor.m_Stride);
2039 BOOST_TEST(descriptor.m_BeginMask == m_Descriptor.m_BeginMask);
2040 BOOST_TEST(descriptor.m_EndMask == m_Descriptor.m_EndMask);
2041 BOOST_TEST(descriptor.m_ShrinkAxisMask == m_Descriptor.m_ShrinkAxisMask);
2042 BOOST_TEST(descriptor.m_EllipsisMask == m_Descriptor.m_EllipsisMask);
2043 BOOST_TEST(descriptor.m_NewAxisMask == m_Descriptor.m_NewAxisMask);
2044 BOOST_TEST(GetDataLayoutName(descriptor.m_DataLayout) == GetDataLayoutName(m_Descriptor.m_DataLayout));
2045 }
2046 armnn::StridedSliceDescriptor m_Descriptor;
2047 };
2048
2049 const std::string layerName("stridedSlice");
2050 const armnn::TensorInfo inputInfo = armnn::TensorInfo({3, 2, 3, 1}, armnn::DataType::Float32);
2051 const armnn::TensorInfo outputInfo = armnn::TensorInfo({3, 1}, armnn::DataType::Float32);
2052
2053 armnn::StridedSliceDescriptor desc({0, 0, 1, 0}, {1, 1, 1, 1}, {1, 1, 1, 1});
2054 desc.m_EndMask = (1 << 4) - 1;
2055 desc.m_ShrinkAxisMask = (1 << 1) | (1 << 2);
2056 desc.m_DataLayout = armnn::DataLayout::NCHW;
2057
2058 armnn::INetworkPtr network = armnn::INetwork::Create();
2059 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2060 armnn::IConnectableLayer* const stridedSliceLayer = network->AddStridedSliceLayer(desc, layerName.c_str());
2061 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
2062
2063 inputLayer->GetOutputSlot(0).Connect(stridedSliceLayer->GetInputSlot(0));
2064 stridedSliceLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
2065
2066 inputLayer->GetOutputSlot(0).SetTensorInfo(inputInfo);
2067 stridedSliceLayer->GetOutputSlot(0).SetTensorInfo(outputInfo);
2068
2069 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2070 BOOST_CHECK(deserializedNetwork);
2071
2072 StridedSliceLayerVerifier verifier(layerName, {inputInfo}, {outputInfo}, desc);
2073 deserializedNetwork->Accept(verifier);
2074}
2075
2076BOOST_AUTO_TEST_CASE(SerializeSubtraction)
2077{
2078 class SubtractionLayerVerifier : public LayerVerifierBase
2079 {
2080 public:
2081 SubtractionLayerVerifier(const std::string& layerName,
2082 const std::vector<armnn::TensorInfo>& inputInfos,
2083 const std::vector<armnn::TensorInfo>& outputInfos)
2084 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
2085
2086 void VisitSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name) override
2087 {
2088 VerifyNameAndConnections(layer, name);
2089 }
2090 };
2091
2092 const std::string layerName("subtraction");
2093 const armnn::TensorInfo info({ 1, 4 }, armnn::DataType::Float32);
2094
2095 armnn::INetworkPtr network = armnn::INetwork::Create();
2096 armnn::IConnectableLayer* const inputLayer0 = network->AddInputLayer(0);
2097 armnn::IConnectableLayer* const inputLayer1 = network->AddInputLayer(1);
2098 armnn::IConnectableLayer* const subtractionLayer = network->AddSubtractionLayer(layerName.c_str());
2099 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(0);
2100
2101 inputLayer0->GetOutputSlot(0).Connect(subtractionLayer->GetInputSlot(0));
2102 inputLayer1->GetOutputSlot(0).Connect(subtractionLayer->GetInputSlot(1));
2103 subtractionLayer->GetOutputSlot(0).Connect(outputLayer->GetInputSlot(0));
2104
2105 inputLayer0->GetOutputSlot(0).SetTensorInfo(info);
2106 inputLayer1->GetOutputSlot(0).SetTensorInfo(info);
2107 subtractionLayer->GetOutputSlot(0).SetTensorInfo(info);
2108
2109 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2110 BOOST_CHECK(deserializedNetwork);
2111
2112 SubtractionLayerVerifier verifier(layerName, {info, info}, {info});
2113 deserializedNetwork->Accept(verifier);
Nattapat Chaimanowong3e14a9d2019-03-18 12:37:06 +00002114}
2115
Sadik Armaganeff363d2019-04-05 15:25:46 +01002116BOOST_AUTO_TEST_CASE(SerializeSwitch)
2117{
2118 class SwitchLayerVerifier : public LayerVerifierBase
2119 {
2120 public:
2121 SwitchLayerVerifier(const std::string& layerName,
2122 const std::vector<armnn::TensorInfo>& inputInfos,
2123 const std::vector<armnn::TensorInfo>& outputInfos)
2124 : LayerVerifierBase(layerName, inputInfos, outputInfos) {}
2125
2126 void VisitSwitchLayer(const armnn::IConnectableLayer* layer, const char* name) override
2127 {
2128 VerifyNameAndConnections(layer, name);
2129 }
2130
2131 void VisitConstantLayer(const armnn::IConnectableLayer* layer,
2132 const armnn::ConstTensor& input,
2133 const char *name) override {}
2134 };
2135
2136 const std::string layerName("switch");
2137 const armnn::TensorInfo info({ 1, 4 }, armnn::DataType::Float32);
2138
2139 std::vector<float> constantData = GenerateRandomData<float>(info.GetNumElements());
2140 armnn::ConstTensor constTensor(info, constantData);
2141
2142 armnn::INetworkPtr network = armnn::INetwork::Create();
2143 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2144 armnn::IConnectableLayer* const constantLayer = network->AddConstantLayer(constTensor, "constant");
2145 armnn::IConnectableLayer* const switchLayer = network->AddSwitchLayer(layerName.c_str());
2146 armnn::IConnectableLayer* const trueOutputLayer = network->AddOutputLayer(0);
2147 armnn::IConnectableLayer* const falseOutputLayer = network->AddOutputLayer(1);
2148
2149 inputLayer->GetOutputSlot(0).Connect(switchLayer->GetInputSlot(0));
2150 constantLayer->GetOutputSlot(0).Connect(switchLayer->GetInputSlot(1));
2151 switchLayer->GetOutputSlot(0).Connect(trueOutputLayer->GetInputSlot(0));
2152 switchLayer->GetOutputSlot(1).Connect(falseOutputLayer->GetInputSlot(0));
2153
2154 inputLayer->GetOutputSlot(0).SetTensorInfo(info);
2155 constantLayer->GetOutputSlot(0).SetTensorInfo(info);
2156 switchLayer->GetOutputSlot(0).SetTensorInfo(info);
2157 switchLayer->GetOutputSlot(1).SetTensorInfo(info);
2158
2159 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2160 BOOST_CHECK(deserializedNetwork);
2161
2162 SwitchLayerVerifier verifier(layerName, {info, info}, {info, info});
2163 deserializedNetwork->Accept(verifier);
2164}
2165
Sadik Armagandb059fd2019-03-20 12:28:32 +00002166BOOST_AUTO_TEST_CASE(SerializeDeserializeNonLinearNetwork)
2167{
2168 class ConstantLayerVerifier : public LayerVerifierBase
2169 {
2170 public:
2171 ConstantLayerVerifier(const std::string& layerName,
2172 const std::vector<armnn::TensorInfo>& inputInfos,
2173 const std::vector<armnn::TensorInfo>& outputInfos,
2174 const armnn::ConstTensor& layerInput)
2175 : LayerVerifierBase(layerName, inputInfos, outputInfos)
2176 , m_LayerInput(layerInput) {}
2177
2178 void VisitConstantLayer(const armnn::IConnectableLayer* layer,
2179 const armnn::ConstTensor& input,
2180 const char* name) override
2181 {
2182 VerifyNameAndConnections(layer, name);
2183
2184 CompareConstTensor(input, m_LayerInput);
2185 }
2186
2187 void VisitAdditionLayer(const armnn::IConnectableLayer* layer, const char* name = nullptr) override {}
2188
2189 private:
2190 armnn::ConstTensor m_LayerInput;
2191 };
2192
2193 const std::string layerName("constant");
2194 const armnn::TensorInfo info({ 2, 3 }, armnn::DataType::Float32);
2195
2196 std::vector<float> constantData = GenerateRandomData<float>(info.GetNumElements());
2197 armnn::ConstTensor constTensor(info, constantData);
2198
2199 armnn::INetworkPtr network(armnn::INetwork::Create());
2200 armnn::IConnectableLayer* input = network->AddInputLayer(0);
2201 armnn::IConnectableLayer* add = network->AddAdditionLayer();
2202 armnn::IConnectableLayer* constant = network->AddConstantLayer(constTensor, layerName.c_str());
2203 armnn::IConnectableLayer* output = network->AddOutputLayer(0);
2204
2205 input->GetOutputSlot(0).Connect(add->GetInputSlot(0));
2206 constant->GetOutputSlot(0).Connect(add->GetInputSlot(1));
2207 add->GetOutputSlot(0).Connect(output->GetInputSlot(0));
2208
2209 input->GetOutputSlot(0).SetTensorInfo(info);
2210 constant->GetOutputSlot(0).SetTensorInfo(info);
2211 add->GetOutputSlot(0).SetTensorInfo(info);
2212
2213 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2214 BOOST_CHECK(deserializedNetwork);
2215
2216 ConstantLayerVerifier verifier(layerName, {}, {info}, constTensor);
2217 deserializedNetwork->Accept(verifier);
2218}
2219
Jim Flynn11af3752019-03-19 17:22:29 +00002220class VerifyLstmLayer : public LayerVerifierBase
2221{
2222public:
2223 VerifyLstmLayer(const std::string& layerName,
2224 const std::vector<armnn::TensorInfo>& inputInfos,
2225 const std::vector<armnn::TensorInfo>& outputInfos,
2226 const armnn::LstmDescriptor& descriptor,
2227 const armnn::LstmInputParams& inputParams) :
2228 LayerVerifierBase(layerName, inputInfos, outputInfos), m_Descriptor(descriptor), m_InputParams(inputParams)
2229 {
2230 }
2231 void VisitLstmLayer(const armnn::IConnectableLayer* layer,
2232 const armnn::LstmDescriptor& descriptor,
2233 const armnn::LstmInputParams& params,
2234 const char* name)
2235 {
2236 VerifyNameAndConnections(layer, name);
2237 VerifyDescriptor(descriptor);
2238 VerifyInputParameters(params);
2239 }
2240protected:
2241 void VerifyDescriptor(const armnn::LstmDescriptor& descriptor)
2242 {
2243 BOOST_TEST(m_Descriptor.m_ActivationFunc == descriptor.m_ActivationFunc);
2244 BOOST_TEST(m_Descriptor.m_ClippingThresCell == descriptor.m_ClippingThresCell);
2245 BOOST_TEST(m_Descriptor.m_ClippingThresProj == descriptor.m_ClippingThresProj);
2246 BOOST_TEST(m_Descriptor.m_CifgEnabled == descriptor.m_CifgEnabled);
2247 BOOST_TEST(m_Descriptor.m_PeepholeEnabled = descriptor.m_PeepholeEnabled);
2248 BOOST_TEST(m_Descriptor.m_ProjectionEnabled == descriptor.m_ProjectionEnabled);
2249 }
2250 void VerifyInputParameters(const armnn::LstmInputParams& params)
2251 {
2252 VerifyConstTensors(
2253 "m_InputToInputWeights", m_InputParams.m_InputToInputWeights, params.m_InputToInputWeights);
2254 VerifyConstTensors(
2255 "m_InputToForgetWeights", m_InputParams.m_InputToForgetWeights, params.m_InputToForgetWeights);
2256 VerifyConstTensors(
2257 "m_InputToCellWeights", m_InputParams.m_InputToCellWeights, params.m_InputToCellWeights);
2258 VerifyConstTensors(
2259 "m_InputToOutputWeights", m_InputParams.m_InputToOutputWeights, params.m_InputToOutputWeights);
2260 VerifyConstTensors(
2261 "m_RecurrentToInputWeights", m_InputParams.m_RecurrentToInputWeights, params.m_RecurrentToInputWeights);
2262 VerifyConstTensors(
2263 "m_RecurrentToForgetWeights", m_InputParams.m_RecurrentToForgetWeights, params.m_RecurrentToForgetWeights);
2264 VerifyConstTensors(
2265 "m_RecurrentToCellWeights", m_InputParams.m_RecurrentToCellWeights, params.m_RecurrentToCellWeights);
2266 VerifyConstTensors(
2267 "m_RecurrentToOutputWeights", m_InputParams.m_RecurrentToOutputWeights, params.m_RecurrentToOutputWeights);
2268 VerifyConstTensors(
2269 "m_CellToInputWeights", m_InputParams.m_CellToInputWeights, params.m_CellToInputWeights);
2270 VerifyConstTensors(
2271 "m_CellToForgetWeights", m_InputParams.m_CellToForgetWeights, params.m_CellToForgetWeights);
2272 VerifyConstTensors(
2273 "m_CellToOutputWeights", m_InputParams.m_CellToOutputWeights, params.m_CellToOutputWeights);
2274 VerifyConstTensors(
2275 "m_InputGateBias", m_InputParams.m_InputGateBias, params.m_InputGateBias);
2276 VerifyConstTensors(
2277 "m_ForgetGateBias", m_InputParams.m_ForgetGateBias, params.m_ForgetGateBias);
2278 VerifyConstTensors(
2279 "m_CellBias", m_InputParams.m_CellBias, params.m_CellBias);
2280 VerifyConstTensors(
2281 "m_OutputGateBias", m_InputParams.m_OutputGateBias, params.m_OutputGateBias);
2282 VerifyConstTensors(
2283 "m_ProjectionWeights", m_InputParams.m_ProjectionWeights, params.m_ProjectionWeights);
2284 VerifyConstTensors(
2285 "m_ProjectionBias", m_InputParams.m_ProjectionBias, params.m_ProjectionBias);
2286 }
2287 void VerifyConstTensors(const std::string& tensorName,
2288 const armnn::ConstTensor* expectedPtr,
2289 const armnn::ConstTensor* actualPtr)
2290 {
2291 if (expectedPtr == nullptr)
2292 {
2293 BOOST_CHECK_MESSAGE(actualPtr == nullptr, tensorName + " should not exist");
2294 }
2295 else
2296 {
2297 BOOST_CHECK_MESSAGE(actualPtr != nullptr, tensorName + " should have been set");
2298 if (actualPtr != nullptr)
2299 {
2300 const armnn::TensorInfo& expectedInfo = expectedPtr->GetInfo();
2301 const armnn::TensorInfo& actualInfo = actualPtr->GetInfo();
2302
2303 BOOST_CHECK_MESSAGE(expectedInfo.GetShape() == actualInfo.GetShape(),
2304 tensorName + " shapes don't match");
2305 BOOST_CHECK_MESSAGE(
2306 GetDataTypeName(expectedInfo.GetDataType()) == GetDataTypeName(actualInfo.GetDataType()),
2307 tensorName + " data types don't match");
2308
2309 BOOST_CHECK_MESSAGE(expectedPtr->GetNumBytes() == actualPtr->GetNumBytes(),
2310 tensorName + " (GetNumBytes) data sizes do not match");
2311 if (expectedPtr->GetNumBytes() == actualPtr->GetNumBytes())
2312 {
2313 //check the data is identical
2314 const char* expectedData = static_cast<const char*>(expectedPtr->GetMemoryArea());
2315 const char* actualData = static_cast<const char*>(actualPtr->GetMemoryArea());
2316 bool same = true;
2317 for (unsigned int i = 0; i < expectedPtr->GetNumBytes(); ++i)
2318 {
2319 same = expectedData[i] == actualData[i];
2320 if (!same)
2321 {
2322 break;
2323 }
2324 }
2325 BOOST_CHECK_MESSAGE(same, tensorName + " data does not match");
2326 }
2327 }
2328 }
2329 }
2330private:
2331 armnn::LstmDescriptor m_Descriptor;
2332 armnn::LstmInputParams m_InputParams;
2333};
2334
2335BOOST_AUTO_TEST_CASE(SerializeDeserializeLstmCifgPeepholeNoProjection)
2336{
2337 armnn::LstmDescriptor descriptor;
2338 descriptor.m_ActivationFunc = 4;
2339 descriptor.m_ClippingThresProj = 0.0f;
2340 descriptor.m_ClippingThresCell = 0.0f;
2341 descriptor.m_CifgEnabled = true; // if this is true then we DON'T need to set the OptCifgParams
2342 descriptor.m_ProjectionEnabled = false;
2343 descriptor.m_PeepholeEnabled = true;
2344
2345 const uint32_t batchSize = 1;
2346 const uint32_t inputSize = 2;
2347 const uint32_t numUnits = 4;
2348 const uint32_t outputSize = numUnits;
2349
2350 armnn::TensorInfo inputWeightsInfo1({numUnits, inputSize}, armnn::DataType::Float32);
2351 std::vector<float> inputToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
2352 armnn::ConstTensor inputToForgetWeights(inputWeightsInfo1, inputToForgetWeightsData);
2353
2354 std::vector<float> inputToCellWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
2355 armnn::ConstTensor inputToCellWeights(inputWeightsInfo1, inputToCellWeightsData);
2356
2357 std::vector<float> inputToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo1.GetNumElements());
2358 armnn::ConstTensor inputToOutputWeights(inputWeightsInfo1, inputToOutputWeightsData);
2359
2360 armnn::TensorInfo inputWeightsInfo2({numUnits, outputSize}, armnn::DataType::Float32);
2361 std::vector<float> recurrentToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
2362 armnn::ConstTensor recurrentToForgetWeights(inputWeightsInfo2, recurrentToForgetWeightsData);
2363
2364 std::vector<float> recurrentToCellWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
2365 armnn::ConstTensor recurrentToCellWeights(inputWeightsInfo2, recurrentToCellWeightsData);
2366
2367 std::vector<float> recurrentToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo2.GetNumElements());
2368 armnn::ConstTensor recurrentToOutputWeights(inputWeightsInfo2, recurrentToOutputWeightsData);
2369
2370 armnn::TensorInfo inputWeightsInfo3({numUnits}, armnn::DataType::Float32);
2371 std::vector<float> cellToForgetWeightsData = GenerateRandomData<float>(inputWeightsInfo3.GetNumElements());
2372 armnn::ConstTensor cellToForgetWeights(inputWeightsInfo3, cellToForgetWeightsData);
2373
2374 std::vector<float> cellToOutputWeightsData = GenerateRandomData<float>(inputWeightsInfo3.GetNumElements());
2375 armnn::ConstTensor cellToOutputWeights(inputWeightsInfo3, cellToOutputWeightsData);
2376
2377 std::vector<float> forgetGateBiasData(numUnits, 1.0f);
2378 armnn::ConstTensor forgetGateBias(inputWeightsInfo3, forgetGateBiasData);
2379
2380 std::vector<float> cellBiasData(numUnits, 0.0f);
2381 armnn::ConstTensor cellBias(inputWeightsInfo3, cellBiasData);
2382
2383 std::vector<float> outputGateBiasData(numUnits, 0.0f);
2384 armnn::ConstTensor outputGateBias(inputWeightsInfo3, outputGateBiasData);
2385
2386 armnn::LstmInputParams params;
2387 params.m_InputToForgetWeights = &inputToForgetWeights;
2388 params.m_InputToCellWeights = &inputToCellWeights;
2389 params.m_InputToOutputWeights = &inputToOutputWeights;
2390 params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
2391 params.m_RecurrentToCellWeights = &recurrentToCellWeights;
2392 params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
2393 params.m_ForgetGateBias = &forgetGateBias;
2394 params.m_CellBias = &cellBias;
2395 params.m_OutputGateBias = &outputGateBias;
2396 params.m_CellToForgetWeights = &cellToForgetWeights;
2397 params.m_CellToOutputWeights = &cellToOutputWeights;
2398
2399 armnn::INetworkPtr network = armnn::INetwork::Create();
2400 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2401 armnn::IConnectableLayer* const cellStateIn = network->AddInputLayer(1);
2402 armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(2);
2403 const std::string layerName("lstm");
2404 armnn::IConnectableLayer* const lstmLayer = network->AddLstmLayer(descriptor, params, layerName.c_str());
2405 armnn::IConnectableLayer* const scratchBuffer = network->AddOutputLayer(0);
2406 armnn::IConnectableLayer* const outputStateOut = network->AddOutputLayer(1);
2407 armnn::IConnectableLayer* const cellStateOut = network->AddOutputLayer(2);
2408 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(3);
2409
2410 // connect up
2411 armnn::TensorInfo inputTensorInfo({ batchSize, inputSize }, armnn::DataType::Float32);
2412 armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits}, armnn::DataType::Float32);
2413 armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
2414 armnn::TensorInfo lstmTensorInfoScratchBuff({ batchSize, numUnits * 3 }, armnn::DataType::Float32);
2415
2416 inputLayer->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(0));
2417 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
2418
2419 outputStateIn->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(1));
2420 outputStateIn->GetOutputSlot(0).SetTensorInfo(outputStateTensorInfo);
2421
2422 cellStateIn->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(2));
2423 cellStateIn->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
2424
2425 lstmLayer->GetOutputSlot(0).Connect(scratchBuffer->GetInputSlot(0));
2426 lstmLayer->GetOutputSlot(0).SetTensorInfo(lstmTensorInfoScratchBuff);
2427
2428 lstmLayer->GetOutputSlot(1).Connect(outputStateOut->GetInputSlot(0));
2429 lstmLayer->GetOutputSlot(1).SetTensorInfo(outputStateTensorInfo);
2430
2431 lstmLayer->GetOutputSlot(2).Connect(cellStateOut->GetInputSlot(0));
2432 lstmLayer->GetOutputSlot(2).SetTensorInfo(cellStateTensorInfo);
2433
2434 lstmLayer->GetOutputSlot(3).Connect(outputLayer->GetInputSlot(0));
2435 lstmLayer->GetOutputSlot(3).SetTensorInfo(outputStateTensorInfo);
2436
2437 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2438 BOOST_CHECK(deserializedNetwork);
2439
2440 VerifyLstmLayer checker(
2441 layerName,
2442 {inputTensorInfo, outputStateTensorInfo, cellStateTensorInfo},
2443 {lstmTensorInfoScratchBuff, outputStateTensorInfo, cellStateTensorInfo, outputStateTensorInfo},
2444 descriptor,
2445 params);
2446 deserializedNetwork->Accept(checker);
2447}
2448
2449BOOST_AUTO_TEST_CASE(SerializeDeserializeLstmNoCifgWithPeepholeAndProjection)
2450{
2451 armnn::LstmDescriptor descriptor;
2452 descriptor.m_ActivationFunc = 4;
2453 descriptor.m_ClippingThresProj = 0.0f;
2454 descriptor.m_ClippingThresCell = 0.0f;
2455 descriptor.m_CifgEnabled = false; // if this is true then we DON'T need to set the OptCifgParams
2456 descriptor.m_ProjectionEnabled = true;
2457 descriptor.m_PeepholeEnabled = true;
2458
2459 const uint32_t batchSize = 2;
2460 const uint32_t inputSize = 5;
2461 const uint32_t numUnits = 20;
2462 const uint32_t outputSize = 16;
2463
2464 armnn::TensorInfo tensorInfo20x5({numUnits, inputSize}, armnn::DataType::Float32);
2465 std::vector<float> inputToInputWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2466 armnn::ConstTensor inputToInputWeights(tensorInfo20x5, inputToInputWeightsData);
2467
2468 std::vector<float> inputToForgetWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2469 armnn::ConstTensor inputToForgetWeights(tensorInfo20x5, inputToForgetWeightsData);
2470
2471 std::vector<float> inputToCellWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2472 armnn::ConstTensor inputToCellWeights(tensorInfo20x5, inputToCellWeightsData);
2473
2474 std::vector<float> inputToOutputWeightsData = GenerateRandomData<float>(tensorInfo20x5.GetNumElements());
2475 armnn::ConstTensor inputToOutputWeights(tensorInfo20x5, inputToOutputWeightsData);
2476
2477 armnn::TensorInfo tensorInfo20({numUnits}, armnn::DataType::Float32);
2478 std::vector<float> inputGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2479 armnn::ConstTensor inputGateBias(tensorInfo20, inputGateBiasData);
2480
2481 std::vector<float> forgetGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2482 armnn::ConstTensor forgetGateBias(tensorInfo20, forgetGateBiasData);
2483
2484 std::vector<float> cellBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2485 armnn::ConstTensor cellBias(tensorInfo20, cellBiasData);
2486
2487 std::vector<float> outputGateBiasData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2488 armnn::ConstTensor outputGateBias(tensorInfo20, outputGateBiasData);
2489
2490 armnn::TensorInfo tensorInfo20x16({numUnits, outputSize}, armnn::DataType::Float32);
2491 std::vector<float> recurrentToInputWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2492 armnn::ConstTensor recurrentToInputWeights(tensorInfo20x16, recurrentToInputWeightsData);
2493
2494 std::vector<float> recurrentToForgetWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2495 armnn::ConstTensor recurrentToForgetWeights(tensorInfo20x16, recurrentToForgetWeightsData);
2496
2497 std::vector<float> recurrentToCellWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2498 armnn::ConstTensor recurrentToCellWeights(tensorInfo20x16, recurrentToCellWeightsData);
2499
2500 std::vector<float> recurrentToOutputWeightsData = GenerateRandomData<float>(tensorInfo20x16.GetNumElements());
2501 armnn::ConstTensor recurrentToOutputWeights(tensorInfo20x16, recurrentToOutputWeightsData);
2502
2503 std::vector<float> cellToInputWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2504 armnn::ConstTensor cellToInputWeights(tensorInfo20, cellToInputWeightsData);
2505
2506 std::vector<float> cellToForgetWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2507 armnn::ConstTensor cellToForgetWeights(tensorInfo20, cellToForgetWeightsData);
2508
2509 std::vector<float> cellToOutputWeightsData = GenerateRandomData<float>(tensorInfo20.GetNumElements());
2510 armnn::ConstTensor cellToOutputWeights(tensorInfo20, cellToOutputWeightsData);
2511
2512 armnn::TensorInfo tensorInfo16x20({outputSize, numUnits}, armnn::DataType::Float32);
2513 std::vector<float> projectionWeightsData = GenerateRandomData<float>(tensorInfo16x20.GetNumElements());
2514 armnn::ConstTensor projectionWeights(tensorInfo16x20, projectionWeightsData);
2515
2516 armnn::TensorInfo tensorInfo16({outputSize}, armnn::DataType::Float32);
2517 std::vector<float> projectionBiasData(outputSize, 0.f);
2518 armnn::ConstTensor projectionBias(tensorInfo16, projectionBiasData);
2519
2520 armnn::LstmInputParams params;
2521 params.m_InputToForgetWeights = &inputToForgetWeights;
2522 params.m_InputToCellWeights = &inputToCellWeights;
2523 params.m_InputToOutputWeights = &inputToOutputWeights;
2524 params.m_RecurrentToForgetWeights = &recurrentToForgetWeights;
2525 params.m_RecurrentToCellWeights = &recurrentToCellWeights;
2526 params.m_RecurrentToOutputWeights = &recurrentToOutputWeights;
2527 params.m_ForgetGateBias = &forgetGateBias;
2528 params.m_CellBias = &cellBias;
2529 params.m_OutputGateBias = &outputGateBias;
2530
2531 // additional params because: descriptor.m_CifgEnabled = false
2532 params.m_InputToInputWeights = &inputToInputWeights;
2533 params.m_RecurrentToInputWeights = &recurrentToInputWeights;
2534 params.m_CellToInputWeights = &cellToInputWeights;
2535 params.m_InputGateBias = &inputGateBias;
2536
2537 // additional params because: descriptor.m_ProjectionEnabled = true
2538 params.m_ProjectionWeights = &projectionWeights;
2539 params.m_ProjectionBias = &projectionBias;
2540
2541 // additional params because: descriptor.m_PeepholeEnabled = true
2542 params.m_CellToForgetWeights = &cellToForgetWeights;
2543 params.m_CellToOutputWeights = &cellToOutputWeights;
2544
2545 armnn::INetworkPtr network = armnn::INetwork::Create();
2546 armnn::IConnectableLayer* const inputLayer = network->AddInputLayer(0);
2547 armnn::IConnectableLayer* const cellStateIn = network->AddInputLayer(1);
2548 armnn::IConnectableLayer* const outputStateIn = network->AddInputLayer(2);
2549 const std::string layerName("lstm");
2550 armnn::IConnectableLayer* const lstmLayer = network->AddLstmLayer(descriptor, params, layerName.c_str());
2551 armnn::IConnectableLayer* const scratchBuffer = network->AddOutputLayer(0);
2552 armnn::IConnectableLayer* const outputStateOut = network->AddOutputLayer(1);
2553 armnn::IConnectableLayer* const cellStateOut = network->AddOutputLayer(2);
2554 armnn::IConnectableLayer* const outputLayer = network->AddOutputLayer(3);
2555
2556 // connect up
2557 armnn::TensorInfo inputTensorInfo({ batchSize, inputSize }, armnn::DataType::Float32);
2558 armnn::TensorInfo cellStateTensorInfo({ batchSize, numUnits}, armnn::DataType::Float32);
2559 armnn::TensorInfo outputStateTensorInfo({ batchSize, outputSize }, armnn::DataType::Float32);
2560 armnn::TensorInfo lstmTensorInfoScratchBuff({ batchSize, numUnits * 4 }, armnn::DataType::Float32);
2561
2562 inputLayer->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(0));
2563 inputLayer->GetOutputSlot(0).SetTensorInfo(inputTensorInfo);
2564
2565 outputStateIn->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(1));
2566 outputStateIn->GetOutputSlot(0).SetTensorInfo(outputStateTensorInfo);
2567
2568 cellStateIn->GetOutputSlot(0).Connect(lstmLayer->GetInputSlot(2));
2569 cellStateIn->GetOutputSlot(0).SetTensorInfo(cellStateTensorInfo);
2570
2571 lstmLayer->GetOutputSlot(0).Connect(scratchBuffer->GetInputSlot(0));
2572 lstmLayer->GetOutputSlot(0).SetTensorInfo(lstmTensorInfoScratchBuff);
2573
2574 lstmLayer->GetOutputSlot(1).Connect(outputStateOut->GetInputSlot(0));
2575 lstmLayer->GetOutputSlot(1).SetTensorInfo(outputStateTensorInfo);
2576
2577 lstmLayer->GetOutputSlot(2).Connect(cellStateOut->GetInputSlot(0));
2578 lstmLayer->GetOutputSlot(2).SetTensorInfo(cellStateTensorInfo);
2579
2580 lstmLayer->GetOutputSlot(3).Connect(outputLayer->GetInputSlot(0));
2581 lstmLayer->GetOutputSlot(3).SetTensorInfo(outputStateTensorInfo);
2582
2583 armnn::INetworkPtr deserializedNetwork = DeserializeNetwork(SerializeNetwork(*network));
2584 BOOST_CHECK(deserializedNetwork);
2585
2586 VerifyLstmLayer checker(
2587 layerName,
2588 {inputTensorInfo, outputStateTensorInfo, cellStateTensorInfo},
2589 {lstmTensorInfoScratchBuff, outputStateTensorInfo, cellStateTensorInfo, outputStateTensorInfo},
2590 descriptor,
2591 params);
2592 deserializedNetwork->Accept(checker);
2593}
2594
Nattapat Chaimanowong30b00202019-02-20 17:31:34 +00002595BOOST_AUTO_TEST_SUITE_END()