From 7bfe31d7c2ec261be26bc2675958c27b5d38858e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=9E=A5=EC=A7=80=EC=84=AD/On-Device=20Lab=28SR=29/Enginee?= =?utf8?q?r/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Mon, 19 Aug 2019 10:12:20 +0900 Subject: [PATCH] Introduce a map storing layouts into TensorBuilders (#6641) This commit introduces a map storing layouts for each operand into TensorBuilders. Signed-off-by: jiseob.jang --- .../neurun/backend/acl_common/TemplTensorBuilder.h | 47 +++++++++++++++++----- runtimes/neurun/backend/cpu/TensorBuilder.cc | 37 ++++++++++++++--- runtimes/neurun/backend/cpu/TensorBuilder.h | 3 +- .../neurun/core/include/backend/ITensorBuilder.h | 2 +- .../neurun/core/src/compiler/ExecutorFactory.cc | 3 +- runtimes/neurun/core/src/compiler/Linear.cc | 3 +- 6 files changed, 77 insertions(+), 18 deletions(-) diff --git a/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h b/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h index 6fba82d..70842e9 100644 --- a/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h +++ b/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h @@ -25,6 +25,7 @@ #include "model/OperandIndexMap.h" #include "AclMemoryManager.h" #include "cpp14/memory.h" +#include namespace neurun { @@ -54,7 +55,7 @@ public: * @param[in] layout Tensor data layout */ void registerTensorInfo(const model::OperandIndex &ind, const model::OperandInfo &info, - model::Layout layout) override; + model::Layout frontend_layout, model::Layout backend_layout) override; /** * @brief Register subtensor information to allocate on ACL-CL backend * @param[in] ind Operand index @@ -96,12 +97,14 @@ private: void buildTensors(void); void buildSubtensors(void); void validate(void); + model::OperandIndex findRootParent(model::OperandIndex index); private: model::OperandIndexMap _tensor_info_map; model::OperandIndexMap _subtensor_info_map; model::OperandIndexMap _apply_dim_correction_map; - model::Layout _layout; + model::OperandIndexMap> _tensor_layouts_map; + ; std::unique_ptr _mem_mgr; // TODO Consider dividing TensorBuilder into Linear and others @@ -146,13 +149,14 @@ TemplTensorBuilder::TemplTensorBuild template void TemplTensorBuilder::registerTensorInfo( - const model::OperandIndex &ind, const model::OperandInfo &info, model::Layout layout) + const model::OperandIndex &ind, const model::OperandInfo &info, model::Layout frontend_layout, + model::Layout backend_layout) { assert(_mem_mgr->tensors().size() == 0); _tensor_info_map.emplace(ind, info); _apply_dim_correction_map.emplace(ind, true); - _layout = layout; + _tensor_layouts_map.insert({ind, std::make_pair(frontend_layout, backend_layout)}); assert(_first_uses_visit.find(ind) == _first_uses_visit.end()); _first_uses_visit[ind] = false; @@ -311,8 +315,11 @@ void TemplTensorBuilder::buildTensor { auto ind = entry.first; const auto &info = entry.second; - // TODO Support NCHW frontend - auto tensor_info = asTensorInfo(info.shape(), info.typeInfo(), model::Layout::NHWC, _layout, + // NOTE SubTensor's layout must be the same with layout of parent tensor + const auto &root_parent = findRootParent(ind); + const auto &frontend_layout = _tensor_layouts_map[root_parent].first; + const auto &backend_layout = _tensor_layouts_map[root_parent].second; + auto tensor_info = asTensorInfo(info.shape(), info.typeInfo(), frontend_layout, backend_layout, _apply_dim_correction_map[ind]); _mem_mgr->buildTensor(ind, tensor_info); } @@ -383,11 +390,15 @@ void TemplTensorBuilder::buildSubten assert(info.type().offset() == parent_tensor->info()->quantization_info().offset); assert(info.type().scale() == parent_tensor->info()->quantization_info().scale); assert(asDataType(info.type().type()) == parent_tensor->info()->data_type()); - // TODO Change to set data_layout for each front-end - auto shape = asTensorShape(info.shape(), model::Layout::NHWC, _layout, + // NOTE SubTensor's layout must be the same with layout of parent tensor + const auto &root_parent = findRootParent(parent); + const auto &frontend_layout = _tensor_layouts_map[root_parent].first; + const auto &backend_layout = _tensor_layouts_map[root_parent].second; + + auto shape = asTensorShape(info.shape(), frontend_layout, backend_layout, _apply_dim_correction_map[current]); ::arm_compute::Coordinates coordinates = - asTensorCoordinate(info.offset(), model::Layout::NHWC, _layout); + asTensorCoordinate(info.offset(), frontend_layout, backend_layout); auto tensor = std::make_shared(parent_tensor.get(), shape, coordinates, true); subtensors[current] = tensor; stack.pop(); @@ -609,6 +620,13 @@ void TemplTensorBuilder::validate(vo assert(_first_uses_visit[it.first]); } + for (auto it : _tensor_layouts_map) + { + assert(_first_uses_visit.find(it.first) != _first_uses_visit.end()); + assert(_first_uses_visit[it.first]); + UNUSED_RELEASE(it); + } + assert(_uses_queue.size() == 0); assert(_first_uses_num == 0); @@ -621,6 +639,17 @@ void TemplTensorBuilder::validate(vo [](std::pair it) { return it.second == 0; })); } +template +model::OperandIndex TemplTensorBuilder::findRootParent( + model::OperandIndex ind) +{ + if (_subtensor_info_map.find(ind) == _subtensor_info_map.end()) + return ind; + + const auto &parent_ind = _subtensor_info_map.at(ind).parent(); + return findRootParent(parent_ind); +} + } // namespace acl_common } // namespace backend } // namespace neurun diff --git a/runtimes/neurun/backend/cpu/TensorBuilder.cc b/runtimes/neurun/backend/cpu/TensorBuilder.cc index 4d6a535..09ba9c1 100644 --- a/runtimes/neurun/backend/cpu/TensorBuilder.cc +++ b/runtimes/neurun/backend/cpu/TensorBuilder.cc @@ -20,6 +20,32 @@ #include "util/logging.h" +namespace +{ + +using namespace neurun; + +// NOTE This backend support only NHWC now +model::OperandInfo asTensorInfo(const model::OperandInfo &info, model::Layout frontend_layout) +{ + const auto &shape = info.shape(); + const auto &rank = shape.rank(); + assert(rank <= 4); + + auto ret = info; + if (frontend_layout == model::Layout::NCHW && rank == 4) + { + // NCHW -> NHWC + uint32_t permutation[4] = {0, 2, 3, 1}; + ret = model::OperandInfo{{shape.dim(permutation[0]), shape.dim(permutation[1]), + shape.dim(permutation[2]), shape.dim(permutation[3])}, + info.typeInfo()}; + } + return ret; +} + +} // namespace + namespace neurun { namespace backend @@ -33,10 +59,11 @@ TensorBuilder::TensorBuilder() : _mem_mgr{new MemoryManager()} } void TensorBuilder::registerTensorInfo(const model::OperandIndex &ind, - const model::OperandInfo &info, model::Layout) + const model::OperandInfo &info, + model::Layout frontend_layout, model::Layout backend_layout) { _tensor_info_map.emplace(ind, info); - // TODO set the layout + _tensor_layouts_map.insert({ind, std::make_pair(frontend_layout, backend_layout)}); } void TensorBuilder::registerSubTensorInfo(const model::OperandIndex &, @@ -49,10 +76,10 @@ void TensorBuilder::registerSubTensorInfo(const model::OperandIndex &, void TensorBuilder::notifyFirstUse(const model::OperandIndex &ind) { assert(_tensor_info_map.find(ind) != _tensor_info_map.end()); - const auto &info = _tensor_info_map.at(ind); - _mem_mgr->buildTensor(ind, info); + const auto tensor_info = asTensorInfo(_tensor_info_map.at(ind), _tensor_layouts_map[ind].first); + _mem_mgr->buildTensor(ind, tensor_info); - const auto size = info.total_size(); + const auto size = tensor_info.total_size(); _mem_mgr->claimPlan(ind, size); } diff --git a/runtimes/neurun/backend/cpu/TensorBuilder.h b/runtimes/neurun/backend/cpu/TensorBuilder.h index 67187fc..1afe363 100644 --- a/runtimes/neurun/backend/cpu/TensorBuilder.h +++ b/runtimes/neurun/backend/cpu/TensorBuilder.h @@ -44,7 +44,7 @@ public: * @param[in] layout Operand data layout */ void registerTensorInfo(const model::OperandIndex &ind, const model::OperandInfo &info, - model::Layout layout) override; + model::Layout frontend_layout, model::Layout backend_layout) override; /** * @brief Register subtensor information to allocate on CPU backend * @param[in] ind Operand index @@ -78,6 +78,7 @@ public: private: std::unique_ptr _mem_mgr; model::OperandIndexMap _tensor_info_map; + model::OperandIndexMap> _tensor_layouts_map; }; } // namespace cpu diff --git a/runtimes/neurun/core/include/backend/ITensorBuilder.h b/runtimes/neurun/core/include/backend/ITensorBuilder.h index 8c70366..ef126e0 100644 --- a/runtimes/neurun/core/include/backend/ITensorBuilder.h +++ b/runtimes/neurun/core/include/backend/ITensorBuilder.h @@ -44,7 +44,7 @@ struct ITensorBuilder * @brief Register tensor information to allocate on backend */ virtual void registerTensorInfo(const model::OperandIndex &, const model::OperandInfo &, - model::Layout) = 0; + model::Layout frontend_layout, model::Layout backend_layout) = 0; /** * @brief Register subtensor information to allocate on backend */ diff --git a/runtimes/neurun/core/src/compiler/ExecutorFactory.cc b/runtimes/neurun/core/src/compiler/ExecutorFactory.cc index 16e4991..df88945 100644 --- a/runtimes/neurun/core/src/compiler/ExecutorFactory.cc +++ b/runtimes/neurun/core/src/compiler/ExecutorFactory.cc @@ -217,7 +217,8 @@ exec::IExecutor *ExecutorFactory::createDataflowExecutor(graph::Graph &graph, bo { const auto info = obj.info(); const auto layout = lower_info->def_factors().getOnlyElement().layout(); - tensor_builder->registerTensorInfo(ind, info, layout); + // TODO Support NCHW frontend + tensor_builder->registerTensorInfo(ind, info, model::Layout::NHWC, layout); // To make this never be deallocated, this is a workaround to use static memory planner tensor_builder->notifyFirstUse(ind); } diff --git a/runtimes/neurun/core/src/compiler/Linear.cc b/runtimes/neurun/core/src/compiler/Linear.cc index 8ae4204..2a933d2 100644 --- a/runtimes/neurun/core/src/compiler/Linear.cc +++ b/runtimes/neurun/core/src/compiler/Linear.cc @@ -211,7 +211,8 @@ void Linear::planTensors() { const auto info = obj.info(); const auto layout = lower_info->def_factors().getOnlyElement().layout(); - tensor_builder->registerTensorInfo(ind, info, layout); + // TODO Support NCHW frontend + tensor_builder->registerTensorInfo(ind, info, model::Layout::NHWC, layout); } tensor_builder_map[ind] = tensor_builder; -- 2.7.4