code: def from_func_graph(
      name: Union[str, bytes],
      graph: func_graph_module.FuncGraph,
      attrs: Dict[str, attr_value_pb2.AttrValue],
      function_type: Optional[function_type_lib.FunctionType] = None,
      overwrite: bool = False,
  ) -> AtomicFunction:
      """Initializes an AtomicFunction from FuncGraph.
  
      Args:
        name: str, the name for the created function.
        graph: Graph, the graph containing the operations in the function
        attrs: dict mapping names of attributes to their AttrValue values
        function_type: known FunctionType to use, otherwise one is derived.
        overwrite: overwrites function definition in the current context if needed
  
      Returns:
        An AtomicFunction instance.
      """
      if attrs and attributes_lib.IMPLEMENTS in attrs:
          # The alternative is to silently drop "implements" tag
          # but it seems likely it would lead to hard to catch bugs.
          # Another alternative is to make func_body to preserve the order
          # of arguments if variables are present. Yet another option
          # is to automatically replace variables as arguments to functions
          # to v.read_value() whenever "implements" tag is present
          # Anytime we annotate existing function we probably want to wrap
          # it with safe read_value for backward compatibility.
          has_resource_vars = any(
              inp.dtype == dtypes.resource for inp in graph.inputs
          )
  
          captured_inputs = (
              graph.external_captures + graph.deferred_external_captures
          )
          assert not any((has_resource_vars, captured_inputs)), (
              'Function {name} has "{attr}={value}" attribute and thus can not '
              "depend on any tensors outside of its signature or modify variables. "
              "\n\nNote: variables are always captured and cause function "
              "re-tracing for every variable called.\n"
              "  inputs: {inputs}\n  captures: {captured}\n\n"
              "To pass a variable to such function use  "
              "use variable.read_value().".format(
                  name=graph.name,
                  attr=attributes_lib.IMPLEMENTS,
                  value=attrs[attributes_lib.IMPLEMENTS],
                  inputs=graph.inputs,
                  captured=captured_inputs,
              )
          )
  
      input_ops = set(arg.op for arg in graph.inputs)
      operations = [
          op for op in graph.get_operations() if op not in input_ops
      ]
  
      graph_output_names = (
          graph._output_names
      )  # pylint: disable=protected-access
      if graph_output_names is not None and all(
          ops.tensor_id(t) in graph_output_names for t in graph.outputs
      ):
          output_names = [
              compat.as_bytes(graph_output_names[ops.tensor_id(t)])
              for t in graph.outputs
          ]
          if len(set(output_names)) != len(output_names):
              # There are duplicate names for some reason, probably an invalid
              # signature. Revert to auto-naming.
              output_names = []
      else:
          output_names = []
      with graph._c_graph.get() as c_graph:  # pylint: disable=protected-access
          fn = pywrap_tf_session.TF_GraphToFunction_wrapper(
              c_graph,
              compat.as_str(name),
              False,
              [
                  o._c_op for o in operations
              ],  # pylint: disable=protected-access
              [
                  t._as_tf_output() for t in graph.inputs
              ],  # pylint: disable=protected-access
              [
                  t._as_tf_output() for t in graph.outputs
              ],  # pylint: disable=protected-access
              output_names,
              [
                  o._c_op for o in graph.control_outputs
              ],  # pylint: disable=protected-access
              [],  # control_output_names
              None,
              compat.as_str(""),
          )
  
      attrs = attributes_lib.parse_func_attrs(attrs or {})
      for attr_name, attr_value in attrs.items():
          serialized = attr_value.SerializeToString()
          pywrap_tf_session.TF_FunctionSetAttrValueProto(
              fn, compat.as_str(attr_name), serialized
          )
  
      name = compat.as_bytes(name)
      bound_context = context.context()
  
      if overwrite and bound_context.has_function(name):
          bound_context.remove_function(name)
  
      bound_context.add_c_function(fn)
      pywrap_tf_session.TF_DeleteFunction(fn)
  
      call_options = CallOptions(
          collective_manager_ids_used=getattr(
              graph, "collective_manager_ids_used", []
          ),
          control_captures=graph.function_captures.control,
          is_stateful=any(
              op._is_stateful for op in operations
          ),  # pylint: disable=protected-access
      )
  
      if not function_type:
          function_type = function_type_utils.derive_from_graph(graph)
  
      return AtomicFunction(
          name,
          bound_context,
          function_type,
          list(
              graph._functions.values()
          ),  # pylint: disable=protected-access,
          call_options,
          cached_graph=graph,
      )
  
imports: import dataclasses
  import traceback
  import typing
  from typing import Any, Dict, List, Optional, Sequence, Union
  from tensorflow.core.framework import attr_value_pb2
  from tensorflow.core.framework import function_pb2
  from tensorflow.core.framework import graph_debug_info_pb2
  from tensorflow.core.function.polymorphism import function_type
  from tensorflow.python.client import pywrap_tf_session
  from tensorflow.python.eager import context
  from tensorflow.python.eager import record
  from tensorflow.python.eager.polymorphic_function import attributes
  from tensorflow.python.eager.polymorphic_function import function_type_utils
  from tensorflow.python.framework import auto_control_deps_utils
  from tensorflow.python.framework import dtypes
  from tensorflow.python.framework import error_interpolation
  from tensorflow.python.framework import errors
  from tensorflow.python.framework import func_graph
  from tensorflow.python.framework import function_def_to_graph
  from tensorflow.python.framework import ops
  from tensorflow.python.ops import handle_data_util
  from tensorflow.python.types import core
  from tensorflow.python.util import compat
  from tensorflow.python.util import function_utils
  from tensorflow.python.util import tf_stack
label_desc: Use image node_id 5 for calling a global function with example usage: from_func_graph(name, graph, attrs, function_type, overwrite) and returns: AtomicFunction