From 89a50ed7a5651cb01a51bab3bf0a0559fd3cb24e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=98=A4=ED=98=95=EC=84=9D/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Staff=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Thu, 8 Nov 2018 10:56:03 +0900 Subject: [PATCH] Build subtensor in acl TensorBuilder (#3513) * Build subtensor in acl TensorBuilder Build subtensor in acl TensorBuilder Change to public function in Convert.cc Signed-off-by: Hyeongseok Oh * Remove deprecated declaration * Remove diff by space line --- .../neurun/src/backend/acl_cl/TensorBuilder.cc | 73 ++++++++++++++++++++++ runtimes/neurun/src/internal/Convert.cc | 2 +- runtimes/neurun/src/internal/Convert.h | 5 ++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc b/runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc index e5fe4b7..c3ff7b1 100644 --- a/runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc +++ b/runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc @@ -17,8 +17,10 @@ #include "backend/acl_cl/TensorBuilder.h" #include +#include #include "operand/Object.h" +#include "internal/Convert.h" #include "logging.h" @@ -78,6 +80,77 @@ void TensorBuilder::prepare(void) tensor->allocator()->init(info); _tensors[ind] = tensor; } + + // 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) + for (auto &entry : _subtensor_info_map) + { + graph::operand::Index 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 CLSubTensor + if (_subtensors.find(current) != _subtensors.end()) + { + stack.pop(); + continue; + } + + auto parent = info.parent(); + std::shared_ptr<::arm_compute::ICLTensor> 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(::internal::asDataType(info.type().type()) == parent_tensor->info()->data_type()); + auto shape = ::internal::asTensorShape(info.shape()); + + // Only support axis: 3 (channel) + ::arm_compute::Coordinates coordinates; + coordinates.set_num_dimensions(4); + assert(info.offset().h() == 0); + assert(info.offset().n() == 0); + assert(info.offset().w() == 0); + coordinates[2] = info.offset().c(); + auto tensor = std::make_shared<::arm_compute::CLSubTensor>(parent_tensor.get(), shape, + coordinates, true); + _subtensors[current] = tensor; + stack.pop(); + } + } } void TensorBuilder::allocate(void) diff --git a/runtimes/neurun/src/internal/Convert.cc b/runtimes/neurun/src/internal/Convert.cc index 170fd26..73112cf 100644 --- a/runtimes/neurun/src/internal/Convert.cc +++ b/runtimes/neurun/src/internal/Convert.cc @@ -23,7 +23,7 @@ namespace internal { ::arm_compute::TensorShape asTensorShape(const ::neurun::graph::operand::Shape &shape, - bool apply_dim_correction = true) + bool apply_dim_correction) { const uint32_t rank = shape.rank(); diff --git a/runtimes/neurun/src/internal/Convert.h b/runtimes/neurun/src/internal/Convert.h index 00a0278..ad6e903 100644 --- a/runtimes/neurun/src/internal/Convert.h +++ b/runtimes/neurun/src/internal/Convert.h @@ -18,8 +18,10 @@ #define __INTERNAL_CONVERT_H__ #include +#include #include +#include "graph/operand/Object.h" #include "graph/operand/Shape.h" #include "graph/operand/TypeInfo.h" #include "util/feature/Shape.h" @@ -28,6 +30,9 @@ namespace internal { +::arm_compute::TensorShape asTensorShape(const ::neurun::graph::operand::Shape &shape, + bool apply_dim_correction = true); +::arm_compute::DataType asDataType(const ::neurun::graph::operand::DataType &type); ::arm_compute::TensorInfo asTensorInfo(const ::neurun::graph::operand::Shape &shape, const ::neurun::graph::operand::TypeInfo &typeInfo); -- 2.7.4