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

Method FunctionalizeInternal

tensorflow/compiler/tf2xla/functionalize_cond.cc:1421–1521  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1419}
1420
1421Status FunctionalizeCond::FunctionalizeInternal() {
1422 // The general approach for converting a tf.cond (as lowered via switch/merge
1423 // nodes) to a functional if is as follows:
1424 // 1. Determine the topological order and collect all the switch and merge
1425 // nodes in the graph;
1426 // 2. Compute the predicates and dominance structure for all the nodes in the
1427 // graph - this includes which predicate must be true for a op to execute
1428 // (predicate values are considered directly rather than attempting to
1429 // determine deeper equivalence). We shall refer to this structure as the
1430 // CondState;
1431 // 3. Sort the merge nodes by nesting depth;
1432 // 4. Extract merge nodes together that have the same CondState and
1433 // AncestorState from the innermost to the outermost into IfOps;
1434 // Note: In the above only nodes that feed into a merge node will be
1435 // considered for functionalization.
1436
1437 // Perform a DFS over the graph and
1438 // * Determine the reverse topological order of the nodes (there should be no
1439 // cycles at this point so the post-order numbering corresponds to the
1440 // reverse topological sorting);
1441 // * Record reverse topological for merge and switch nodes;
1442 std::vector<Node*> rev_topo_order;
1443 std::vector<Node*> merge_order;
1444 DFS(*graph_, nullptr, [&](Node* n) {
1445 if (IsSwitch(n)) {
1446 AddSwitchId(n->id());
1447 }
1448 if (IsMerge(n)) {
1449 merge_order.push_back(n);
1450 }
1451 if (n->IsOp()) {
1452 rev_topo_order.push_back(n);
1453 }
1454 });
1455
1456 // No merges to functionalize.
1457 if (merge_order.empty()) {
1458 // No merges mean no switch values consumed (as only considering values
1459 // fetchable as output of merge);
1460 DeleteReachableAndDeadNodes(merge_order);
1461 return Status::OK();
1462 }
1463
1464 TF_RETURN_IF_ERROR(DetermineStates(std::move(rev_topo_order)));
1465 if (VLOG_IS_ON(4)) DumpGraphWithCondState("id");
1466
1467 // Sort the merge nodes from innermost outwards.
1468 SortMergeNodes(&merge_order);
1469
1470 // Cluster merge nodes by (CondId, AncestorId, predicate) in order of
1471 // nesting. (CondId, AncestorId) is not enough, e.g.
1472 // pred1 = array_ops.placeholder(dtypes.bool, name='pred1')
1473 // pred2 = array_ops.placeholder(dtypes.bool, name='pred2')
1474 // cond1 = control_flow_ops.cond(pred1, ...)
1475 // cond2 = control_flow_ops.cond(pred2, ...)
1476 // cond3 = control_flow_ops.cond(pred1, use cond1 and cond2)
1477 // cond4 = control_flow_ops.cond(pred2, use cond1 and cond2)
1478 // cond3 and cond4 have the same (CondId, AncestorId), but they should not

Callers 1

FunctionalizeMethod · 0.80

Calls 15

DFSFunction · 0.85
InternalFunction · 0.85
IsOpMethod · 0.80
LookupCondIdMethod · 0.80
IsDeadMethod · 0.80
LookupAncestorIdMethod · 0.80
AddMergeMethod · 0.80
BuildAndReplaceMethod · 0.80
nameMethod · 0.65
IsSwitchFunction · 0.50
IsMergeFunction · 0.50
idMethod · 0.45

Tested by

no test coverage detected