class_docstr: Run in session mode or Eager mode.
  
  This is a compatibility util between graph and eager TensorFlow.
  
  The graph runner allow to run function defining small TensorFlow graphs:
   * In eager mode: The function is simply run eagerly and the result is
     returned
   * In graph mode: The first time, the function is compiled in a new graph,
     then, every time the same function will be called, the cached graph and
     session will be run.
  
  Ideally, one graph runner should only be used with a single function to avoid
  having too many opened session in session mode.
  Limitations:
   * Currently the graph runner only support function with single input
     and output. Support for more complex function could be added and should be
     relatively straightforward.
   * A different graph is created for each input shape, so it isn't really
     adapted for dynamic batch size.
  
  Usage:
    graph_runner = TFGraphRunner()
    output = graph_runner.run(tf.sigmoid, np.ones(shape=(5,)))
class_docstr_tok: ["Run","in","session","mode","or","Eager","mode",".","This","is","a","compatibility","util","between","graph","and","eager","TensorFlow",".","The","graph","runner","allow","to","run","function","defining","small","TensorFlow","graphs",":","*","In","eager","mode",":","The","function","is","simply","run","eagerly","and","the","result","is","returned","*","In","graph","mode",":","The","first","time",",","the","function","is","compiled","in","a","new","graph",",","then",",","every","time","the","same","function","will","be","called",",","the","cached","graph","and","session","will","be","run",".","Ideally",",","one","graph","runner","should","only","be","used","with","a","single","function","to","avoid","having","too","many","opened","session","in","session","mode",".","Limitations",":","*","Currently","the","graph","runner","only","support","function","with","single","input","and","output",".","Support","for","more","complex","function","could","be","added","and","should","be","relatively","straightforward",".","*","A","different","graph","is","created","for","each","input","shape",",","so","it","is","n't","really","adapted","for","dynamic","batch","size",".","Usage",":","graph_runner","=","TFGraphRunner","(",")","output","=","graph_runner.run","(","tf.sigmoid",",","np.ones","(","shape=","(","5",",",")",")",")"]
docstr: Execute the given TensorFlow function.
docstr_tok: ["Execute","the","given","TensorFlow","function","."]
code: def run(self, fct, input_):
      """Execute the given TensorFlow function."""
      # TF 2.0
      if tf.executing_eagerly():
          return fct(input_).numpy()
      # TF 1.0
      else:
          # Should compile the function if this is the first time encountered
          if not isinstance(input_, np.ndarray):
              input_ = np.array(input_)
          run_args = RunArgs(fct=fct, input=input_)
          signature = self._build_signature(run_args)
          if signature not in self._graph_run_cache:
              graph_run = self._build_graph_run(run_args)
              self._graph_run_cache[signature] = graph_run
          else:
              graph_run = self._graph_run_cache[signature]
  
          # Then execute the cached graph
          return graph_run.session.run(
              graph_run.output,
              feed_dict={graph_run.placeholder: input_},
          )
  
imports: from __future__ import annotations
  import collections
  import contextlib
  from typing import Any, Union
  import numpy
  from tensorflow_datasets.core.utils import py_utils
  from tensorflow_datasets.core.utils import tree_utils
  from tensorflow_datasets.core.utils import type_utils
  from tensorflow_datasets.core.utils.lazy_imports_utils import tensorflow
label_desc: Use image node_id 4 for calling the TFGraphRunner obj's underlying member method code with example usage: obj.run(fct, input_) and returns: fct, graph_run