• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
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 
15 #include <cstdlib>
16 #include <doctest/doctest.h>
17 
18 armnn::INetworkPtr DeserializeNetwork(const std::string& serializerString);
19 
20 std::string SerializeNetwork(const armnn::INetwork& network);
21 
22 void CompareConstTensor(const armnn::ConstTensor& tensor1, const armnn::ConstTensor& tensor2);
23 
24 class LayerVerifierBase : public armnn::IStrategy
25 {
26 public:
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 
37 protected:
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 
44 private:
45     std::string m_LayerName;
46     std::vector<armnn::TensorInfo> m_InputTensorInfos;
47     std::vector<armnn::TensorInfo> m_OutputTensorInfos;
48 };
49 
50 template<typename Descriptor>
51 class LayerVerifierBaseWithDescriptor : public LayerVerifierBase
52 {
53 public:
LayerVerifierBaseWithDescriptor(const std::string & layerName,const std::vector<armnn::TensorInfo> & inputInfos,const std::vector<armnn::TensorInfo> & outputInfos,const Descriptor & descriptor)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 
ExecuteStrategy(const armnn::IConnectableLayer * layer,const armnn::BaseDescriptor & descriptor,const std::vector<armnn::ConstTensor> & constants,const char * name,const armnn::LayerBindingId id=0)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             case armnn::LayerType::Constant: break;
73             default:
74             {
75                 VerifyNameAndConnections(layer, name);
76                 const Descriptor& internalDescriptor = static_cast<const Descriptor&>(descriptor);
77                 VerifyDescriptor(internalDescriptor);
78                 break;
79             }
80         }
81     }
82 
83 protected:
VerifyDescriptor(const Descriptor & descriptor)84     void VerifyDescriptor(const Descriptor& descriptor)
85     {
86         CHECK(descriptor == m_Descriptor);
87     }
88 
89     Descriptor m_Descriptor;
90 };
91 
92 template<typename T>
CompareConstTensorData(const void * data1,const void * data2,unsigned int numElements)93 void CompareConstTensorData(const void* data1, const void* data2, unsigned int numElements)
94 {
95     T typedData1 = static_cast<T>(data1);
96     T typedData2 = static_cast<T>(data2);
97     CHECK(typedData1);
98     CHECK(typedData2);
99 
100     for (unsigned int i = 0; i < numElements; i++)
101     {
102         CHECK(typedData1[i] == typedData2[i]);
103     }
104 }
105 
106 
107 template <typename Descriptor>
108 class LayerVerifierBaseWithDescriptorAndConstants : public LayerVerifierBaseWithDescriptor<Descriptor>
109 {
110 public:
LayerVerifierBaseWithDescriptorAndConstants(const std::string & layerName,const std::vector<armnn::TensorInfo> & inputInfos,const std::vector<armnn::TensorInfo> & outputInfos,const Descriptor & descriptor,const std::vector<armnn::ConstTensor> & constants)111     LayerVerifierBaseWithDescriptorAndConstants(const std::string& layerName,
112                                                 const std::vector<armnn::TensorInfo>& inputInfos,
113                                                 const std::vector<armnn::TensorInfo>& outputInfos,
114                                                 const Descriptor& descriptor,
115                                                 const std::vector<armnn::ConstTensor>& constants)
116             : LayerVerifierBaseWithDescriptor<Descriptor>(layerName, inputInfos, outputInfos, descriptor)
117             , m_Constants(constants) {}
118 
ExecuteStrategy(const armnn::IConnectableLayer * layer,const armnn::BaseDescriptor & descriptor,const std::vector<armnn::ConstTensor> & constants,const char * name,const armnn::LayerBindingId id=0)119     void ExecuteStrategy(const armnn::IConnectableLayer* layer,
120                          const armnn::BaseDescriptor& descriptor,
121                          const std::vector<armnn::ConstTensor>& constants,
122                          const char* name,
123                          const armnn::LayerBindingId id = 0) override
124     {
125         armnn::IgnoreUnused(id);
126 
127         switch (layer->GetType())
128         {
129             case armnn::LayerType::Input: break;
130             case armnn::LayerType::Output: break;
131             case armnn::LayerType::Constant: break;
132             default:
133             {
134                 this->VerifyNameAndConnections(layer, name);
135                 const Descriptor& internalDescriptor = static_cast<const Descriptor&>(descriptor);
136                 this->VerifyDescriptor(internalDescriptor);
137 
138                 for(std::size_t i = 0; i < constants.size(); i++)
139                 {
140                     CompareConstTensor(constants[i], m_Constants[i]);
141                 }
142             }
143         }
144     }
145 
146 private:
147     std::vector<armnn::ConstTensor> m_Constants;
148 };
149 
150 template<typename DataType>
GenerateRandomData(size_t size)151 static std::vector<DataType> GenerateRandomData(size_t size)
152 {
153     constexpr bool isIntegerType = std::is_integral<DataType>::value;
154     using Distribution =
155         typename std::conditional<isIntegerType,
156                                   std::uniform_int_distribution<DataType>,
157                                   std::uniform_real_distribution<DataType>>::type;
158 
159     static constexpr DataType lowerLimit = std::numeric_limits<DataType>::min();
160     static constexpr DataType upperLimit = std::numeric_limits<DataType>::max();
161 
162     static Distribution distribution(lowerLimit, upperLimit);
163     static std::default_random_engine generator;
164 
165     std::vector<DataType> randomData(size);
166     generate(randomData.begin(), randomData.end(), []() { return distribution(generator); });
167 
168     return randomData;
169 }