ArmNN
 20.02
TensorHelpers.hpp File Reference
#include <armnn/Tensor.hpp>
#include <QuantizeHelper.hpp>
#include <boost/assert.hpp>
#include <boost/multi_array.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/test/tools/floating_point_comparison.hpp>
#include <boost/test/unit_test.hpp>
#include <array>
#include <cmath>
#include <vector>

Go to the source code of this file.

Classes

struct  SelectiveComparer< T, isQuantized >
 
struct  SelectiveComparer< T, false >
 

Functions

template<typename T >
bool SelectiveCompare (T a, T b)
 
template<typename T >
bool SelectiveCompareBoolean (T a, T b)
 
template<typename T , std::size_t n>
boost::test_tools::predicate_result CompareTensors (const boost::multi_array< T, n > &a, const boost::multi_array< T, n > &b, bool compareBoolean=false)
 
template<typename T , std::size_t n>
boost::multi_array< T, n > MakeTensor (const armnn::TensorInfo &tensorInfo)
 
template<typename T , std::size_t n>
boost::multi_array< T, n > MakeTensor (const armnn::TensorInfo &tensorInfo, const std::vector< T > &flat)
 
template<typename T , std::size_t n>
boost::multi_array< T, n > MakeRandomTensor (const armnn::TensorInfo &tensorInfo, unsigned int seed, float min=-10.0f, float max=10.0f)
 

Variables

constexpr float g_FloatCloseToZeroTolerance = 1.0e-6f
 

Function Documentation

◆ CompareTensors()

boost::test_tools::predicate_result CompareTensors ( const boost::multi_array< T, n > &  a,
const boost::multi_array< T, n > &  b,
bool  compareBoolean = false 
)

Definition at line 75 of file TensorHelpers.hpp.

References SelectiveCompare(), and SelectiveCompareBoolean().

Referenced by BOOST_AUTO_TEST_CASE(), CompareTestResultIfSupported(), DetectionPostProcessImpl(), ParserPrototxtFixture< armnnOnnxParser::IOnnxParser >::RunTest(), ParserFlatbuffersSerializeFixture::RunTest(), and ParserFlatbuffersFixture::RunTest().

78 {
79  // Checks they are same shape.
80  for (unsigned int i=0; i<n; i++)
81  {
82  if (a.shape()[i] != b.shape()[i])
83  {
84  boost::test_tools::predicate_result res(false);
85  res.message() << "Different shapes ["
86  << a.shape()[i]
87  << "!="
88  << b.shape()[i]
89  << "]";
90  return res;
91  }
92  }
93 
94  // Now compares element-wise.
95 
96  // Fun iteration over n dimensions.
97  std::array<unsigned int, n> indices;
98  for (unsigned int i = 0; i < n; i++)
99  {
100  indices[i] = 0;
101  }
102 
103  std::stringstream errorString;
104  int numFailedElements = 0;
105  constexpr int maxReportedDifferences = 3;
106 
107  while (true)
108  {
109  bool comparison;
110  // As true for uint8_t is non-zero (1-255) we must have a dedicated compare for Booleans.
111  if(compareBoolean)
112  {
113  comparison = SelectiveCompareBoolean(a(indices), b(indices));
114  }
115  else
116  {
117  comparison = SelectiveCompare(a(indices), b(indices));
118  }
119 
120  if (!comparison)
121  {
122  ++numFailedElements;
123 
124  if (numFailedElements <= maxReportedDifferences)
125  {
126  if (numFailedElements >= 2)
127  {
128  errorString << ", ";
129  }
130  errorString << "[";
131  for (unsigned int i = 0; i < n; ++i)
132  {
133  errorString << indices[i];
134  if (i != n - 1)
135  {
136  errorString << ",";
137  }
138  }
139  errorString << "]";
140 
141  errorString << " (" << +a(indices) << " != " << +b(indices) << ")";
142  }
143  }
144 
145  ++indices[n - 1];
146  for (unsigned int i=n-1; i>0; i--)
147  {
148  if (indices[i] == a.shape()[i])
149  {
150  indices[i] = 0;
151  ++indices[i - 1];
152  }
153  }
154 
155  if (indices[0] == a.shape()[0])
156  {
157  break;
158  }
159  }
160 
161  boost::test_tools::predicate_result comparisonResult(true);
162  if (numFailedElements > 0)
163  {
164  comparisonResult = false;
165  comparisonResult.message() << numFailedElements << " different values at: ";
166  if (numFailedElements > maxReportedDifferences)
167  {
168  errorString << ", ... (and " << (numFailedElements - maxReportedDifferences) << " other differences)";
169  }
170  comparisonResult.message() << errorString.str();
171  }
172 
173  return comparisonResult;
174 }
bool SelectiveCompareBoolean(T a, T b)
bool SelectiveCompare(T a, T b)

