//
StageGenerator::StageGenerator(
const ::internal::tflite::operand::Set &ctx,
- const std::shared_ptr<::internal::arm_compute::TensorBuilder> &tensor_builder)
- : _ctx(ctx), _tensor_builder(tensor_builder)
+ const std::shared_ptr<::internal::arm_compute::TensorBuilder> &tensor_builder,
+ const std::shared_ptr<::internal::common::TensorBuilder> &common_tensor_builder)
+ : _ctx(ctx), _tensor_builder(tensor_builder), _common_tensor_builder(common_tensor_builder)
{
// DO NOTHING
}
#include "internal/Model.h"
#include "backend/acl_cl/TensorBuilder.h"
+#include "internal/common/TensorBuilder.h"
namespace internal
{
{
public:
StageGenerator(const ::internal::tflite::operand::Set &ctx,
- const std::shared_ptr<::internal::arm_compute::TensorBuilder> &tensor_builder);
+ const std::shared_ptr<::internal::arm_compute::TensorBuilder> &tensor_builder,
+ const std::shared_ptr<::internal::common::TensorBuilder> &common_tensor_builder);
virtual std::shared_ptr<ITensorBuilder> tensor_builder() override { return _tensor_builder; }
private:
const ::internal::tflite::operand::Set &_ctx;
std::shared_ptr<::internal::arm_compute::TensorBuilder> _tensor_builder;
+ std::shared_ptr<::internal::common::TensorBuilder> _common_tensor_builder;
};
} // namespace arm_compute
StageGenerator::StageGenerator(
const ::internal::tflite::operand::Set &operand_ctx,
- const std::shared_ptr<::internal::cpu::TensorBuilder> &tensor_builder)
- : _ctx(operand_ctx), _tensor_builder(tensor_builder)
+ const std::shared_ptr<::internal::cpu::TensorBuilder> &tensor_builder,
+ const std::shared_ptr<::internal::common::TensorBuilder> &common_tensor_builder)
+ : _ctx(operand_ctx), _tensor_builder(tensor_builder),
+ _common_tensor_builder(common_tensor_builder)
{
// DO NOTHING
}
#include "internal/cpu.h"
#include "TensorBuilder.h"
+#include "internal/common/TensorBuilder.h"
+
namespace internal
{
namespace cpu
{
public:
StageGenerator(const ::internal::tflite::operand::Set &ctx,
- const std::shared_ptr<::internal::cpu::TensorBuilder> &tensor_builder);
+ const std::shared_ptr<::internal::cpu::TensorBuilder> &tensor_builder,
+ const std::shared_ptr<::internal::common::TensorBuilder> &common_tensor_builder);
virtual std::shared_ptr<ITensorBuilder> tensor_builder() override { return _tensor_builder; }
private:
const ::internal::tflite::operand::Set &_ctx;
std::shared_ptr<::internal::cpu::TensorBuilder> _tensor_builder;
+ std::shared_ptr<::internal::common::TensorBuilder> _common_tensor_builder;
};
} // namespace cpu
#include "internal/Padding.h"
#include "internal/IInitializerGenerator.h"
#include "internal/IStageGenerator.h"
+#include "internal/common/Tensor.h"
+#include "internal/common/TensorBuilder.h"
#include "util/EnvVar.h"
#include "compilation.h"
class BackendResolver
{
public:
- BackendResolver(::internal::BackendManager &backend_manager)
+ BackendResolver(::internal::BackendManager &backend_manager) : _backend_manager(backend_manager)
{
#define OP(InternalName, NnApiName) \
{ \
const auto &backend_str = \
::nnfw::util::EnvVar{std::string("OP_BACKEND_") + #NnApiName}.asString("acl_cl"); \
- auto backend = backend_manager.get(backend_str); \
+ auto backend = _backend_manager.get(backend_str); \
_gen_map[typeid(::internal::tflite::op::InternalName::Node)] = backend; \
}
std::shared_ptr<::internal::IStageGenerator> getStageGenerator(const std::type_index &type);
std::shared_ptr<::internal::ITensorBuilder> getTensorBuilder(const std::type_index &type);
std::set<std::shared_ptr<::internal::ITensorBuilder>> getAllTensorBuilders();
+ std::shared_ptr<::internal::common::TensorBuilder> getCommonTensorBuilder();
private:
std::unordered_map<std::type_index, ::internal::Backend> _gen_map;
+ ::internal::BackendManager &_backend_manager;
};
std::shared_ptr<::internal::IInitializerGenerator>
return ret;
}
+std::shared_ptr<::internal::common::TensorBuilder> BackendResolver::getCommonTensorBuilder()
+{
+ return _backend_manager.getCommonTensorBuilder();
+}
+
#include "backend/acl_cl/InitializerGenerator.h"
#include "backend/acl_cl/StageGenerator.h"
//#include "internal/cpu/InitializerGenerator.h"
void addStage(const Stage &stage) override;
public:
- void finalize(const std::set<std::shared_ptr<::internal::ITensorBuilder>> &tensor_builders);
+ void finalize(BackendResolver &backend_resolver);
public:
const std::map<int, ::arm_compute::TensorInfo> &tensor_info_ctx() { return _tensor_info_ctx; }
void PlanBuilder::addStage(const Stage &stage) { _stages.emplace_back(stage); }
-void PlanBuilder::finalize(
- const std::set<std::shared_ptr<::internal::ITensorBuilder>> &tensor_builders)
+void PlanBuilder::finalize(BackendResolver &backend_resolver)
{
+ auto tensor_builders = backend_resolver.getAllTensorBuilders();
+ auto common_tensor_builder = backend_resolver.getCommonTensorBuilder();
+
// Mark tensors
const auto &operations = _plan.model().operations();
tensor_builder->prepare(_tensor_info_ctx);
}
+ common_tensor_builder->prepare(_tensor_info_ctx);
+
// Process Stage
ExecutionBuilder execution_builder{_plan};
tensor_builder->allocate();
}
+ common_tensor_builder->allocate();
+
// Fill weight/bias
for (auto it = _initializer_ctx.begin(); it != _initializer_ctx.end(); ++it)
{
op.accept(TensorMarker{*tensor_builder});
}
- plan_builder.finalize(backend_resolver.getAllTensorBuilders());
+ plan_builder.finalize(backend_resolver);
return ANEURALNETWORKS_NO_ERROR;
}
{
const auto &operands = _plan.model().operands();
+ _common_tensor_builder = std::make_shared<::internal::common::TensorBuilder>();
+
// Add arm_compute backend
{
auto acl_tensor_builder = std::make_shared<::internal::arm_compute::TensorBuilder>(_plan);
auto acl_initializer_gen =
std::make_shared<::internal::arm_compute::InitializerGenerator>(operands);
- auto acl_stage_gen =
- std::make_shared<::internal::arm_compute::StageGenerator>(operands, acl_tensor_builder);
+ auto acl_stage_gen = std::make_shared<::internal::arm_compute::StageGenerator>(
+ operands, acl_tensor_builder, _common_tensor_builder);
// TODO Do not use magic string for backend id
_gen_map["acl_cl"] = {acl_initializer_gen, acl_stage_gen};
{
auto cpu_tensor_builder = std::make_shared<::internal::cpu::TensorBuilder>(_plan);
auto cpu_initializer_gen = std::make_shared<::internal::cpu::InitializerGenerator>(operands);
- auto cpu_stage_gen =
- std::make_shared<::internal::cpu::StageGenerator>(operands, cpu_tensor_builder);
+ auto cpu_stage_gen = std::make_shared<::internal::cpu::StageGenerator>(
+ operands, cpu_tensor_builder, _common_tensor_builder);
// TODO Do not use magic string for backend id
_gen_map["cpu"] = {cpu_initializer_gen, cpu_stage_gen};
Backend BackendManager::get(const std::string &key) { return _gen_map.at(key); }
+std::shared_ptr<::internal::common::TensorBuilder> BackendManager::getCommonTensorBuilder()
+{
+ return _common_tensor_builder;
+}
+
} // namespace internal
#include "internal/IInitializerGenerator.h"
#include "internal/IStageGenerator.h"
#include "internal/ITensorBuilder.h"
+#include "internal/common/TensorBuilder.h"
namespace internal
{
Backend get(const std::string &key);
+ std::shared_ptr<::internal::common::TensorBuilder> getCommonTensorBuilder();
+
private:
::internal::arm_compute::Plan &_plan;
std::map<std::string, Backend> _gen_map;
+ std::shared_ptr<::internal::common::TensorBuilder> _common_tensor_builder;
};
} // namespace internal
--- /dev/null
+#ifndef __INTERNAL_COMMON_TENSOR_H__
+#define __INTERNAL_COMMON_TENSOR_H__
+
+#include <arm_compute/core/ITensor.h>
+#include <arm_compute/core/TensorInfo.h>
+
+namespace internal
+{
+namespace common
+{
+
+class Tensor : public ::arm_compute::ITensor
+{
+public:
+ Tensor() = default;
+
+ Tensor(::arm_compute::TensorInfo info) : _info(info)
+ {
+ // DO_NOTING
+ }
+
+ Tensor(uint8_t *buffer) : _buffer(buffer)
+ {
+ // DO NOTHING
+ }
+
+public:
+ void setBuffer(uint8_t *buffer) { _buffer = buffer; }
+
+public:
+ ::arm_compute::TensorInfo *info() const override
+ {
+ return const_cast<::arm_compute::TensorInfo *>(&_info);
+ }
+
+ ::arm_compute::TensorInfo *info() override { return &_info; }
+
+ uint8_t *buffer() const override { return _buffer; }
+
+ void allocate()
+ {
+ uint32_t size = _info.total_size(); // NOTE This size may not be accurate
+ _buffer = new uint8_t[size]; // NOTE The allocated buffer is never deallocated.
+ }
+
+private:
+ ::arm_compute::TensorInfo _info;
+ uint8_t *_buffer = nullptr;
+};
+
+} // common
+} // internal
+
+#endif // __INTERNAL_COMMON_TENSOR_H__
--- /dev/null
+#include "TensorBuilder.h"
+
+#include <algorithm>
+
+namespace internal
+{
+namespace common
+{
+
+TensorBuilder::TensorBuilder()
+{
+ // DO NOTHING
+}
+
+void TensorBuilder::mark(const ::internal::tflite::operand::Index &ind)
+{
+ assert(_tensors.size() == 0);
+
+ _inds.insert(ind.asInt());
+}
+
+void TensorBuilder::prepare(const std::map<int, ::arm_compute::TensorInfo> &tensor_info_ctx)
+{
+ assert(_tensors.size() == 0);
+
+ for (auto ind_int : _inds)
+ {
+ ::internal::tflite::operand::Index ind{ind_int};
+ auto tensor = std::make_shared<::internal::common::Tensor>(tensor_info_ctx.at(ind.asInt()));
+ _tensors[ind.asInt()] = tensor;
+ }
+}
+
+void TensorBuilder::allocate(void)
+{
+ assert(_inds.size() == _tensors.size());
+
+ for (auto it : _tensors)
+ {
+ it.second->allocate();
+ }
+}
+
+std::shared_ptr<::internal::common::Tensor>
+TensorBuilder::at(const ::internal::tflite::operand::Index &ind)
+{
+ return _tensors.at(ind.asInt());
+}
+
+} // namespace common
+} // namespace internal
--- /dev/null
+#ifndef __INTERNAL_COMMON_TENSOR_BUILDER_H__
+#define __INTERNAL_COMMON_TENSOR_BUILDER_H__
+
+#include <unordered_set>
+#include <unordered_map>
+
+#include "internal/ITensorBuilder.h"
+#include "internal/common/Tensor.h"
+
+namespace internal
+{
+namespace common
+{
+
+class Plan;
+
+class TensorBuilder : public ::internal::ITensorBuilder
+{
+public:
+ TensorBuilder();
+
+ virtual void mark(const ::internal::tflite::operand::Index &ind) override;
+ virtual void prepare(const std::map<int, ::arm_compute::TensorInfo> &tensor_info_ctx) override;
+ virtual void allocate(void) override;
+
+ std::shared_ptr<::internal::common::Tensor> at(const ::internal::tflite::operand::Index &ind);
+
+private:
+ std::unordered_set<int> _inds;
+ std::unordered_map<int, std::shared_ptr<::internal::common::Tensor>> _tensors;
+};
+
+} // namespace common
+} // namespace internal
+
+#endif // __INTERNAL_COMMON_TENSOR_BUILDER_H__