diff options
Diffstat (limited to 'runtime/neurun/core/src/compiler/SubTensorAnalyzer.cc')
-rw-r--r-- | runtime/neurun/core/src/compiler/SubTensorAnalyzer.cc | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/runtime/neurun/core/src/compiler/SubTensorAnalyzer.cc b/runtime/neurun/core/src/compiler/SubTensorAnalyzer.cc new file mode 100644 index 000000000..dae1a74ff --- /dev/null +++ b/runtime/neurun/core/src/compiler/SubTensorAnalyzer.cc @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SubTensorAnalyzer.h" + +#include <typeinfo> + +#include "cpp14/memory.h" +#include "ir/OperandIndexSequence.h" +#include "util/logging.h" +#include "util/Coordinates.h" + +namespace neurun +{ +namespace compiler +{ + +void SubTensorAnalyzer::visit(const ir::operation::Concat &node) +{ + // If operator is concat (or other operators related with subsumption), fill subsumption info + // TODO: if one tensor is subset of many parents or model input + // Solution 1. Handle 1st parent only, ignore others (need to invert for other children) + // Solution 2. Insert copy operation for other parents + int32_t axis_raw = node.param().axis; + + const auto &output_index = node.getOutputs().at(0); + const auto &inputs = node.getInputs(); + + int32_t axis_point = 0; + const auto rank = _graph.operands().at(output_index).shape().rank(); + int32_t axis = axis_raw < 0 ? (axis_raw + rank) : axis_raw; + assert(rank > axis); + + for (const auto &input_index : inputs) + { + // NOTE Not support multiple parent tensor yet + // + // Let us consider the following example (where OP_i is not a CONCAT): + // + // %0 = OP_0 + // %1 = OP_1 + // %2 = OP_2 + // %3 = CONCAT(%0, %1) + // %4 = CONCAT(%0, %2) + // + // %0 and %1 SHOULD be consecutive in order to eliminate the former CONCAT operation, + // which makes it impossible to eliminate the latter CONCAT operation. + // - Note that %0 and %2 cannot be consecutive. + if (_graph.operands().at(input_index).parent_info() != nullptr) + { + return; + } + + // NOTE Not support the case that concat's input is a constant or a input of model + if (_graph.operands().at(input_index).isConstant() || _graph.getInputs().contains(input_index)) + { + return; + } + } + + for (const auto &input_index : inputs) + { + auto input_shape = _graph.operands().at(input_index).shape(); + assert(rank == input_shape.rank()); + + neurun::util::Coordinates coordinate_info{}; + for (int i = 0; i < rank; i++) + { + coordinate_info.set(i, 0); + } + coordinate_info.set(axis, axis_point); + + auto parentInfo = + nnfw::cpp14::make_unique<ir::operand::ParentInfo>(output_index, coordinate_info); + + _graph.operands().at(input_index).parent_info(std::move(parentInfo)); + + axis_point += input_shape.dim(axis); + } +} + +} // namespace compiler +} // namespace neurun |