| 2478 | } |
| 2479 | |
| 2480 | Status FunctionDefToBodyHelper( |
| 2481 | const FunctionDef& fdef, const AttrSlice& attrs, |
| 2482 | const FunctionLibraryDefinition* const lib_def, |
| 2483 | const std::function<Status(const string&, const OpDef**)>& get_func_sig, |
| 2484 | std::unique_ptr<FunctionBody>* fbody) { |
| 2485 | // Instantiates the function template into a graph def. |
| 2486 | InstantiationResult result; |
| 2487 | TF_RETURN_IF_ERROR(InstantiateFunction(fdef, attrs, get_func_sig, &result)); |
| 2488 | |
| 2489 | std::unique_ptr<Graph> graph(new Graph(lib_def)); |
| 2490 | GraphConstructorOptions opts; |
| 2491 | opts.allow_internal_ops = true; |
| 2492 | opts.expect_device_spec = false; |
| 2493 | TF_RETURN_IF_ERROR(ConvertNodeDefsToGraph(opts, result.nodes, graph.get())); |
| 2494 | |
| 2495 | // Call BuildControlFlowInfo to validate that this function body has |
| 2496 | // well-formed control flow. |
| 2497 | std::vector<ControlFlowInfo> dummy; |
| 2498 | TF_RETURN_IF_ERROR(BuildControlFlowInfo(graph.get(), &dummy)); |
| 2499 | |
| 2500 | *fbody = absl::make_unique<FunctionBody>(fdef, result.arg_types, |
| 2501 | result.ret_types, graph.release()); |
| 2502 | return Status::OK(); |
| 2503 | } |
| 2504 | |
| 2505 | Status FunctionDefToBodyHelper(const FunctionDef& fdef, const AttrSlice& attrs, |
| 2506 | const FunctionLibraryDefinition* lib_def, |