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

Dynamic subgraph compile support #17623

Merged
merged 56 commits into from
Mar 19, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
639db17
passed args down to acceptSubgraph
samskalicky Feb 17, 2020
5898d53
added example and set param names on inputs to subgraph to map
samskalicky Feb 18, 2020
2294584
increased lib_api version number
samskalicky Feb 19, 2020
fad8e74
fixed whitespace
samskalicky Feb 19, 2020
734f1c4
fixed spacing
samskalicky Feb 19, 2020
934ae8f
Merge branch 'master' of https://github.com/apache/incubator-mxnet in…
samskalicky Feb 20, 2020
ceed9be
added info about lib_api.h to README
samskalicky Feb 20, 2020
098db85
updated readme for new args argument to reviewSubgraph
samskalicky Feb 20, 2020
cfcc0a6
added more tests
samskalicky Feb 20, 2020
1fa7f1d
added example for partitioning HybridBlock in-place without forward pass
samskalicky Feb 21, 2020
8f37c48
added example for partitioning
samskalicky Feb 21, 2020
729173f
fixed whitespace
samskalicky Feb 21, 2020
bb90d70
fixed sanity
samskalicky Feb 21, 2020
06c3841
fixed lint
samskalicky Feb 21, 2020
f8f6191
added support for passing aux
samskalicky Feb 22, 2020
dc17e3f
fixed lint
samskalicky Feb 22, 2020
56bbb01
sanity
samskalicky Feb 22, 2020
a12517d
perl changes
samskalicky Feb 22, 2020
c5d322e
replaced code with hybridize call
samskalicky Feb 24, 2020
4333260
added unittest for gluon optimize_for
samskalicky Feb 24, 2020
adde456
fixed whitespace
samskalicky Feb 24, 2020
8f58f33
fixed test
samskalicky Feb 24, 2020
4daefa7
addressed comments
samskalicky Feb 26, 2020
68f3de0
fixed grammar
samskalicky Feb 26, 2020
3e4b09a
Merge branch 'master' of https://github.com/apache/incubator-mxnet in…
samskalicky Feb 26, 2020
520edcc
fixed spelling
samskalicky Feb 26, 2020
55d575b
added aux argument to the reviewSubgraph API in README
samskalicky Feb 26, 2020
005b53c
updated infer shape to use aux for optimize_for
samskalicky Feb 27, 2020
a51486c
Merge branch 'subgraph_compile' of https://github.com/samskalicky/inc…
samskalicky Feb 27, 2020
668e315
fixed spacing
samskalicky Feb 27, 2020
bb7e52d
changed shape/dtype keys so they dont conflict with MXNet operator attrs
samskalicky Feb 27, 2020
20382ae
added error message to show missing arg/aux
samskalicky Feb 27, 2020
a2a9df1
added calls to setDLtensor for MXTensor constructors
samskalicky Feb 27, 2020
23958da
changed tests to pass aux in addition to args
samskalicky Feb 27, 2020
4f1d0d2
fixed bug passing attributes
samskalicky Feb 29, 2020
127bcbf
fixed memory leak where user attribute strings were not freed
samskalicky Feb 29, 2020
3f57b9b
added passing down shapes/dtypes to subgraph inputs
samskalicky Feb 29, 2020
c971fdc
fixed style
samskalicky Feb 29, 2020
2d9995a
fixed docstring
samskalicky Mar 5, 2020
ade7d48
removed space
samskalicky Mar 5, 2020
736cd8f
changed defines
samskalicky Mar 6, 2020
7fb9ea3
fixed bug in indexing into map with shapes/types when annotating the …
samskalicky Mar 13, 2020
b0a79e5
added support for MKLDNN tensor format conversion in case user does p…
samskalicky Mar 13, 2020
488740a
cleaned up code and added comments
samskalicky Mar 13, 2020
3b278be
fixed whitespace
samskalicky Mar 13, 2020
26734fe
added guards around MKLDNN checks for non-MKLDNN builds
samskalicky Mar 13, 2020
277288d
refactor to use pointers to reduce code duplication
samskalicky Mar 14, 2020
5940450
added MKLDNN guards for custom op
samskalicky Mar 14, 2020
c1d3f5e
fixed whitespace
samskalicky Mar 14, 2020
0b38e5c
added subgraph property API to let subg_prop initialize subgraph inputs
samskalicky Mar 16, 2020
d59a4dc
moved custom code to subgraph property API, cleaned up build_subgraph.cc
samskalicky Mar 16, 2020
5abc8c3
added support for ops with multiple outputs and InitSubgraphInputs
samskalicky Mar 16, 2020
90f6973
fixed sanity, removed prints
samskalicky Mar 16, 2020
28b6bef
fixed whitespace
samskalicky Mar 16, 2020
516d149
fixed shape/dtype parsing
samskalicky Mar 17, 2020
4e2efec
fixed lint
samskalicky Mar 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 2 additions & 13 deletions src/operator/subgraph/build_subgraph.cc
Original file line number Diff line number Diff line change
Expand Up @@ -560,18 +560,6 @@ void CutGraphInputs(const std::vector<nnvm::NodeEntry*> &input_entries,
}
nnvm::ObjectPtr n = nnvm::CreateVariableNode(
var_name + std::to_string(name_count_map[var_name]));
// set attribute for subgraph input to indicate if it is from an arg/param to model
if (e->node->is_variable()) {
n->attrs.dict["isArg"] = "True";
n->attrs.dict["argName"] = var_name;
} else {
n->attrs.dict["isArg"] = "False";
}
// pass down other attributes if available
if (e->node->attrs.dict.count("__dtype__") > 0)
n->attrs.dict["__dtype__"] = e->node->attrs.dict["__dtype__"];
if (e->node->attrs.dict.count("__shape__") > 0)
n->attrs.dict["__shape__"] = e->node->attrs.dict["__shape__"];

