code: def tf_function(
      *,
      num_args,
      optional=0,
      api_function=False,
      overwrites_signature=False,
      is_loop_body=False,
      dict_interface=False,
  ):
      def decorator(function):
          def decorated(self, *args, _initialize=False, **kwargs):
              assert api_function or not _initialize
              assert len(args) == 0 or len(kwargs) == 0
              assert len(args) == 0 or len(args) == num_args
  
              # Function name and qualname
              name = function.__name__
              qualname = function.__qualname__
  
              # Parameters-to-graph mapping
              if not hasattr(self, "_{name}_graphs".format(name=name)):
                  setattr(
                      self, "_{name}_graphs".format(name=name), dict()
                  )
                  assert function.__qualname__.endswith("." + name)
                  setattr(
                      self,
                      "_{name}_qualname".format(name=name),
                      function.__qualname__,
                  )
              function_graphs = getattr(
                  self, "_{name}_graphs".format(name=name)
              )
              qualname = getattr(
                  self, "_{name}_qualname".format(name=name)
              )
  
              # Handle overwriting signature
              if overwrites_signature:
                  setattr(
                      self,
                      "_{name}_overwritten".format(name=name),
                      overwrites_signature,
                  )
              overwritten = getattr(
                  self, "_{name}_overwritten".format(name=name), False
              )
  
              # Graph signature
              input_signature = self.input_signature(function=name)
              output_signature = self.output_signature(function=name)
  
              # Apply raw function if qualname mismatch, which indicates super() call
              if function.__qualname__ != qualname:
                  assert not _initialize
                  if not overwritten:
                      assert (
                          num_args - optional
                          <= input_signature.num_args()
                          <= num_args
                      )
                  return function(self, *args, **kwargs)
  
              # Check number of arguments
              assert (
                  num_args - optional
                  <= input_signature.num_args()
                  <= num_args
              )
  
              # Graph parameters
              params_kwargs = {
                  key: arg
                  for key, arg in kwargs.items()
                  if key not in input_signature
              }
              graph_params = tuple(
                  make_key(x=arg) for arg in params_kwargs.values()
              )
  
              # Check whether output_signature is parametrized
              if not isinstance(output_signature, SignatureDict):
                  output_signature = output_signature(**params_kwargs)
  
              # Function graph
              if str(graph_params) not in function_graphs:
                  assert not api_function or _initialize
  
                  def function_graph(*args):
                      with self:
                          # TODO: tf.name_scope instead?
                          kwargs = input_signature.args_to_kwargs(
                              args=args, from_dict=dict_interface
                          )
                          args = function(
                              self,
                              **kwargs.to_kwargs(),
                              **params_kwargs,
                          )
                          args = output_signature.kwargs_to_args(
                              kwargs=args, to_dict=dict_interface
                          )
                      return args
  
                  function_graph.__name__ = name
                  function_graph.__qualname__ = qualname
  
                  function_graphs[str(graph_params)] = tf.function(
                      func=function_graph,
                      input_signature=input_signature.to_list(
                          to_dict=dict_interface
                      ),
                      autograph=False
                      # experimental_implements=None, experimental_autograph_options=None,
                      # experimental_relax_shapes=False, experimental_compile=None
                  )
  
              # Do not call function if initialization
              if _initialize:
                  return
  
              # Graph arguments
              if len(kwargs) > 0:
                  graph_args = input_signature.kwargs_to_args(
                      kwargs=kwargs,
                      to_dict=dict_interface,
                      outer_tuple=True,
                  )
              else:
                  graph_args = args
  
              # Apply function graph
              with self:
                  output_args = function_graphs[str(graph_params)](
                      *graph_args
                  )
              if not is_loop_body:
                  return output_signature.args_to_kwargs(
                      args=output_args,
                      outer_tuple=True,
                      from_dict=dict_interface,
                  )
              else:
                  return output_args
  
          return decorated
  
      return decorator
  
imports: import functools
  import json
  import os
  import re
  import numpy
  import tensorflow
  from tensorforce import TensorforceError, util
  import tensorforce.core
  from tensorforce.core import SignatureDict, TensorSpec, tf_util, VariableDict
label_desc: Use image node_id 2 for calling a global function with example usage: tf_function() and returns: decorator, decorated, function, output_signature, output_args, args