class_docstr: Type of the functions returned by theano.function or
  theano.FunctionMaker.create.
  
  `Function` is the callable object that does computation.  It has the storage
  of inputs and outputs, performs the packing and unpacking of inputs and
  return values. It implements the square-bracket indexing so that you can
  look up the value of a symbolic node.
  
  Functions are copyable via {{{fn.copy()}}} and {{{copy.copy(fn)}}}.
  When a function is copied, this instance is duplicated. Contrast with
  self.maker (instance of `FunctionMaker`) that is shared between copies.
  The meaning of copying a function is that the containers and their current
  values will all be duplicated. This requires that mutable inputs be
  copied, whereas immutable inputs may be shared between copies.
  
  A Function instance is hashable, on the basis of its memory
  address (its id).
  
  A Function instance is only equal to itself.
  
  A Function instance may be serialized using the `pickle` or
  `cPickle` modules.  This will save all default inputs, the graph,
  and WRITEME to the pickle file.
  
  A Function instance have a ``trust_input`` field that default to
  False. When True, we don't do extra check of the input to give
  better error message. In some case, python code will still return
  the good results if you pass a python or numpy scalar instead of a
  numpy tensor.  C code should raise an error if you pass an object
  of the wrong type.
  
  Attributes
  ----------
  finder
  inv_finder
class_docstr_tok: ["Type","of","the","functions","returned","by","theano.function","or","theano.FunctionMaker.create",".","`","Function","`","is","the","callable","object","that","does","computation",".","It","has","the","storage","of","inputs","and","outputs",",","performs","the","packing","and","unpacking","of","inputs","and","return","values",".","It","implements","the","square-bracket","indexing","so","that","you","can","look","up","the","value","of","a","symbolic","node",".","Functions","are","copyable","via","{","{","{","fn.copy","(",")","}","}","}","and","{","{","{","copy.copy","(","fn",")","}","}","}",".","When","a","function","is","copied",",","this","instance","is","duplicated",".","Contrast","with","self.maker","(","instance","of","`","FunctionMaker","`",")","that","is","shared","between","copies",".","The","meaning","of","copying","a","function","is","that","the","containers","and","their","current","values","will","all","be","duplicated",".","This","requires","that","mutable","inputs","be","copied",",","whereas","immutable","inputs","may","be","shared","between","copies",".","A","Function","instance","is","hashable",",","on","the","basis","of","its","memory","address","(","its","id",")",".","A","Function","instance","is","only","equal","to","itself",".","A","Function","instance","may","be","serialized","using","the","`","pickle","`","or","`","cPickle","`","modules",".","This","will","save","all","default","inputs",",","the","graph",",","and","WRITEME","to","the","pickle","file",".","A","Function","instance","have","a","``","trust_input","``","field","that","default","to","False",".","When","True",",","we","do","n't","do","extra","check","of","the","input","to","give","better","error","message",".","In","some","case",",","python","code","will","still","return","the","good","results","if","you","pass","a","python","or","numpy","scalar","instead","of","a","numpy","tensor",".","C","code","should","raise","an","error","if","you","pass","an","object","of","the","wrong","type",".","Attributes","--","--","--","--","--","finder","inv_finder"]
docstr: Evaluates value of a function on given arguments.
  
  Parameters
  ----------
  args : list
      List of inputs to the function. All inputs are required, even when
      some of them are not necessary to calculate requested subset of
      outputs.
  
  kwargs : dict
      The function inputs can be passed as keyword argument. For this, use
      the name of the input or the input instance as the key.
  
      Keyword argument ``output_subset`` is a list of either indices of the
      function's outputs or the keys belonging to the `output_keys` dict
      and represent outputs that are requested to be calculated. Regardless
      of the presence of ``output_subset``, the updates are always calculated
      and processed. To disable the updates, you should use the ``copy``
      method with ``delete_updates=True``.
  
  Returns
  -------
  list
      List of outputs on indices/keys from ``output_subset`` or all of them,
      if ``output_subset`` is not passed.