◆ MakeRandomTensor()

boost::multi_array<T, n> MakeRandomTensor ( const armnn::TensorInfo tensorInfo,
unsigned int  seed,
float  min = -10.0f,
float  max = 10.0f 
)

Definition at line 223 of file TensorHelpers.hpp.

References TensorInfo::GetNumElements(), TensorInfo::GetQuantizationOffset(), and TensorInfo::GetQuantizationScale().

227 {
228  boost::random::mt19937 gen(seed);
229  boost::random::uniform_real_distribution<float> dist(min, max);
230 
231  std::vector<float> init(tensorInfo.GetNumElements());
232  for (unsigned int i = 0; i < init.size(); i++)
233  {
234  init[i] = dist(gen);
235  }
236 
237  const float qScale = tensorInfo.GetQuantizationScale();
238  const int32_t qOffset = tensorInfo.GetQuantizationOffset();
239 
240  return MakeTensor<T, n>(tensorInfo, armnnUtils::QuantizedVector<T>(init, qScale, qOffset));
241 }
int32_t GetQuantizationOffset() const
Definition: Tensor.cpp:264
float GetQuantizationScale() const
Definition: Tensor.cpp:247
unsigned int GetNumElements() const
Definition: Tensor.hpp:93

◆ MakeTensor() [1/2]

boost::multi_array<T, n> MakeTensor ( const armnn::TensorInfo tensorInfo)

Definition at line 179 of file TensorHelpers.hpp.

References TensorInfo::GetShape().

180 {
181  std::array<unsigned int, n> shape;
182 
183  for (unsigned int i = 0; i < n; i++)
184  {
185  shape[i] = tensorInfo.GetShape()[i];
186  }
187 
188  return boost::multi_array<T, n>(shape);
189 }
const TensorShape & GetShape() const
Definition: Tensor.hpp:88

◆ MakeTensor() [2/2]

boost::multi_array<T, n> MakeTensor ( const armnn::TensorInfo tensorInfo,
const std::vector< T > &  flat 
)

Definition at line 193 of file TensorHelpers.hpp.

References TensorInfo::GetNumDimensions(), TensorInfo::GetNumElements(), and TensorInfo::GetShape().

194 {
195  BOOST_ASSERT_MSG(flat.size() == tensorInfo.GetNumElements(), "Wrong number of components supplied to tensor");
196 
197  std::array<unsigned int, n> shape;
198 
199  // NOTE: tensorInfo.GetNumDimensions() might be different from n
200  const unsigned int returnDimensions = static_cast<unsigned int>(n);
201  const unsigned int actualDimensions = tensorInfo.GetNumDimensions();
202 
203  const unsigned int paddedDimensions =
204  returnDimensions > actualDimensions ? returnDimensions - actualDimensions : 0u;
205 
206  for (unsigned int i = 0u; i < returnDimensions; i++)
207  {
208  if (i < paddedDimensions)
209  {
210  shape[i] = 1u;
211  }
212  else
213  {
214  shape[i] = tensorInfo.GetShape()[i - paddedDimensions];
215  }
216  }
217 
218  boost::const_multi_array_ref<T, n> arrayRef(&flat[0], shape);
219  return boost::multi_array<T, n>(arrayRef);
220 }
const TensorShape & GetShape() const
Definition: Tensor.hpp:88
unsigned int GetNumDimensions() const
Definition: Tensor.hpp:92
unsigned int GetNumElements() const
Definition: Tensor.hpp:93

◆ SelectiveCompare()

bool SelectiveCompare ( a,
b 
)

Definition at line 63 of file TensorHelpers.hpp.

References SelectiveComparer< T, isQuantized >::Compare().

Referenced by CompareTensors().

64 {
65  return SelectiveComparer<T, armnn::IsQuantizedType<T>()>::Compare(a, b);
66 };

◆ SelectiveCompareBoolean()

bool SelectiveCompareBoolean ( a,
b 
)

Definition at line 69 of file TensorHelpers.hpp.

Referenced by CompareTensors().

70 {
71  return (((a == 0) && (b == 0)) || ((a != 0) && (b != 0)));
72 };

Variable Documentation

◆ g_FloatCloseToZeroTolerance

constexpr float g_FloatCloseToZeroTolerance = 1.0e-6f

Definition at line 23 of file TensorHelpers.hpp.

Referenced by SelectiveComparer< T, false >::Compare().