*e = nnvm::NodeEntry{n, 0, 0};
}
Expand All @@ -591,7 +579,7 @@ void ReattachGraphInputs(const std::vector<nnvm::NodeEntry*> &input_entries,
}

/*!
* \brief Replace a set of nodes belonging to the same subgraph with a subgrpah node
* \brief Replace a set of nodes belonging to the same subgraph with a subgraph node
* and keep the subgraph in the subgraph node.
*/
void CreateSubgraphNode(nnvm::Graph* g,
Expand Down Expand Up @@ -621,6 +609,7 @@ void CreateSubgraphNode(nnvm::Graph* g,
sym.outputs[i] = *output_entries[i];
}
const SubgraphPropertyPtr& subg_prop = g->GetAttr<SubgraphPropertyPtr>("subgraph_property");
subg_prop->InitSubgraphInputs(&input_entries, &orig_input_entries);
nnvm::ObjectPtr n = subg_prop->CreateSubgraphNode(sym, subgraph_selector, subgraph_id);
// CreateSubgraphNode returns NULL if subgraph property determines that subgraph is sub-optimal
// In that case, subgraph node is not created and graph is not modified
Expand Down
115 changes: 107 additions & 8 deletions src/operator/subgraph/partitioner/custom_subgraph_property.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,16 @@ class CustomSubgraphProperty: public SubgraphProperty {
mxnet::ShapeVector shapes = g.GetAttr<mxnet::ShapeVector>("shape");
for (unsigned nid = 0; nid < indexed_graph.num_nodes(); nid++) {
nnvm::Node* node = const_cast<nnvm::Node*>(indexed_graph[nid].source);
// get the output entry ID for this node
const uint32_t out_entry_id = indexed_graph.entry_id(nid, 0);
mxnet::TShape shape = shapes[out_entry_id];
std::stringstream ss;
ss << shape;
ss << "[";
// set the output shapes for this node
for (unsigned oid = 0; oid < node->num_outputs(); oid++) {
const uint32_t out_entry_id = indexed_graph.entry_id(nid, oid);
mxnet::TShape shape = shapes[out_entry_id];
ss << shape;
if(oid < node->num_outputs()-1) ss << ",";
}
ss << "]";
node->attrs.dict[MX_STR_SHAPE] = ss.str();
}
}
Expand All @@ -193,11 +198,16 @@ class CustomSubgraphProperty: public SubgraphProperty {
std::vector<int> dtypes = g.GetAttr<std::vector<int> >("dtype");
for (unsigned nid = 0; nid < indexed_graph.num_nodes(); nid++) {
nnvm::Node* node = const_cast<nnvm::Node*>(indexed_graph[nid].source);
// get the output entry ID for this node
const uint32_t out_entry_id = indexed_graph.entry_id(nid, 0);
int dtype = dtypes[out_entry_id];
std::stringstream ss;
ss << dtype;
ss << "[";
// set the output dtypes for this node
for (unsigned oid = 0; oid < node->num_outputs(); oid++) {
const uint32_t out_entry_id = indexed_graph.entry_id(nid, oid);
int dtype = dtypes[out_entry_id];
ss << dtype;
if(oid < node->num_outputs()-1) ss << ",";
}
ss << "]";
node->attrs.dict[MX_STR_DTYPE] = ss.str();
}
}
Expand Down Expand Up @@ -299,6 +309,38 @@ class CustomSubgraphProperty: public SubgraphProperty {
n->attrs.name = "_op" + std::to_string(subgraph_id);
n->attrs.subgraphs.push_back(std::make_shared<nnvm::Symbol>(sym));

// set shapes
{
std::stringstream ss;
ss << "[";
for (unsigned i=0; i < sym.outputs.size(); i++) {
nnvm::Node* n = sym.outputs[i].node.get();
if (n->attrs.dict.count("__shape__") > 0) {
std::string& shape = n->attrs.dict["__shape__"];
Copy link
Contributor

Choose a reason for hiding this comment

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

modify logic for the case when n is a subgraph node and shape a list of lists

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

ss << shape.substr(1,shape.length()-2); //strip off outer square brackets []
}
if (i < sym.outputs.size()-1)
ss << ",";
}
ss << "]";
n->attrs.dict["__shape__"]=ss.str();
}
// set dtypes
{
std::stringstream ss;
ss << "[";
for (unsigned i=0; i < sym.outputs.size(); i++) {
nnvm::Node* n = sym.outputs[i].node.get();
if (n->attrs.dict.count("__dtype__") > 0) {
std::string& dtype = n->attrs.dict["__dtype__"];
ss << dtype.substr(1,dtype.length()-2); //strip off outer square brackets []
}
if (i < sym.outputs.size()-1)
ss << ",";
}
ss << "]";
n->attrs.dict["__dtype__"]=ss.str();
}
// set user specified attributes
for (auto attr : user_attrs)
n->attrs.dict[attr.first] = attr.second;
Expand All @@ -308,6 +350,63 @@ class CustomSubgraphProperty: public SubgraphProperty {
return nullptr;
}
}

virtual void InitSubgraphInputs(std::vector<nnvm::NodeEntry*>* input_entries,
std::vector<nnvm::NodeEntry>* orig_input_entries) const {
std::cout << "in InitSubgraphInputs" << std::endl;
samskalicky marked this conversation as resolved.
Show resolved Hide resolved
for (size_t i = 0; i < input_entries->size(); ++i) {
nnvm::NodeEntry *e = input_entries->at(i);
nnvm::NodeEntry& orig = orig_input_entries->at(i);

// set attribute for subgraph input to indicate if it is from an arg/param to model
if (orig.node->is_variable()) {
// get name of original output entry
nnvm::Symbol sym;
sym.outputs.push_back(orig);
const auto output_names = sym.ListOutputNames();
CHECK_EQ(output_names.size(), 1U);
const std::string& var_name = output_names[0];

e->node->attrs.dict["isArg"] = "True";
e->node->attrs.dict["argName"] = var_name;
} else {
e->node->attrs.dict["isArg"] = "False";
}

// pass down other attributes if available
if (orig.node->attrs.dict.count("__dtype__") > 0) {
// get dtype string from other node
std::string& dtype = orig.node->attrs.dict["__dtype__"];
int idx = 0;
// find the beginning of the output dtype for the particular output index
for (unsigned x=0; x < orig.index; x++)
idx = dtype.find("[",idx+1);
if (idx == 0) idx++; // if output index is 0, start after first square bracket [
int stop = dtype.find("]",idx); // find stop index for this output dtype
std::stringstream ss;
// create new dtype string for this node
ss << "[" << dtype.substr(idx,stop-idx+1) << "]";
e->node->attrs.dict["__dtype__"] = ss.str();
}

if (orig.node->attrs.dict.count("__shape__") > 0) {
// get shape string from other node
std::string& shape = orig.node->attrs.dict["__shape__"];
int idx = 0;
// find the beginning of the output shape for the particular output index
for (unsigned x=0; x < orig.index; x++)
idx = shape.find("[",idx+1);
if (idx == 0) idx++; // if output index is 0, start after first square bracket [
int stop = shape.find("]",idx); // find stop index for this output shape
std::stringstream ss;
// create new shape string for this node
ss << "[" << shape.substr(idx,stop-idx+1) << "]";
e->node->attrs.dict["__shape__"] = ss.str();
}
}
std::cout << "-----------------------------" << std::endl;
}

// override CreateSubgraphSelector
virtual SubgraphSelectorPtr CreateSubgraphSelector() const {
return std::make_shared<CustomContainOpSelector>(supported_nodes);
Expand Down
8 changes: 8 additions & 0 deletions src/operator/subgraph/subgraph_property.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,14 @@ class SubgraphProperty {
std::vector<nnvm::NodeEntry>* orig_input_entries) const {
subgraph_node->inputs = *orig_input_entries;
}
/*!
* \brief Initialize subgraph internal inputs with external input entries.
* Called before CreateSubgraphNode, optional
* \param input_entries input entries inside subgraph
* \param orig_input_entries input entries outside subgraph
*/
virtual void InitSubgraphInputs(std::vector<nnvm::NodeEntry*>* input_entries,
std::vector<nnvm::NodeEntry>* orig_input_entries) const {}
/*!
* \brief Set an attr with name in the attr map.
*/
Expand Down