code: def __call__(self, *args, **kwargs):
      """
      Evaluates value of a function on given arguments.
  
      Parameters
      ----------
      args : list
          List of inputs to the function. All inputs are required, even when
          some of them are not necessary to calculate requested subset of
          outputs.
  
      kwargs : dict
          The function inputs can be passed as keyword argument. For this, use
          the name of the input or the input instance as the key.
  
          Keyword argument ``output_subset`` is a list of either indices of the
          function's outputs or the keys belonging to the `output_keys` dict
          and represent outputs that are requested to be calculated. Regardless
          of the presence of ``output_subset``, the updates are always calculated
          and processed. To disable the updates, you should use the ``copy``
          method with ``delete_updates=True``.
  
      Returns
      -------
      list
          List of outputs on indices/keys from ``output_subset`` or all of them,
          if ``output_subset`` is not passed.
      """
  
      def restore_defaults():
          for i, (required, refeed, value) in enumerate(self.defaults):
              if refeed:
                  if isinstance(value, gof.Container):
                      value = value.storage[0]
                  self[i] = value
  
      profile = self.profile
      t0 = time.time()
  
      output_subset = kwargs.pop("output_subset", None)
      if output_subset is not None and self.output_keys is not None:
          output_subset = [
              self.output_keys.index(key) for key in output_subset
          ]
  
      # Reinitialize each container's 'provided' counter
      if self.trust_input:
          i = 0
          for arg in args:
              s = self.input_storage[i]
              s.storage[0] = arg
              i += 1
      else:
          for c in self.input_storage:
              c.provided = 0
  
          if len(args) + len(kwargs) > len(self.input_storage):
              raise TypeError(
                  "Too many parameter passed to theano function"
              )
  
          # Set positional arguments
          i = 0
          for arg in args:
              # TODO: provide a Param option for skipping the filter if we
              #      really want speed.
              s = self.input_storage[i]
              # see this emails for a discuation about None as input
              # https://groups.google.com/group/theano-dev/browse_thread/thread/920a5e904e8a8525/4f1b311a28fc27e5
              if arg is None:
                  s.storage[0] = arg
              else:
                  try:
                      s.storage[0] = s.type.filter(
                          arg,
                          strict=s.strict,
                          allow_downcast=s.allow_downcast,
                      )
  
                  except Exception as e:
                      function_name = "theano function"
                      argument_name = "argument"
                      if self.name:
                          function_name += (
                              ' with name "' + self.name + '"'
                          )
                      if hasattr(arg, "name") and arg.name:
                          argument_name += (
                              ' with name "' + arg.name + '"'
                          )
                      where = (
                          theano.gof.utils.get_variable_trace_string(
                              self.maker.inputs[i].variable
                          )
                      )
                      if len(e.args) == 1:
                          e.args = (
                              "Bad input "
                              + argument_name
                              + " to "
                              + function_name
                              + " at index %d (0-based). %s"
                              % (i, where)
                              + e.args[0],
                          )
                      else:
                          e.args = (
                              "Bad input "
                              + argument_name
                              + " to "
                              + function_name
                              + " at index %d (0-based). %s"
                              % (i, where),
                          ) + e.args
                      restore_defaults()
                      raise
              s.provided += 1
              i += 1
  
      # Set keyword arguments
      if kwargs:  # for speed, skip the iteritems for empty kwargs
          for k, arg in iteritems(kwargs):
              self[k] = arg
  
      if (
          not self.trust_input
          and
          # The getattr is only needed for old pickle
          getattr(self, "_check_for_aliased_inputs", True)
      ):
          # Collect aliased inputs among the storage space
          args_share_memory = []
          for i in xrange(len(self.input_storage)):
              i_var = self.maker.inputs[i].variable
              i_val = self.input_storage[i].storage[0]
              if hasattr(i_var.type, "may_share_memory"):
                  is_aliased = False
                  for j in xrange(len(args_share_memory)):
                      group_j = izip(
                          [
                              self.maker.inputs[k].variable
                              for k in args_share_memory[j]
                          ],
                          [
                              self.input_storage[k].storage[0]
                              for k in args_share_memory[j]
                          ],
                      )
                      if any(
                          [
                              (
                                  var.type is i_var.type
                                  and var.type.may_share_memory(
                                      val, i_val
                                  )
                              )
                              for (var, val) in group_j
                          ]
                      ):
                          is_aliased = True
                          args_share_memory[j].append(i)
                          break
  
                  if not is_aliased:
                      args_share_memory.append([i])
  
          # Check for groups of more than one argument that share memory
          for group in args_share_memory:
              if len(group) > 1:
                  # copy all but the first
                  for j in group[1:]:
                      self.input_storage[j].storage[0] = copy.copy(
                          self.input_storage[j].storage[0]
                      )
  
      # Check if inputs are missing, or if inputs were set more than once, or
      # if we tried to provide inputs that are supposed to be implicit.
      if not self.trust_input:
          for c in self.input_storage:
              if c.required and not c.provided:
                  restore_defaults()
                  raise TypeError(
                      "Missing required input: %s"
                      % getattr(
                          self.inv_finder[c],
                          "variable",
                          self.inv_finder[c],
                      )
                  )
              if c.provided > 1:
                  restore_defaults()
                  raise TypeError(
                      "Multiple values for input: %s"
                      % getattr(
                          self.inv_finder[c],
                          "variable",
                          self.inv_finder[c],
                      )
                  )
              if c.implicit and c.provided > 0:
                  restore_defaults()
                  raise TypeError(
                      "Tried to provide value for implicit input: %s"
                      % getattr(
                          self.inv_finder[c],
                          "variable",
                          self.inv_finder[c],
                      )
                  )
  
      # Do the actual work
      t0_fn = time.time()
      try:
          outputs = (
              self.fn()
              if output_subset is None
              else self.fn(output_subset=output_subset)
          )
      except Exception:
          restore_defaults()
          if hasattr(self.fn, "position_of_error"):
              # this is a new vm-provided function or c linker
              # they need this because the exception manipulation
              # done by raise_with_op is not implemented in C.
              thunk = None
              if hasattr(self.fn, "thunks"):
                  thunk = self.fn.thunks[self.fn.position_of_error]
              gof.link.raise_with_op(
                  node=self.fn.nodes[self.fn.position_of_error],
                  thunk=thunk,
                  storage_map=getattr(self.fn, "storage_map", None),
              )
          else:
              # old-style linkers raise their own exceptions
              raise
  
      dt_fn = time.time() - t0_fn
      self.maker.mode.fn_time += dt_fn
      if profile:
          profile.vm_call_time += dt_fn
  
      # Retrieve the values that were computed
      if outputs is None:
          outputs = [x.data for x in self.output_storage]
      assert len(outputs) == len(self.output_storage)
  
      # Remove internal references to required inputs.
      # These cannot be re-used anyway.
      for c in self.input_storage:
          if c.required:
              c.storage[0] = None
  
      # if we are allowing garbage collection, remove the
      # output reference from the internal storage cells
      if getattr(self.fn, "allow_gc", False):
          assert len(self.output_storage) == len(
              self.maker.fgraph.outputs
          )
          for o_container, o_variable in zip(
              self.output_storage, self.maker.fgraph.outputs
          ):
              if o_variable.owner is not None:
                  # this node is the variable of computation
                  # WARNING: This circumvents the 'readonly' attribute in x
                  o_container.storage[0] = None
  
      if getattr(self.fn, "need_update_inputs", True):
          # Update the inputs that have an update function
          for input, storage in reversed(
              list(zip(self.maker.expanded_inputs, self.input_storage))
          ):
              if input.update is not None:
                  storage.data = outputs.pop()
      else:
          outputs = outputs[: self.n_returned_outputs]
  
      # Put default values back in the storage
      restore_defaults()
      #
      # NOTE: This logic needs to be replicated in
      #       scan.
      #       grep for 'PROFILE_CODE'
      #
  
      dt_call = time.time() - t0
      theano.compile.profiling.total_fct_exec_time += dt_call
      self.maker.mode.call_time += dt_call
      if profile:
          profile.fct_callcount += 1
          profile.fct_call_time += dt_call
          if hasattr(self.fn, "update_profile"):
              self.fn.update_profile(profile)
          if profile.ignore_first_call:
              profile.reset()
              profile.ignore_first_call = False
      if self.return_none:
          return None
      elif (
          self.unpack_single
          and len(outputs) == 1
          and output_subset is None
      ):
          return outputs[0]
      else:
          if self.output_keys is not None:
              assert len(self.output_keys) == len(outputs)
  
              if output_subset is None:
                  return dict(izip(self.output_keys, outputs))
              else:
                  return dict(
                      (self.output_keys[index], outputs[index])
                      for index in output_subset
                  )
  
          if output_subset is None:
              return outputs
          else:
              return [outputs[i] for i in output_subset]
  
imports: from __future__ import absolute_import, print_function, division
  import copy
  from six import string_types, iteritems, iterkeys
  from six.moves import xrange
  import six.moves.copyreg
  import six.moves.cPickle
  from itertools import chain
  import time
  import warnings
  import numpy
  import theano
  from theano import config, gof
  from theano.compat import izip
  from theano.gof import graph
  import theano.compile.profiling
  from theano.compile.io import In, SymbolicInput, SymbolicOutput
  from theano.compile.ops import deep_copy_op, view_op
  from theano.gof.graph import is_same_graph
  from theano.gof.op import ops_with_inner_function
  import logging
label_desc: Use image node_id 7 for calling the Function obj's underlying member method code with example usage: obj.__call__() and returns: None, outputs, outputs, unknown, dict, dict