From: Павел Ильютченко/AI Tools Lab /SRR/Engineer/삼성전자
Date: Thu, 8 Aug 2019 14:03:16 +0000 (+0300)
Subject: [mir_onnx] Improve core structure of ONNX importer (#6297)
X-Git-Tag: submit/tizen/20190809.050447~10
X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7f1943df10438ef1b07735f7b7f781e5c1a27ce1;p=platform%2Fcore%2Fml%2Fnnfw.git
[mir_onnx] Improve core structure of ONNX importer (#6297)
* Fix right initializer loading
* Fix output creation
* Other fixes
Signed-off-by: Pavel Iliutchenko
---
diff --git a/compiler/mir-onnx-importer/ONNXImporterImpl.cpp b/compiler/mir-onnx-importer/ONNXImporterImpl.cpp
index a76f56e..447f03f 100644
--- a/compiler/mir-onnx-importer/ONNXImporterImpl.cpp
+++ b/compiler/mir-onnx-importer/ONNXImporterImpl.cpp
@@ -18,19 +18,12 @@
#include "ONNXHelpers.h"
#include "ONNXOpRegistration.h"
-#include "mir/IrDotDumper.h"
-#include "mir/ops/ConstantOp.h"
-#include "mir/ops/Conv2DOp.h"
-#include "mir/ops/DepthwiseConv2DOp.h"
-#include "mir/ops/ElementwiseOp.h"
-#include "mir/ops/InputOp.h"
-#include "mir/ops/OutputOp.h"
-#include "mir/ops/TransposeOp.h"
#include "mir/Operation.h"
#include "mir/Shape.h"
#include "mir/TensorUtil.h"
#include "mir/TensorVariant.h"
-#include "onnx/onnx.pb.h"
+
+#include "mir/ops/ConstantOp.h"
#include
@@ -91,6 +84,7 @@ void ONNXImporterImpl::collectUnsupportedOps()
const auto &onnx_node = _model->graph().node(i);
assert(onnx_node.has_op_type());
const auto &op_type = onnx_node.op_type();
+
const auto *converter = NodeConverterRegistry::getInstance().lookup(op_type);
if (converter == nullptr)
problems_op_set.insert(op_type);
@@ -106,32 +100,24 @@ void ONNXImporterImpl::collectUnsupportedOps()
void ONNXImporterImpl::createGraphInputs()
{
- auto &graph = _model->graph();
- auto &initializer = graph.initializer();
- auto &value_info = graph.value_info();
- std::map onnx_tensors;
+ const auto &graph = _model->graph();
+ const auto &initializer = graph.initializer();
+ const auto &value_info = graph.value_info();
- // Collect all initializers of the given graph
- for (int i = 0; i < graph.initializer_size(); i++)
+ // Create all initializer Tensors
+ for (const auto &tensor : initializer)
{
- const onnx::TensorProto &tensor = graph.initializer(i);
- assert(onnx_tensors.find(tensor.name()) == onnx_tensors.end());
- onnx_tensors[tensor.name()] = &tensor;
+ assert(tensor.has_name());
+ const auto mir_tensor = createTensor(&tensor);
+ auto *op = _graph->create(tensor.name(), mir_tensor);
+ _tensorNameToOutput.emplace(tensor.name(), op->getOutput(0));
}
for (auto &input : graph.input())
{
assert(input.has_name());
- auto name = input.name();
- if (onnx_tensors.find(name) != onnx_tensors.end())
- {
- const onnx::TensorProto *onnx_tensor = onnx_tensors[name];
- _constantTensors.insert(std::make_pair(name, createTensor(onnx_tensor)));
- auto constant = _graph->create(name, _constantTensors.at(name));
- _tensorNameToOutput[name] = constant->getOutput(0);
- }
- else
+ if (_tensorNameToOutput.find(input.name()) == _tensorNameToOutput.end())
{
const auto &onnx_input_shape = input.type().tensor_type().shape();
mir::Shape shape(onnx_input_shape.dim_size());
@@ -140,9 +126,9 @@ void ONNXImporterImpl::createGraphInputs()
assert(onnx_input_shape.dim(i).has_dim_value());
shape.dim(i) = static_cast(onnx_input_shape.dim(i).dim_value());
}
- // TODO: Temporary solution!
- auto node = _graph->create(name, shape);
- _tensorNameToOutput[name] = node->getOutput(0);
+
+ auto *op = _graph->create(input.name(), shape);
+ _tensorNameToOutput.emplace(input.name(), op->getOutput(0));
}
}
}
@@ -151,46 +137,49 @@ std::unique_ptr ONNXImporterImpl::createIR()
{
createGraphInputs();
- // for all nodes in onnx graph
+ // Forming partially ordered computation graph
for (auto &onnx_node : _model->graph().node())
{
assert(onnx_node.has_op_type());
- auto op_type = onnx_node.op_type().c_str();
- // Fill inputs of the given node
- std::vector inputs(onnx_node.input_size());
- std::vector outputs;
+ auto &op_type = onnx_node.op_type();
+ auto &inputs = onnx_node.input();
+
+ std::vector mir_inputs;
+ std::vector mir_outputs;
- for (int i = 0; i < onnx_node.input_size(); i++)
+ for (const auto &input_name : inputs)
{
- auto &name = onnx_node.input(i);
- if (!name.empty())
+ if (!input_name.empty())
{
- assert(_tensorNameToOutput.find(name) != _tensorNameToOutput.end());
- inputs[i] = _tensorNameToOutput[name];
+ const auto mir_op_iter = _tensorNameToOutput.find(input_name);
+ assert(mir_op_iter != _tensorNameToOutput.end());
+ mir_inputs.emplace_back(mir_op_iter->second);
}
}
-
+ // Get converter
const auto *node_converter = NodeConverterRegistry::getInstance().lookup(op_type);
- outputs = node_converter->convert(onnx_node, inputs, _graph.get());
- assert(!outputs.empty());
+ assert(node_converter);
+ mir_outputs = node_converter->convert(onnx_node, mir_inputs, _graph.get());
+ assert(!mir_outputs.empty());
// Set outputs' names
- for (int i = 0; i < outputs.size(); i++)
+ for (int i = 0; i < mir_outputs.size(); i++)
{
- outputs[i]->getNode()->setName(onnx_node.output(i));
- auto result = _tensorNameToOutput.emplace(outputs[i]->getNode()->getName(), outputs[i]);
+ mir_outputs[i]->getNode()->setName(onnx_node.output(i));
+ auto result = _tensorNameToOutput.emplace(onnx_node.output(i), mir_outputs[i]);
if (!result.second)
- throw std::runtime_error("Name duplication: " + outputs[i]->getNode()->getName());
+ throw std::runtime_error("Name duplication: " + mir_outputs[i]->getNode()->getName());
}
- assert(!outputs.empty());
- // FIXME: it should be done properly via the given graph outputs
- _graphOutputs.assign(outputs.begin(), outputs.end());
}
- // set graph outputs
- // TODO: it should be done with onnx graph outputs
- for (auto output : _graphOutputs)
+ // Set graph outputs
+ const auto &outputs = _model->graph().output();
+ for (const auto &output : outputs)
{
- _graph->create(output->getNode()->getName(), output);
- output->getNode()->setName("");
+ assert(output.has_name());
+ auto output_iter = _tensorNameToOutput.find(output.name());
+ if (output_iter == _tensorNameToOutput.end())
+ throw std::runtime_error("Bad output name!");
+
+ _graph->create(output.name(), output_iter->second);
}
return std::move(_graph);
diff --git a/compiler/mir-onnx-importer/ONNXImporterImpl.h b/compiler/mir-onnx-importer/ONNXImporterImpl.h
index 31ba69a..ba07405 100644
--- a/compiler/mir-onnx-importer/ONNXImporterImpl.h
+++ b/compiler/mir-onnx-importer/ONNXImporterImpl.h
@@ -18,8 +18,6 @@
#define _MIR_ONNX_IMPORTER_H
#include "mir/Graph.h"
-#include "mir/TensorVariant.h"
-
#include "onnx/onnx.pb.h"
#include