From eba1d0bea39a7d926ef2f992375ce52b9dc140b2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EA=B9=80=EC=9A=A9=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, 24 Jun 2019 15:55:22 +0900 Subject: [PATCH] [neurun] Separate prepare of TemplTensorBuilder (#5473) Separate prepare of TemplTensorBuilder to buildTensors and buildSubtensors Signed-off-by: Yongseop Kim --- .../neurun/backend/acl_common/TemplTensorBuilder.h | 177 +++++++++++---------- 1 file changed, 96 insertions(+), 81 deletions(-) diff --git a/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h b/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h index b7a8e48..4f78a49 100644 --- a/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h +++ b/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h @@ -80,6 +80,10 @@ public: void dimCorrection(const model::OperandIndex &index, bool apply_dim_correction); private: + void buildTensors(void); + void buildSubtensors(void); + +private: model::OperandIndexMap _tensor_info_map; model::OperandIndexMap _subtensor_info_map; model::OperandIndexMap _apply_dim_correction_map; @@ -152,87 +156,8 @@ void TemplTensorBuilder::notifyLastU template void TemplTensorBuilder::prepare(void) { - assert(_mem_mgr->tensors().size() == 0); - - // TODO Handle SubTensor(subsumption) - // Currently this TemplTensorBuilder does not have subsumption info yet - // Allocated subtensor will be mapped to _subtensors instead of _tensors - assert(_mem_mgr->subtensors().size() == 0); - - for (auto &entry : _tensor_info_map) - { - auto ind = entry.first; - const auto &info = entry.second; - auto tensor_info = - asTensorInfo(info.shape(), info.typeInfo(), _layout, _apply_dim_correction_map[ind]); - _mem_mgr->buildTensor(ind, tensor_info); - } - - // To make subtensor, parent tensor must be made first - // For this condition, use stack - // 1) Push one subtensor index to stack (iterate subtensors) - // 2) If tensor at stack top is already made, pop and go to 4) - // 3) If tensor pushed at 1) is not made, check parent tensor - // 3-1) If parent tensor is already made, we can make child tensor - // Make child tensor and pop, go to 4) - // 3-2) If parent tensor is not made, we can't make child tensor yet - // Push parent tensor index to stack and return to 4) - // 4) If stack is empty, return to 1), else return to 2) - auto &tensors = _mem_mgr->tensors(); - auto &subtensors = _mem_mgr->subtensors(); - for (auto &entry : _subtensor_info_map) - { - model::OperandIndex ind = entry.first; - - std::stack stack; - stack.push(ind); - - while (!stack.empty()) - { - const auto current = stack.top(); - const auto &info = _subtensor_info_map.at(current); - - // Already generated SubTensor - if (subtensors.find(current) != subtensors.end()) - { - stack.pop(); - continue; - } - - auto parent = info.parent(); - std::shared_ptr parent_tensor; - - if (tensors.find(parent) != tensors.end()) - { - // Parent is allocated as tensor - parent_tensor = tensors[parent]; - } - else if (subtensors.find(parent) != subtensors.end()) - { - // Parent is allocated as subtensor - parent_tensor = subtensors[parent]; - } - else - { - // Cannot find allocated parent tensor: allocate parent first - assert(_subtensor_info_map.find(parent) != _subtensor_info_map.end()); - stack.push(parent); - continue; - } - assert(parent_tensor != nullptr); - - // Child's type should be same with parent - 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(), _layout, _apply_dim_correction_map[current]); - ::arm_compute::Coordinates coordinates = asTensorCoordinate(info.offset(), _layout); - auto tensor = std::make_shared(parent_tensor.get(), shape, coordinates, true); - subtensors[current] = tensor; - stack.pop(); - } - } + buildTensors(); + buildSubtensors(); } template @@ -333,6 +258,96 @@ TemplTensorBuilder::releaseMemoryMan return std::move(_mem_mgr); } +template +void TemplTensorBuilder::buildTensors(void) +{ + assert(_mem_mgr->tensors().size() == 0); + + for (auto &entry : _tensor_info_map) + { + auto ind = entry.first; + const auto &info = entry.second; + auto tensor_info = + asTensorInfo(info.shape(), info.typeInfo(), _layout, _apply_dim_correction_map[ind]); + _mem_mgr->buildTensor(ind, tensor_info); + } +} + +template +void TemplTensorBuilder::buildSubtensors(void) +{ + // TODO Handle SubTensor(subsumption) + // Currently this TemplTensorBuilder does not have subsumption info yet + // Allocated subtensor will be mapped to _subtensors instead of _tensors + assert(_mem_mgr->subtensors().size() == 0); + + // To make subtensor, parent tensor must be made first + // For this condition, use stack + // 1) Push one subtensor index to stack (iterate subtensors) + // 2) If tensor at stack top is already made, pop and go to 4) + // 3) If tensor pushed at 1) is not made, check parent tensor + // 3-1) If parent tensor is already made, we can make child tensor + // Make child tensor and pop, go to 4) + // 3-2) If parent tensor is not made, we can't make child tensor yet + // Push parent tensor index to stack and return to 4) + // 4) If stack is empty, return to 1), else return to 2) + auto &tensors = _mem_mgr->tensors(); + auto &subtensors = _mem_mgr->subtensors(); + for (auto &entry : _subtensor_info_map) + { + model::OperandIndex ind = entry.first; + + std::stack stack; + stack.push(ind); + + while (!stack.empty()) + { + const auto current = stack.top(); + const auto &info = _subtensor_info_map.at(current); + + // Already generated SubTensor + if (subtensors.find(current) != subtensors.end()) + { + stack.pop(); + continue; + } + + auto parent = info.parent(); + std::shared_ptr parent_tensor; + + if (tensors.find(parent) != tensors.end()) + { + // Parent is allocated as tensor + parent_tensor = tensors[parent]; + } + else if (subtensors.find(parent) != subtensors.end()) + { + // Parent is allocated as subtensor + parent_tensor = subtensors[parent]; + } + else + { + // Cannot find allocated parent tensor: allocate parent first + assert(_subtensor_info_map.find(parent) != _subtensor_info_map.end()); + stack.push(parent); + continue; + } + assert(parent_tensor != nullptr); + + // Child's type should be same with parent + 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(), _layout, _apply_dim_correction_map[current]); + ::arm_compute::Coordinates coordinates = asTensorCoordinate(info.offset(), _layout); + auto tensor = std::make_shared(parent_tensor.get(), shape, coordinates, true); + subtensors[current] = tensor; + stack.pop(); + } + } +} + } // namespace acl_common } // namespace backend } // namespace neurun -- 2.7.4