summaryrefslogtreecommitdiff
path: root/runtime/neurun/core/src/compiler/SubTensorAnalyzer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/neurun/core/src/compiler/SubTensorAnalyzer.cc')
-rw-r--r--runtime/neurun/core/src/compiler/SubTensorAnalyzer.cc96
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