#include "internal/arm_compute/Cast.h"
#include "internal/arm_compute/kernel/View.h"
#include "internal/nnapi/kernel/Reader.h"
+#include "internal/nnapi/feature/Reader.h"
+#include "internal/nnapi/feature/View.h"
+#include "internal/arm_compute/feature/View.h"
#include "internal/layers/GenericReshapeLayer.h"
#include "internal/layers/SimpleArithmeticAdditionLayer.h"
#include "util/kernel/IndexIterator.h"
+#include "util/feature/IndexIterator.h"
#include "compilation.h"
#include "model.h"
#include <stack>
+static void initFeatureTensor(::arm_compute::ITensor &tensor,
+ const nnfw::util::feature::Shape &feature_shape,
+ const uint8_t *feature_base, const size_t feature_size)
+{
+ const ::internal::nnapi::feature::Reader<float> from{feature_shape, feature_base, feature_size};
+ ::internal::arm_compute::feature::View<float> into{&tensor};
+
+ ::nnfw::util::feature::iterate(feature_shape) << [&](uint32_t ch, uint32_t row, uint32_t col) {
+ const auto value = from.at(ch, row, col);
+ into.at(ch, row, col) = value;
+ };
+}
+
+static void initVectorTensor(::arm_compute::ITensor &tensor, const uint8_t *vec_base,
+ const size_t vec_size)
+{
+ for (uint32_t n = 0; n < vec_size; ++n)
+ {
+ const ::arm_compute::Coordinates coordinate{n};
+
+ float *into = reinterpret_cast<float *>(tensor.ptr_to_element(coordinate));
+
+ const float *from = reinterpret_cast<const float *>(vec_base) + n;
+ const auto value = *from;
+
+ *into = value;
+ }
+}
+
void PlanBuilder::finalize(void) const
{
// CLTensor objects to be initialized later
const ::internal::tflite::operand::Index operand_index{it->first};
_plan.operands().at(operand_index).access(it->second);
}
+
+ // Initialize CLTensors that have data in their corresponding NNAPI operand but are not
+ // initialized yet
+ const auto &operands = _plan.model().operands();
+ for (int idx = 0; idx < operands.size(); ++idx)
+ {
+ const ::internal::tflite::operand::Index operand_idx{idx};
+ if (isAllocated(idx) && operands.at(operand_idx).hasData() &&
+ _initializer_ctx.find(idx) == _initializer_ctx.end())
+ {
+ const auto rank = operands.at(operand_idx).shape().rank();
+ auto base = operands.at(operand_idx).data().base();
+ ::arm_compute::ICLTensor &tensor = *(_plan.operands().at(operand_idx).ptr());
+
+ switch (rank)
+ {
+ case 0: // scalar
+ {
+ initVectorTensor(tensor, base, 1);
+ break;
+ }
+ case 1: // vector
+ {
+ auto size = operands.at(operand_idx).shape().asVector();
+ initVectorTensor(tensor, base, size);
+ break;
+ }
+ case 4: // feature
+ {
+ const auto feature_shape = operands.at(operand_idx).shape().asFeature();
+ auto size = operands.at(operand_idx).data().size();
+ initFeatureTensor(tensor, feature_shape, base, size);
+ break;
+ }
+ default:
+ throw std::runtime_error("Not supported, yet");
+ break;
+ }
+ }
+ }
}
//