MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / FoldMergeNode

Method FoldMergeNode

tensorflow/core/grappler/optimizers/constant_folding.cc:1350–1439  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1348}
1349
1350Status ConstantFolding::FoldMergeNode(NodeDef* node, GraphDef* output_graph) {
1351 // Merge nodes are special, in the sense that they execute as soon as one of
1352 // their input is ready. We can therefore fold a merge node iff it has at
1353 // least one constant input without control dependency.
1354 // We still need to ensure that the nodes in the fanin of the merge node are
1355 // scheduled. We'll therefore add a control dependency from the merge node
1356 // to the folded constant. We end up with:
1357 // * the merge node and its inputs are preserved as is
1358 // * a new constant node C1, driven by the merge node through a control
1359 // dependency, initialized to the value of the folded input
1360 // * a new constant node C2, driven by the merge node through a control
1361 // dependency, initialized to the index of the folded input
1362 // * the fanout of the merge nodes is rewired to be driven by either C1 or
1363 // C2.
1364 for (int input_index = 0; input_index < node->input_size(); ++input_index) {
1365 const auto& input = node->input(input_index);
1366 if (IsControlInput(input)) {
1367 // Try the next input.
1368 continue;
1369 }
1370 NodeDef* input_node = node_map_->GetNode(input);
1371 if (!IsReallyConstant(*input_node)) {
1372 continue;
1373 }
1374 bool valid_input = true;
1375 for (const string& fanin_of_input : input_node->input()) {
1376 if (IsControlInput(fanin_of_input)) {
1377 valid_input = false;
1378 break;
1379 }
1380 }
1381 if (!valid_input) {
1382 // Try the next input
1383 continue;
1384 }
1385
1386 string const_out_name = OptimizedNodeName(*node, "_const");
1387 string const_index_name = OptimizedNodeName(*node, "_index");
1388 if (node_map_->GetNode(const_out_name) ||
1389 node_map_->GetNode(const_index_name)) {
1390 // Intended name already exists.
1391 return errors::AlreadyExists(
1392 strings::StrCat(const_out_name, " or ", const_index_name,
1393 " already present in the graph"));
1394 }
1395
1396 NodeDef* const_out = output_graph->add_node();
1397 *const_out = *input_node;
1398 const_out->set_name(const_out_name);
1399 const_out->set_device(node->device());
1400 *const_out->add_input() = AsControlDependency(*node);
1401 node_map_->AddNode(const_out->name(), const_out);
1402 node_map_->AddOutput(node->name(), const_out->name());
1403
1404 NodeDef* const_index = output_graph->add_node();
1405 const_index->set_op("Const");
1406 Tensor index(DT_INT32, TensorShape({}));
1407 index.flat<int32>()(0) = input_index;

Callers

nothing calls this directly

Calls 15

IsControlInputFunction · 0.85
IsReallyConstantFunction · 0.85
AsControlDependencyFunction · 0.85
ParseNodeNameFunction · 0.85
set_opMethod · 0.80
AsProtoTensorContentMethod · 0.80
GetOutputsMethod · 0.80
nameMethod · 0.65
StrCatFunction · 0.50
TensorShapeClass · 0.50
input_sizeMethod · 0.45
inputMethod · 0.45

Tested by

no test coverage detected