};
#include "support/tflite/interp/Builder.h"
+#include "support/tflite/Quantization.h"
#include <random>
-template <typename T> class RandomGenerator
+class RandomGenerator
{
public:
- RandomGenerator(int seed, T mean, T stddev) : _rand{seed}, _dist{mean, stddev}
+ RandomGenerator(int seed, float mean, float stddev,
+ const TfLiteQuantizationParams quantization = make_default_quantization())
+ : _rand{seed}, _dist{mean, stddev}, _quantization{quantization}
{
// DO NOTHING
}
- T operator()(const ::nnfw::util::tensor::Shape &, const ::nnfw::util::tensor::Index &)
+public:
+ template <typename T>
+ T generate(const ::nnfw::util::tensor::Shape &, const ::nnfw::util::tensor::Index &)
{
- return (*this)();
+ return generate<T>();
}
- T operator()(void)
+ template <typename T> T generate(void)
{
return _dist(_rand);
}
private:
std::minstd_rand _rand;
- std::normal_distribution<T> _dist;
+ std::normal_distribution<float> _dist;
+ const TfLiteQuantizationParams _quantization;
};
+template <>
+uint8_t RandomGenerator::generate<uint8_t>(void);
+
// For NNAPI testing
struct RandomTestParam
{
class RandomTestRunner
{
public:
- RandomTestRunner(int seed, const RandomTestParam ¶m)
- : _randgen{seed, 0.0f, 2.0f}, _param{param}
+ RandomTestRunner(int seed, const RandomTestParam ¶m,
+ const TfLiteQuantizationParams quantization = make_default_quantization())
+ : _randgen{seed, 0.0f, 2.0f, quantization}, _param{param}
{
// DO NOTHING
}
int run(const nnfw::support::tflite::interp::Builder &builder);
private:
- RandomGenerator<float> _randgen;
+ RandomGenerator _randgen;
const RandomTestParam _param;
public:
#include "util/tensor/Object.h"
+using namespace std::placeholders;
+
+template <> uint8_t RandomGenerator::generate<uint8_t>(void)
+{
+ return static_cast<uint8_t>(_dist(_rand) / _quantization.scale + _quantization.zero_point);
+}
+
//
// Random Test Runner
//
assert(tfl_interp_view.shape() == nnapi_view.shape());
- const nnfw::util::tensor::Object<float> data(tfl_interp_view.shape(), _randgen);
+ auto fp = static_cast<float (RandomGenerator::*)(const ::nnfw::util::tensor::Shape &,
+ const ::nnfw::util::tensor::Index &)>(
+ &RandomGenerator::generate<float>);
+ const nnfw::util::tensor::Object<float> data(tfl_interp_view.shape(),
+ std::bind(fp, _randgen, _1, _2));
assert(tfl_interp_view.shape() == data.shape());
assert(tensor->type == kTfLiteFloat32);
const int seed = 1; /* TODO Add an option for seed value */
- RandomGenerator<float> randgen{seed, 0.0f, 0.2f};
+ RandomGenerator randgen{seed, 0.0f, 0.2f};
const float *end = reinterpret_cast<const float *>(tensor->data.raw_const + tensor->bytes);
for (float *ptr = tensor->data.f; ptr < end; ptr++)
{
- *ptr = randgen();
+ *ptr = randgen.generate<float>();
}
}
}
assert(tensor->type == kTfLiteFloat32);
const int seed = 1; /* TODO Add an option for seed value */
- RandomGenerator<float> randgen{seed, 0.0f, 0.2f};
+ RandomGenerator randgen{seed, 0.0f, 0.2f};
const float *end = reinterpret_cast<const float *>(tensor->data.raw_const + tensor->bytes);
for (float *ptr = tensor->data.f; ptr < end; ptr++)
{
- *ptr = randgen();
+ *ptr = randgen.generate<float>();
}
}
}