From: 김용섭/On-Device Lab(SR)/Engineer/삼성전자 Date: Tue, 3 Sep 2019 04:52:29 +0000 (+0900) Subject: [neurun] Make {pre|post}Visit of TemplTensorBuilder recursive (#7064) X-Git-Tag: accepted/tizen/unified/20190904.110638~31 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2911891c8bea0860e0e29d1d88399dc1d815e9f8;p=platform%2Fcore%2Fml%2Fnnfw.git [neurun] Make {pre|post}Visit of TemplTensorBuilder recursive (#7064) Make {pre|post}Visit of TemplTensorBuilder recursive to support for more than two consecutive concat layers Signed-off-by: Yongseop Kim --- diff --git a/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h b/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h index 6bb0e00..4c723f9 100644 --- a/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h +++ b/runtimes/neurun/backend/acl_common/TemplTensorBuilder.h @@ -417,60 +417,42 @@ void TemplTensorBuilder::preVisit( return; } - // NOTE. Handling subtensors can be done if they are on a concat or - // two consecutive concats(double concats). - // More than two consecutive concats cannot be done for now. - // TODO Enable handle concats recursively - auto def_handler = [this](const model::OperandIndex &ind) { - bool is_subtensor = _subtensor_info_map.find(ind) != _subtensor_info_map.end(); - bool is_parent = _parent_def.find(ind) != _parent_def.end(); - if (!is_subtensor && !is_parent) - { - _mem_mgr->startLifetime(ind); - return; - } - - auto test_and_set_as_parent = [this](const model::OperandIndex &ind) { - assert(_parent_def.find(ind) != _parent_def.end()); - if (_parent_def[ind]) - _parent_def[ind] = 0; - }; - - auto test_and_def_as_parent = [this](const model::OperandIndex &ind) { - assert(_parent_def.find(ind) != _parent_def.end()); - if (_parent_def[ind]) - { - _parent_def[ind] = 0; - _mem_mgr->startLifetime(ind); - } - }; - - // TODO Elaborate below code. How to clean these conditions/branches? - if (is_subtensor && is_parent) - { - test_and_set_as_parent(ind); - test_and_def_as_parent(_subtensor_info_map.at(ind).parent()); - } - else if (is_subtensor) - { - const model::OperandIndex &parent_ind = _subtensor_info_map.at(ind).parent(); + std::function def_handler = + [this, &def_handler](const model::OperandIndex &ind) { + bool is_subtensor = _subtensor_info_map.find(ind) != _subtensor_info_map.end(); + bool is_parent = _parent_def.find(ind) != _parent_def.end(); + if (!is_subtensor && !is_parent) + { + _mem_mgr->startLifetime(ind); + return; + } - // Its parent is a subtensor? - if (_subtensor_info_map.find(parent_ind) != _subtensor_info_map.end()) - { - test_and_set_as_parent(parent_ind); - test_and_def_as_parent(_subtensor_info_map.at(parent_ind).parent()); - } - else - { - test_and_def_as_parent(parent_ind); - } - } - else if (is_parent) - { - test_and_def_as_parent(ind); - } - }; + if (is_parent) + { + if (_parent_def[ind] == 0) + return; + + _parent_def[ind] = 0; + + if (is_subtensor) + { + const auto &it = _parent_def.find(ind); + _parent_def.erase(it); + def_handler(ind); + } + else + { + _mem_mgr->startLifetime(ind); + } + } + else if (is_subtensor) + { + const model::OperandIndex &parent_ind = _subtensor_info_map.at(ind).parent(); + if (_parent_def[parent_ind] == 0) + return; + def_handler(parent_ind); + } + }; // See #5642 model::OperandIndexMap outputs_map; @@ -510,64 +492,41 @@ void TemplTensorBuilder::postVisit( return; } - // NOTE. Handling subtensors can be done if they are on a concat or - // two consecutive concats(double concats). - // More than two consecutive concats cannot be done for now. - // TODO Enable handle concats recursively - auto use_handler = [this](const model::OperandIndex &ind) { - bool is_subtensor = _subtensor_info_map.find(ind) != _subtensor_info_map.end(); - bool is_parent = _parent_uses.find(ind) != _parent_uses.end(); - if (!is_subtensor && !is_parent) - { - _mem_mgr->finishLifetime(ind); - return; - } - - auto decr_as_parent = [this](const model::OperandIndex &ind) { - assert(_parent_uses.find(ind) != _parent_uses.end()); - assert(_parent_uses[ind] > 0); - --_parent_uses[ind]; - }; - - auto decr_test_and_use_as_parent = [this](const model::OperandIndex &ind) { - assert(_parent_uses.find(ind) != _parent_uses.end()); - assert(_parent_uses[ind] > 0); - if (--_parent_uses[ind] == 0) - _mem_mgr->finishLifetime(ind); - }; - - // TODO Elaborate below code. How to clean these conditions/branches? - if (is_subtensor && is_parent) - { - decr_as_parent(ind); - if (_parent_uses[ind] == 0) - { - decr_test_and_use_as_parent(_subtensor_info_map.at(ind).parent()); - } - } - else if (is_subtensor) - { - const model::OperandIndex &parent_ind = _subtensor_info_map.at(ind).parent(); + std::function use_handler = + [this, &use_handler](const model::OperandIndex &ind) { + bool is_subtensor = _subtensor_info_map.find(ind) != _subtensor_info_map.end(); + bool is_parent = _parent_uses.find(ind) != _parent_uses.end(); + if (!is_subtensor && !is_parent) + { + _mem_mgr->finishLifetime(ind); + return; + } - // Its parent is a subtensor? - if (_subtensor_info_map.find(parent_ind) != _subtensor_info_map.end()) - { - decr_as_parent(parent_ind); - if (_parent_uses[parent_ind] == 0) + // This handler shall be executed by the linear executor so that + // The parent operand will always be done after the subtensor + if (is_parent) { - decr_test_and_use_as_parent(_subtensor_info_map.at(parent_ind).parent()); + --_parent_uses[ind]; + assert(_parent_uses[ind] == 0); + + if (is_subtensor) + { + const auto &it = _parent_uses.find(ind); + _parent_uses.erase(it); + use_handler(ind); + } + else + { + _mem_mgr->finishLifetime(ind); + } } - } - else - { - decr_test_and_use_as_parent(parent_ind); - } - } - else if (is_parent) - { - decr_test_and_use_as_parent(ind); - } - }; + else if (is_subtensor) + { + const model::OperandIndex &parent_ind = _subtensor_info_map.at(ind).parent(); + --_parent_uses[parent_ind]; + assert(_parent_uses[parent_ind] > 0); + } + }; // See #5642 const auto &inputs = node.getInputs();