| 585 | using tensorflow::string; |
| 586 | |
| 587 | TF_Function* TF_GraphToFunctionWithControlOutputs( |
| 588 | const TF_Graph* fn_body, const char* fn_name, |
| 589 | unsigned char append_hash_to_fn_name, int num_opers, |
| 590 | const TF_Operation* const* opers, int ninputs, const TF_Output* inputs, |
| 591 | int noutputs, const TF_Output* outputs, const char* const* output_names, |
| 592 | int ncontrol_outputs, const TF_Operation* const* control_outputs, |
| 593 | const char* const* control_output_names, const TF_FunctionOptions* opts, |
| 594 | const char* description, TF_Status* status) { |
| 595 | tensorflow::mutex_lock l(*const_cast<tensorflow::mutex*>(&fn_body->mu)); |
| 596 | |
| 597 | // Process inputs. |
| 598 | std::vector<tensorflow::OutputTensor> input_tensors; |
| 599 | std::unordered_map<const Node*, std::vector<int>> input_nodes; |
| 600 | status->status = tensorflow::ProcessInputs(fn_body, fn_name, ninputs, inputs, |
| 601 | &input_tensors, &input_nodes); |
| 602 | if (TF_GetCode(status) != TF_OK) return nullptr; |
| 603 | |
| 604 | // Process outputs. |
| 605 | std::vector<tensorflow::OutputTensor> output_tensors; |
| 606 | status->status = tensorflow::ProcessOutputs(fn_body, fn_name, noutputs, |
| 607 | outputs, &output_tensors); |
| 608 | if (TF_GetCode(status) != TF_OK) return nullptr; |
| 609 | |
| 610 | // Process output names. |
| 611 | std::vector<string> output_names_vec; |
| 612 | if (output_names) { |
| 613 | output_names_vec.reserve(noutputs); |
| 614 | for (int i = 0; i < noutputs; ++i) { |
| 615 | output_names_vec.push_back(string(output_names[i])); |
| 616 | } |
| 617 | } |
| 618 | |
| 619 | // Process control output names. |
| 620 | std::vector<string> control_output_names_vec; |
| 621 | if (control_output_names) { |
| 622 | control_output_names_vec.reserve(ncontrol_outputs); |
| 623 | for (int i = 0; i < ncontrol_outputs; ++i) { |
| 624 | control_output_names_vec.push_back(string(output_names[i])); |
| 625 | } |
| 626 | } |
| 627 | |
| 628 | // Compute body nodes. |
| 629 | std::vector<const Node*> body_nodes; |
| 630 | status->status = tensorflow::ComputeBodyNodes( |
| 631 | fn_body, fn_name, num_opers, opers, input_nodes, &body_nodes); |
| 632 | if (TF_GetCode(status) != TF_OK) return nullptr; |
| 633 | |
| 634 | // Compute body nodes. |
| 635 | std::vector<const Node*> control_output_nodes; |
| 636 | for (int i = 0; i < ncontrol_outputs; ++i) { |
| 637 | control_output_nodes.push_back(&control_outputs[i]->node); |
| 638 | } |
| 639 | |
| 640 | // Do the actual function creation. |
| 641 | TF_Function* tf_function = new TF_Function(); |
| 642 | DCHECK(append_hash_to_fn_name <= 1); |
| 643 | status->status = tensorflow::GraphToFunctionDef( |
| 644 | fn_body->graph, fn_name, append_hash_to_fn_name != 0, body_nodes, |
no test coverage detected