From 94df0692f1de9d98854164078cf6ee4a61b000d7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=98=A4=ED=98=95=EC=84=9D/=EB=8F=99=EC=9E=91=EC=A0=9C?= =?utf8?q?=EC=96=B4Lab=28SR=29/Staff=20Engineer/=EC=82=BC=EC=84=B1?= =?utf8?q?=EC=A0=84=EC=9E=90?= Date: Fri, 31 Aug 2018 16:34:09 +0900 Subject: [PATCH] [neurun] Initialize use & def information (#2543) Initialize use & def information in model finishing phase Add test code to check initialized use&def information Signed-off-by: Hyeongseok Oh --- runtimes/neurun/src/graph/Graph.cc | 24 +++++++ runtimes/neurun/src/graph/Graph.h | 3 + runtimes/neurun/test/graph/operand/UseDef.cc | 101 +++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 runtimes/neurun/test/graph/operand/UseDef.cc diff --git a/runtimes/neurun/src/graph/Graph.cc b/runtimes/neurun/src/graph/Graph.cc index b0bc637..abdabc7 100644 --- a/runtimes/neurun/src/graph/Graph.cc +++ b/runtimes/neurun/src/graph/Graph.cc @@ -94,6 +94,9 @@ void Graph::finishBuilding(void) assert(_phase == Phase::BUILDING); _phase = Phase::MODEL; + // Initialize operand use-def + initializeUseDef(); + // Call graph verifications for the MODEL phase { verifier::DAGChecker dag_checker; @@ -135,6 +138,27 @@ std::unique_ptr Graph::linearize(void) return std::move(linear); } +void Graph::initializeUseDef() +{ + std::function initUseDef = + [&](const operation::Index &index, const operation::Node &node) -> void { + + auto outputs = node.getOutputs(); + for (auto output : outputs.list()) + { + operands().at(output).appendDef(index); + } + + auto inputs = node.getInputs(); + for (auto input : inputs.list()) + { + operands().at(input).appendUse(index); + } + }; + + operations().iterate(initUseDef); +} + } // namespace graph } // namespace neurun diff --git a/runtimes/neurun/src/graph/Graph.h b/runtimes/neurun/src/graph/Graph.h index 82355df..f05bdba 100644 --- a/runtimes/neurun/src/graph/Graph.h +++ b/runtimes/neurun/src/graph/Graph.h @@ -76,6 +76,9 @@ public: std::unique_ptr linearize(void); bool isBuildingPhase(void) { return _phase == Phase::BUILDING; } +private: + void initializeUseDef(); + // Accessors public: const operand::IndexSet &getInputs() const { return _inputs; } diff --git a/runtimes/neurun/test/graph/operand/UseDef.cc b/runtimes/neurun/test/graph/operand/UseDef.cc new file mode 100644 index 0000000..e89eeb6 --- /dev/null +++ b/runtimes/neurun/test/graph/operand/UseDef.cc @@ -0,0 +1,101 @@ +#include + +#include "graph/Graph.h" +#include "graph/verifier/IVerifier.h" +#include "nnfw/std/memory.h" +#include "graph/operand/Index.h" +#include "graph/operation/Index.h" + +#include + +using IOIndex = neurun::graph::operand::IO::Index; +using Index = neurun::graph::operand::Index; +using IndexSet = neurun::graph::operand::IndexSet; + +namespace +{ + +class MockNode : public neurun::graph::operation::Node +{ +public: + MockNode(Index input, Index output) + { + setInputs({input}); + setOutputs({output}); + } + +public: + virtual void accept(neurun::graph::operation::NodeVisitor &&) const override {} +}; + +class MultiInputMockNode : public neurun::graph::operation::Node +{ +public: + MultiInputMockNode(IndexSet inputs, Index output) + { + setInputs(inputs); + setOutputs({output}); + } + +public: + virtual void accept(neurun::graph::operation::NodeVisitor &&) const override {} +}; + +} // namespace anonymous + +TEST(graph_operand_usedef, usedef_test) +{ + neurun::graph::Graph graph; + neurun::graph::verifier::DAGChecker verifier; + + neurun::graph::operand::Shape shape{1u}; + neurun::graph::operand::TypeInfo type{ANEURALNETWORKS_TENSOR_INT32, 0, 0}; + shape.dim(0) = 3; + + // Model Input/Output + auto input_operand = graph.addOperand(shape, type); + auto output_operand = graph.addOperand(shape, type); + + graph.addInput(input_operand); + graph.operands().at(input_operand).setAsModelInput(); + graph.addOutput(output_operand); + + // MockNode1 + auto operand_index1 = graph.addOperand(shape, type); + auto mocknode_index1 = + graph.addOperation(nnfw::make_unique(input_operand, operand_index1)); + graph.operands().at(operand_index1).setAsOperationOutput(); + + // MockNode2 + auto operand_index2 = graph.addOperand(shape, type); + auto mocknode_index2 = + graph.addOperation(nnfw::make_unique(input_operand, operand_index2)); + graph.operands().at(operand_index2).setAsOperationOutput(); + // MultiInputMockNode + auto multiinput_index = graph.addOperation(nnfw::make_unique( + IndexSet{operand_index1, operand_index2}, output_operand)); + graph.operands().at(output_operand).setAsOperationOutput(); + + ASSERT_EQ(verifier.verify(graph), true); + graph.finishBuilding(); + + const auto &operations = graph.operations(); + // Check def + ASSERT_EQ(graph.operands().at(operand_index1).getDef().contains(mocknode_index1), true); + ASSERT_EQ(graph.operands().at(operand_index2).getDef().contains(mocknode_index2), true); + ASSERT_EQ(graph.operands().at(output_operand).getDef().contains(multiinput_index), true); + + ASSERT_EQ(graph.operands().at(operand_index1).getDef().contains(mocknode_index2), false); + ASSERT_EQ(graph.operands().at(operand_index1).getDef().contains(multiinput_index), false); + + // Check use + ASSERT_EQ(graph.operands().at(input_operand).getUses().contains(mocknode_index1), true); + ASSERT_EQ(graph.operands().at(input_operand).getUses().contains(mocknode_index2), true); + ASSERT_EQ(graph.operands().at(input_operand).getUses().contains(multiinput_index), false); + ASSERT_EQ(graph.operands().at(operand_index1).getUses().contains(multiinput_index), true); + ASSERT_EQ(graph.operands().at(operand_index2).getUses().contains(multiinput_index), true); + + ASSERT_EQ(graph.operands().at(input_operand).getUses().size(), 2); + ASSERT_EQ(graph.operands().at(operand_index1).getUses().size(), 1); + ASSERT_EQ(graph.operands().at(output_operand).getUses().size(), 0); +} -- 2.7.4