diff options
Diffstat (limited to 'runtimes/neurun/src/graph')
60 files changed, 1276 insertions, 2586 deletions
diff --git a/runtimes/neurun/src/graph/Graph.cc b/runtimes/neurun/src/graph/Graph.cc index 07194ff7e..832e2b887 100644 --- a/runtimes/neurun/src/graph/Graph.cc +++ b/runtimes/neurun/src/graph/Graph.cc @@ -19,116 +19,62 @@ #include <algorithm> #include <bitset> -#include "logging.h" -#include "verifier/IVerifier.h" -#include "nnfw/std/memory.h" +#include "util/logging.h" +#include "verifier/Verifier.h" +#include "cpp14/memory.h" #include "linear/Linear.h" #include "operation/LowerInfo.h" #include "operand/LowerInfo.h" #include "operand/Shape4DConvert.h" -#include "codegen/BackendResolver.h" -#include "backend/IBackendConfig.h" +#include "compiler/BackendResolver.h" +#include "backend/interface/IConfig.h" +#include "pass/PermutationInsertionPass.h" +#include "pass/PermutationEliminationPass.h" namespace neurun { namespace graph { -operand::Index Graph::addOperand(const operand::Shape &shape, const operand::TypeInfo &type) -{ - return _operands.append(shape, type); -} +Graph::Graph(void) = default; -operation::Index Graph::addOperation(std::unique_ptr<operation::Node> &&node) +Graph::~Graph(void) = default; + +model::operand::Index Graph::addOperand(const model::operand::Shape &shape, + const model::operand::TypeInfo &type) { - assert(_phase == Phase::BUILDING); - return _operations.append(std::move(node)); + return _model->operands.append(shape, type); } -// TODO : If operand's use-def information is introduced, -// Following API and implements would be refactored. -/** - * @brief Insert operation into between an operand and next operation. - * - * @param prev_operand_index is an previous operand index of insertion. - * @param next_operation_index is an next operation index of insertion. - * @param node is an operation::Node to insert. - * - * @return operation::Index - */ -operation::Index Graph::insertOperation(const operand::Index &prev_operand_index, - const operation::Index &next_operation_index, - std::unique_ptr<operation::Node> &&node) +model::operation::Index Graph::addOperation(std::unique_ptr<model::operation::Node> &&node) { - assert(_phase != Phase::BUILDING); - auto &next_operation = _operations.at(next_operation_index); - auto next_input_indexes = next_operation.getInputs(); - - assert(next_input_indexes.contains(prev_operand_index)); - assert(node->getInputs().size() == 0); // node to be inserted must not have any inputs - - node->setInputs({prev_operand_index}); - - // For multi input operation (ex. concat) - operand::IndexSet index_set; - auto cur_output_indexes = node->getOutputs(); - assert(cur_output_indexes.size() == 1); // Assume output of inserted node size always 1 - auto cur_output_index = cur_output_indexes.at(operand::IO::Index{0}); - // TODO : If the API for setting input one by one is introduced, it would be changed to simple. - for (auto next_input_index : next_input_indexes) - { - if (prev_operand_index == next_input_index) - { - index_set.append(cur_output_index); - } - else - { - index_set.append(next_input_index); - } - } - - next_operation.setInputs(index_set); - - operation::Index node_index = _operations.append(std::move(node)); - - // Update Use/Def info - { - _operands.at(prev_operand_index).removeUse(next_operation_index); - _operands.at(cur_output_index).appendUse(next_operation_index); - - _operands.at(prev_operand_index).appendUse(node_index); - - auto node_output_indexes = _operations.at(node_index).getOutputs(); - assert(node_output_indexes.size() == 1); - auto node_output_index = node_output_indexes.at(operand::IO::Index{0}); - _operands.at(node_output_index).appendDef(node_index); - } - - return node_index; + assert(isBuildingPhase()); + return _model->operations.append(std::move(node)); } -void Graph::setOperandValue(const operand::Index &ind, std::unique_ptr<operand::Data> &&data) +void Graph::setOperandValue(const model::operand::Index &ind, + std::unique_ptr<model::operand::Data> &&data) { - assert(_phase == Phase::BUILDING); - assert(_operands.exist(ind)); - _operands.at(ind).data(std::move(data)); + assert(isBuildingPhase()); + assert(_model->operands.exist(ind)); + _model->operands.at(ind).data(std::move(data)); } -void Graph::addInput(const operand::Index &ind) +void Graph::addInput(const model::operand::Index &ind) { - assert(_phase == Phase::BUILDING); - _inputs.append(ind); + assert(isBuildingPhase()); + _model->inputs.append(ind); } -void Graph::addOutput(const operand::Index &ind) +void Graph::addOutput(const model::operand::Index &ind) { - assert(_phase == Phase::BUILDING); - _outputs.append(ind); + assert(isBuildingPhase()); + _model->outputs.append(ind); } void Graph::finishBuilding(void) { - assert(_phase == Phase::BUILDING); + assert(isBuildingPhase()); _phase = Phase::MODEL; // Initialize operand use-def @@ -136,8 +82,8 @@ void Graph::finishBuilding(void) // Call graph verifications for the MODEL phase { - verifier::DAGChecker dag_checker; - dag_checker.verify(*this); + assert(verifier::DAGChecker().verify(*this)); + assert(verifier::EdgeConsistencyChecker().verify(*this)); } } @@ -148,106 +94,174 @@ void Graph::lower(void) // Lower { // operand::LowerInfo holder - std::unordered_map<operand::Index, std::unique_ptr<operand::LowerInfo>> operands_lower_info; + std::unordered_map<model::operand::Index, std::unique_ptr<operand::LowerInfo>> + operands_lower_info; - _operands.iterate([&](const operand::Index &index, const operand::Object &object) { + _model->operands.iterate([&](const model::operand::Index &index, + const model::operand::Object &object) { operands_lower_info[index] = - nnfw::make_unique<operand::LowerInfo>(operand::asShape4D(object.shape())); + nnfw::cpp14::make_unique<operand::LowerInfo>(graph::operand::asShape4D(object.shape())); }); - auto _backend_resolver = codegen::BackendResolver(_operands); + _backend_resolver = nnfw::cpp14::make_unique<compiler::BackendResolver>(_model->operands); + + _model->operations.iterate( + [&](const model::operation::Index &index, model::operation::Node &node) { + auto backend = _backend_resolver->getBackend(typeid(node)); + + // Operation LowerInfo + setLowerInfo(index, nnfw::cpp14::make_unique<graph::operation::LowerInfo>(backend)); - _operations.iterate([&](const operation::Index &, operation::Node &node) { - auto backend = _backend_resolver.getBackend(typeid(node)); + // LowerInfo for in/output operands + for (auto operand : node.getInputs()) + { + auto &&lower_info = operands_lower_info.at(operand); + lower_info->addUseBackend(backend); + } + for (auto operand : node.getOutputs()) + { + auto &&lower_info = operands_lower_info.at(operand); + lower_info->addDefBackend(backend); + } + }); + + // Add def backend to model input/output operand as default backend + for (auto index : getInputs()) + { + auto &&lower_info = operands_lower_info.at(index); + lower_info->addDefBackend(_backend_resolver->getDefaultBackend()); + } - // Operation LowerInfo - node.lower_info(nnfw::make_unique<operation::LowerInfo>(backend)); + for (auto index : getOutputs()) + { + auto &&lower_info = operands_lower_info.at(index); + lower_info->addUseBackend(_backend_resolver->getDefaultBackend()); + } - // LowerInfo for in/output operands + // Add DefBackend constants same as UseBackend + // NOTE This assumes a constant operand is used by only one operation + _model->operations.iterate([&](const model::operation::Index &, model::operation::Node &node) { + // LowerInfo for input operands for (auto operand : node.getInputs()) { auto &&lower_info = operands_lower_info.at(operand); - lower_info->addUseLayout(backend.config()->getOperandLayout()); - } - for (auto operand : node.getOutputs()) - { - auto &&lower_info = operands_lower_info.at(operand); - lower_info->addDefLayout(backend.config()->getOperandLayout()); + if (lower_info->def_backends().empty()) + { + lower_info->addDefBackend(lower_info->use_backends().getOnlyElement()); + } } }); // Set LowerInfo for each operand from the operand::LowerInfo holder - _operands.iterate([&](const operand::Index &index, operand::Object &object) { + _model->operands.iterate([&](const model::operand::Index &index, + model::operand::Object &object) { object.lower_info(std::move(operands_lower_info[index])); // Dump operand LowerInfo + // TODO Extract this dumping procedure to be reusable + if (!object.lower_info()->def_backends().empty() || + !object.lower_info()->use_backends().empty()) { - auto layouts_to_string = [](const operand::LayoutSet &layouts) { + auto backends_to_string = [](const operand::BackendSet &backends) { std::string str; - for (auto layout : layouts) + for (auto backend : backends) { - const char *name = ""; - if (layout == operand::Layout::NHWC) - name = "NHWC"; - if (layout == operand::Layout::NCHW) - name = "NCHW"; - str += name; + str += backend->config()->id(); + str += " "; + } + return "{ " + str + "}"; + }; + + auto operation_index_to_string = [](const model::operation::IndexList &operations) { + std::string str; + for (auto op : operations.list()) + { + str += std::to_string(op.value()); str += " "; } return "{ " + str + "}"; }; const auto &lower_info = object.lower_info(); - const auto &shape = lower_info->shape(); - std::string def_layouts = layouts_to_string(lower_info->def_layouts()); - std::string use_layouts = layouts_to_string(lower_info->use_layouts()); + const auto &shape = object.shape(); + const auto &lower_shape = lower_info->shape(); + std::string def_ops = operation_index_to_string(object.getDef()); + std::string use_ops = operation_index_to_string(object.getUses()); + std::string def_layouts = backends_to_string(lower_info->def_backends()); + std::string use_layouts = backends_to_string(lower_info->use_backends()); VERBOSE(Lower) << "* Operand #" << index.value() << " LowerInfo" << std::endl; - VERBOSE(Lower) << " - 4D Shape (NHWC) : { " << shape.n() << " " << shape.h() << " " - << shape.w() << " " << shape.c() << " " + VERBOSE(Lower) << " - Shape : { " << shape.dim(0) << " " + << (shape.rank() > 1 ? shape.dim(1) : 0) << " " + << (shape.rank() > 2 ? shape.dim(2) : 0) << " " + << (shape.rank() > 3 ? shape.dim(3) : 0) << " " << "}" << std::endl; - VERBOSE(Lower) << " - Def Layout : " << def_layouts << std::endl; - VERBOSE(Lower) << " - Use Layout : " << use_layouts << std::endl; + VERBOSE(Lower) << " - Def Operations : " << def_ops << std::endl; + VERBOSE(Lower) << " - Use Operations : " << use_ops << std::endl; + VERBOSE(Lower) << " - Lower Info" << std::endl; + VERBOSE(Lower) << " - 4D Shape (NHWC) : { " << lower_shape.n() << " " << lower_shape.h() + << " " << lower_shape.w() << " " << lower_shape.c() << " " + << "}" << std::endl; + VERBOSE(Lower) << " - Def Backends : " << def_layouts << std::endl; + VERBOSE(Lower) << " - Use Backends : " << use_layouts << std::endl; } }); } - // Graph verifications for the LOWERED phase + // Run PermutationInsertionPass { - verifier::DAGChecker dag_checker; - dag_checker.verify(*this); + pass::PermutationInsertionPass pi_pass(*this); + pi_pass.run(); + pass::PermutationEliminationPass pe_pass(*this); + pe_pass.run(); } - _phase = Phase::LOWERED; + // Graph verifications for the LOWERED phase + { + assert(verifier::DAGChecker().verify(*this)); + assert(verifier::EdgeConsistencyChecker().verify(*this)); + } } std::unique_ptr<linear::Linear> Graph::linearize(void) { - assert(_phase == Phase::LOWERED); + assert(_phase == Phase::MODEL); - auto linear = nnfw::make_unique<linear::Linear>(*this); + auto linear = nnfw::cpp14::make_unique<linear::Linear>(*this); // TODO Move the operations and operands to linear object - - _phase = Phase::LINEARIZED; - return std::move(linear); } void Graph::initializeUseDef() { - operations().iterate([&](const operation::Index &index, const operation::Node &node) -> void { - auto outputs = node.getOutputs(); - for (auto output : outputs) - { - operands().at(output).appendDef(index); - } + operations().iterate( + [&](const model::operation::Index &index, const model::operation::Node &node) -> void { + auto outputs = node.getOutputs(); + for (auto output : outputs) + { + operands().at(output).appendDef(index); + } + + auto inputs = node.getInputs(); + for (auto input : inputs) + { + operands().at(input).appendUse(index); + } + }); +} - auto inputs = node.getInputs(); - for (auto input : inputs) - { - operands().at(input).appendUse(index); - } - }); +const operation::LowerInfo *Graph::getLowerInfo(const model::operation::Index &index) const +{ + auto itr = _operation_lower_info.find(index); + if (itr == _operation_lower_info.end()) + return nullptr; + return itr->second.get(); +} + +void Graph::setLowerInfo(const model::operation::Index &index, + std::unique_ptr<operation::LowerInfo> &&lower_info) +{ + _operation_lower_info.insert(std::make_pair(index, std::move(lower_info))); } } // namespace graph @@ -273,7 +287,8 @@ template class Graph::PostDfsIterator<false>; template <bool is_const> void Graph::DefaultIterator<is_const>::iterate(GraphRef graph, const IterFn &fn) const { - graph._operations.iterate([&](const operation::Index &, NodeRef node) -> void { fn(node); }); + graph.operations().iterate( + [&](const model::operation::Index &index, NodeRef node) -> void { fn(index, node); }); } // @@ -285,30 +300,34 @@ void Graph::PostDfsIterator<is_const>::iterate(GraphRef graph, const IterFn &fn) { assert(!graph.isBuildingPhase()); // Restrict iteration condition - std::vector<bool> visited(graph._operations.size(), false); + std::unordered_map<model::operation::Index, bool> visited; + graph.operations().iterate( + [&](const model::operation::Index &index, NodeRef) { visited[index] = false; }); - std::function<void(const operation::Index &, NodeRef)> dfs_recursive = - [&](const operation::Index &index, NodeRef node) -> void { - if (visited[index.asInt()]) + std::function<void(const model::operation::Index &, NodeRef)> dfs_recursive = + [&](const model::operation::Index &index, NodeRef node) -> void { + if (visited[index]) return; - visited[index.asInt()] = true; + visited[index] = true; for (auto output : node.getOutputs()) { - const auto &operand = graph._operands.at(output); + const auto &operand = graph.operands().at(output); for (const auto &use : operand.getUses().list()) { - dfs_recursive(use, graph._operations.at(use)); + dfs_recursive(use, graph.operations().at(use)); } } - fn(node); + fn(index, node); }; - graph._operations.iterate(dfs_recursive); + graph.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; })); + assert(std::all_of( + visited.begin(), visited.end(), + [](const std::pair<const model::operation::Index, bool> &v) { return v.second; })); } } // namespace graph diff --git a/runtimes/neurun/src/graph/Graph.h b/runtimes/neurun/src/graph/Graph.h index dd1489a93..afcfdce12 100644 --- a/runtimes/neurun/src/graph/Graph.h +++ b/runtimes/neurun/src/graph/Graph.h @@ -19,10 +19,8 @@ #include <functional> -#include "graph/operation/Node.h" -#include "graph/operation/Set.h" -#include "graph/operand/IndexSet.h" -#include "graph/operand/Set.h" +#include "model/operation/Node.h" +#include "graph/Model.h" namespace neurun { @@ -34,6 +32,14 @@ class Linear; namespace neurun { +namespace compiler +{ +class BackendResolver; +} // namespace compiler +} // namespace neurun + +namespace neurun +{ namespace graph { @@ -43,9 +49,7 @@ private: enum class Phase { BUILDING, - MODEL, - LOWERED, - LINEARIZED // Everything is moved to Linear object so this Graph object is no longer effective + MODEL }; public: @@ -53,9 +57,10 @@ public: { public: using GraphRef = typename std::conditional<is_const, const Graph &, Graph &>::type; - using NodeRef = - typename std::conditional<is_const, const operation::Node &, operation::Node &>::type; - using IterFn = std::function<void(NodeRef)>; + using IndexRef = const model::operation::Index &; + using NodeRef = typename std::conditional<is_const, const model::operation::Node &, + model::operation::Node &>::type; + using IterFn = std::function<void(IndexRef, NodeRef)>; public: virtual ~Iterator() = default; @@ -66,6 +71,7 @@ public: { public: using GraphRef = typename Iterator<is_const>::GraphRef; + using IndexRef = typename Iterator<is_const>::IndexRef; using NodeRef = typename Iterator<is_const>::NodeRef; using IterFn = typename Iterator<is_const>::IterFn; @@ -78,6 +84,7 @@ public: { public: using GraphRef = typename Iterator<is_const>::GraphRef; + using IndexRef = typename Iterator<is_const>::IndexRef; using NodeRef = typename Iterator<is_const>::NodeRef; using IterFn = typename Iterator<is_const>::IterFn; @@ -87,20 +94,21 @@ public: using PostDfsConstIterator = PostDfsIterator<true>; public: - Graph(void) = default; + Graph(void); + ~Graph(void); // Graph Building public: - operand::Index addOperand(const operand::Shape &shape, const operand::TypeInfo &type); - operation::Index addOperation(std::unique_ptr<operation::Node> &&node); - operation::Index insertOperation(const operand::Index &prev_operand_index, - const operation::Index &next_operation_index, - std::unique_ptr<operation::Node> &&node); - void setOperandValue(const operand::Index &ind, std::unique_ptr<operand::Data> &&data); - void addInput(const operand::Index &ind); - void addOutput(const operand::Index &ind); + model::operand::Index addOperand(const model::operand::Shape &shape, + const model::operand::TypeInfo &type); + model::operation::Index addOperation(std::unique_ptr<model::operation::Node> &&node); + void setOperandValue(const model::operand::Index &ind, + std::unique_ptr<model::operand::Data> &&data); + void addInput(const model::operand::Index &ind); + void addOutput(const model::operand::Index &ind); void finishBuilding(void); void lower(void); + void removeOperand(const model::operand::Index &ind) { _model->operands.remove(ind); } std::unique_ptr<linear::Linear> linearize(void); bool isBuildingPhase(void) const { return _phase == Phase::BUILDING; } @@ -109,18 +117,33 @@ private: // Accessors public: - const operand::IndexSet &getInputs() const { return _inputs; } - const operand::IndexSet &getOutputs() const { return _outputs; } - const operand::Set &operands() const { return _operands; } - operand::Set &operands() { return _operands; } // TODO Remove this non-const accessor - const operation::Set &operations() const { return _operations; } + const model::operand::IndexSet &getInputs() const { return _model->inputs; } + model::operand::IndexSet &getInputs() { return _model->inputs; } + const model::operand::IndexSet &getOutputs() const { return _model->outputs; } + model::operand::IndexSet &getOutputs() { return _model->outputs; } + const model::operand::Set &operands() const { return _model->operands; } + model::operand::Set &operands() + { + return _model->operands; + } // TODO Remove this non-const accessor + const model::operation::Set &operations() const { return _model->operations; } + model::operation::Set &operations() { return _model->operations; } + const compiler::BackendResolver *backend_resolver() const { return _backend_resolver.get(); } private: Phase _phase{Phase::BUILDING}; - operation::Set _operations; - operand::Set _operands; - operand::IndexSet _inputs; - operand::IndexSet _outputs; + std::unique_ptr<Model> _model{new Model}; + + // For LOWERED phase +public: + const operation::LowerInfo *getLowerInfo(const model::operation::Index &index) const; + void setLowerInfo(const model::operation::Index &index, + std::unique_ptr<operation::LowerInfo> &&lower_info); + +private: + std::unique_ptr<compiler::BackendResolver> _backend_resolver; + std::unordered_map<model::operation::Index, std::unique_ptr<operation::LowerInfo>> + _operation_lower_info; }; } // namespace graph diff --git a/runtimes/neurun/src/graph/Index.h b/runtimes/neurun/src/graph/Index.h index 864aaffd0..3263d12ad 100644 --- a/runtimes/neurun/src/graph/Index.h +++ b/runtimes/neurun/src/graph/Index.h @@ -18,6 +18,7 @@ #define __NEURUN_GRAPH_INDEX_H__ #include <functional> +#include <limits> #include <stdint.h> namespace neurun @@ -27,7 +28,11 @@ namespace graph template <typename T, typename DummyTag> class Index { +private: + static const T UNDEFINED = std::numeric_limits<T>::max(); + public: + explicit Index(void) : _index{UNDEFINED} {} explicit Index(T o) : _index{o} {} explicit Index(int32_t o) : _index{static_cast<T>(o)} {} // For legacy code compatibility Index(const Index &o) : _index{o._index} {} diff --git a/runtimes/neurun/src/graph/operand/DataType.h b/runtimes/neurun/src/graph/Model.h index 8878901fd..20bb713af 100644 --- a/runtimes/neurun/src/graph/operand/DataType.h +++ b/runtimes/neurun/src/graph/Model.h @@ -14,30 +14,27 @@ * limitations under the License. */ -#ifndef __NEURUN_GRAPH_OPERAND_DATATYPE_H__ -#define __NEURUN_GRAPH_OPERAND_DATATYPE_H__ +#ifndef __NEURUN_GRAPH_MODEL_H__ +#define __NEURUN_GRAPH_MODEL_H__ + +#include "model/operation/Set.h" +#include "model/operand/IndexSet.h" +#include "model/operand/Set.h" namespace neurun { namespace graph { -namespace operand -{ -enum class DataType +struct Model { - SCALAR_FLOAT32 = 0, - SCALAR_INT32 = 1, - SCALAR_UINT32 = 2, - - TENSOR_FLOAT32 = 3, - TENSOR_INT32 = 4, - - TENSOR_QUANT8_ASYMM = 5, + model::operation::Set operations; + model::operand::Set operands; + model::operand::IndexSet inputs; + model::operand::IndexSet outputs; }; -} // namespace operand } // namespace graph } // namespace neurun -#endif // __NEURUN_GRAPH_OPERAND_DATATYPE_H__ +#endif // __NEURUN_GRAPH_MODEL_H__ diff --git a/runtimes/neurun/src/graph/dumper/Dumper.cc b/runtimes/neurun/src/graph/dumper/Dumper.cc index 3788317ce..efffc5849 100644 --- a/runtimes/neurun/src/graph/dumper/Dumper.cc +++ b/runtimes/neurun/src/graph/dumper/Dumper.cc @@ -18,7 +18,7 @@ #include <string> -#include "logging.h" +#include "util/logging.h" namespace neurun { @@ -27,9 +27,9 @@ namespace graph namespace dumper { -using namespace neurun::graph::operation; +using namespace neurun::model::operation; -void Dumper::visit(const Conv2D::Implicit::Node &node) +void Dumper::visit(const Conv2DNode &node) { VERBOSE(LIR) << "* Conv2D(Implicit)" << std::endl; VERBOSE(LIR) << " - Inputs : IFM(" << node.getInputs().at(0).value() << ") Kernel(" @@ -38,21 +38,21 @@ void Dumper::visit(const Conv2D::Implicit::Node &node) VERBOSE(LIR) << " - Output : OFM(" << node.getOutputs().at(0).value() << ")" << std::endl; } -void Dumper::visit(const MaxPool2D::Implicit::Node &node) +void Dumper::visit(const MaxPool2DNode &node) { VERBOSE(LIR) << "* MaxPool2D(Implicit)" << std::endl; VERBOSE(LIR) << " - Inputs : IFM(" << node.getInputs().at(0).value() << ")" << std::endl; VERBOSE(LIR) << " - Output : OFM(" << node.getOutputs().at(0).value() << ")" << std::endl; } -void Dumper::visit(const AvgPool2D::Implicit::Node &node) +void Dumper::visit(const AvgPool2DNode &node) { VERBOSE(LIR) << "* AvgPool2D(Implicit)" << std::endl; VERBOSE(LIR) << " - Inputs : IFM(" << node.getInputs().at(0).value() << ")" << std::endl; VERBOSE(LIR) << " - Output : OFM(" << node.getOutputs().at(0).value() << ")" << std::endl; } -void Dumper::visit(const Concat::Node &node) +void Dumper::visit(const ConcatNode &node) { VERBOSE(LIR) << "* Concat" << std::endl; std::string inputs; @@ -64,7 +64,7 @@ void Dumper::visit(const Concat::Node &node) VERBOSE(LIR) << " - Output : OFM(" << node.getOutputs().at(0).value() << ")" << std::endl; } -void Dumper::visit(const FullyConnected::Node &node) +void Dumper::visit(const FullyConnectedNode &node) { VERBOSE(LIR) << "* FullyConnected" << std::endl; VERBOSE(LIR) << " - Inputs : IFM(" << node.getInputs().at(0).value() << ") Weight(" @@ -73,7 +73,7 @@ void Dumper::visit(const FullyConnected::Node &node) VERBOSE(LIR) << " - Output : OFM(" << node.getOutputs().at(0).value() << ")" << std::endl; } -void Dumper::visit(const Reshape::Node &node) +void Dumper::visit(const ReshapeNode &node) { VERBOSE(LIR) << "* Reshape" << std::endl; // TODO The shape index should be "node.getInputs().at(1).value()" but not valid for now @@ -83,36 +83,28 @@ void Dumper::visit(const Reshape::Node &node) VERBOSE(LIR) << " - Output : OFM(" << node.getOutputs().at(0).value() << ")" << std::endl; } -void Dumper::visit(const Softmax::Node &node) +void Dumper::visit(const SoftmaxNode &node) { VERBOSE(LIR) << "* Softmax" << std::endl; VERBOSE(LIR) << " - Inputs : IFM(" << node.getInputs().at(0).value() << ")" << std::endl; VERBOSE(LIR) << " - Output : OFM(" << node.getOutputs().at(0).value() << ")" << std::endl; } -void Dumper::visit(const NOP::Node &node) -{ - VERBOSE(LIR) << "* NOP" << std::endl; - std::string inputs, outputs; - for (auto i : node.getInputs()) - { - inputs += std::to_string(i.value()) + ","; - } - VERBOSE(LIR) << " - Inputs : IFM(" << inputs << ")" << std::endl; - for (auto i : node.getOutputs()) - { - outputs += std::to_string(i.value()) + ","; - } - VERBOSE(LIR) << " - Outputs : OFM(" << outputs << ")" << std::endl; -} - -void Dumper::visit(const Permute::Node &node) +void Dumper::visit(const PermuteNode &node) { VERBOSE(LIR) << "* Permute" << std::endl; VERBOSE(LIR) << " - Inputs : IFM(" << node.getInputs().at(0).value() << ")" << std::endl; VERBOSE(LIR) << " - Output : OFM(" << node.getOutputs().at(0).value() << ")" << std::endl; } +void Dumper::visit(const AddNode &node) +{ + VERBOSE(LIR) << "* Add" << std::endl; + VERBOSE(LIR) << " - Inputs : Input(" << node.getInputs().at(0).value() << ", " + << node.getInputs().at(1).value() << ")" << std::endl; + VERBOSE(LIR) << " - Output : Output(" << node.getOutputs().at(0).value() << ")" << std::endl; +} + } // namespace dumper } // namespace graph } // namespace neurun diff --git a/runtimes/neurun/src/graph/dumper/Dumper.h b/runtimes/neurun/src/graph/dumper/Dumper.h index dee490cbd..8c079a11d 100644 --- a/runtimes/neurun/src/graph/dumper/Dumper.h +++ b/runtimes/neurun/src/graph/dumper/Dumper.h @@ -17,7 +17,7 @@ #ifndef __NEURUN_GRAPH_DUMPER_H__ #define __NEURUN_GRAPH_DUMPER_H__ -#include "graph/operation/NodeVisitor.h" +#include "model/operation/NodeVisitor.h" namespace neurun { @@ -26,21 +26,21 @@ namespace graph namespace dumper { -class Dumper : public graph::operation::NodeVisitor +class Dumper : public model::operation::NodeVisitor { public: Dumper() = default; public: - void visit(const graph::operation::Conv2D::Implicit::Node &node) override; - void visit(const graph::operation::MaxPool2D::Implicit::Node &node) override; - void visit(const graph::operation::AvgPool2D::Implicit::Node &node) override; - void visit(const graph::operation::Concat::Node &node) override; - void visit(const graph::operation::FullyConnected::Node &node) override; - void visit(const graph::operation::Reshape::Node &node) override; - void visit(const graph::operation::Softmax::Node &node) override; - void visit(const graph::operation::NOP::Node &node) override; - void visit(const graph::operation::Permute::Node &node) override; + void visit(const model::operation::Conv2DNode &node) override; + void visit(const model::operation::MaxPool2DNode &node) override; + void visit(const model::operation::AvgPool2DNode &node) override; + void visit(const model::operation::ConcatNode &node) override; + void visit(const model::operation::FullyConnectedNode &node) override; + void visit(const model::operation::ReshapeNode &node) override; + void visit(const model::operation::SoftmaxNode &node) override; + void visit(const model::operation::PermuteNode &node) override; + void visit(const model::operation::AddNode &node) override; }; } // namespace dumper diff --git a/runtimes/neurun/src/graph/operand/BackendSet.cc b/runtimes/neurun/src/graph/operand/BackendSet.cc new file mode 100644 index 000000000..9a284d722 --- /dev/null +++ b/runtimes/neurun/src/graph/operand/BackendSet.cc @@ -0,0 +1,77 @@ +/* + * 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 "BackendSet.h" + +#include <cassert> + +namespace neurun +{ +namespace graph +{ +namespace operand +{ + +BackendSet::BackendSet(std::initializer_list<const backend::Backend *> backends) +{ + for (auto backend : backends) + { + _set.insert(backend); + } +} + +const backend::Backend *BackendSet::getOnlyElement() const +{ + assert(_set.size() == 1u); + return *_set.begin(); +} + +BackendSet BackendSet::operator|(const BackendSet &other) const +{ + auto ret = *this; + for (auto backend : other) + { + ret.add(backend); + } + return ret; +} + +BackendSet BackendSet::operator&(const BackendSet &other) const +{ + BackendSet ret; + for (auto backend : other) + { + if (contains(backend)) + { + ret.add(backend); + } + } + return ret; +} + +BackendSet BackendSet::operator-(const BackendSet &other) const +{ + auto ret = *this; + for (auto backend : other) + { + ret.remove(backend); + } + return ret; +} + +} // namespace operand +} // namespace graph +} // namespace neurun diff --git a/runtimes/neurun/src/graph/operand/BackendSet.h b/runtimes/neurun/src/graph/operand/BackendSet.h new file mode 100644 index 000000000..8b457a084 --- /dev/null +++ b/runtimes/neurun/src/graph/operand/BackendSet.h @@ -0,0 +1,72 @@ +/* + * 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. + */ + +#ifndef __NEURUN_GRAPH_OPERAND_BACKEND_SET_H__ +#define __NEURUN_GRAPH_OPERAND_BACKEND_SET_H__ + +#include <initializer_list> +#include <unordered_set> + +namespace neurun +{ +namespace backend +{ +class Backend; +} // namespace backend +} // namespace neurun + +namespace neurun +{ +namespace graph +{ +namespace operand +{ + +class BackendSet +{ +public: + BackendSet() = default; + BackendSet(std::initializer_list<const backend::Backend *> backends); + +public: + void add(const backend::Backend *backend) { _set.insert(backend); } + void remove(const backend::Backend *backend) { _set.erase(backend); } + uint32_t size() const { return static_cast<uint32_t>(_set.size()); } + bool empty() const { return _set.empty(); } + bool contains(const backend::Backend *backend) const { return _set.find(backend) != _set.end(); } + const backend::Backend *getOnlyElement() const; + +public: + BackendSet operator|(const BackendSet &other) const; // Union + BackendSet operator&(const BackendSet &other) const; // Intersect + BackendSet operator-(const BackendSet &other) const; // Minus + +public: + std::unordered_set<const backend::Backend *>::const_iterator begin() const + { + return _set.begin(); + } + std::unordered_set<const backend::Backend *>::const_iterator end() const { return _set.end(); } + +private: + std::unordered_set<const backend::Backend *> _set; +}; + +} // namespace operand +} // namespace graph +} // namespace neurun + +#endif // __NEURUN_GRAPH_OPERAND_BACKEND_SET_H__ diff --git a/runtimes/neurun/src/graph/operand/Data.h b/runtimes/neurun/src/graph/operand/Data.h deleted file mode 100644 index e36a9a2ae..000000000 --- a/runtimes/neurun/src/graph/operand/Data.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERAND_DATA_H__ -#define __NEURUN_GRAPH_OPERAND_DATA_H__ - -#include <algorithm> - -namespace neurun -{ -namespace graph -{ -namespace operand -{ - -struct Data -{ - virtual ~Data() = default; - - virtual size_t size(void) const = 0; - virtual const uint8_t *base(void) const = 0; -}; - -class CachedData final : public Data -{ -public: - CachedData(const uint8_t *base, size_t size) : _base{new uint8_t[size]}, _size{size} - { - std::copy(base, base + size, _base); - } - -public: - ~CachedData() { delete[] _base; } - -public: - size_t size(void) const override { return _size; } - const uint8_t *base(void) const override { return _base; } - -private: - uint8_t *_base; - size_t _size; -}; - -class ExternalData final : public Data -{ -public: - ExternalData(const uint8_t *base, size_t size) : _base{base}, _size{size} - { - // DO NOTHING - } - -public: - size_t size(void) const override { return _size; } - const uint8_t *base(void) const override { return _base; } - -private: - const uint8_t *_base; - const size_t _size; -}; - -} // namespace operand -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERAND_DATA_H__ diff --git a/runtimes/neurun/src/graph/operand/IndexSet.h b/runtimes/neurun/src/graph/operand/IndexSet.h deleted file mode 100644 index 2d37de788..000000000 --- a/runtimes/neurun/src/graph/operand/IndexSet.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERAND_INDEX_SET_H__ -#define __NEURUN_GRAPH_OPERAND_INDEX_SET_H__ - -#include <initializer_list> -#include <vector> - -#include "Index.h" - -namespace neurun -{ -namespace graph -{ -namespace operand -{ - -class IndexSet -{ -public: - IndexSet(void) = default; - IndexSet(std::initializer_list<Index> list); - IndexSet(std::initializer_list<int32_t> list); - IndexSet(std::initializer_list<uint32_t> list); - -public: - void append(const Index &index) { _set.emplace_back(index); } - -public: - uint32_t size() const { return static_cast<uint32_t>(_set.size()); } - const Index &at(IO::Index set_index) const { return _set.at(set_index.asInt()); } - const Index &at(uint32_t index) const { return _set.at(index); } - bool contains(const Index &index) const; - -public: - std::vector<Index>::const_iterator begin(void) const { return _set.begin(); } - std::vector<Index>::const_iterator end(void) const { return _set.end(); } - -private: - std::vector<Index> _set; -}; - -} // namespace operand -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERAND_INDEX_SET_H__ diff --git a/runtimes/neurun/src/graph/operand/LowerInfo.h b/runtimes/neurun/src/graph/operand/LowerInfo.h index d91c29fb7..7900e54d9 100644 --- a/runtimes/neurun/src/graph/operand/LowerInfo.h +++ b/runtimes/neurun/src/graph/operand/LowerInfo.h @@ -19,7 +19,7 @@ #include <stdint.h> -#include "LayoutSet.h" +#include "BackendSet.h" namespace neurun { @@ -60,17 +60,19 @@ public: public: const Shape4D &shape(void) const { return _shape; } - const LayoutSet &def_layouts(void) const { return _def_layouts; } - const LayoutSet &use_layouts(void) const { return _use_layouts; } + const BackendSet &def_backends(void) const { return _def_backends; } + const BackendSet &use_backends(void) const { return _use_backends; } public: - void addDefLayout(const Layout &layout) { _def_layouts.add(layout); } - void addUseLayout(const Layout &layout) { _use_layouts.add(layout); } + void addDefBackend(const backend::Backend *backend) { _def_backends.add(backend); } + void addUseBackend(const backend::Backend *backend) { _use_backends.add(backend); } + void removeDefBackend(const backend::Backend *backend) { _def_backends.remove(backend); } + void removeUseBackend(const backend::Backend *backend) { _use_backends.remove(backend); } private: Shape4D _shape; - LayoutSet _def_layouts; - LayoutSet _use_layouts; + BackendSet _def_backends; + BackendSet _use_backends; }; } // namespace operand diff --git a/runtimes/neurun/src/graph/operand/Object.cc b/runtimes/neurun/src/graph/operand/Object.cc deleted file mode 100644 index 7b95cea97..000000000 --- a/runtimes/neurun/src/graph/operand/Object.cc +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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 "Object.h" - -namespace neurun -{ -namespace graph -{ -namespace operand -{ - -size_t Object::operandSize(void) const -{ - const uint32_t ranks = _shape.rank(); - int32_t elements = 1; - - for (uint32_t rank = 0; rank < ranks; rank++) - { - elements *= _shape.dim(rank); - } - - DataType type = _type.type(); - size_t element_size = 0; - - // Value of type is matched with OperandCode enum in NeuralNetworks.h - switch (type) - { - case DataType::SCALAR_FLOAT32: - case DataType::TENSOR_FLOAT32: - element_size = sizeof(float); - break; - case DataType::SCALAR_INT32: - case DataType::TENSOR_INT32: - element_size = sizeof(int32_t); - break; - case DataType::SCALAR_UINT32: - element_size = sizeof(uint32_t); - break; - case DataType::TENSOR_QUANT8_ASYMM: - element_size = sizeof(uint8_t); - break; - default: - throw std::runtime_error{"Unsuppported type size"}; - } - - return element_size * elements; -} - -bool Object::setUsage(const OperandUsage usage) -{ - if (usageIsDefined() && (_usage != usage)) - { - // Already set as different type - return false; - } - - _usage = usage; - - return true; -} - -void Object::appendUse(const ::neurun::graph::operation::Index &idx) -{ - assert(_usage != OperandUsage::NOT_DEFINED); - assert(!_uses.contains(idx)); - - _uses.append(idx); -} - -void Object::removeUse(const ::neurun::graph::operation::Index &idx) -{ - assert(_usage != OperandUsage::NOT_DEFINED); - assert(_uses.contains(idx)); - - _uses.remove(idx); -} - -void Object::appendDef(const ::neurun::graph::operation::Index &idx) -{ - assert(_usage != OperandUsage::NOT_DEFINED && _usage != OperandUsage::CONSTANT); - assert(_def.size() == 0); - - _def.append(idx); -} - -void Object::removeDef(const ::neurun::graph::operation::Index &idx) -{ - assert(_usage != OperandUsage::NOT_DEFINED); - assert(_def.contains(idx)); - - _def.remove(idx); -} - -void Object::lower_info(std::unique_ptr<LowerInfo> &&lower_info) -{ - _lower_info = std::move(lower_info); -} - -const LowerInfo *Object::lower_info() const { return _lower_info.get(); } - -} // namespace operand -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operand/Object.h b/runtimes/neurun/src/graph/operand/Object.h deleted file mode 100644 index 17e46ab28..000000000 --- a/runtimes/neurun/src/graph/operand/Object.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERAND_OBJECT_H__ -#define __NEURUN_GRAPH_OPERAND_OBJECT_H__ - -#include <cassert> -#include <cstdint> -#include <memory> -#include <algorithm> - -#include "Shape.h" -#include "Data.h" -#include "TypeInfo.h" -#include "LowerInfo.h" -#include "graph/operation/IndexList.h" - -namespace neurun -{ -namespace graph -{ -namespace operand -{ - -// Operand usage should be exact one of these -enum class OperandUsage -{ - NOT_DEFINED, - MODEL_INPUT, - CONSTANT, - OPERATION_OUTPUT, -}; - -class Object -{ -public: - explicit Object(const Shape &shape, const TypeInfo &type) - : _shape{shape}, _type{type}, _usage{OperandUsage::NOT_DEFINED} - { - // DO NOTHING - } - -public: - const Shape &shape(void) const { return _shape; } - const TypeInfo &typeInfo(void) const { return _type; } - size_t operandSize(void) const; - bool setAsConstant() { return setUsage(OperandUsage::CONSTANT); } - bool setAsModelInput() { return setUsage(OperandUsage::MODEL_INPUT); } - bool setAsOperationOutput() { return setUsage(OperandUsage::OPERATION_OUTPUT); } - bool usageIsDefined(void) const { return _usage != OperandUsage::NOT_DEFINED; } - bool isModelInput(void) const { return _usage == OperandUsage::MODEL_INPUT; } - - const operation::IndexList &getUses() const { return _uses; } - const operation::IndexList &getDef() const { return _def; } - void appendUse(const operation::Index &idx); - void removeUse(const operation::Index &idx); - void appendDef(const operation::Index &idx); - void removeDef(const operation::Index &idx); - -private: - bool setUsage(OperandUsage usage); - -public: - void data(std::unique_ptr<Data> &&data) { _data = std::move(data); } - const Data &data(void) const { return *_data; } - -public: - template <typename T, typename... Args> void data(Args &&... args) - { - data(std::unique_ptr<T>(new T{std::forward<Args>(args)...})); - } - -public: - template <typename T> T asScalar(void) const - { - assert((_shape.rank() == 0) || ((_shape.rank() == 1) && (_shape.dim(0) == 1))); - assert(_data != nullptr); - assert((_data->base() != nullptr) && (_data->size() == sizeof(T))); - - return *(reinterpret_cast<const T *>(_data->base())); - } - -public: - void lower_info(std::unique_ptr<LowerInfo> &&lower_info); - const LowerInfo *lower_info() const; - -private: - const Shape _shape; - const TypeInfo _type; - std::unique_ptr<Data> _data; - OperandUsage _usage; - - operation::IndexList _uses; - operation::IndexList _def; // size is 0 (constant) or 1 (from def operation) - - std::unique_ptr<LowerInfo> _lower_info; -}; - -} // namespace operand -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERAND_OBJECT_H__ diff --git a/runtimes/neurun/src/graph/operand/ParentInfo.h b/runtimes/neurun/src/graph/operand/ParentInfo.h new file mode 100644 index 000000000..5e6f56237 --- /dev/null +++ b/runtimes/neurun/src/graph/operand/ParentInfo.h @@ -0,0 +1,79 @@ +/* + * 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. + */ + +/** + * @file ParentInfo.h + * @brief This file contains ParentInfo class and internal Coordinate4D class + * to represent subsumption between operand + */ + +#ifndef __NEURUN_GRAPH_OPERAND_PARENT_INFO_H__ +#define __NEURUN_GRAPH_OPERAND_PARENT_INFO_H__ + +#include <stdint.h> + +#include "model/operand/Index.h" +#include "util/feature/Coordinate4D.h" + +namespace neurun +{ +namespace graph +{ +namespace operand +{ + +using neurun::util::feature::Coordinate4D; + +/** + * @brief Class to represent parent operand in child operand + */ +class ParentInfo +{ +public: + /** + * @brief Construct a new ParentInfo object + * @param[in] parent Index of parent operand + * @param[in] coordinate Offset of child operand in parent operand + * @return + */ + ParentInfo(const model::operand::Index parent, const Coordinate4D &coordinate) + : _parent{parent}, _coordinate{coordinate} + { + // DO NOTHING + } + +public: + /** + * @brief Return parent index + * @return Parent index + */ + model::operand::Index parent(void) const { return _parent; } + /** + * @brief Retern offset in parent + * @return Offset + */ + Coordinate4D offset(void) const { return _coordinate; } + +private: + model::operand::Index _parent; + Coordinate4D _coordinate; +}; + +} // namespace operand +} // namespace graph +} // namespace neurun + +#endif // __NEURUN_GRAPH_OPERAND_PARENT_INFO_H__ diff --git a/runtimes/neurun/src/graph/operand/Set.cc b/runtimes/neurun/src/graph/operand/Set.cc deleted file mode 100644 index 60dad2336..000000000 --- a/runtimes/neurun/src/graph/operand/Set.cc +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 "Set.h" - -#include "nnfw/std/memory.h" - -namespace neurun -{ -namespace graph -{ -namespace operand -{ - -const Index Set::generateIndex() -{ - assert((_index_count) <= 0x7fffffff); - - return Index{_index_count++}; -} - -Index Set::append(const Shape &shape, const TypeInfo &type) -{ - auto index = generateIndex(); - - _objects[index] = nnfw::make_unique<Object>(shape, type); - - return index; -} - -const Object &Set::at(const Index &index) const { return *(_objects.at(index)); } - -Object &Set::at(const Index &index) { return *(_objects.at(index)); } - -bool Set::exist(const Index &index) const { return index.value() < _objects.size(); } - -void Set::iterate(const std::function<void(const Index &, const Object &)> &fn) const -{ - for (const auto &e : _objects) - { - fn(e.first, *e.second); - } -} - -void Set::iterate(const std::function<void(const Index &, Object &)> &fn) -{ - for (auto &e : _objects) - { - fn(e.first, *e.second); - } -} - -} // namespace operand -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operand/Set.h b/runtimes/neurun/src/graph/operand/Set.h deleted file mode 100644 index c8266fed0..000000000 --- a/runtimes/neurun/src/graph/operand/Set.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERAND_SET_H__ -#define __NEURUN_GRAPH_OPERAND_SET_H__ - -#include <memory> -#include <unordered_map> - -#include "Object.h" -#include "Index.h" - -namespace neurun -{ -namespace graph -{ -namespace operand -{ - -class Set -{ -public: - Set() : _index_count(0) {} - -public: - Index append(const Shape &, const TypeInfo &); - -public: - const Object &at(const Index &) const; - Object &at(const Index &); - bool exist(const Index &) const; - void iterate(const std::function<void(const Index &, const Object &)> &fn) const; - void iterate(const std::function<void(const Index &, Object &)> &fn); - -private: - const Index generateIndex(); - -private: - std::unordered_map<Index, std::unique_ptr<Object>> _objects; - uint32_t _index_count; -}; - -} // namespace operand -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERAND_SET_H__ diff --git a/runtimes/neurun/src/graph/operand/Shape.cc b/runtimes/neurun/src/graph/operand/Shape.cc deleted file mode 100644 index f6d7a6999..000000000 --- a/runtimes/neurun/src/graph/operand/Shape.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 <cassert> - -#include "Shape.h" - -namespace neurun -{ -namespace graph -{ -namespace operand -{ - -Shape::Shape(uint32_t rank) { _dims.resize(rank); } - -int32_t Shape::asVector(void) const -{ - assert(rank() == 1); - - return dim(0); -} - -nnfw::util::feature::Shape Shape::asFeature(void) const -{ - assert(rank() == 4); - - // Feature Map in NNAPI - // - Dimension(0) -> Batch - // - Dimension(1) -> Height - // - Dimension(2) -> Width - // - Dimension(3) -> Depth - const auto batch = dim(0); - const auto depth = dim(3); - const auto height = dim(1); - const auto width = dim(2); - - return nnfw::util::feature::Shape(batch, depth, height, width); -} - -nnfw::util::kernel::Shape Shape::asKernel(void) const -{ - assert(rank() == 4); - - // Convolution Kernel in NNAPI - // - Dimension(0) -> Count - // - Dimension(1) -> Height - // - Dimension(2) -> Width - // - Dimension(3) -> Depth - const auto count = dim(0); - const auto depth = dim(3); - const auto height = dim(1); - const auto width = dim(2); - - return nnfw::util::kernel::Shape(count, depth, height, width); -} - -} // namespace operand -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operand/Shape.h b/runtimes/neurun/src/graph/operand/Shape.h deleted file mode 100644 index 3ae970e85..000000000 --- a/runtimes/neurun/src/graph/operand/Shape.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERAND_SHAPE_H__ -#define __NEURUN_GRAPH_OPERAND_SHAPE_H__ - -#include <vector> -#include <cstdint> - -#include "util/feature/Shape.h" -#include "util/kernel/Shape.h" - -namespace neurun -{ -namespace graph -{ -namespace operand -{ - -struct Shape -{ -public: - Shape(uint32_t rank); - -public: - uint32_t rank(void) const { return _dims.size(); } - -public: - int32_t dim(uint32_t n) const { return _dims.at(n); } - int32_t &dim(uint32_t n) { return _dims.at(n); } - const std::vector<int32_t> &dims() const { return _dims; } - -public: - int32_t asVector(void) const; - nnfw::util::feature::Shape asFeature(void) const; - nnfw::util::kernel::Shape asKernel(void) const; - -private: - std::vector<int32_t> _dims; -}; - -} // namespace operand -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERAND_SHAPE_H__ diff --git a/runtimes/neurun/src/graph/operand/Shape4DConvert.h b/runtimes/neurun/src/graph/operand/Shape4DConvert.h index b840d19b8..73cf0903a 100644 --- a/runtimes/neurun/src/graph/operand/Shape4DConvert.h +++ b/runtimes/neurun/src/graph/operand/Shape4DConvert.h @@ -26,7 +26,7 @@ namespace graph namespace operand { -inline LowerInfo::Shape4D asShape4D(const Shape &shape) +inline LowerInfo::Shape4D asShape4D(const model::operand::Shape &shape) { switch (shape.rank()) { @@ -34,16 +34,16 @@ inline LowerInfo::Shape4D asShape4D(const Shape &shape) return LowerInfo::Shape4D(1, 1, 1, 1); case 1u: - return LowerInfo::Shape4D(1, 1, 1, shape.dim(0)); + return LowerInfo::Shape4D(shape.dim(0), 1, 1, 1); case 2u: - return LowerInfo::Shape4D(1, 1, shape.dim(1), shape.dim(0)); + return LowerInfo::Shape4D(shape.dim(0), shape.dim(1), 1, 1); case 3u: - return LowerInfo::Shape4D(1, shape.dim(2), shape.dim(1), shape.dim(0)); + return LowerInfo::Shape4D(shape.dim(0), shape.dim(1), shape.dim(2), 1); case 4u: - return LowerInfo::Shape4D(shape.dim(3), shape.dim(2), shape.dim(1), shape.dim(0)); + return LowerInfo::Shape4D(shape.dim(0), shape.dim(1), shape.dim(2), shape.dim(3)); default: throw "Unsupported rank > 4"; diff --git a/runtimes/neurun/src/graph/operand/TypeInfo.h b/runtimes/neurun/src/graph/operand/TypeInfo.h deleted file mode 100644 index 41f4453e5..000000000 --- a/runtimes/neurun/src/graph/operand/TypeInfo.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERAND_TYPEINFO_H__ -#define __NEURUN_GRAPH_OPERAND_TYPEINFO_H__ - -#include <cstdint> - -#include <NeuralNetworks.h> - -#include "DataType.h" - -namespace neurun -{ -namespace graph -{ -namespace operand -{ - -class TypeInfo -{ -public: - TypeInfo(OperandCode type, float scale, int32_t offset) - : _type(typeFromOperandCode(type)), _scale(scale), _offset(offset) - { - // DO NOTHING - } - -public: - DataType type() const { return _type; } - float scale() const { return _scale; } - int32_t offset() const { return _offset; } - -private: - // Now neurun::graph::operand::DataType share same enum value with OperandCode - // in NeuralNetworks.h. - // If we don't share same value, we must fix this mapping function. - DataType typeFromOperandCode(OperandCode type); - -private: - DataType _type; - float _scale; - int32_t _offset; -}; -} // namespace operand -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERAND_TYPEINFO_H__ diff --git a/runtimes/neurun/src/graph/operation/AvgPool2D.cc b/runtimes/neurun/src/graph/operation/AvgPool2D.cc deleted file mode 100644 index b2612c6b5..000000000 --- a/runtimes/neurun/src/graph/operation/AvgPool2D.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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 "AvgPool2D.h" - -#include <cassert> - -#include "NodeVisitor.h" -#include "LowerInfo.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace AvgPool2D -{ -namespace Implicit -{ - -void Node::accept(NodeVisitor &&v) const { v.visit(*this); } - -Node::Node(const graph::operation::Node::InitParam &init_param) -{ - assert(init_param.input_count == 7); - assert(init_param.output_count == 1); - - // Each input should be interpreted as follows: - // - // 0 -> IFM Tensor Index - // 1 -> Padding Code (ANEURALNETWORKS_PADDING_SAME or ANEURALNETWORKS_PADDING_VALID) Index - // 2 -> Horizontal (over width) Stride Index - // 3 -> Vertial (over height) Stride Index - // 4 -> Filter Width Index - // 5 -> Filter Height Index - // 6 -> FuseCode (activation) Index - - setInputs({init_param.inputs[0]}); - setOutputs({init_param.outputs[0]}); - - _param.padding_index = init_param.inputs[1]; - _param.hstride_index = init_param.inputs[2]; - _param.vstride_index = init_param.inputs[3]; - - _param.kw_index = init_param.inputs[4]; - _param.kh_index = init_param.inputs[5]; - _param.activation_index = init_param.inputs[6]; -} - -void Node::setInputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setInputs(indexes); -} - -void Node::setOutputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setOutputs(indexes); -} - -} // namespace Implicit -} // namespace AvgPool2D -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/AvgPool2D.h b/runtimes/neurun/src/graph/operation/AvgPool2D.h deleted file mode 100644 index a856b9cd4..000000000 --- a/runtimes/neurun/src/graph/operation/AvgPool2D.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_AVGPOOL2D_H__ -#define __NEURUN_GRAPH_OPERATION_AVGPOOL2D_H__ - -#include <memory> - -#include "graph/operation/Node.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace AvgPool2D -{ -namespace Implicit -{ - -struct Param -{ - int32_t kw_index; - int32_t kh_index; - - int32_t hstride_index; - int32_t vstride_index; - - int32_t padding_index; - int32_t activation_index; -}; - -class Node : public graph::operation::Node -{ -public: - Node(const graph::operation::Node::InitParam &init_param); - -public: - virtual void accept(NodeVisitor &&) const override; - -public: - virtual void setInputs(const operand::IndexSet &indexes) override; - virtual void setOutputs(const operand::IndexSet &indexes) override; - -public: - const Param ¶m() const { return _param; } - -private: - Param _param; -}; - -} // namespace Implicit -} // namespace AvgPool2D -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_AVGPOOL2D_H__ diff --git a/runtimes/neurun/src/graph/operation/Concat.cc b/runtimes/neurun/src/graph/operation/Concat.cc deleted file mode 100644 index 952cf687c..000000000 --- a/runtimes/neurun/src/graph/operation/Concat.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 "Concat.h" - -#include <cassert> - -#include "NodeVisitor.h" -#include "LowerInfo.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace Concat -{ - -void Node::accept(NodeVisitor &&v) const { v.visit(*this); } - -Node::Node(const graph::operation::Node::InitParam &init_param) -{ - assert(init_param.input_count > 2); // At least one one input tensor and axis - assert(init_param.output_count == 1); - - // When there are N + 1 inputs, each input should be interpreted as follows: - // - // [0, N) -> Input tensors - // N -> Axis - // - - { - operand::IndexSet inds; - for (uint32_t n = 0; n < init_param.input_count - 1; ++n) - { - inds.append(operand::Index{init_param.inputs[n]}); - } - setInputs(inds); - } - setOutputs({init_param.outputs[0]}); - - _param.axis_index = init_param.inputs[init_param.input_count - 1]; -} - -void Node::setOutputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setOutputs(indexes); -} - -} // namespace Concat -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/Concat.h b/runtimes/neurun/src/graph/operation/Concat.h deleted file mode 100644 index dab17d031..000000000 --- a/runtimes/neurun/src/graph/operation/Concat.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_CONCAT_H__ -#define __NEURUN_GRAPH_OPERATION_CONCAT_H__ - -#include <memory> - -#include "graph/operation/Node.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace Concat -{ - -struct Param -{ - int32_t axis_index; -}; - -class Node : public graph::operation::Node -{ -public: - Node(const graph::operation::Node::InitParam &init_param); - -public: - virtual void accept(NodeVisitor &&) const override; - -public: - virtual void setOutputs(const operand::IndexSet &indexes) override; - -public: - const Param ¶m() const { return _param; } - -private: - Param _param; -}; - -} // namespace Concat -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_CONCAT_H__ diff --git a/runtimes/neurun/src/graph/operation/Conv2D.cc b/runtimes/neurun/src/graph/operation/Conv2D.cc deleted file mode 100644 index f88955db1..000000000 --- a/runtimes/neurun/src/graph/operation/Conv2D.cc +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 "Conv2D.h" - -#include <cassert> - -#include "NodeVisitor.h" -#include "LowerInfo.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace Conv2D -{ -namespace Implicit -{ - -void Node::accept(NodeVisitor &&v) const { v.visit(*this); } - -Node::Node(const graph::operation::Node::InitParam &init_param) -{ - assert(init_param.input_count == 7 && init_param.output_count == 1); - - // Each input should be interpreted as follows: - // - // - // 0 -> IFM Tensor Index - // 1 -> Kernel Tensor Index - // 2 -> Bias Tensor Index - // 3 -> Padding Code (ANEURALNETWORKS_PADDING_SAME or ANEURALNETWORKS_PADDING_VALID) Index - // 4 -> Stride (width) Index - // 5 -> Stride (height) INdex - // 6 -> Activation Index - - setInputs({init_param.inputs[0], init_param.inputs[1], init_param.inputs[2]}); - setOutputs({init_param.outputs[0]}); - - _param.padding_index = init_param.inputs[3]; - _param.hstride_index = init_param.inputs[4]; - _param.vstride_index = init_param.inputs[5]; - _param.activation_index = init_param.inputs[6]; -} - -void Node::setInputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 3); - - graph::operation::Node::setInputs(indexes); -} - -void Node::setOutputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setOutputs(indexes); -} - -} // namespace Implicit -} // namespace Conv2D -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/Conv2D.h b/runtimes/neurun/src/graph/operation/Conv2D.h deleted file mode 100644 index f75058a30..000000000 --- a/runtimes/neurun/src/graph/operation/Conv2D.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_CONV2D_H__ -#define __NEURUN_GRAPH_OPERATION_CONV2D_H__ - -#include <memory> - -#include "graph/operation/Node.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace Conv2D -{ -namespace Implicit -{ - -struct Param -{ - int32_t hstride_index; - int32_t vstride_index; - - int32_t padding_index; - int32_t activation_index; -}; - -class Node : public graph::operation::Node -{ -public: - Node(const graph::operation::Node::InitParam &); - -public: - virtual void accept(NodeVisitor &&) const override; - -public: - virtual void setInputs(const operand::IndexSet &indexes) override; - virtual void setOutputs(const operand::IndexSet &indexes) override; - -public: - const Param ¶m() const { return _param; } - -private: - Param _param; -}; - -} // namespace Implicit -} // namespace Conv2D -} // namespace coperation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_CONV2D_H__ diff --git a/runtimes/neurun/src/graph/operation/FullyConnected.cc b/runtimes/neurun/src/graph/operation/FullyConnected.cc deleted file mode 100644 index 0a6553d1e..000000000 --- a/runtimes/neurun/src/graph/operation/FullyConnected.cc +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 "FullyConnected.h" - -#include <cassert> - -#include "NodeVisitor.h" -#include "LowerInfo.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace FullyConnected -{ - -void Node::accept(NodeVisitor &&v) const { v.visit(*this); } - -Node::Node(const graph::operation::Node::InitParam &init_param) -{ - assert(init_param.input_count == 4 && init_param.output_count == 1); - - // Each input should be interpreted as follows: - // - // 0 -> A tensor, specifying the input. - // 1 -> A 2-D tensor, specifying the weights - // 2 -> A 1-D tensor, specifying the bias - // 3 -> An INT32 value, and has to be one of the FuseCode values - - setInputs({init_param.inputs[0], init_param.inputs[1], init_param.inputs[2]}); - setOutputs({init_param.outputs[0]}); - - _param.activation_index = init_param.inputs[3]; -} - -void Node::setInputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 3); - - graph::operation::Node::setInputs(indexes); -} - -void Node::setOutputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setOutputs(indexes); -} - -} // namespace FullyConnected -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/FullyConnected.h b/runtimes/neurun/src/graph/operation/FullyConnected.h deleted file mode 100644 index a1f920e4b..000000000 --- a/runtimes/neurun/src/graph/operation/FullyConnected.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_FULLYCONNECTED_H__ -#define __NEURUN_GRAPH_OPERATION_FULLYCONNECTED_H__ - -#include <memory> - -#include "graph/operation/Node.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace FullyConnected -{ - -struct Param -{ - int32_t activation_index; -}; - -class Node : public graph::operation::Node -{ -public: - Node(const graph::operation::Node::InitParam &init_param); - -public: - virtual void accept(NodeVisitor &&) const override; - -public: - virtual void setInputs(const operand::IndexSet &indexes) override; - virtual void setOutputs(const operand::IndexSet &indexes) override; - -public: - const Param ¶m() const { return _param; } - -private: - Param _param; -}; - -} // namespace FullyConnected -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_FULLYCONNECTED_H__ diff --git a/runtimes/neurun/src/graph/operation/IndexList.cc b/runtimes/neurun/src/graph/operation/IndexList.cc deleted file mode 100644 index cdc5997ea..000000000 --- a/runtimes/neurun/src/graph/operation/IndexList.cc +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 "IndexList.h" - -#include <algorithm> - -namespace neurun -{ -namespace graph -{ -namespace operation -{ - -IndexList::IndexList(std::initializer_list<Index> list) : _list(list) -{ - // DO NOTHING -} - -bool IndexList::contains(const ::neurun::graph::operation::Index &index) const -{ - return std::find(_list.begin(), _list.end(), index) != _list.end(); -} - -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/IndexList.h b/runtimes/neurun/src/graph/operation/IndexList.h deleted file mode 100644 index cfac46abc..000000000 --- a/runtimes/neurun/src/graph/operation/IndexList.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_INDEX_LIST_H__ -#define __NEURUN_GRAPH_OPERATION_INDEX_LIST_H__ - -#include <initializer_list> -#include <list> - -#include "Index.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ - -class IndexList -{ -public: - IndexList(void) = default; - IndexList(std::initializer_list<Index> list); - -public: - void append(const Index &index) { _list.push_back(index); } - void remove(const Index &index) { _list.remove(index); } - -public: - uint32_t size() const { return static_cast<uint32_t>(_list.size()); } - const std::list<Index> &list() const { return _list; } - bool contains(const Index &index) const; - -private: - std::list<Index> _list; -}; - -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_INDEX_LIST_H__ diff --git a/runtimes/neurun/src/graph/operation/LowerInfo.cc b/runtimes/neurun/src/graph/operation/LowerInfo.cc index 2998b1922..7862fd0c9 100644 --- a/runtimes/neurun/src/graph/operation/LowerInfo.cc +++ b/runtimes/neurun/src/graph/operation/LowerInfo.cc @@ -23,7 +23,7 @@ namespace graph namespace operation { -LowerInfo::LowerInfo(const backend::Backend &backend) : _backend(backend) +LowerInfo::LowerInfo(const backend::Backend *backend) : _backend(backend) { // DO NOTHING } diff --git a/runtimes/neurun/src/graph/operation/LowerInfo.h b/runtimes/neurun/src/graph/operation/LowerInfo.h index f3fbbf178..e920b0eb9 100644 --- a/runtimes/neurun/src/graph/operation/LowerInfo.h +++ b/runtimes/neurun/src/graph/operation/LowerInfo.h @@ -31,11 +31,11 @@ namespace operation class LowerInfo { public: - LowerInfo(const backend::Backend &backend); - const backend::Backend &backend() const { return _backend; } + LowerInfo(const backend::Backend *backend); + const backend::Backend *backend() const { return _backend; } private: - backend::Backend _backend; + const backend::Backend *_backend; }; } // namespace operation diff --git a/runtimes/neurun/src/graph/operation/MaxPool2D.cc b/runtimes/neurun/src/graph/operation/MaxPool2D.cc deleted file mode 100644 index 76648baf6..000000000 --- a/runtimes/neurun/src/graph/operation/MaxPool2D.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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 "MaxPool2D.h" - -#include <cassert> - -#include "NodeVisitor.h" -#include "LowerInfo.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace MaxPool2D -{ -namespace Implicit -{ - -void Node::accept(NodeVisitor &&v) const { v.visit(*this); } - -Node::Node(const graph::operation::Node::InitParam &init_param) -{ - assert(init_param.input_count == 7); - assert(init_param.output_count == 1); - - // Each input should be interpreted as follows: - // - // 0 -> IFM Tensor Index - // 1 -> Padding Code (ANEURALNETWORKS_PADDING_SAME or ANEURALNETWORKS_PADDING_VALID) Index - // 2 -> Horizontal (over width) Stride Index - // 3 -> Vertial (over height) Stride Index - // 4 -> Filter Width Index - // 5 -> Filter Height Index - // 6 -> FuseCode (activation) Index - - setInputs({init_param.inputs[0]}); - setOutputs({init_param.outputs[0]}); - - _param.padding_index = init_param.inputs[1]; - _param.hstride_index = init_param.inputs[2]; - _param.vstride_index = init_param.inputs[3]; - - _param.kw_index = init_param.inputs[4]; - _param.kh_index = init_param.inputs[5]; - _param.activation_index = init_param.inputs[6]; -} - -void Node::setInputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setInputs(indexes); -} - -void Node::setOutputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setOutputs(indexes); -} - -} // namespace Implicit -} // namespace MaxPool2D -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/MaxPool2D.h b/runtimes/neurun/src/graph/operation/MaxPool2D.h deleted file mode 100644 index 30f9b0b50..000000000 --- a/runtimes/neurun/src/graph/operation/MaxPool2D.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_MAXPOOL2D_H__ -#define __NEURUN_GRAPH_OPERATION_MAXPOOL2D_H__ - -#include <memory> - -#include "graph/operation/Node.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace MaxPool2D -{ -namespace Implicit -{ - -struct Param -{ - int32_t kw_index; - int32_t kh_index; - - int32_t hstride_index; - int32_t vstride_index; - - int32_t padding_index; - int32_t activation_index; -}; - -class Node : public graph::operation::Node -{ -public: - virtual void accept(NodeVisitor &&) const override; - -public: - Node(const graph::operation::Node::InitParam &init_param); - -public: - virtual void setInputs(const operand::IndexSet &indexes) override; - virtual void setOutputs(const operand::IndexSet &indexes) override; - -public: - const Param ¶m() const { return _param; } - -private: - Param _param; -}; - -} // namespace Implicit -} // namespace MaxPool2D -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_MAXPOOL2D_H__ diff --git a/runtimes/neurun/src/graph/operation/NOP.h b/runtimes/neurun/src/graph/operation/NOP.h deleted file mode 100644 index 51b0f6f71..000000000 --- a/runtimes/neurun/src/graph/operation/NOP.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_NOP_H__ -#define __NEURUN_GRAPH_OPERATION_NOP_H__ - -#include <memory> - -#include "graph/operation/Node.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace NOP -{ - -class Node : public graph::operation::Node -{ -public: - Node(const graph::operation::Node::InitParam &) {} - -public: - virtual void accept(NodeVisitor &&) const override; -}; - -} // namespace NOP -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_NOP_H__ diff --git a/runtimes/neurun/src/graph/operation/Node.cc b/runtimes/neurun/src/graph/operation/Node.cc deleted file mode 100644 index f472bc08c..000000000 --- a/runtimes/neurun/src/graph/operation/Node.cc +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 "Node.h" - -#include "LowerInfo.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ - -Node::Node() = default; - -Node::~Node() = default; - -void Node::lower_info(std::unique_ptr<LowerInfo> &&lower_info) -{ - _lower_info = std::move(lower_info); -} - -const LowerInfo *Node::lower_info() const { return _lower_info.get(); } - -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/Node.h b/runtimes/neurun/src/graph/operation/Node.h deleted file mode 100644 index 9e98184e3..000000000 --- a/runtimes/neurun/src/graph/operation/Node.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_NODE_H__ -#define __NEURUN_GRAPH_OPERATION_NODE_H__ - -#include <memory> - -#include "graph/operand/IndexSet.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ - -class LowerInfo; -struct NodeVisitor; - -class Node -{ -public: - struct InitParam - { - uint32_t input_count; - const uint32_t *inputs; - uint32_t output_count; - const uint32_t *outputs; - }; - -public: - Node(); - virtual ~Node(); - -public: - virtual void accept(NodeVisitor &&) const = 0; - -public: - virtual const operand::IndexSet &getInputs() const { return _inputs; } - virtual const operand::IndexSet &getOutputs() const { return _outputs; } - // It's for only input/output tensors but const data. - virtual void setInputs(const operand::IndexSet &indexes) { _inputs = indexes; } - virtual void setOutputs(const operand::IndexSet &indexes) { _outputs = indexes; } - -public: - void lower_info(std::unique_ptr<LowerInfo> &&lower_info); - const LowerInfo *lower_info() const; - -private: - operand::IndexSet _inputs; - operand::IndexSet _outputs; - std::unique_ptr<LowerInfo> _lower_info; -}; - -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_NODE_H__ diff --git a/runtimes/neurun/src/graph/operation/NodeVisitor.h b/runtimes/neurun/src/graph/operation/NodeVisitor.h deleted file mode 100644 index 28d19b0af..000000000 --- a/runtimes/neurun/src/graph/operation/NodeVisitor.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_NODE_VISITOR_H__ -#define __NEURUN_GRAPH_OPERATION_NODE_VISITOR_H__ - -#include "Conv2D.h" -#include "MaxPool2D.h" -#include "AvgPool2D.h" -#include "Concat.h" -#include "Reshape.h" -#include "FullyConnected.h" -#include "Softmax.h" -#include "NOP.h" -#include "Permute.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ - -struct NodeVisitor -{ - virtual ~NodeVisitor() = default; - - virtual void visit(const Conv2D::Implicit::Node &) = 0; - virtual void visit(const MaxPool2D::Implicit::Node &) = 0; - virtual void visit(const AvgPool2D::Implicit::Node &) = 0; - virtual void visit(const Concat::Node &) = 0; - virtual void visit(const Reshape::Node &) = 0; - virtual void visit(const FullyConnected::Node &) = 0; - virtual void visit(const Softmax::Node &) = 0; - virtual void visit(const NOP::Node &) = 0; - virtual void visit(const Permute::Node &) = 0; -}; - -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_NODE_VISITOR_H__ diff --git a/runtimes/neurun/src/graph/operation/Op.lst b/runtimes/neurun/src/graph/operation/Op.lst deleted file mode 100644 index 23b4123cb..000000000 --- a/runtimes/neurun/src/graph/operation/Op.lst +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - */ - -#ifndef OP -#error Define OP before including this file -#endif - -// NOTE The relation between "Internal Name" and "NN API Name" is "1 : N". - -// Internal Name | NN API Name -OP(Conv2D::Implicit , CONV_2D) -OP(AvgPool2D::Implicit , AVERAGE_POOL_2D) -OP(MaxPool2D::Implicit , MAX_POOL_2D) -OP(Concat , CONCATENATION) -OP(FullyConnected , FULLY_CONNECTED) -OP(Reshape , RESHAPE) -OP(Softmax , SOFTMAX) diff --git a/runtimes/neurun/src/graph/operation/Permute.cc b/runtimes/neurun/src/graph/operation/Permute.cc deleted file mode 100644 index 2688e5e5f..000000000 --- a/runtimes/neurun/src/graph/operation/Permute.cc +++ /dev/null @@ -1,41 +0,0 @@ -#include "Permute.h" - -#include <cassert> - -#include "NodeVisitor.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace Permute -{ - -void Node::accept(NodeVisitor &&v) const { v.visit(*this); } - -Node::Node(const operand::Index &input, const operand::Index &output) -{ - setInputs({input}); - setOutputs({output}); -} - -void Node::setInputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setInputs(indexes); -} - -void Node::setOutputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setOutputs(indexes); -} - -} // namespace Permute -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/Permute.h b/runtimes/neurun/src/graph/operation/Permute.h deleted file mode 100644 index 540f869b1..000000000 --- a/runtimes/neurun/src/graph/operation/Permute.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __NEURUN_GRAPH_OPERATION_PERMUTE_PERMUTE_H__ -#define __NEURUN_GRAPH_OPERATION_PERMUTE_PERMUTE_H__ - -#include "graph/operation/Node.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace Permute -{ - -class Node : public graph::operation::Node -{ -public: - virtual void accept(NodeVisitor &&) const override; - -public: - Node(const operand::Index &input, const operand::Index &output); - -public: - virtual void setInputs(const operand::IndexSet &indexes) override; - virtual void setOutputs(const operand::IndexSet &indexes) override; -}; - -} // namespace Permute -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_PERMUTE_PERMUTE_H__ diff --git a/runtimes/neurun/src/graph/operation/Reshape.cc b/runtimes/neurun/src/graph/operation/Reshape.cc deleted file mode 100644 index e6bc2117f..000000000 --- a/runtimes/neurun/src/graph/operation/Reshape.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 "Reshape.h" - -#include <cassert> - -#include "NodeVisitor.h" -#include "LowerInfo.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace Reshape -{ - -void Node::accept(NodeVisitor &&v) const { v.visit(*this); } - -Node::Node(const graph::operation::Node::InitParam &init_param) -{ - assert(init_param.input_count == 2 && init_param.output_count == 1); - - // Each input should be interpreted as follows: - // - // 0 -> A tensor, specifying the tensor to be reshaped. - // 1 -> A 1-D tensor of type ANEURALNETWORKS_TENSOR_INT32, defining the shape of the output - // tensor - - // TODO Second input should be shape tensor (init_param.inputs[1]) - setInputs({init_param.inputs[0] /* , init_param.inputs[1] */}); - setOutputs({init_param.outputs[0]}); -} - -void Node::setInputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); // TODO Should be 2 (See also the constructor) - - graph::operation::Node::setInputs(indexes); -} - -void Node::setOutputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setOutputs(indexes); -} - -} // namespace Reshape -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/Reshape.h b/runtimes/neurun/src/graph/operation/Reshape.h deleted file mode 100644 index 168719b46..000000000 --- a/runtimes/neurun/src/graph/operation/Reshape.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_RESHAPE_H__ -#define __NEURUN_GRAPH_OPERATION_RESHAPE_H__ - -#include <memory> - -#include "graph/operation/Node.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace Reshape -{ - -class Node : public graph::operation::Node -{ -public: - virtual void accept(NodeVisitor &&) const override; - -public: - Node(const graph::operation::Node::InitParam &init_param); - -public: - virtual void setInputs(const operand::IndexSet &indexes) override; - virtual void setOutputs(const operand::IndexSet &indexes) override; -}; - -} // namespace Reshape -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_RESHAPE_H__ diff --git a/runtimes/neurun/src/graph/operation/Set.cc b/runtimes/neurun/src/graph/operation/Set.cc deleted file mode 100644 index a1ddfa6d4..000000000 --- a/runtimes/neurun/src/graph/operation/Set.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 "Set.h" - -#include <cassert> - -namespace neurun -{ -namespace graph -{ -namespace operation -{ - -const Index Set::generateIndex() -{ - assert((_index_count) <= 0x7fffffff); - - return Index{_index_count++}; -} - -Index Set::append(std::unique_ptr<Node> &&node) -{ - auto index = generateIndex(); - - _nodes[index] = std::move(node); - return index; -} - -const Node &Set::at(const Index &index) const { return *(_nodes.at(index)); } - -Node &Set::at(const Index &index) { return *(_nodes.at(index)); } - -bool Set::exist(const Index &index) const { return _nodes.find(index) != _nodes.end(); } - -void Set::iterate(const std::function<void(const Index &, const Node &)> &fn) const -{ - for (auto it = _nodes.begin(); it != _nodes.end(); ++it) - { - fn(it->first, *it->second); - } -} - -void Set::iterate(const std::function<void(const Index &, Node &)> &fn) -{ - for (auto it = _nodes.begin(); it != _nodes.end(); ++it) - { - fn(it->first, *it->second); - } -} - -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/Set.h b/runtimes/neurun/src/graph/operation/Set.h deleted file mode 100644 index bc6913ff4..000000000 --- a/runtimes/neurun/src/graph/operation/Set.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_SET_H__ -#define __NEURUN_GRAPH_OPERATION_SET_H__ - -#include <memory> - -#include "graph/operation/Index.h" -#include "Node.h" - -#include <unordered_map> - -namespace neurun -{ -namespace graph -{ -namespace operation -{ - -class Set -{ -public: - Set() : _index_count(0) {} - -public: - Index append(std::unique_ptr<Node> &&node); - -public: - const Node &at(const Index &) const; - Node &at(const Index &); - bool exist(const Index &) const; - uint32_t size() const { return _nodes.size(); } - void iterate(const std::function<void(const Index &, const Node &)> &fn) const; - void iterate(const std::function<void(const Index &, Node &)> &fn); - -private: - const Index generateIndex(); - -private: - std::unordered_map<Index, std::unique_ptr<Node>> _nodes; - uint32_t _index_count; -}; - -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_SET_H__ diff --git a/runtimes/neurun/src/graph/operation/Softmax.cc b/runtimes/neurun/src/graph/operation/Softmax.cc deleted file mode 100644 index 3b3c8661f..000000000 --- a/runtimes/neurun/src/graph/operation/Softmax.cc +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 "Softmax.h" - -#include <cassert> - -#include "NodeVisitor.h" -#include "LowerInfo.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace Softmax -{ - -void Node::accept(NodeVisitor &&v) const { v.visit(*this); } - -Node::Node(const graph::operation::Node::InitParam &init_param) -{ - assert(init_param.input_count == 2 && init_param.output_count == 1); - - // Each input should be interpreted as follows: - // - // 0 -> A 2-D or 4-D tensor, specifying the tensor to be reshaped. - // 1 -> FLOAT32 value, specifying the positive scaling factor for the exponent, beta. - - setInputs({init_param.inputs[0]}); - setOutputs({init_param.outputs[0]}); - - _param.scale_index = init_param.inputs[1]; -} - -void Node::setInputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setInputs(indexes); -} - -void Node::setOutputs(const operand::IndexSet &indexes) -{ - assert(indexes.size() == 1); - - graph::operation::Node::setOutputs(indexes); -} - -} // namespace Softmax -} // namespace operation -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/operation/Softmax.h b/runtimes/neurun/src/graph/operation/Softmax.h deleted file mode 100644 index e87a27518..000000000 --- a/runtimes/neurun/src/graph/operation/Softmax.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - */ - -#ifndef __NEURUN_GRAPH_OPERATION_SOFTMAX_H__ -#define __NEURUN_GRAPH_OPERATION_SOFTMAX_H__ - -#include <memory> - -#include "graph/operation/Node.h" - -namespace neurun -{ -namespace graph -{ -namespace operation -{ -namespace Softmax -{ - -struct Param -{ - int32_t scale_index; -}; - -class Node : public graph::operation::Node -{ -public: - virtual void accept(NodeVisitor &&) const override; - -public: - Node(const graph::operation::Node::InitParam &init_param); - -public: - virtual void setInputs(const operand::IndexSet &indexes) override; - virtual void setOutputs(const operand::IndexSet &indexes) override; - -public: - const Param ¶m() const { return _param; } - -private: - Param _param; -}; - -} // namespace Softmax -} // namespace operation -} // namespace graph -} // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_SOFTMAX_H__ diff --git a/runtimes/neurun/src/graph/operation/Index.h b/runtimes/neurun/src/graph/pass/OperandPass.cc index 3902d039b..3c24d3830 100644 --- a/runtimes/neurun/src/graph/operation/Index.h +++ b/runtimes/neurun/src/graph/pass/OperandPass.cc @@ -14,22 +14,23 @@ * limitations under the License. */ -#ifndef __NEURUN_GRAPH_OPERATION_INDEX_H__ -#define __NEURUN_GRAPH_OPERATION_INDEX_H__ +#include "OperandPass.h" -#include "graph/Index.h" +#include "graph/Graph.h" namespace neurun { namespace graph { -namespace operation +namespace pass { -using Index = ::neurun::graph::Index<uint32_t, struct IndexTag>; +void OperandPass::run() +{ + _graph.operands().iterate([&](const model::operand::Index &index, + model::operand::Object &object) { callback(index, object); }); +} -} // namespace operation +} // namespace pass } // namespace graph } // namespace neurun - -#endif // __NEURUN_GRAPH_OPERATION_INDEX_H__ diff --git a/runtimes/neurun/src/graph/operand/IndexSet.cc b/runtimes/neurun/src/graph/pass/OperandPass.h index 037965a6d..b84391082 100644 --- a/runtimes/neurun/src/graph/operand/IndexSet.cc +++ b/runtimes/neurun/src/graph/pass/OperandPass.h @@ -14,43 +14,43 @@ * limitations under the License. */ -#include "IndexSet.h" +#ifndef __NEURUN_GRAPH_PASS_OPERAND_PASS_H__ +#define __NEURUN_GRAPH_PASS_OPERAND_PASS_H__ -#include <algorithm> +#include "Pass.h" +#include "model/operand/Index.h" namespace neurun { -namespace graph +namespace model { namespace operand { +class Object; +} // namespace operand +} // namespace graph +} // namespace neurun -IndexSet::IndexSet(std::initializer_list<Index> list) : _set(list) +namespace neurun { - // DO NOTHING -} - -IndexSet::IndexSet(std::initializer_list<int32_t> list) +namespace graph { - for (auto val : list) - { - _set.emplace_back(static_cast<uint32_t>(val)); - } -} - -IndexSet::IndexSet(std::initializer_list<uint32_t> list) +namespace pass { - for (auto val : list) - { - _set.emplace_back(val); - } -} -bool IndexSet::contains(const Index &index) const +class OperandPass : public Pass { - return std::find(_set.begin(), _set.end(), index) != _set.end(); -} +public: + using Pass::Pass; -} // namespace operand +public: + virtual std::string id() = 0; + virtual void run() override final; + virtual void callback(const model::operand::Index &i, model::operand::Object &o) = 0; +}; + +} // namespace pass } // namespace graph } // namespace neurun + +#endif // __NEURUN_GRAPH_PASS_OPERAND_PASS_H__ diff --git a/runtimes/neurun/src/graph/operand/TypeInfo.cc b/runtimes/neurun/src/graph/pass/OperationPass.cc index 5642b1e8f..e71f79188 100644 --- a/runtimes/neurun/src/graph/operand/TypeInfo.cc +++ b/runtimes/neurun/src/graph/pass/OperationPass.cc @@ -14,22 +14,23 @@ * limitations under the License. */ -#include "TypeInfo.h" +#include "OperationPass.h" + +#include "graph/Graph.h" namespace neurun { namespace graph { -namespace operand +namespace pass { -DataType TypeInfo::typeFromOperandCode(OperandCode type) +void OperationPass::run() { - // Now neurun::graph::operand::DataType share same enum value with OperandCode - // in NeuralNetworks.h. - return static_cast<DataType>(static_cast<uint32_t>(type)); + _graph.operations().iterate([&](const model::operation::Index &index, + model::operation::Node &node) { callback(index, node); }); } -} // namespace operand +} // namespace pass } // namespace graph } // namespace neurun diff --git a/runtimes/neurun/src/graph/pass/OperationPass.h b/runtimes/neurun/src/graph/pass/OperationPass.h new file mode 100644 index 000000000..e86f1aa57 --- /dev/null +++ b/runtimes/neurun/src/graph/pass/OperationPass.h @@ -0,0 +1,71 @@ +/* + * 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. + */ + +/** + * @file OperationPass.h + * @brief This file contains OperationPass class + */ + +#ifndef __NEURUN_GRAPH_PASS_OPERATION_PASS_H__ +#define __NEURUN_GRAPH_PASS_OPERATION_PASS_H__ + +#include "Pass.h" + +#include "model/operation/Index.h" +#include "model/operation/Node.h" + +namespace neurun +{ +namespace graph +{ +namespace pass +{ + +/** + * @brief Class to iterate over operations and calls callback() method + */ +class OperationPass : public Pass +{ +public: + using Pass::Pass; + +public: + /** + * @brief Returns string id for this pass. Same with class name. + * + * @return string id + */ + virtual std::string id() = 0; + + /** + * @brief Run the pass + */ + virtual void run() override final; + + /** + * @brief The function that will be executed for each operations + * + * @param i[in] Index of the operation node + * @param n[in] The operation node + */ + virtual void callback(const model::operation::Index &i, model::operation::Node &n) = 0; +}; + +} // namespace pass +} // namespace graph +} // namespace neurun + +#endif // __NEURUN_GRAPH_PASS_OPERATION_PASS_H__ diff --git a/runtimes/neurun/src/graph/operation/NOP.cc b/runtimes/neurun/src/graph/pass/Pass.cc index 18c3246ce..4c3436961 100644 --- a/runtimes/neurun/src/graph/operation/NOP.cc +++ b/runtimes/neurun/src/graph/pass/Pass.cc @@ -14,23 +14,15 @@ * limitations under the License. */ -#include "NOP.h" - -#include "NodeVisitor.h" -#include "LowerInfo.h" +#include "Pass.h" namespace neurun { namespace graph { -namespace operation -{ -namespace NOP +namespace pass { -void Node::accept(NodeVisitor &&v) const { v.visit(*this); } - -} // namespace NOP -} // namespace operation +} // namespace pass } // namespace graph } // namespace neurun diff --git a/runtimes/neurun/src/graph/operand/Index.h b/runtimes/neurun/src/graph/pass/Pass.h index a6850d061..4200936d1 100644 --- a/runtimes/neurun/src/graph/operand/Index.h +++ b/runtimes/neurun/src/graph/pass/Pass.h @@ -14,21 +14,16 @@ * limitations under the License. */ -#ifndef __NEURUN_GRAPH_OPERAND_INDEX_H__ -#define __NEURUN_GRAPH_OPERAND_INDEX_H__ +#ifndef __NEURUN_GRAPH_PASS_PASS_H__ +#define __NEURUN_GRAPH_PASS_PASS_H__ -#include "graph/Index.h" +#include <string> namespace neurun { namespace graph { -namespace operand -{ - -using Index = ::neurun::graph::Index<uint32_t, struct IndexTag>; - -} // namespace operand +class Graph; } // namespace graph } // namespace neurun @@ -36,16 +31,25 @@ namespace neurun { namespace graph { -namespace operand +namespace pass { -namespace IO + +class Pass { +public: + Pass(Graph &graph) : _graph{graph} {} + virtual ~Pass() = default; + +public: + virtual std::string id() = 0; + virtual void run() = 0; -using Index = ::neurun::graph::Index<uint32_t, struct IndexTag>; +protected: + Graph &_graph; +}; -} // namespace IO -} // namespace operand +} // namespace pass } // namespace graph } // namespace neurun -#endif // __NEURUN_GRAPH_OPERAND_INDEX_H__ +#endif // __NEURUN_GRAPH_PASS_PASS_H__ diff --git a/runtimes/neurun/src/graph/pass/PermutationEliminationPass.cc b/runtimes/neurun/src/graph/pass/PermutationEliminationPass.cc new file mode 100644 index 000000000..848f6b574 --- /dev/null +++ b/runtimes/neurun/src/graph/pass/PermutationEliminationPass.cc @@ -0,0 +1,192 @@ +/* + * 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 "PermutationEliminationPass.h" + +#include "model/operand/Object.h" +#include "graph/Graph.h" +#include "backend/interface/IConfig.h" +#include "util/logging.h" +#include "compiler/BackendResolver.h" + +namespace neurun +{ +namespace graph +{ +namespace pass +{ +void PermutationEliminationPass::callback(const model::operand::Index &inp_index, + model::operand::Object &object) +{ + if (_graph.getInputs().contains(inp_index)) + { + eliminateInput(inp_index, object); + } + else if (_graph.getOutputs().contains(inp_index)) + { + eliminateOutput(inp_index, object); + } +} + +void PermutationEliminationPass::eliminateInput(const model::operand::Index &inp_index, + model::operand::Object &object) +{ + auto &model_inputs = _graph.getInputs(); + + // get uses of the model's given input + auto uses = object.getUses(); + + // input must be used just by permutation + if (uses.size() != 1) + { + return; + } + + for (auto input_use : uses.list()) + { + auto &perm_operation = _graph.operations().at(input_use); + auto perm_inputs = perm_operation.getInputs(); + + auto perm_outputs = perm_operation.getOutputs(); + + if (!isPermuteLayerToEliminate(perm_inputs, perm_outputs, true)) + { + return; + } + + assert(perm_inputs.at(0) == inp_index); + + VERBOSE(PermutationEliminationPass::EliminateInput) << "remove NHWC_TO_NCHW permutation\n"; + + // set model's new input, which was output of permutation + model_inputs.replace(inp_index, perm_outputs.at(0)); + + // remove model's input, which is also input of permutation + _graph.removeOperand(inp_index); + + // remove permutation operation + _graph.operations().remove(input_use); + + VERBOSE(PermutationEliminationPass::EliminateInput) + << inp_index.value() << " is model's input and is removed. New input is " + << perm_outputs.at(0).value() << "\n" + << input_use.value() << " is removed permutation operation\n"; + } +} + +void PermutationEliminationPass::eliminateOutput(const model::operand::Index &out_index, + model::operand::Object &object) +{ + auto &model_outputs = _graph.getOutputs(); + + // get defs of the model's given output + auto defs = object.getDef(); + + // output must use just permutation + if (defs.size() != 1) + { + return; + } + + for (auto output_def : defs.list()) + { + auto &perm_operation = _graph.operations().at(output_def); + auto perm_outputs = perm_operation.getOutputs(); + + auto perm_inputs = perm_operation.getInputs(); + if (!isPermuteLayerToEliminate(perm_inputs, perm_outputs, false)) + { + return; + } + + assert(perm_outputs.at(0) == out_index); + + VERBOSE(PermutationEliminationPass::EliminateOutput) << "remove NCHW_TO_NHWC permutation\n"; + + // Update operations' output that is used by permute operand + for (auto perm_input_index : perm_inputs) + { + auto &perm_input_operand = _graph.operands().at(perm_input_index); + perm_input_operand.removeUse(output_def); + } + + // set model's new output, which was input of permutation + model_outputs.replace(out_index, perm_inputs.at(0)); + + // remove model's output, which is also output of permutation + _graph.removeOperand(out_index); + + // remove permutation operation + _graph.operations().remove(output_def); + + VERBOSE(PermutationEliminationPass::EliminateOutput) + << out_index.value() << " is model's output and is removed. New output is " + << perm_inputs.at(0).value() << "\n" + << output_def.value() << " is removed permutation operation\n"; + } +} + +bool PermutationEliminationPass::isPermuteLayerToEliminate( + const model::operand::IndexSet &inp_indexes, const model::operand::IndexSet &out_indexes, + bool is_for_model_input) +{ + auto input_def_backends = _graph.operands().at(inp_indexes.at(0)).lower_info()->def_backends(); + auto output_def_backends = _graph.operands().at(out_indexes.at(0)).lower_info()->def_backends(); + + auto input_layout = input_def_backends.getOnlyElement()->config()->getOperandLayout(); + auto output_layout = output_def_backends.getOnlyElement()->config()->getOperandLayout(); + + if (input_def_backends.size() != 1 || output_def_backends.size() != 1) + { + return false; + } + + // all operands' backend must be the same + for (auto index : inp_indexes) + { + auto op_backend_set = _graph.operands().at(index).lower_info()->def_backends(); + if (op_backend_set.size() != 1 || + input_layout != op_backend_set.getOnlyElement()->config()->getOperandLayout()) + { + return false; + } + } + // all operands' backend must be the same + for (auto index : out_indexes) + { + auto op_backend_set = _graph.operands().at(index).lower_info()->def_backends(); + if (op_backend_set.size() != 1 || + output_layout != op_backend_set.getOnlyElement()->config()->getOperandLayout()) + { + return false; + } + } + + if (is_for_model_input) + { + // check if this is NHWC_TO_NCHW permutation: must have single input, which is model's input + return (inp_indexes.size() == 1 && input_layout == graph::operand::Layout::NHWC && + output_layout == graph::operand::Layout::NCHW); + } + + // check if this is NCHW_TO_NHWC permutation: must have single output, which is model's output + return (out_indexes.size() == 1 && input_layout == graph::operand::Layout::NCHW && + output_layout == graph::operand::Layout::NHWC); +} + +} // namespace pass +} // namespace graph +} // namespace neurun diff --git a/runtimes/neurun/src/graph/pass/PermutationEliminationPass.h b/runtimes/neurun/src/graph/pass/PermutationEliminationPass.h new file mode 100644 index 000000000..2b528c479 --- /dev/null +++ b/runtimes/neurun/src/graph/pass/PermutationEliminationPass.h @@ -0,0 +1,87 @@ +/* + * 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. + */ + +#ifndef __NEURUN_GRAPH_PASS_PERMUTATION_ELIMINATION_PASS_H__ +#define __NEURUN_GRAPH_PASS_PERMUTATION_ELIMINATION_PASS_H__ + +#include "OperandPass.h" +#include "model/operand/Object.h" +#include "model/operand/IndexSet.h" + +namespace neurun +{ +namespace graph +{ +namespace pass +{ + +class PermutationEliminationPass : public OperandPass +{ +public: + using OperandPass::OperandPass; + +public: + virtual std::string id() override { return "PermutationEliminationPass"; } + + virtual void callback(const model::operand::Index &index, model::operand::Object &object); + +private: + /** + * @brief Remove Permute operation that permutates input + * + * Note: This function aslo removes model's input and + * sets output of permutation as model's new input + * + * @param inp_index is the target operand index for the elimination + * @param object is the target operand object for the elimination + * + * @return + */ + void eliminateInput(const model::operand::Index &inp_index, model::operand::Object &object); + + /** + * @brief Remove Permute operation that permutates output of a model + * + * Note: This function aslo removes model's output and + * sets input of permutation as model's new output + * + * @param out_index is the target operand index for the elimination + * @param object is the target operand object for the elimination + * + * @return + */ + void eliminateOutput(const model::operand::Index &out_index, model::operand::Object &object); + + /** + * @brief Determine if passed operands are permute layer's input and output, that must be + * eliminated + * + * @param inp_index indexes of the input operand to operation + * @param out_index indexes of the output operand to operation + * @param is_for_model_input checking for model's input or output + * + * @return if it is permutation layer + */ + bool isPermuteLayerToEliminate(const model::operand::IndexSet &inp_indexes, + const model::operand::IndexSet &out_indexes, + bool is_for_model_input); +}; + +} // namespace pass +} // namespace graph +} // namespace neurun + +#endif // __NEURUN_GRAPH_PASS_PERMUTATION_ELIMINATION_PASS_H__ diff --git a/runtimes/neurun/src/graph/pass/PermutationInsertionPass.cc b/runtimes/neurun/src/graph/pass/PermutationInsertionPass.cc new file mode 100644 index 000000000..9b833b8c5 --- /dev/null +++ b/runtimes/neurun/src/graph/pass/PermutationInsertionPass.cc @@ -0,0 +1,191 @@ +/* + * 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 "PermutationInsertionPass.h" + +#include <cassert> +#include <utility> +#include <unordered_map> + +#include "model/operand/Object.h" +#include "graph/operation/LowerInfo.h" +#include "graph/Graph.h" +#include "backend/interface/IConfig.h" +#include "util/logging.h" +#include "cpp14/memory.h" +#include "model/operation/PermuteNode.h" +#include "graph/operand/Shape4DConvert.h" +#include "compiler/BackendResolver.h" + +namespace neurun +{ +namespace graph +{ +namespace pass +{ + +void PermutationInsertionPass::callback(const model::operand::Index &index, + model::operand::Object &object) +{ + auto &&operand_li = object.lower_info(); + assert(operand_li); + + // NOTE Later, constants also will have Def + // Ignore constants + if (operand_li->def_backends().size() == 0) + { + return; + } + + std::list<model::operation::Index> permute_indexes; + + // Build a map for all necessary type of operands + std::unordered_map<const backend::Backend *, model::operand::Index> backend_to_index; + { + assert(operand_li->def_backends().size() == 1); + for (auto backend : operand_li->def_backends()) + { + backend_to_index.insert({backend, index}); + } + + auto insert_set = operand_li->use_backends() - operand_li->def_backends(); + for (auto backend : insert_set) + { + const auto permute_operation_index = insertPermute(index, backend); + permute_indexes.push_back(permute_operation_index); + VERBOSE(PermutationInsertionPass) << "Insert 'Permute' operation for operand " + << index.value() << std::endl; + const auto &permute_operation = _graph.operations().at(permute_operation_index); + const auto permuted_operand_index = permute_operation.getOutputs().at(0); + backend_to_index.insert({backend, permuted_operand_index}); + } + } + + // Update operations' input that uses this operand + { + std::list<model::operation::Index> remove_list; + + auto uses = object.getUses(); + for (auto use : uses.list()) + { + // If permute operation, ignore it + if (std::find(permute_indexes.begin(), permute_indexes.end(), use) != permute_indexes.end()) + continue; + + auto &operation = _graph.operations().at(use); + auto operation_li = _graph.getLowerInfo(use); + assert(operation_li); + auto backend = operation_li->backend(); + + auto use_node_inputs = operation.getInputs(); + assert(use_node_inputs.contains(index)); + + auto new_index = backend_to_index.at(backend); + if (index != new_index) + { + // Update from operation + operation.replaceInput(index, new_index); + + // Update from operand + remove_list.push_back( + use); // Removal should be done in another loop since we are in the loop + _graph.operands().at(new_index).appendUse(use); + } + } + + for (auto &operation : remove_list) + { + object.removeUse(operation); + } + } +} + +model::operation::Index +PermutationInsertionPass::insertPermute(const model::operand::Index &operand_index, + const backend::Backend *backend) +{ + assert(!_graph.isBuildingPhase()); + + auto &operand = _graph.operands().at(operand_index); + + // Generate output operand and permute operation + auto out_operand_index = _graph.addOperand(operand.shape(), operand.typeInfo()); + auto &out_operand = _graph.operands().at(out_operand_index); + out_operand.setAsOperationOutput(); + // change model output if operand_index is model output index + auto &model_outputs = _graph.getOutputs(); + if (model_outputs.contains(operand_index)) + { + model_outputs.replace(operand_index, out_operand_index); + } + out_operand.setAsOperationOutput(); + auto out_operand_li = + nnfw::cpp14::make_unique<operand::LowerInfo>(operand::asShape4D(operand.shape())); + out_operand_li->addDefBackend(backend); + out_operand_li->addUseBackend(backend); + out_operand.lower_info(std::move(out_operand_li)); + + // Update LowerInfo of input operand + operand.lower_info()->removeUseBackend(backend); + operand.lower_info()->addUseBackend(operand.lower_info()->def_backends().getOnlyElement()); + + using PermuteNode = model::operation::PermuteNode; + + // Find Permutation Type + auto type = [&]() { + auto input_layout = + operand.lower_info()->def_backends().getOnlyElement()->config()->getOperandLayout(); + auto output_layout = + out_operand.lower_info()->def_backends().getOnlyElement()->config()->getOperandLayout(); + + if (input_layout == graph::operand::Layout::NHWC && + output_layout == graph::operand::Layout::NCHW) + { + return PermuteNode::Type::NHWC_TO_NCHW; + } + else if (input_layout == graph::operand::Layout::NCHW && + output_layout == graph::operand::Layout::NHWC) + { + return PermuteNode::Type::NCHW_TO_NHWC; + } + else + { + return PermuteNode::Type::COPY; + } + }(); + + // Insert permute operation to the graph + auto insert_node = nnfw::cpp14::make_unique<PermuteNode>(operand_index, out_operand_index, type); + + auto node_index = _graph.operations().append(std::move(insert_node)); + const auto &node = _graph.operations().at(node_index); + + _graph.setLowerInfo(node_index, nnfw::cpp14::make_unique<graph::operation::LowerInfo>( + _graph.backend_resolver()->getDefaultBackend())); + + // Update Use/Def info + { + _graph.operands().at(operand_index).appendUse(node_index); + + auto node_out_indexes = node.getOutputs(); + auto node_out_index = node_out_indexes.at(model::operand::IO::Index{0}); + _graph.operands().at(node_out_index).appendDef(node_index); + } + return node_index; +} +} // namespace pass +} // namespace graph +} // namespace neurun diff --git a/runtimes/neurun/src/graph/pass/PermutationInsertionPass.h b/runtimes/neurun/src/graph/pass/PermutationInsertionPass.h new file mode 100644 index 000000000..b2d417e82 --- /dev/null +++ b/runtimes/neurun/src/graph/pass/PermutationInsertionPass.h @@ -0,0 +1,57 @@ +/* + * 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. + */ + +#ifndef __NEURUN_GRAPH_PASS_PERMUTATION_INSERTION_PASS_H__ +#define __NEURUN_GRAPH_PASS_PERMUTATION_INSERTION_PASS_H__ + +#include "OperandPass.h" +#include "model/operand/Object.h" //for model::operation::Index + +namespace neurun +{ +namespace graph +{ +namespace pass +{ + +class PermutationInsertionPass : public OperandPass +{ +public: + using OperandPass::OperandPass; + +public: + virtual std::string id() override { return "PermutationInsertionPass"; } + virtual void callback(const model::operand::Index &index, model::operand::Object &object); + + /** + * @brief Insert Permute operation that has given operand as input + * + * @param operand_index is the target operand index for the insertion + * @param backend is the output operand's backend type + * + * @return model::operation::Index + */ + model::operation::Index insertPermute(const model::operand::Index &operand_index, + const backend::Backend *backend); + +private: +}; + +} // namespace pass +} // namespace graph +} // namespace neurun + +#endif // __NEURUN_GRAPH_PASS_PERMUTATION_INSERTION_PASS_H__ diff --git a/runtimes/neurun/src/graph/verifier/IVerifier.cc b/runtimes/neurun/src/graph/verifier/IVerifier.cc deleted file mode 100644 index f8402695a..000000000 --- a/runtimes/neurun/src/graph/verifier/IVerifier.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 "IVerifier.h" - -#include "graph/Graph.h" - -namespace neurun -{ -namespace graph -{ -namespace verifier -{ - -bool DAGChecker::verify(const Graph &graph) const -{ - auto &operations = graph.operations(); - bool cyclic = false; - std::vector<bool> visited(operations.size(), false); - std::vector<bool> on_stack(operations.size(), false); - - std::function<void(const operation::Index &index, const operation::Node &)> dfs_recursive = - [&](const operation::Index &index, const operation::Node &node) -> void { - if (on_stack[index.value()]) - cyclic = true; - if (visited[index.value()]) - return; - visited[index.value()] = true; - on_stack[index.value()] = true; - - auto outputs = node.getOutputs(); - for (auto output : outputs) - { - // 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.getInputs(); - for (auto input : inputs) - { - if (output == input) - { - dfs_recursive(cand_index, cand_node); - } - } - }); - } - - on_stack[index.value()] = false; - }; - - operations.iterate(dfs_recursive); - - return !cyclic; -} - -} // namespace verifier -} // namespace graph -} // namespace neurun diff --git a/runtimes/neurun/src/graph/verifier/Verifier.cc b/runtimes/neurun/src/graph/verifier/Verifier.cc new file mode 100644 index 000000000..a5b53af85 --- /dev/null +++ b/runtimes/neurun/src/graph/verifier/Verifier.cc @@ -0,0 +1,97 @@ +/* + * 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 "Verifier.h" + +#include "graph/Graph.h" + +#include "util/logging.h" + +namespace neurun +{ +namespace graph +{ +namespace verifier +{ + +// +// DAGChecker +// + +bool DAGChecker::verify(const Graph &graph) const +{ + auto &operations = graph.operations(); + bool cyclic = false; + + std::unordered_map<model::operation::Index, bool> visited; + operations.iterate([&](const model::operation::Index &index, const model::operation::Node &) { + visited[index] = false; + }); + std::unordered_map<model::operation::Index, bool> on_stack = visited; // Copy from visited + + std::function<void(const model::operation::Index &index, const model::operation::Node &)> + dfs_recursive = + [&](const model::operation::Index &index, const model::operation::Node &node) -> void { + if (on_stack[index]) + cyclic = true; + if (visited[index]) + return; + visited[index] = true; + on_stack[index] = true; + + for (auto output : node.getOutputs()) + { + const auto &operand = graph.operands().at(output); + for (const auto &use : operand.getUses().list()) + { + dfs_recursive(use, graph.operations().at(use)); + } + } + + on_stack[index] = false; + }; + + operations.iterate(dfs_recursive); + + return !cyclic; +} + +// +// EdgeConsistencyVerifier +// + +bool EdgeConsistencyChecker::verify(const Graph &graph) const +{ + auto &operations = graph.operations(); + uint32_t mismatches = 0; + operations.iterate([&](const model::operation::Index &index, const model::operation::Node &node) { + for (auto operand_index : node.getInputs()) + { + auto &operand = graph.operands().at(operand_index); + mismatches += (operand.getUses().contains(index) ? 0 : 1); + } + for (auto operand_index : node.getOutputs()) + { + auto &operand = graph.operands().at(operand_index); + mismatches += (operand.getDef().contains(index) ? 0 : 1); + } + }); + return mismatches == 0; +} + +} // namespace verifier +} // namespace graph +} // namespace neurun diff --git a/runtimes/neurun/src/graph/verifier/IVerifier.h b/runtimes/neurun/src/graph/verifier/Verifier.h index 17fe03f24..5f1f79ee6 100644 --- a/runtimes/neurun/src/graph/verifier/IVerifier.h +++ b/runtimes/neurun/src/graph/verifier/Verifier.h @@ -14,8 +14,8 @@ * limitations under the License. */ -#ifndef __NEURUN_GRAPH_VERIFIER_I_VERIFIER_H__ -#define __NEURUN_GRAPH_VERIFIER_I_VERIFIER_H__ +#ifndef __NEURUN_GRAPH_VERIFIER_VERIFIER_H__ +#define __NEURUN_GRAPH_VERIFIER_VERIFIER_H__ namespace neurun { @@ -55,8 +55,14 @@ public: virtual bool verify(const Graph &graph) const override; }; +class EdgeConsistencyChecker : public IVerifier +{ +public: + virtual bool verify(const Graph &graph) const override; +}; + } // namespace verifier } // namespace graph } // namespace neurun -#endif // __NEURUN_GRAPH_VERIFIER_I_VERIFIER_H__ +#endif // __NEURUN_GRAPH_VERIFIER_VERIFIER_H__ |