static */
| 1728 | |
| 1729 | /* static */ |
| 1730 | FunctionDef FunctionDefHelper::Define(const string& name, |
| 1731 | gtl::ArraySlice<string> arg_def, |
| 1732 | gtl::ArraySlice<string> ret_def, |
| 1733 | gtl::ArraySlice<string> attr_def, |
| 1734 | gtl::ArraySlice<Node> node_def) { |
| 1735 | FunctionDef fdef; |
| 1736 | OpDefBuilder b(name); |
| 1737 | for (const auto& a : arg_def) b.Input(a); |
| 1738 | for (const auto& r : ret_def) b.Output(r); |
| 1739 | for (const auto& a : attr_def) b.Attr(a); |
| 1740 | |
| 1741 | OpRegistrationData op_reg_data; |
| 1742 | TF_CHECK_OK(b.Finalize(&op_reg_data)); |
| 1743 | fdef.mutable_signature()->Swap(&op_reg_data.op_def); |
| 1744 | |
| 1745 | // Mapping from legacy output names to NodeDef outputs. |
| 1746 | std::unordered_map<string, string> ret_index; |
| 1747 | for (const auto& a : fdef.signature().input_arg()) { |
| 1748 | ret_index[a.name()] = a.name(); |
| 1749 | } |
| 1750 | |
| 1751 | // For looking up OpDefs |
| 1752 | auto* op_def_registry = OpRegistry::Global(); |
| 1753 | |
| 1754 | // Function body |
| 1755 | for (const auto& src : node_def) { |
| 1756 | NodeDef* n = fdef.add_node_def(); |
| 1757 | n->set_op(src.op); |
| 1758 | n->set_name(src.ret[0]); |
| 1759 | for (const auto& a : src.attr) { |
| 1760 | n->mutable_attr()->insert({a.first, a.second.proto}); |
| 1761 | } |
| 1762 | for (const string& a : src.arg) { |
| 1763 | const auto iter = ret_index.find(a); |
| 1764 | CHECK(iter != ret_index.end()) |
| 1765 | << "Node input '" << a << "' in '" << src.ret[0] << "' of " << name; |
| 1766 | n->add_input(iter->second); |
| 1767 | } |
| 1768 | for (const string& d : src.dep) { |
| 1769 | n->add_input(strings::StrCat("^", d)); |
| 1770 | } |
| 1771 | |
| 1772 | // Add the outputs of this node to ret_index. |
| 1773 | const OpDef* op_def = nullptr; |
| 1774 | TF_CHECK_OK(op_def_registry->LookUpOpDef(n->op(), &op_def)) << n->op(); |
| 1775 | CHECK(op_def != nullptr) << n->op(); |
| 1776 | NameRangeMap output_names; |
| 1777 | TF_CHECK_OK(NameRangesForNode(*n, *op_def, nullptr, &output_names)); |
| 1778 | for (const auto& o : output_names) { |
| 1779 | CHECK_LE(o.second.second, src.ret.size()) |
| 1780 | << "Missing ret for output '" << o.first << "' in '" << src.ret[0] |
| 1781 | << "' of " << name; |
| 1782 | for (int i = o.second.first; i < o.second.second; ++i) { |
| 1783 | ret_index[src.ret[i]] = |
| 1784 | strings::StrCat(src.ret[0], ":", o.first, ":", i - o.second.first); |
| 1785 | } |
| 1786 | } |
| 1787 | if (op_def->is_stateful()) fdef.mutable_signature()->set_is_stateful(true); |
nothing calls this directly
no test coverage detected