ArmNN
 20.08
TensorHelpers.hpp File Reference
#include <armnn/Tensor.hpp>
#include <armnn/utility/Assert.hpp>
#include <QuantizeHelper.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, 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 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().

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

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

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

◆ MakeTensor() [1/2]

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

Definition at line 185 of file TensorHelpers.hpp.

References TensorInfo::GetShape().

186 {
187  std::array<unsigned int, n> shape;
188 
189  for (unsigned int i = 0; i < n; i++)
190  {
191  shape[i] = tensorInfo.GetShape()[i];
192  }
193 
194  return boost::multi_array<T, n>(shape);
195 }
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 199 of file TensorHelpers.hpp.

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

201 {
202  if (!isDynamic)
203  {
204  ARMNN_ASSERT_MSG(flat.size() == tensorInfo.GetNumElements(), "Wrong number of components supplied to tensor");
205  }
206 
207  std::array<unsigned int, n> shape;
208 
209  // NOTE: tensorInfo.GetNumDimensions() might be different from n
210  const unsigned int returnDimensions = static_cast<unsigned int>(n);
211  const unsigned int actualDimensions = tensorInfo.GetNumDimensions();
212 
213  const unsigned int paddedDimensions =
214  returnDimensions > actualDimensions ? returnDimensions - actualDimensions : 0u;
215 
216  for (unsigned int i = 0u; i < returnDimensions; i++)
217  {
218  if (i < paddedDimensions)
219  {
220  shape[i] = 1u;
221  }
222  else
223  {
224  shape[i] = tensorInfo.GetShape()[i - paddedDimensions];
225  }
226  }
227 
228  boost::const_multi_array_ref<T, n> arrayRef(&flat[0], shape);
229  return boost::multi_array<T, n>(arrayRef);
230 }
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 63 of file TensorHelpers.hpp.

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

Referenced by CompareTensors().

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

◆ 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().