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

Function ReachableFunctions

tensorflow/core/framework/function.cc:1468–1557  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1466constexpr char kApiImplements[] = "api_implements";
1467
1468std::set<string> ReachableFunctions(
1469 const FunctionLibraryDefinition& flib,
1470 const protobuf::RepeatedPtrField<NodeDef>& nodes) {
1471 // Functions that are reachable from the graph.
1472 std::set<string> reachable_funcs;
1473
1474 // For any functions, if it has attribute "api_implements" =
1475 // "some_interface" and it is reachable, then it means any other
1476 // function with same attribute name and value could also be potentially
1477 // reachable, eg via implementation_selector swapping the nodedef.
1478 absl::flat_hash_set<string> reachable_api_interface;
1479
1480 // Functions might be reachable from the nested function calls, so we keep a
1481 // queue of functions that we have to check.
1482 gtl::InlinedVector<const FunctionDef*, 4> func_queue;
1483
1484 // Add reachable and not already processed functions to the functions queue.
1485 const auto add_to_func_queue = [&](const string& func_name) {
1486 const FunctionDef* func = flib.Find(func_name);
1487 if (func && reachable_funcs.find(func_name) == reachable_funcs.end()) {
1488 func_queue.push_back(func);
1489 }
1490 };
1491
1492 // If any function with certain API name is reachable, all the other functions
1493 // with same API name should also be checked.
1494 const auto add_function_with_api_interface = [&](const string& api_name) {
1495 if (!reachable_api_interface.contains(api_name)) {
1496 reachable_api_interface.insert(api_name);
1497 for (const auto& func_name : flib.ListFunctionNames()) {
1498 const auto& func_def = flib.Find(func_name);
1499 const auto attr_it = func_def->attr().find(kApiImplements);
1500 if (attr_it != func_def->attr().end() &&
1501 attr_it->second.s() == api_name) {
1502 add_to_func_queue(func_name);
1503 }
1504 }
1505 }
1506 };
1507
1508 // Add all the functions that are reachable from the given node to the queue.
1509 const auto process_node = [&](const NodeDef& node) {
1510 // Node itself can be a call to the function.
1511 add_to_func_queue(node.op());
1512
1513 // Or node can have an attribute referencing a function.
1514 for (const auto& attr : node.attr()) {
1515 const auto& attr_value = attr.second;
1516
1517 // 1. AttrValue.func
1518 if (attr_value.has_func()) {
1519 add_to_func_queue(attr_value.func().name());
1520 }
1521
1522 // 2. AttrValue.ListValue.func
1523 if (attr_value.has_list()) {
1524 for (const auto& func : attr_value.list().func()) {
1525 add_to_func_queue(func.name());

Callers 1

Calls 15

containsMethod · 0.80
ListFunctionNamesMethod · 0.80
attrMethod · 0.80
listMethod · 0.80
pop_backMethod · 0.80
signatureMethod · 0.80
FindGradientMethod · 0.80
nameMethod · 0.65
FindMethod · 0.45
findMethod · 0.45
endMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected