blob: c6f148b1a194e17a9d25c9b63084051b2f3d605b [file] [log] [blame]
Finn Williamsb454c5c2021-02-09 15:56:23 +00001//
2// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include <armnn/Descriptors.hpp>
7#include <armnn/INetwork.hpp>
8#include <armnn/TypesUtils.hpp>
9#include <armnnDeserializer/IDeserializer.hpp>
10#include <armnn/utility/IgnoreUnused.hpp>
11
12#include <random>
13#include <vector>
14
Sadik Armagan1625efc2021-06-10 18:24:34 +010015#include <cstdlib>
16#include <doctest/doctest.h>
Finn Williamsb454c5c2021-02-09 15:56:23 +000017
18armnn::INetworkPtr DeserializeNetwork(const std::string& serializerString);
19
20std::string SerializeNetwork(const armnn::INetwork& network);
21
22void CompareConstTensor(const armnn::ConstTensor& tensor1, const armnn::ConstTensor& tensor2);
23
24class LayerVerifierBase : public armnn::IStrategy
25{
26public:
27 LayerVerifierBase(const std::string& layerName,
28 const std::vector<armnn::TensorInfo>& inputInfos,
29 const std::vector<armnn::TensorInfo>& outputInfos);
30
31 void ExecuteStrategy(const armnn::IConnectableLayer* layer,
32 const armnn::BaseDescriptor& descriptor,
33 const std::vector<armnn::ConstTensor>& constants,
34 const char* name,
35 const armnn::LayerBindingId id = 0) override;
36
37protected:
38 void VerifyNameAndConnections(const armnn::IConnectableLayer* layer, const char* name);
39
40 void VerifyConstTensors(const std::string& tensorName,
41 const armnn::ConstTensor* expectedPtr,
42 const armnn::ConstTensor* actualPtr);
43
44private:
45 std::string m_LayerName;
46 std::vector<armnn::TensorInfo> m_InputTensorInfos;
47 std::vector<armnn::TensorInfo> m_OutputTensorInfos;
48};
49
50template<typename Descriptor>
51class LayerVerifierBaseWithDescriptor : public LayerVerifierBase
52{
53public:
54 LayerVerifierBaseWithDescriptor(const std::string& layerName,
55 const std::vector<armnn::TensorInfo>& inputInfos,
56 const std::vector<armnn::TensorInfo>& outputInfos,
57 const Descriptor& descriptor)
58 : LayerVerifierBase(layerName, inputInfos, outputInfos)
59 , m_Descriptor(descriptor) {}
60
61 void ExecuteStrategy(const armnn::IConnectableLayer* layer,
62 const armnn::BaseDescriptor& descriptor,
63 const std::vector<armnn::ConstTensor>& constants,
64 const char* name,
65 const armnn::LayerBindingId id = 0) override
66 {
67 armnn::IgnoreUnused(constants, id);
68 switch (layer->GetType())
69 {
70 case armnn::LayerType::Input: break;
71 case armnn::LayerType::Output: break;
72 default:
73 {
74 VerifyNameAndConnections(layer, name);
75 const Descriptor& internalDescriptor = static_cast<const Descriptor&>(descriptor);
76 VerifyDescriptor(internalDescriptor);
77 break;
78 }
79 }
80 }
81
82protected:
83 void VerifyDescriptor(const Descriptor& descriptor)
84 {
Sadik Armagan1625efc2021-06-10 18:24:34 +010085 CHECK(descriptor == m_Descriptor);
Finn Williamsb454c5c2021-02-09 15:56:23 +000086 }
87
88 Descriptor m_Descriptor;
89};
90
91template<typename T>
92void CompareConstTensorData(const void* data1, const void* data2, unsigned int numElements)
93{
94 T typedData1 = static_cast<T>(data1);
95 T typedData2 = static_cast<T>(data2);
Sadik Armagan1625efc2021-06-10 18:24:34 +010096 CHECK(typedData1);
97 CHECK(typedData2);
Finn Williamsb454c5c2021-02-09 15:56:23 +000098
99 for (unsigned int i = 0; i < numElements; i++)
100 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100101 CHECK(typedData1[i] == typedData2[i]);
Finn Williamsb454c5c2021-02-09 15:56:23 +0000102 }
103}
104
105
106template <typename Descriptor>
107class LayerVerifierBaseWithDescriptorAndConstants : public LayerVerifierBaseWithDescriptor<Descriptor>
108{
109public:
110 LayerVerifierBaseWithDescriptorAndConstants(const std::string& layerName,
111 const std::vector<armnn::TensorInfo>& inputInfos,
112 const std::vector<armnn::TensorInfo>& outputInfos,
113 const Descriptor& descriptor,
114 const std::vector<armnn::ConstTensor>& constants)
115 : LayerVerifierBaseWithDescriptor<Descriptor>(layerName, inputInfos, outputInfos, descriptor)
116 , m_Constants(constants) {}
117
118 void ExecuteStrategy(const armnn::IConnectableLayer* layer,
119 const armnn::BaseDescriptor& descriptor,
120 const std::vector<armnn::ConstTensor>& constants,
121 const char* name,
122 const armnn::LayerBindingId id = 0) override
123 {
124 armnn::IgnoreUnused(id);
125
126 switch (layer->GetType())
127 {
128 case armnn::LayerType::Input: break;
129 case armnn::LayerType::Output: break;
130 default:
131 {
132 this->VerifyNameAndConnections(layer, name);
133 const Descriptor& internalDescriptor = static_cast<const Descriptor&>(descriptor);
134 this->VerifyDescriptor(internalDescriptor);
135
136 for(std::size_t i = 0; i < constants.size(); i++)
137 {
138 CompareConstTensor(constants[i], m_Constants[i]);
139 }
140 }
141 }
142 }
143
144private:
145 std::vector<armnn::ConstTensor> m_Constants;
146};
147
148template<typename DataType>
149static std::vector<DataType> GenerateRandomData(size_t size)
150{
151 constexpr bool isIntegerType = std::is_integral<DataType>::value;
152 using Distribution =
153 typename std::conditional<isIntegerType,
154 std::uniform_int_distribution<DataType>,
155 std::uniform_real_distribution<DataType>>::type;
156
157 static constexpr DataType lowerLimit = std::numeric_limits<DataType>::min();
158 static constexpr DataType upperLimit = std::numeric_limits<DataType>::max();
159
160 static Distribution distribution(lowerLimit, upperLimit);
161 static std::default_random_engine generator;
162
163 std::vector<DataType> randomData(size);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100164 generate(randomData.begin(), randomData.end(), []() { return distribution(generator); });
Finn Williamsb454c5c2021-02-09 15:56:23 +0000165
166 return randomData;
167}