| 1385 | } |
| 1386 | |
| 1387 | const FunctionDef* FunctionLibraryDefinition::GetAttrImpl( |
| 1388 | const NodeDef& ndef) const { |
| 1389 | if (ndef.op() != kGradientOp) { |
| 1390 | // If 'ndef' calls a function and the function's def has the attr, |
| 1391 | // returns it. |
| 1392 | return Find(ndef.op()); |
| 1393 | } |
| 1394 | |
| 1395 | // If ndef is SymbolicGradient[f=Foo], we use Foo's gradient or |
| 1396 | // Foo's attributes. |
| 1397 | const NameAttrList* forward_func_attrs; |
| 1398 | if (!TryGetNodeAttr(ndef, kFuncAttr, &forward_func_attrs)) { |
| 1399 | return nullptr; |
| 1400 | } |
| 1401 | const string& func_name = forward_func_attrs->name(); |
| 1402 | { |
| 1403 | tf_shared_lock l(mu_); |
| 1404 | const string& grad_name = FindGradientHelper(func_name); |
| 1405 | // If 'func' has a user-defined gradient function, uses the grad |
| 1406 | // function's attrs to see if noinline is specified. Otherwise, |
| 1407 | // uses func's attrs. |
| 1408 | if (!grad_name.empty()) { |
| 1409 | return &(FindHelper(grad_name)->fdef); |
| 1410 | } |
| 1411 | return &(FindHelper(func_name)->fdef); |
| 1412 | } |
| 1413 | } |
| 1414 | |
| 1415 | std::vector<string> FunctionLibraryDefinition::ListFunctionNames() const { |
| 1416 | std::vector<string> function_names; |