--- /dev/null
+#ifndef __NNFW_UTIL_TENSOR_OBJECT_H__
+#define __NNFW_UTIL_TENSOR_OBJECT_H__
+
+#include "util/tensor/Shape.h"
+#include "util/tensor/Index.h"
+#include "util/tensor/IndexIterator.h"
+#include "util/tensor/NonIncreasingStride.h"
+#include "util/tensor/Reader.h"
+
+#include <vector>
+
+namespace nnfw
+{
+namespace util
+{
+namespace tensor
+{
+
+template<typename T> class Object final : public Reader<T>
+{
+public:
+ using Generator = std::function<T (const Shape &shape, const Index &index)>;
+
+public:
+ Object(const Shape &shape, const Generator &fn) : _shape{shape}
+ {
+ // Set 'stride'
+ _stride.init(shape);
+
+ // Pre-allocate buffer
+ _values.resize(_shape.dim(0) * _stride.at(0));
+
+ // Set 'value'
+ iterate(_shape) << [this, &fn] (const Index &index)
+ {
+ _values.at(_stride.offset(index)) = fn(_shape, index);
+ };
+ }
+
+public:
+ const Shape &shape(void) const { return _shape; }
+
+public:
+ T at(const Index &index) const override
+ {
+ return _values.at(_stride.offset(index));
+ }
+
+private:
+ Shape _shape;
+ NonIncreasingStride _stride;
+
+private:
+ std::vector<T> _values;
+};
+
+} // namespace tensor
+} // namespace util
+} // namespace nnfw
+
+#endif // __NNFW_UTIL_FEATURE_OBJECT_H__
#include "util/environment.h"
#include "util/fp32.h"
+#include "util/vector.h"
#include "util/tensor/IndexIterator.h"
+#include "util/tensor/Object.h"
#include "support/tflite/interp/FlatBufferBuilder.h"
#include "support/tflite/Diff.h"
std::default_random_engine generator(0);
std::uniform_real_distribution<float> distribution(0.0f, 1.0f);
+ auto number_fn = [&] (const nnfw::util::tensor::Shape &, const nnfw::util::tensor::Index &)
+ {
+ return distribution(generator);
+ };
+
for (const auto &id : interpreter.inputs())
{
auto view = nnfw::support::tflite::TensorView<float>::make(interpreter, id);
+ const nnfw::util::tensor::Object<float> data(view.shape(), number_fn);
+
+ assert(view.shape() == data.shape());
nnfw::util::tensor::iterate(view.shape()) << [&] (const nnfw::util::tensor::Index &ind)
{
- view.at(ind) = distribution(generator);
+ view.at(ind) = data.at(ind);
};
}
}
#include "util/feature/IndexIterator.h"
#include "util/feature/Object.h"
#include "util/feature/Reader.h"
+#include "util/tensor/Object.h"
+
#include "util/fp32.h"
#include "util/environment.h"
#include "support/tflite/Diff.h"
#include "support/tflite/FeatureView.h"
+#include "support/tflite/TensorView.h"
#include "support/tflite/interp/FunctionBuilder.h"
#include <iostream>
// Initialize random number generator
std::minstd_rand random(SEED);
- // Fill IFM with random numbers
- auto ifm_gen = [&random] (const nnfw::util::feature::Shape &, const nnfw::util::feature::Index &)
- {
- std::normal_distribution<float> dist(0.0f,2.0f);
- return dist(random);
- };
- const nnfw::util::feature::Shape ifm_shape{IFM_C, IFM_H, IFM_W};
- const nnfw::util::feature::Object<float> ifm{ifm_shape, ifm_gen};
-
std::cout << "Configurations:" << std::endl;
#define PRINT_NEWLINE() { std::cout << std::endl; }
#define PRINT_VALUE(value) { std::cout << " " << #value << ": " << (value) << std::endl; }
// Set Tensor #1 as Input #0, and Tensor #0 as Output #0
interp.SetInputs({1});
interp.SetOutputs({0});
-
- // Allocate Tensor
- interp.AllocateTensors();
-
- // Fill IFM data in HWC order
- {
- nnfw::support::tflite::FeatureView<float> interp_input{interp, InputIndex{0}};
-
- for (uint32_t row = 0; row < ifm.shape().H; ++row)
- {
- for (uint32_t col = 0; col < ifm.shape().W; ++col)
- {
- for (uint32_t ch = 0; ch < ifm.shape().C; ++ch)
- {
- const auto value = ifm.at(ch, row, col);
- interp_input.at(ch, row, col) = value;
- }
- }
- }
- }
};
const nnfw::support::tflite::interp::FunctionBuilder builder(setup);
pure->UseNNAPI(false);
delegated->UseNNAPI(true);
+ // Allocate Tensors
+ pure->AllocateTensors();
+ delegated->AllocateTensors();
+
+ assert(pure->inputs() == delegated->inputs());
+
+ // Fill IFM with random numbers
+ auto ifm_gen = [&random] (const nnfw::util::tensor::Shape &, const nnfw::util::tensor::Index &)
+ {
+ std::normal_distribution<float> dist(0.0f, 2.0f);
+ return dist(random);
+ };
+
+ for (const auto id : pure->inputs())
+ {
+ auto pure_view = nnfw::support::tflite::TensorView<float>::make(*pure, id);
+ auto nnapi_view = nnfw::support::tflite::TensorView<float>::make(*pure, id);
+
+ assert(pure_view.shape() == nnapi_view.shape());
+
+ const nnfw::util::tensor::Object<float> data(pure_view.shape(), ifm_gen);
+
+ assert(pure_view.shape() == data.shape());
+
+ nnfw::util::tensor::iterate(pure_view.shape()) << [&] (const nnfw::util::tensor::Index &ind)
+ {
+ const auto value = data.at(ind);
+
+ pure_view.at(ind) = value;
+ nnapi_view.at(ind) = value;
+ };
+ }
+
// Let's Rock-n-Roll!
pure->Invoke();
delegated->Invoke();