class_docstr: Caches a weak chain of transformations for all bijector instances.
  
  On a cache miss, the other side of the transformation is produced
  and both sides are cached before returning a result. The input object
  is cached with a strong reference, while the transformed output is
  held weakly. When there are no more references to the result, both
  directions of the mapping are cleared simultaneously.
  
  The general contracts are:
    1) The inputs used on cache misses will always be retained
       until their corresponding outputs are abandoned.
    2) `forward` will return a cached result if and only if
       `inverse` would have returned a cached result.
  
  Retaining results in such a manner guarantees that there will be no
  circular references, allowing the garbage collector to remove "dead"
  links from the cache.
  
  Example usage:
  
  ```py
  bij = MyBijector()
  cache = BijectorCache(bijector=bij)
  
  x = tf.constant(1.)
  ref = weakref.ref(x)
  
  for i in range(10):
    assert (len(cache.weak_keys(direction='forward'))
            == len(cache.weak_keys(direction='inverse'))
            == i)
    x = cache.forward(x)
  
  for i in range(10):
    assert len(cache.weak_keys(direction='inverse')) == 10 - i
    x = cache.inverse(x)
    assert len(cache.weak_keys(direction='forward')) == 10 - i
  
  assert len(cache.weak_keys(direction='inverse')) == 0
  assert ref() == x
  
  x = None
  assert len(cache.weak_keys(direction='forward')) == 0
  ```
class_docstr_tok: ["Caches","a","weak","chain","of","transformations","for","all","bijector","instances",".","On","a","cache","miss",",","the","other","side","of","the","transformation","is","produced","and","both","sides","are","cached","before","returning","a","result",".","The","input","object","is","cached","with","a","strong","reference",",","while","the","transformed","output","is","held","weakly",".","When","there","are","no","more","references","to","the","result",",","both","directions","of","the","mapping","are","cleared","simultaneously",".","The","general","contracts","are",":","1",")","The","inputs","used","on","cache","misses","will","always","be","retained","until","their","corresponding","outputs","are","abandoned",".","2",")","`","forward","`","will","return","a","cached","result","if","and","only","if","`","inverse","`","would","have","returned","a","cached","result",".","Retaining","results","in","such","a","manner","guarantees","that","there","will","be","no","circular","references",",","allowing","the","garbage","collector","to","remove","``","dead","''","links","from","the","cache",".","Example","usage",":","``","`","py","bij","=","MyBijector","(",")","cache","=","BijectorCache","(","bijector=bij",")","x","=","tf.constant","(","1",".",")","ref","=","weakref.ref","(","x",")","for","i","in","range","(","10",")",":","assert","(","len","(","cache.weak_keys","(","direction='forward","'",")",")","==","len","(","cache.weak_keys","(","direction='inverse","'",")",")","==","i",")","x","=","cache.forward","(","x",")","for","i","in","range","(","10",")",":","assert","len","(","cache.weak_keys","(","direction='inverse","'",")",")","==","10","-","i","x","=","cache.inverse","(","x",")","assert","len","(","cache.weak_keys","(","direction='forward","'",")",")","==","10","-","i","assert","len","(","cache.weak_keys","(","direction='inverse","'",")",")","==","0","assert","ref","(",")","==","x","x","=","None","assert","len","(","cache.weak_keys","(","direction='forward","'",")",")","==","0","``","`"]
docstr: Retrieves or computes `out` and `attrs` for the argument.
  
  When called, this method checks the input->output cache for previously
  computed values. On cache miss, it invokes the forward function and
  inserts references from input->output and output->input in the corresponding
  caches.
  
  The reference to the output is weak, such that both sides of the cache will
  be cleared symmetrically if the output is GCed. In contract, the reference
  to the argument is strong: it can be recovered as long as a reference to the
  output is held.
  
  Examples:
  
  ```python
  cache = BijectorCache()
  x = tf.random.normal()
  y, attrs = cache._lookup(x, '_forward', '_inverse')
  attrs['foo'] = 'bar'
  
  assert cache.inverse._lookup(y, '_inverse', '_forward') == (x, attrs)
  ```
  
  Args:
    input: The singular ordered argument passed to the wrapped function.
    forward_name: `str`, the name of the function implementing the bijector's
      forward transformation (typically `'_forward'`).
    inverse_name: `str`, the name of the function implementing the bijector's
      inverse transformation (typically `'_inverse'`).
    **kwargs: Additional arguments associated with the transformation.
      These arguments are interpreted as inputs to both `x->y` and `y->x`.
  Returns:
    A tuple containing `output`, and a dictionary of `attributes`.
    Like `kwargs`, attributes are associated with both the `x->y` and `y->x`
    transformations. Unlike kwargs, they do not affect the behavior of
    either function. It's left to the user to add things to attributes.
