`OperationIndex` was used for Subgraph indices, which can be confusing.
This commit introduces `SubgraphIndex` for `Subgraph`s.
Signed-off-by: Hanjoung Lee <hanjoung.lee@samsung.com>
// For LOWERED phase
public:
- const operation::LowerInfo *getLowerInfo(const model::OperationIndex &subg_index) const;
- void setLowerInfo(const model::OperationIndex &subg_index,
+ const operation::LowerInfo *getLowerInfo(const model::SubgraphIndex &subg_index) const;
+ void setLowerInfo(const model::SubgraphIndex &subg_index,
std::unique_ptr<operation::LowerInfo> &&lower_info);
const operand::LowerInfo *getLowerInfo(const model::OperandIndex &index) const;
operand::LowerInfo *getLowerInfo(const model::OperandIndex &index);
struct LowerInfoMap
{
- std::unordered_map<model::OperationIndex, std::unique_ptr<operation::LowerInfo>> operation;
+ std::unordered_map<model::SubgraphIndex, std::unique_ptr<operation::LowerInfo>> operation;
model::OperandIndexMap<std::unique_ptr<operand::LowerInfo>> operand;
};
struct IOIndexTag;
using IOIndex = ::neurun::util::Index<uint32_t, IOIndexTag>;
+struct SubgraphIndexTag;
+using SubgraphIndex = ::neurun::util::Index<uint32_t, SubgraphIndexTag>;
+
} // namespace model
} // namespace neurun
#include <memory>
#include "Subgraph.h"
+#include "model/Index.h"
#include <unordered_map>
-using neurun::model::OperationIndex;
-
namespace neurun
{
namespace model
SubgraphContext() : _index_count(0) {}
public:
- OperationIndex append(std::unique_ptr<Subgraph> &&subg);
- OperationIndex append(const OperationIndex &index, const Operation &node);
- void remove(const OperationIndex &index) { _subgs.erase(index); };
+ SubgraphIndex append(std::unique_ptr<Subgraph> &&subg);
+ SubgraphIndex append(const OperationIndex &index, const Operation &node);
+ void remove(const SubgraphIndex &index) { _subgs.erase(index); };
public:
- const Subgraph &at(const OperationIndex &) const;
- Subgraph &at(const OperationIndex &);
- std::unique_ptr<Subgraph> releaseAt(const OperationIndex &index)
+ const Subgraph &at(const SubgraphIndex &) const;
+ Subgraph &at(const SubgraphIndex &);
+ std::unique_ptr<Subgraph> releaseAt(const SubgraphIndex &index)
{
return std::move(_subgs.at(index));
}
- Subgraph *getAt(const OperationIndex &index) { return _subgs.at(index).get(); }
- bool exist(const OperationIndex &) const;
+ Subgraph *getAt(const SubgraphIndex &index) { return _subgs.at(index).get(); }
+ bool exist(const SubgraphIndex &) const;
bool hasNode(const OperationIndex &node_index) const;
- OperationIndex findNode(const OperationIndex &node_index) const;
+ SubgraphIndex findNode(const OperationIndex &node_index) const;
uint32_t size() const { return _subgs.size(); }
- void iterate(const std::function<void(const OperationIndex &, const Subgraph &)> &fn) const;
- void iterate(const std::function<void(const OperationIndex &, Subgraph &)> &fn);
+ void iterate(const std::function<void(const SubgraphIndex &, const Subgraph &)> &fn) const;
+ void iterate(const std::function<void(const SubgraphIndex &, Subgraph &)> &fn);
// TODO: Extract this into external helper function
void dump(const std::string &msg) const;
void clear() { _subgs.clear(); }
private:
- OperationIndex generateIndex();
+ SubgraphIndex generateIndex();
private:
- std::unordered_map<OperationIndex, std::unique_ptr<Subgraph>> _subgs;
+ std::unordered_map<SubgraphIndex, std::unique_ptr<Subgraph>> _subgs;
uint32_t _index_count;
};
std::shared_ptr<exec::IExecutor> Compiler::createDataflowExecutor(graph::Graph &model)
{
auto operand_context = std::make_shared<OperandContext>();
- std::unordered_map<model::OperationIndex, std::unique_ptr<backend::IStage>> stages;
+ std::unordered_map<model::SubgraphIndex, std::unique_ptr<backend::IStage>> stages;
model.subg_ctx().iterate(
- [&](const model::OperationIndex &subg_index, const model::operation::Subgraph &subg) {
+ [&](const model::SubgraphIndex &subg_index, const model::operation::Subgraph &subg) {
auto backend = model.getLowerInfo(subg_index)->backend();
// Generate Stage
};
// TODO Remove this method and make `append` to get index value as an argument
- void setNextIndex(const model::OperationIndex next_index) { _next_index = next_index; }
+ void setNextIndex(const model::SubgraphIndex next_index) { _next_index = next_index; }
exec::DataflowExecutor::CodeMap &&releaseCodeMap() { return std::move(_code_map); }
private:
- model::OperationIndex _next_index;
+ model::SubgraphIndex _next_index;
exec::DataflowExecutor::CodeMap _code_map;
};
// Create jobs
_subg_ctx->iterate(
- [&](const model::OperationIndex &subg_index, const model::operation::Subgraph &subg) {
+ [&](const model::SubgraphIndex &subg_index, const model::operation::Subgraph &subg) {
VERBOSE(DataflowExecutor) << "Add a job #" << subg_index.value() << std::endl;
_finished_jobs.emplace_back(nnfw::cpp14::make_unique<Job>(
subg_index, _code_map.at(subg_index).get(), subg.getInputs(), subg.getOutputs()));
class DataflowExecutor : public ExecutorBase
{
public:
- using CodeMap = std::unordered_map<model::OperationIndex, std::unique_ptr<FunctionSequence>>;
+ using CodeMap = std::unordered_map<model::SubgraphIndex, std::unique_ptr<FunctionSequence>>;
private:
void notify(const model::OperandIndexSequence &operands);
namespace exec
{
-Job::Job(const model::OperationIndex &index, IFunction *fn,
+Job::Job(const model::SubgraphIndex &index, IFunction *fn,
const model::OperandIndexSequence &inputs, const model::OperandIndexSequence &outputs)
: _index{index}, _fn{fn}, _outputs{outputs}
{
#include <unordered_set>
#include "exec/IFunction.h"
-#include "model/OperationIndex.h"
+#include "model/Index.h"
#include "model/OperandIndexSequence.h"
namespace neurun
* @param inputs Input operand list
* @param outputs Output operand list
*/
- Job(const model::OperationIndex &index, IFunction *fn, const model::OperandIndexSequence &inputs,
+ Job(const model::SubgraphIndex &index, IFunction *fn, const model::OperandIndexSequence &inputs,
const model::OperandIndexSequence &outputs);
/**
* @brief Remove the given operand from blocking input list
*/
bool ready() const { return _blocking_inputs.empty(); }
/**
- * @brief Return operation index
+ * @brief Return subgraph index
*
- * @return Operation index
+ * @return Subgraph index
*/
- model::OperationIndex index() const { return _index; }
+ model::SubgraphIndex index() const { return _index; }
/**
* @brief Return output indices
*
const model::OperandIndexSequence &outputs() const { return _outputs; }
private:
- model::OperationIndex _index;
+ model::SubgraphIndex _index;
IFunction *_fn;
std::unordered_set<model::OperandIndex> _blocking_inputs;
const model::OperandIndexSequence _outputs;
// Are they mergeable?
// 1. the same backend id?
// 2. if 1 is true, the subg and a node are connected?
- auto mergeable = [&](const model::OperationIndex &subg_index,
+ auto mergeable = [&](const model::SubgraphIndex &subg_index,
const model::OperationIndex &node_index) {
const auto &subg = _subg_ctx->at(subg_index);
const auto &node = _model->operations.at(node_index);
};
model::operation::Subgraph *subg = nullptr;
- model::OperationIndex subg_index;
+ model::SubgraphIndex subg_index;
// Make subgraphs while checking whether a node can be merged into a subgraph.
// NOTE: The below method appends nodes while making one subgraph if needed. If something better
subg = nullptr;
});
- _subg_ctx->iterate([&](const model::OperationIndex &, model::operation::Subgraph &subg) {
+ _subg_ctx->iterate([&](const model::SubgraphIndex &, model::operation::Subgraph &subg) {
assert(subg.operations().size() > 0);
std::reverse(std::begin(subg.operations()), std::end(subg.operations()));
});
});
}
-const operation::LowerInfo *Graph::getLowerInfo(const model::OperationIndex &subg_index) const
+const operation::LowerInfo *Graph::getLowerInfo(const model::SubgraphIndex &subg_index) const
{
if (!_lower_info_map)
return nullptr;
return itr->second.get();
}
-void Graph::setLowerInfo(const model::OperationIndex &subg_index,
+void Graph::setLowerInfo(const model::SubgraphIndex &subg_index,
std::unique_ptr<operation::LowerInfo> &&lower_info)
{
assert(_lower_info_map);
// Get SubgraphSequence by topological sorting
{
// _subg_ctx can't access a subgraph by an operand so that input_to_subgs can offer it
- std::unordered_map<model::OperandIndex, model::OperationIndexList> input_to_subgs;
+ std::unordered_map<model::OperandIndex, std::list<model::SubgraphIndex>> input_to_subgs;
// Get the relations between input/subgraph to be used for dfs-post-iter
//
// [SUBG3]
// |
// [4]
- _subg_ctx->iterate(
- [&](const model::OperationIndex &subg_idx, model::operation::Subgraph &subg) {
- for (auto input : subg.getInputs())
- {
- // only valid_inputs
- const auto &operand = _model->operands.at(input);
- if (operand.isConstant())
- continue;
-
- auto it = input_to_subgs.find(input);
- if (it == input_to_subgs.end())
- {
- model::OperationIndexList list{subg_idx};
- input_to_subgs[input] = list;
- }
- else
- {
- it->second.append(subg_idx);
- }
- }
- });
+ _subg_ctx->iterate([&](const model::SubgraphIndex &subg_idx, model::operation::Subgraph &subg) {
+ for (auto input : subg.getInputs())
+ {
+ // only valid_inputs
+ const auto &operand = _model->operands.at(input);
+ if (operand.isConstant())
+ continue;
+
+ auto it = input_to_subgs.find(input);
+ if (it == input_to_subgs.end())
+ {
+ std::list<model::SubgraphIndex> list{subg_idx};
+ input_to_subgs[input] = list;
+ }
+ else
+ {
+ it->second.push_back(subg_idx);
+ }
+ }
+ });
- std::unordered_map<model::OperationIndex, bool> visited;
- _subg_ctx->iterate([&](const model::OperationIndex &index, const model::operation::Subgraph &) {
+ std::unordered_map<model::SubgraphIndex, bool> visited;
+ _subg_ctx->iterate([&](const model::SubgraphIndex &index, const model::operation::Subgraph &) {
visited[index] = false;
});
- std::function<void(const model::OperationIndex &, model::operation::Subgraph &)> dfs_recursive =
- [&](const model::OperationIndex &index, model::operation::Subgraph &subg) -> void {
+ std::function<void(const model::SubgraphIndex &, model::operation::Subgraph &)> dfs_recursive =
+ [&](const model::SubgraphIndex &index, model::operation::Subgraph &subg) -> void {
if (visited[index])
return;
visited[index] = true;
if (it != input_to_subgs.end())
{
const auto &subg_index_list = it->second;
- for (const auto &index : subg_index_list.list())
+ for (const auto &index : subg_index_list)
{
auto &subg = _subg_ctx->at(index);
dfs_recursive(index, subg);
_subg_ctx->iterate(dfs_recursive);
// All of the nodes must have been visited.
- assert(std::all_of(
- visited.begin(), visited.end(),
- [](const std::pair<const model::OperationIndex, bool> &v) { return v.second; }));
+ assert(
+ std::all_of(visited.begin(), visited.end(),
+ [](const std::pair<const model::SubgraphIndex, bool> &v) { return v.second; }));
// NOTE. Now these subgraph are on the reverse order
std::reverse(_elements->begin(), _elements->end());
}
}
-const graph::operation::LowerInfo *Linear::getLowerInfo(const model::OperationIndex &index) const
+const graph::operation::LowerInfo *Linear::getLowerInfo(const model::SubgraphIndex &index) const
{
if (!_lower_info_map)
return nullptr;
private:
// TODO Replace these getLowerInfo methods with ones of LowerInfoMap in the future
- const graph::operation::LowerInfo *getLowerInfo(const model::OperationIndex &index) const;
+ const graph::operation::LowerInfo *getLowerInfo(const model::SubgraphIndex &index) const;
const graph::operand::LowerInfo *getLowerInfo(const model::OperandIndex &index) const;
private:
namespace operation
{
-OperationIndex SubgraphContext::generateIndex()
+SubgraphIndex SubgraphContext::generateIndex()
{
assert((_index_count) <= UINT32_MAX);
- return OperationIndex{_index_count++};
+ return SubgraphIndex{_index_count++};
}
-OperationIndex SubgraphContext::append(std::unique_ptr<Subgraph> &&subgraph)
+SubgraphIndex SubgraphContext::append(std::unique_ptr<Subgraph> &&subgraph)
{
auto index = generateIndex();
_subgs[index] = std::move(subgraph);
return index;
}
-OperationIndex SubgraphContext::append(const OperationIndex &index, const Operation &node)
+SubgraphIndex SubgraphContext::append(const OperationIndex &index, const Operation &node)
{
std::unique_ptr<Subgraph> subg = nnfw::cpp14::make_unique<model::operation::Subgraph>();
subg->appendOperation(index, node);
return append(std::move(subg));
}
-const Subgraph &SubgraphContext::at(const OperationIndex &index) const
+const Subgraph &SubgraphContext::at(const SubgraphIndex &index) const
{
return *(_subgs.at(index));
}
-Subgraph &SubgraphContext::at(const OperationIndex &index) { return *(_subgs.at(index)); }
+Subgraph &SubgraphContext::at(const SubgraphIndex &index) { return *(_subgs.at(index)); }
-bool SubgraphContext::exist(const OperationIndex &index) const
+bool SubgraphContext::exist(const SubgraphIndex &index) const
{
return _subgs.find(index) != _subgs.end();
}
return false;
}
-OperationIndex SubgraphContext::findNode(const OperationIndex &node_index) const
+SubgraphIndex SubgraphContext::findNode(const OperationIndex &node_index) const
{
for (auto it = _subgs.begin(); it != _subgs.end(); ++it)
{
}
assert(true && "DO NOT ENTER HERE");
- return OperationIndex(UINT32_MAX); // CAN'T ENTER HERE
+ return SubgraphIndex(UINT32_MAX); // CAN'T ENTER HERE
}
void SubgraphContext::iterate(
- const std::function<void(const OperationIndex &, const Subgraph &)> &fn) const
+ const std::function<void(const SubgraphIndex &, const Subgraph &)> &fn) const
{
for (auto it = _subgs.begin(); it != _subgs.end(); ++it)
{
}
}
-void SubgraphContext::iterate(const std::function<void(const OperationIndex &, Subgraph &)> &fn)
+void SubgraphContext::iterate(const std::function<void(const SubgraphIndex &, Subgraph &)> &fn)
{
for (auto it = _subgs.begin(); it != _subgs.end(); ++it)
{
void SubgraphContext::dump(const std::string &msg) const
{
VERBOSE(SubgraphContext) << "SubgraphContext(" << msg << ")" << std::endl;
- iterate([&](const OperationIndex &idx, const model::operation::Subgraph &subg) {
+ iterate([&](const SubgraphIndex &idx, const model::operation::Subgraph &subg) {
VERBOSE(SubgraphContext) << idx.value() << "] " << subg.getStr() << std::endl;
});
}