Skip to content

Commit f833100

Browse files
committed
[SubGraph] default graph-related Bugfix; updating unittest
- This patch fixes default-graph-related bugs. - This patch update unittests - This patch adds some codes to print `subgraph` info in summarize() Signed-off-by: Eunju Yang <[email protected]>
1 parent d35333d commit f833100

File tree

5 files changed

+132
-24
lines changed

5 files changed

+132
-24
lines changed

nntrainer/graph/network_graph.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ class NetworkGraph {
7272
*/
7373
auto sg = std::make_shared<SubGraphNode>(tensor_manager);
7474
sg->setName("default");
75+
sg->setSubGraphInfo(tensor_manager, exec_mode, lookahead, tensor_format,
76+
tensor_dtype_str);
7577
graph.addNode(SGNODE(sg));
7678
}
7779

@@ -144,6 +146,16 @@ class NetworkGraph {
144146
*/
145147
~NetworkGraph() = default;
146148

149+
/**
150+
* @brief getter of SubGraphNode
151+
*/
152+
std::shared_ptr<SubGraphNode> getSubGraph(const std::string &name) {
153+
if (!graph.verifyNode(name))
154+
return nullptr;
155+
else
156+
return SGNODE(graph.getNode(name));
157+
}
158+
147159
/**
148160
* @brief Realize the network's internal layers
149161
*/

nntrainer/graph/subgraph_node.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,8 @@ std::unique_ptr<SubGraphNode>
931931
createSubGraphNode(std::unique_ptr<nntrainer::SubGraphNode> &&subgraph,
932932
const std::vector<std::string> &properties);
933933

934-
SubGraphType createSubGraph(const std::vector<std::string> &properties = {});
934+
std::shared_ptr<SubGraphNode>
935+
createSubGraph(const std::vector<std::string> &properties = {});
935936

936937
bool is_representation_equal(const GraphLayerNodeRepresentation &lhs,
937938
const GraphLayerNodeRepresentation &rhs);

nntrainer/models/neuralnet.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,12 +1112,23 @@ int NeuralNetwork::addSubGraph(SubGraphType subgraph) {
11121112
// Check the subgraph exists and create a new subgraph if not
11131113
const auto &subgraph_name = subgraph->getName();
11141114
if (graph_map.find(subgraph_name) == graph_map.end()) {
1115+
1116+
/**
1117+
* @note Code to handle `default` graph
1118+
* This is undesirable way to handle `default` graph, but it is necessary to
1119+
* support legacy unittests.
1120+
* @todo update `NetworkGraph` not to create default subgraph in
1121+
* constructor. Then, this codeblock should be updated as well.
1122+
*/
1123+
if (model_graph.getSubGraph(subgraph_name) != nullptr)
1124+
return ML_ERROR_INVALID_PARAMETER;
1125+
11151126
graph_representation.push_back(subgraph);
11161127
graph_map[subgraph_name] = subgraph;
1128+
model_graph.addSubGraph(subgraph);
11171129

11181130
// Insert the layers in subgraph to the graph
11191131
for (auto layer : subgraph->getLayerNodes()) {
1120-
model_graph.addLayer(layer);
11211132
graph_ln_representation.push_back(layer);
11221133
}
11231134
} else {
@@ -1137,16 +1148,26 @@ int NeuralNetwork::addLayer(NodeType layer) {
11371148
/** Check the subgraph exists and create a new subgraph if not */
11381149
const auto &subgraph_name = layer->getSubGraphName();
11391150
if (graph_map.find(subgraph_name) == graph_map.end()) {
1140-
const auto &sg = createSubGraph();
1141-
sg->setName(subgraph_name);
1151+
1152+
/**
1153+
* @note Code to handle `default` graph
1154+
* This is undesirable way to handle `default` graph, but it is necessary to
1155+
* support legacy unittests.
1156+
* @todo update `NetworkGraph` not to create default subgraph in
1157+
* constructor. Then, this codeblock should be updated as well.
1158+
*/
1159+
auto sg = model_graph.getSubGraph(subgraph_name);
1160+
if (sg == nullptr) {
1161+
sg = createSubGraph();
1162+
sg->setName(subgraph_name);
1163+
}
11421164
graph_representation.push_back(sg);
11431165
graph_map[subgraph_name] = sg;
11441166
}
11451167

11461168
/** Insert the layer to the graph */
11471169
model_graph.addLayer(layer);
11481170
graph_ln_representation.push_back(layer);
1149-
graph_map[subgraph_name]->addLayer(layer);
11501171

11511172
return status;
11521173
}
@@ -1375,6 +1396,9 @@ void NeuralNetwork::print(std::ostream &out, unsigned int flags,
13751396

13761397
for (auto sg_iter = model_graph.cbegin(); sg_iter != model_graph.cend();
13771398
++sg_iter) {
1399+
print_graph_layer_info(
1400+
out, {"<" + sg_iter->getName() + ">", sg_iter->getType(), "", ""});
1401+
out << std::string(total_col_size, '.') << '\n';
13781402
for (auto iter = sg_iter->cbegin(); iter != sg_iter->cend(); ++iter) {
13791403
std::string first_dim;
13801404
if (iter->getOutputDimensions().empty()) {
@@ -1414,6 +1438,9 @@ void NeuralNetwork::print(std::ostream &out, unsigned int flags,
14141438

14151439
for (auto sg_iter = model_graph.cbegin(); sg_iter != model_graph.cend();
14161440
++sg_iter) {
1441+
print_graph_layer_info(
1442+
out, {"<" + sg_iter->getName() + ">", sg_iter->getType(), "", ""});
1443+
out << std::string(total_col_size, '.') << '\n';
14171444
for (auto iter = sg_iter->cbegin(); iter != sg_iter->cend(); ++iter) {
14181445
const std::vector<std::string> &input_layer_names =
14191446
iter->getInputConnections();

nntrainer/models/neuralnet.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,11 +703,21 @@ s * @retval shared_ptr<const Tensor>
703703

704704
AppContext app_context; /** Configurations bound to current app */
705705

706+
/**
707+
* @note model_graph - updated to reflect the changes made to the graph
708+
* It will recreated when compile() is called.
709+
*/
706710
NetworkGraph model_graph; /** Network Model Graph */
711+
712+
/**
713+
* @note _represemtation - updated to reflect the changes made to the graph
714+
* It saves the node information when addSubGraph / addLayer is called.
715+
* This info will be used in compilation time
716+
*/
707717
GraphRepresentation
708718
graph_representation; /** Unsorted subgraph representation */
709719
std::unordered_map<std::string, SubGraphType>
710-
graph_map; /** hashmap for the graph */
720+
graph_map; /** hashmap for the graph - shofrtcut for graph_representation */
711721
GraphLayerNodeRepresentation
712722
graph_ln_representation; /** Unsorted graph representation with successive
713723
layer nodes */

test/unittest/unittest_nntrainer_subgraph.cpp

Lines changed: 76 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,77 @@ TEST(nntrainer_SubGraph, create_subgraph_02_p) {
9898
}
9999

100100
/**
101-
* @brief Unittest to create a subgraph with layers
102-
* create a graph
101+
* @brief Unittest for `addSubGraph`
103102
*/
104-
TEST(nntrainer_SubGraph, create_subgraph_03_p) {
103+
TEST(nntrainer_SubGraph, add_subgraph_01_p) {
104+
static auto &ac = nntrainer::AppContext::Global();
105+
std::shared_ptr<ml::train::Model> model =
106+
ml::train::createModel(ml::train::ModelType::NEURAL_NET);
107+
std::shared_ptr<ml::train::SubGraph> sg =
108+
ml::train::createSubGraph("subgraph", {"subgraph_name=graph0"});
109+
EXPECT_EQ(sg->getName(), "graph0");
110+
EXPECT_EQ(model->addSubGraph(sg), ML_ERROR_NONE);
111+
}
112+
113+
/**
114+
* @brief Test to add multiple subgraphs.
115+
*/
116+
TEST(nntrainer_SubGraph, add_subgraph_02_p) {
117+
static auto &ac = nntrainer::AppContext::Global();
118+
std::shared_ptr<ml::train::Model> model =
119+
ml::train::createModel(ml::train::ModelType::NEURAL_NET);
120+
121+
std::vector<std::shared_ptr<ml::train::SubGraph>> subgraphs;
122+
for (int i = 0; i < 5; ++i)
123+
subgraphs.push_back(ml::train::createSubGraph(
124+
ml::train::SubGraphType::SUBGRAPH_CPU,
125+
{withKey("subgraph_name", "subgraph_" + std::to_string(i))}));
126+
127+
for (int i = 0; i < 5; ++i)
128+
EXPECT_EQ(model->addSubGraph(subgraphs[i]), ML_ERROR_NONE);
129+
model->summarize(std::cout, ml_train_summary_type_e::ML_TRAIN_SUMMARY_MODEL);
130+
subgraphs.clear();
131+
}
132+
133+
/**
134+
* @brief Negative unittest for `addSubGraph`
135+
* @note Please note that model create `default` subgraph by default
136+
*/
137+
TEST(nntrainer_SubGraph, add_subgraph_01_n) {
105138
static auto &ac = nntrainer::AppContext::Global();
106139

107-
// subgraph named `default`
108140
std::shared_ptr<ml::train::Model> model1 =
109141
ml::train::createModel(ml::train::ModelType::NEURAL_NET);
110-
model1->addSubGraph(ml::train::createSubGraph("subgraph"));
111-
model1->addLayer(ml::train::createLayer(
112-
"fully_connected", {withKey("name", "fc0"), withKey("unit", 2)}));
113142

114-
// subgraph named `default`
115-
std::shared_ptr<ml::train::Model> model2 =
143+
// subgraph named `default` <- invalid
144+
// add default SubGraph returns ML_ERROR_INVALID_PARAMETER
145+
EXPECT_EQ(model1->addSubGraph(ml::train::createSubGraph("subgraph")),
146+
ML_ERROR_INVALID_PARAMETER);
147+
EXPECT_EQ(model1->addSubGraph(
148+
ml::train::createSubGraph(ml::train::SubGraphType::SUBGRAPH_CPU)),
149+
ML_ERROR_INVALID_PARAMETER);
150+
}
151+
152+
/**
153+
* @brief Test to add multiple subgraphs with same name.
154+
* error handling sohlud be done.
155+
*/
156+
TEST(nntrainer_SubGraph, add_subgraph_02_n) {
157+
static auto &ac = nntrainer::AppContext::Global();
158+
std::shared_ptr<ml::train::Model> model =
116159
ml::train::createModel(ml::train::ModelType::NEURAL_NET);
117-
model2->addLayer(ml::train::createLayer(
118-
"fully_connected", {withKey("name", "fc0"), withKey("unit", 2)}));
119160

120-
EXPECT_EQ(*NNPTR(model1) == *NNPTR(model2), true);
161+
std::vector<std::shared_ptr<ml::train::SubGraph>> subgraphs;
162+
for (int i = 0; i < 5; ++i)
163+
subgraphs.push_back(
164+
ml::train::createSubGraph(ml::train::SubGraphType::SUBGRAPH_CPU,
165+
{withKey("subgraph_name", "subgraph")}));
166+
167+
EXPECT_EQ(model->addSubGraph(subgraphs[0]), ML_ERROR_NONE);
168+
for (int i = 1; i < 5; ++i)
169+
EXPECT_EQ(model->addSubGraph(subgraphs[i]), ML_ERROR_INVALID_PARAMETER);
170+
171+
subgraphs.clear();
121172
}
122173

123174
/**
@@ -130,7 +181,7 @@ TEST(nntrainer_SubGraph, create_subgraph_04_p) {
130181
std::shared_ptr<ml::train::Model> model1 =
131182
ml::train::createModel(ml::train::ModelType::NEURAL_NET);
132183
std::shared_ptr<ml::train::SubGraph> sg =
133-
ml::train::createSubGraph("subgraph");
184+
ml::train::createSubGraph("subgraph", {"subgraph_name=graph0"});
134185
// 2. add three layers to subgraph
135186
sg->addLayer(ml::train::createLayer(
136187
"fully_connected", {withKey("name", "fc0"), withKey("unit", 2)}));
@@ -140,6 +191,7 @@ TEST(nntrainer_SubGraph, create_subgraph_04_p) {
140191
"fully_connected", {withKey("name", "fc2"), withKey("unit", 2)}));
141192
// 3. add a subgraph to model
142193
model1->addSubGraph(sg);
194+
model1->summarize(std::cout, ml_train_summary_type_e::ML_TRAIN_SUMMARY_MODEL);
143195

144196
// add three layers to model directly
145197
// It implies a default subgraph creation and adding layers to the defulat
@@ -152,8 +204,12 @@ TEST(nntrainer_SubGraph, create_subgraph_04_p) {
152204
"fully_connected", {withKey("name", "fc1"), withKey("unit", 2)}));
153205
model2->addLayer(ml::train::createLayer(
154206
"fully_connected", {withKey("name", "fc2"), withKey("unit", 2)}));
207+
model2->summarize(std::cout, ml_train_summary_type_e::ML_TRAIN_SUMMARY_MODEL);
155208

156-
EXPECT_EQ(*NNPTR(model1) == *NNPTR(model2), true);
209+
EXPECT_EQ(is_representation_equal(NNPTR(model1)->getFlatGraph(),
210+
NNPTR(model2)->getFlatGraph()),
211+
true);
212+
EXPECT_EQ(*NNPTR(model1) == *NNPTR(model2), false);
157213
}
158214

159215
/**
@@ -169,7 +225,8 @@ TEST(nntrainer_SubGraph, create_subgraph_05_n) {
169225
model1->addSubGraph(ml::train::createSubGraph(
170226
"subgraph", {withKey("subgraph_name", "graph_1")}));
171227
model1->addLayer(ml::train::createLayer(
172-
"fully_connected", {withKey("name", "fc0"), withKey("unit", 2)}));
228+
"fully_connected", {withKey("name", "fc0"), withKey("unit", 2),
229+
withKey("subgraph_name", "graph_1")}));
173230

174231
// subgraph named `default`
175232
std::shared_ptr<ml::train::Model> model2 =
@@ -179,11 +236,12 @@ TEST(nntrainer_SubGraph, create_subgraph_05_n) {
179236

180237
// not equal model (subgraph name is different)
181238
EXPECT_EQ(*NNPTR(model1) == *NNPTR(model2), false);
182-
183-
// layer nodes are equal
184239
EXPECT_EQ(is_representation_equal(NNPTR(model1)->getFlatGraph(),
185240
NNPTR(model2)->getFlatGraph()),
186-
true);
241+
false);
242+
243+
model1->summarize(std::cout, ml_train_summary_type_e::ML_TRAIN_SUMMARY_MODEL);
244+
model2->summarize(std::cout, ml_train_summary_type_e::ML_TRAIN_SUMMARY_MODEL);
187245
}
188246

189247
int main(int argc, char **argv) {

0 commit comments

Comments
 (0)