diff options
author | Chunseok Lee <chunseok.lee@samsung.com> | 2019-01-08 17:36:34 +0900 |
---|---|---|
committer | Chunseok Lee <chunseok.lee@samsung.com> | 2019-01-08 17:36:34 +0900 |
commit | bd11b24234d7d43dfe05a81c520aa01ffad06e42 (patch) | |
tree | 57d0d4044977e4fa0e50cd9ba40b32006dff19eb /runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc | |
parent | 91f4ba45449f700a047a4aeea00b1a7c84e94c75 (diff) | |
download | nnfw-bd11b24234d7d43dfe05a81c520aa01ffad06e42.tar.gz nnfw-bd11b24234d7d43dfe05a81c520aa01ffad06e42.tar.bz2 nnfw-bd11b24234d7d43dfe05a81c520aa01ffad06e42.zip |
Imported Upstream version 0.3upstream/0.3
Diffstat (limited to 'runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc')
-rw-r--r-- | runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc | 193 |
1 files changed, 180 insertions, 13 deletions
diff --git a/runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc b/runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc index 05943c26a..b5c038200 100644 --- a/runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc +++ b/runtimes/neurun/src/backend/acl_cl/TensorBuilder.cc @@ -17,8 +17,12 @@ #include "backend/acl_cl/TensorBuilder.h" #include <cassert> +#include <stack> #include "operand/Object.h" +#include "Convert.h" + +#include "util/logging.h" namespace neurun { @@ -32,34 +36,124 @@ TensorBuilder::TensorBuilder() // DO NOTHING } -void TensorBuilder::mark(const ::neurun::graph::operand::Index &ind) +void TensorBuilder::registerTensorInfo(const model::operand::Index &ind, + const compiler::TensorInfo &info) +{ + assert(_tensors.size() == 0); + + _tensor_info_map.insert({ind, info}); +} + +void TensorBuilder::registerSubTensorInfo(const model::operand::Index &ind, + const compiler::SubTensorInfo &info) { assert(_tensors.size() == 0); - _inds.insert(ind); + _subtensor_info_map.insert({ind, info}); +} + +void TensorBuilder::notifyFirstUse(const model::operand::Index &) +{ + // DO NOTHING +} + +void TensorBuilder::notifyLastUse(const model::operand::Index &) +{ + // DO NOTHING } -void TensorBuilder::prepare(codegen::Plan &plan, - const std::map<int, ::arm_compute::TensorInfo> &tensor_info_ctx) +void TensorBuilder::prepare(void) { assert(_tensors.size() == 0); // TODO Handle SubTensor(subsumption) // Currently this TensorBuilder does not have subsumption info yet + // Allocated subtensor will be mapped to _subtensors instead of _tensors + assert(_subtensors.size() == 0); - for (auto ind_int : _inds) + for (auto &entry : _tensor_info_map) { - ::neurun::graph::operand::Index ind{ind_int}; - auto tensor = std::make_shared<::arm_compute::CLTensor>(); - tensor->allocator()->init(tensor_info_ctx.at(ind.asInt())); - plan.operands().set(ind, std::make_shared<operand::Object>(tensor)); + auto ind = entry.first; + const auto &info = entry.second; + auto tensor = std::make_shared<::neurun::backend::acl_cl::operand::CLTensor>(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) + { + model::operand::Index ind = entry.first; + + std::stack<model::operand::Index> 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<::neurun::backend::acl_cl::operand::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(asDataType(info.type().type()) == parent_tensor->info()->data_type()); + auto shape = 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<::neurun::backend::acl_cl::operand::CLSubTensor>( + parent_tensor.get(), shape, coordinates, true); + _subtensors[current] = tensor; + stack.pop(); + } + } } void TensorBuilder::allocate(void) { - assert(_inds.size() == _tensors.size()); + assert(_tensor_info_map.size() == _tensors.size()); for (const auto &tensor_entry : _tensors) { @@ -68,10 +162,83 @@ void TensorBuilder::allocate(void) } } -std::shared_ptr<::arm_compute::CLTensor> -TensorBuilder::at(const ::neurun::graph::operand::Index &ind) +std::shared_ptr<::neurun::backend::operand::ITensor> +TensorBuilder::tensorAt(const model::operand::Index &ind) +{ + if (_tensors.find(ind) != _tensors.end()) + { + return _tensors.at(ind); + } + else + { + return _subtensors.at(ind); + } +} + +std::shared_ptr<backend::operand::IObject> +TensorBuilder::wrapTensor(const model::operand::Index &ind) { - return _tensors.at(ind); + if (_objects.find(ind) != _objects.end()) + { + return _objects.at(ind); + } + else + { + if (_tensors.find(ind) != _tensors.end()) + { + return _objects[ind] = std::make_shared<operand::Object>(_tensors.at(ind)); + } + else + { + return _objects[ind] = std::make_shared<operand::Object>(_subtensors.at(ind)); + } + } +} + +void TensorBuilder::iterate(const IterateFunction &fn) +{ + for (auto it : _tensors) + { + fn(it.first); + } + for (auto it : _subtensors) + { + fn(it.first); + } +} + +std::shared_ptr<::neurun::backend::acl_cl::operand::ICLTensor> +TensorBuilder::at(const ::neurun::model::operand::Index &ind) +{ + if (_tensors.find(ind) != _tensors.end()) + { + return _tensors.at(ind); + } + else + { + return _subtensors.at(ind); + } +} + +bool TensorBuilder::isSubTensorOf(const model::operand::Index &parent, + const model::operand::Index &child) +{ + if (_subtensor_info_map.find(child) == _subtensor_info_map.end()) + { + return false; + } + + if (_subtensors.find(child) == _subtensors.end()) + { + return false; + } + + if (_subtensor_info_map.at(child).parent() != parent) + { + return false; + } + + return true; } } // namespace acl_cl |