ArmNN
 20.11
TensorHelpers.hpp File Reference
#include <armnn/Tensor.hpp>
#include <armnn/utility/Assert.hpp>
#include <armnnUtils/FloatingPointComparison.hpp>
#include <QuantizeHelper.hpp>
#include <boost/multi_array.hpp>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/random/mersenne_twister.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, bool isDynamic=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, bool isDynamic=false)
 
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,
bool  isDynamic = false 
)

Definition at line 73 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().

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

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

235 {
236  boost::random::mt19937 gen(seed);
237  boost::random::uniform_real_distribution<float> dist(min, max);
238 
239  std::vector<float> init(tensorInfo.GetNumElements());
240  for (unsigned int i = 0; i < init.size(); i++)
241  {
242  init[i] = dist(gen);
243  }
244 
245  const float qScale = tensorInfo.GetQuantizationScale();
246  const int32_t qOffset = tensorInfo.GetQuantizationOffset();
247 
248  return MakeTensor<T, n>(tensorInfo, armnnUtils::QuantizedVector<T>(init, qScale, qOffset));
249 }
int32_t GetQuantizationOffset() const
Definition: Tensor.cpp:469
float GetQuantizationScale() const
Definition: Tensor.cpp:452
unsigned int GetNumElements() const
Definition: Tensor.hpp:192

◆ MakeTensor() [1/2]

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

Definition at line 183 of file TensorHelpers.hpp.

References TensorInfo::GetShape().

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

◆ MakeTensor() [2/2]

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

Definition at line 197 of file TensorHelpers.hpp.

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

199 {
200  if (!isDynamic)
201  {
202  ARMNN_ASSERT_MSG(flat.size() == tensorInfo.GetNumElements(), "Wrong number of components supplied to tensor");
203  }
204 
205  std::array<unsigned int, n> shape;
206 
207  // NOTE: tensorInfo.GetNumDimensions() might be different from n
208  const unsigned int returnDimensions = static_cast<unsigned int>(n);
209  const unsigned int actualDimensions = tensorInfo.GetNumDimensions();
210 
211  const unsigned int paddedDimensions =
212  returnDimensions > actualDimensions ? returnDimensions - actualDimensions : 0u;
213 
214  for (unsigned int i = 0u; i < returnDimensions; i++)
215  {
216  if (i < paddedDimensions)
217  {
218  shape[i] = 1u;
219  }
220  else
221  {
222  shape[i] = tensorInfo.GetShape()[i - paddedDimensions];
223  }
224  }
225 
226  boost::const_multi_array_ref<T, n> arrayRef(&flat[0], shape);
227  return boost::multi_array<T, n>(arrayRef);
228 }
const TensorShape & GetShape() const
Definition: Tensor.hpp:187
#define ARMNN_ASSERT_MSG(COND, MSG)
Definition: Assert.hpp:15
unsigned int GetNumDimensions() const
Definition: Tensor.hpp:191
unsigned int GetNumElements() const
Definition: Tensor.hpp:192

◆ SelectiveCompare()

bool SelectiveCompare ( a,
b 
)

Definition at line 61 of file TensorHelpers.hpp.

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

Referenced by CompareTensors().

62 {
64 };
bool Compare(T a, T b, float tolerance=0.000001f)

◆ SelectiveCompareBoolean()

bool SelectiveCompareBoolean ( a,
b 
)

Definition at line 67 of file TensorHelpers.hpp.

Referenced by CompareTensors().

68 {
69  return (((a == 0) && (b == 0)) || ((a != 0) && (b != 0)));
70 };

Variable Documentation

◆ g_FloatCloseToZeroTolerance

constexpr float g_FloatCloseToZeroTolerance = 1.0e-6f

Definition at line 22 of file TensorHelpers.hpp.

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