docstr_tok: ["Retrieves","or","computes","`","out","`","and","`","attrs","`","for","the","argument",".","When","called",",","this","method","checks","the","input-",">","output","cache","for","previously","computed","values",".","On","cache","miss",",","it","invokes","the","forward","function","and","inserts","references","from","input-",">","output","and","output-",">","input","in","the","corresponding","caches",".","The","reference","to","the","output","is","weak",",","such","that","both","sides","of","the","cache","will","be","cleared","symmetrically","if","the","output","is","GCed",".","In","contract",",","the","reference","to","the","argument","is","strong",":","it","can","be","recovered","as","long","as","a","reference","to","the","output","is","held",".","Examples",":","``","`","python","cache","=","BijectorCache","(",")","x","=","tf.random.normal","(",")","y",",","attrs","=","cache._lookup","(","x",",","'_forward","'",",","'_inverse","'",")","attrs","[","'foo","'","]","=","'bar'","assert","cache.inverse._lookup","(","y",",","'_inverse","'",",","'_forward","'",")","==","(","x",",","attrs",")","``","`","Args",":","input",":","The","singular","ordered","argument","passed","to","the","wrapped","function",".","forward_name",":","`","str","`",",","the","name","of","the","function","implementing","the","bijector's","forward","transformation","(","typically","`","'_forward","'","`",")",".","inverse_name",":","`","str","`",",","the","name","of","the","function","implementing","the","bijector's","inverse","transformation","(","typically","`","'_inverse","'","`",")",".","*","*","kwargs",":","Additional","arguments","associated","with","the","transformation",".","These","arguments","are","interpreted","as","inputs","to","both","`","x-",">","y","`","and","`","y-",">","x","`",".","Returns",":","A","tuple","containing","`","output","`",",","and","a","dictionary","of","`","attributes","`",".","Like","`","kwargs","`",",","attributes","are","associated","with","both","the","`","x-",">","y","`","and","`","y-",">","x","`","transformations",".","Unlike","kwargs",",","they","do","not","affect","the","behavior","of","either","function",".","It","'s","left","to","the","user","to","add","things","to","attributes","."]
code: def _lookup(self, input, forward_name, inverse_name, **kwargs):
      """Retrieves or computes `out` and `attrs` for the argument.
  
      When called, this method checks the input->output cache for previously
      computed values. On cache miss, it invokes the forward function and
      inserts references from input->output and output->input in the corresponding
      caches.
  
      The reference to the output is weak, such that both sides of the cache will
      be cleared symmetrically if the output is GCed. In contract, the reference
      to the argument is strong: it can be recovered as long as a reference to the
      output is held.
  
      Examples:
  
      ```python
      cache = BijectorCache()
      x = tf.random.normal()
      y, attrs = cache._lookup(x, '_forward', '_inverse')
      attrs['foo'] = 'bar'
  
      assert cache.inverse._lookup(y, '_inverse', '_forward') == (x, attrs)
      ```
  
      Args:
        input: The singular ordered argument passed to the wrapped function.
        forward_name: `str`, the name of the function implementing the bijector's
          forward transformation (typically `'_forward'`).
        inverse_name: `str`, the name of the function implementing the bijector's
          inverse transformation (typically `'_inverse'`).
        **kwargs: Additional arguments associated with the transformation.
          These arguments are interpreted as inputs to both `x->y` and `y->x`.
      Returns:
        A tuple containing `output`, and a dictionary of `attributes`.
        Like `kwargs`, attributes are associated with both the `x->y` and `y->x`
        transformations. Unlike kwargs, they do not affect the behavior of
        either function. It's left to the user to add things to attributes.
      """
      if input is None:
          raise ValueError("Input must not be None.")
      input_ref, output_ref, attrs, _ = self._get_or_create_edge(
          input, forward_name, kwargs
      )
      if output_ref:
          output = output_ref()
      else:
          # Get the output structure, and declare a
          # weakref to clear it from the cache once it gets GCed
          output = nest.map_structure(
              _containerize,
              self._invoke(input, forward_name, kwargs, attrs),
          )
          output_ref = WeakStructRef(
              output,
              subkey=(
                  self.bijector,
                  self.bijector_class,
                  inverse_name,
                  kwargs,
              ),
              callback=self.storage.maybe_del,
          )
          # Set the input->output mapping.
          self.storage[input_ref] = _DirectedFunctionInvocation(
              input_ref, output_ref, attributes=attrs, dependencies=None
          )
          # As long as outputs are around keep strong references to inputs,
          # allowing us to recover the argument on request.
          to_retain = tuple(
              x() for x in input_ref.ref_set - output_ref.ref_set
          )
          self.storage[output_ref] = _DirectedFunctionInvocation(
              output_ref,
              input_ref,
              attributes=attrs,
              dependencies=to_retain,
          )
      return output
  
imports: import collections
  import weakref
  import numpy
  import tensorflow.compat.v2
  from tensorflow.python.util import nest
label_desc: Use image node_id 12 for calling the BijectorCache obj's underlying member method code with example usage: obj._lookup(input, forward_name, inverse_name) and returns: output