Skip to content
This repository has been archived by the owner on Jan 3, 2023. It is now read-only.

Compiling multiple-outputs nodes [Pre-WIP] #90

Closed
wants to merge 3 commits into from

Conversation

Krovatkin
Copy link
Contributor

No description provided.

multiple output nodes up to SGCompiler::CompileSubgraph

refining the initial impl after discussion's w/ Matt

fixing compile errors

formatting

tests1

fixing comp errors after rebase

results in compute
Copy link
Contributor

@mbrookhart mbrookhart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, yes, I think this is the right direction. There are some things to correct, as you mentioned, but I'm not seeing any major design flaws.

There's some code in create_layer_funcs and ParseNNVMGraph that deals with breaking "split", a multi-output mxnet op, into a number of smaller "split" ops. The emitter implementation of split is also based on breaking "split" down. We might be able to clean up the code if we can use this index idea instead, but that might also make the sgcompiler more complex.

@@ -29,6 +29,7 @@ class Emitter {
Emitter();
// maps of ngraph operation generator functions
OpEmitter ngraph_op_funcs_;
std::map<NodePtr, NgraphNodePtr> op_map_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why public?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that was an accident... Rebasing was very painful because I was modifying the same exact methods Louis moved out Graph

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch, yeah. Sorry.

if (!in_vec(subgraph_nodes, n))
for (auto i : n->inputs_) {
if (in_vec(subgraph_nodes, i)) {
if (!in_vec(outNodes, i)) { // TODO: use set
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

order matters, we're preserving a topological sort here, don't use set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it could've worked for outNodes since we are in complete control of a mapping process and we use these indices only after we are done editing outNodes so the indices are relatively stable, but you are right I'd rather postpone testing this theory.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point. Probably not worth fixing now, but good to keep in mind.

//@#$ FIX
auto index = std::distance(
begin(outNodes),
std::find(begin(outNodes), end(outNodes),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting. I would have just used a counter...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seemed more concise back then... I'll try counter when I get stn working

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's a problem, no need to change if you don't want to.

std::function<bool(NodePtr)> func) {
auto subgraph_nodes = SelectNodes(node, func);
std::pair<std::vector<NodePtr>, std::vector<NodePtr>> FindSubgraph(
Graph &graph, NodePtr s, std::function<bool(NodePtr)> func) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We switched everything from s to node a while back to make the names a little clearer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will fix.

auto in_tmpGraphInputs = [&tmpGraph](NodePtr n) {
auto in_tmpGraphInputs = [&tmpGraph](
NodePtr
n) { //[nikolayk] 2nd time seeing this pattern why not use set?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

topological sort order

sub_graph->subgraph_outputs_.end(), results.begin(),
[this](const NodePtr X) { return this->op_map_[X]; });

auto result = std::make_shared<ngraph::op::Tuple>(results);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't Core getting rid of Tuple? Will that cause issues here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will cross that bridge when we get there. As of now, we are free to use Tuple which in the near future will become XLATuple which can continue to use until we ready to make a switch to GetOutputElement

for (size_t i = 0; i < subgraph->subgraph_outputs_.size(); i++) {
nes.push_back(nnvm::NodeEntry{node, i, 0});
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


auto osg = std::dynamic_pointer_cast<Graph>(n);
auto index_of =
[osg](nnvm::NodeEntry ne) -> int /*note, this returns an int*/ {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:) I'm not sure the comment is needed

@@ -205,31 +218,41 @@ nnvm::Graph Compiler::Compile() {
// register compiled subgraph with nnvm
register_subgraph(sg);
// create nnvm node
auto sg_node = CreateNNVMNode(sg);
auto sg_nodes = CreateNNVMNode(sg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sg_node_entries would be a little clearer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will change

}

// TODO: [nikolayk] why don't we just walk
// subgraph_outputs_[...]->orig_nodes_ and be done w/ the whole thing?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would probably work.

@@ -205,31 +218,41 @@ nnvm::Graph Compiler::Compile() {
// register compiled subgraph with nnvm
register_subgraph(sg);
// create nnvm node
auto sg_node = CreateNNVMNode(sg);
auto sg_nodes = CreateNNVMNode(sg);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will change

@@ -29,6 +29,7 @@ class Emitter {
Emitter();
// maps of ngraph operation generator functions
OpEmitter ngraph_op_funcs_;
std::map<NodePtr, NgraphNodePtr> op_map_;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that was an accident... Rebasing was very painful because I was modifying the same exact methods Louis moved out Graph

if (!in_vec(subgraph_nodes, n))
for (auto i : n->inputs_) {
if (in_vec(subgraph_nodes, i)) {
if (!in_vec(outNodes, i)) { // TODO: use set
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it could've worked for outNodes since we are in complete control of a mapping process and we use these indices only after we are done editing outNodes so the indices are relatively stable, but you are right I'd rather postpone testing this theory.

//@#$ FIX
auto index = std::distance(
begin(outNodes),
std::find(begin(outNodes), end(outNodes),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seemed more concise back then... I'll try counter when I get stn working

std::function<bool(NodePtr)> func) {
auto subgraph_nodes = SelectNodes(node, func);
std::pair<std::vector<NodePtr>, std::vector<NodePtr>> FindSubgraph(
Graph &graph, NodePtr s, std::function<bool(NodePtr)> func) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will fix.

if (pos != end(outNodes)) {
outNodes.erase(pos);
}
i->subgraph_ = -1; // are any of these in outNodes should we
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the comment erasing works just fine

@@ -235,7 +225,8 @@ void CollapseSubgraphs(Graph &graph) {
if (node->subgraph_ == i) tmpGraph->AddNode(node);

if (tmpGraph->nodes_.size() == 0) {
// if we don't find any nodes, assume we've run out of subgraphs
// if we don't find any nodes, assume we've run out of subgraphs TODO:
// [nikolayk] how did we get there?
Copy link
Contributor Author

@Krovatkin Krovatkin Dec 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we might want to turn this into a for-loop since we know the maximum number of sub graphs?

@@ -49,39 +51,82 @@ void SGCompiler::CompileSubgraph(std::shared_ptr<Graph> sub_graph) {

// map the inputs into a parameter list
// TODO: std::transform?
ngraph::op::Parameters parameters;
ngraph::op::Parameters forward_parameters;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to check the comments behind this change; I didn't realize forward_parameters got renamed to parameters.

sub_graph->subgraph_outputs_.end(), results.begin(),
[this](const NodePtr X) { return this->op_map_[X]; });

auto result = std::make_shared<ngraph::op::Tuple>(results);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will cross that bridge when we get there. As of now, we are free to use Tuple which in the near future will become XLATuple which can continue to use until we ready to make a switch to GetOutputElement


f = std::make_shared<ngraph::Function>(result, result->get_value_type(),
backward_parameters);
//////////////////////////////////////////////////////////////////////////////
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the scariest part.

@mbrookhart mbrookhart added the WIP label Dec 18, 2017
@mbrookhart mbrookhart closed this Mar 15, 2018
@mbrookhart mbrookhart deleted the krovatkin/multiple_outputs3 branch March 15, 2018 16:21
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants