From: 이한종/동작제어Lab(SR)/Engineer/삼성전자 Date: Thu, 9 Aug 2018 06:16:08 +0000 (+0900) Subject: [neurun] Graph : Introduce Graph (#2235) X-Git-Tag: 0.2~306 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=734f12e8904e372c2ea447f1fea64d7eaf93885d;p=platform%2Fcore%2Fml%2Fnnfw.git [neurun] Graph : Introduce Graph (#2235) This commit introduces `neurun::graph::Graph` which represents our new Graph IR. Note that nodes in the graph is operations. Signed-off-by: Hanjoung Lee --- diff --git a/runtimes/neurun/src/graph/Graph.cc b/runtimes/neurun/src/graph/Graph.cc new file mode 100644 index 0000000..86f1a14 --- /dev/null +++ b/runtimes/neurun/src/graph/Graph.cc @@ -0,0 +1,74 @@ +#include "Graph.h" + +#include +#include + +#include "logging.h" + +namespace neurun +{ +namespace graph +{ + +operand::Index Graph::addOperand(const ::internal::tflite::operand::Shape &shape) +{ + return _operands.append(shape); +} + +operation::Index Graph::addOperation(std::unique_ptr &&node) +{ + + return _operations.append(std::move(node)); +} + +void Graph::setOperandValue(const operand::Index &ind, + std::unique_ptr<::internal::tflite::operand::Data> &&data) +{ + assert(_operands.exist(ind)); + _operands.at(ind).data(std::move(data)); +} + +void Graph::addInput(const operand::Index &ind) { _inputs.append(ind); } + +void Graph::addOutput(const operand::Index &ind) { _outputs.append(ind); } + +void Graph::iteratePostDfs(const std::function &fn) const +{ + std::vector visited(_operations.size(), false); + + std::function dfs_recursive = + [&](const operation::Index &index, const operation::Node &node) -> void { + if (visited[index.asInt()]) + return; + visited[index.asInt()] = true; + + auto outputs = node.outputs(); + for (auto output : outputs.list()) + { + // TODO Fix traversing algorithm + // Every time need to search for operations that has `outgoing` as incoming from all + // operations but we can hold that info cached + _operations.iterate( + [&](const operation::Index &cand_index, const operation::Node &cand_node) { + auto inputs = cand_node.inputs(); + for (auto input : inputs.list()) + { + if (output == input) + { + dfs_recursive(cand_index, cand_node); + } + } + }); + } + + fn(node); + }; + + _operations.iterate(dfs_recursive); + + // All of the operations(nodes) must have been visited. + assert(std::all_of(visited.begin(), visited.end(), [](bool v) { return v; })); +} + +} // namespace graph +} // namespace neurun diff --git a/runtimes/neurun/src/graph/Graph.h b/runtimes/neurun/src/graph/Graph.h new file mode 100644 index 0000000..0c35843 --- /dev/null +++ b/runtimes/neurun/src/graph/Graph.h @@ -0,0 +1,50 @@ +#ifndef __NEURUN_GRAPH_GRAPH_H__ +#define __NEURUN_GRAPH_GRAPH_H__ + +#include + +#include "graph/operation/Node.h" +#include "graph/operation/Set.h" +#include "graph/operand/IndexSet.h" +#include "graph/operand/Set.h" + +namespace neurun +{ +namespace graph +{ + +class Graph +{ +public: + Graph(void) = default; + + // Graph Building +public: + operand::Index addOperand(const ::internal::tflite::operand::Shape &shape); + operation::Index addOperation(std::unique_ptr &&node); + void setOperandValue(const operand::Index &ind, + std::unique_ptr<::internal::tflite::operand::Data> &&data); + void addInput(const operand::Index &ind); + void addOutput(const operand::Index &ind); + + // Accessors +public: + const operand::IndexSet &inputs() const { return _inputs; } + const operand::IndexSet &outputs() const { return _outputs; } + const operand::Set &operands() const { return _operands; } + +public: + // TODO Introduce Iterator class to support many kinds of interation + void iteratePostDfs(const std::function &fn) const; + +private: + operation::Set _operations; + operand::Set _operands; + operand::IndexSet _inputs; + operand::IndexSet _outputs; +}; + +} // namespace graph +} // namespace neurun + +#endif // __NEURUN_GRAPH_GRAPH_H__ diff --git a/runtimes/neurun/src/internal/Model.h b/runtimes/neurun/src/internal/Model.h index 60a695e..0df6dbd 100644 --- a/runtimes/neurun/src/internal/Model.h +++ b/runtimes/neurun/src/internal/Model.h @@ -173,10 +173,10 @@ public: bool isModelInput(void) const { return _usage == OperandUsage::MODEL_INPUT; } private: - void data(std::unique_ptr &&data) { _data = std::move(data); } bool setUsage(OperandUsage usage); public: + void data(std::unique_ptr &&data) { _data = std::move(data); } const Data &data(void) const { return *_data; } public: diff --git a/runtimes/neurun/test/Graph.cc b/runtimes/neurun/test/Graph.cc new file mode 100644 index 0000000..32f3a5e --- /dev/null +++ b/runtimes/neurun/test/Graph.cc @@ -0,0 +1,18 @@ +#include + +#include "graph/Graph.h" + +TEST(Graph, inputs_and_outputs) +{ + ::neurun::graph::Graph graph; + + graph.addInput({0u}); + graph.addInput({1u}); + + graph.addOutput({10u}); + graph.addOutput({11u}); + graph.addOutput({12u}); + + ASSERT_EQ(graph.inputs().size(), 2); + ASSERT_EQ(graph.outputs().size(), 3); +}