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: Looks up user-defined attributes associated with this argument.
  
  Attributes are dictionaries that store arbitrary information about the
  transformation; for example, its log Jacobian determinant. Each cache lookup
  will also return the corresponding `attributes` dictionary, which the user
  may populate however they want. Attributes are "bidirectional", such that
  `cache.forward_attributes(x)` will return the same dictionary instance as
  `cache.inverse_attributes(cache.forward(x))`.
  
  This method is "lazy", in the sense that it doesn't invoke the wrapped
  transformation. Whether `attributes` or `__call__` are invoked first does
  not affect behavior.
  
  Examples:
  
  ```python
  ## Basic Usage
  bijector = tfb.Exp()
  cache = BijectorCache(bijector=bijector)
  x = tf.random.normal()
  
  # Compute some attribute for x, and add it to the cache.
  ildj = -bijector.forward_log_det_jacobian(x)
  cache.forward_attributes(x)['ildj'] = ildj
  
  # Apply the forward transformation, and lookup the attribute by `y`.
  y = cache.forward(x)
  assert ildj is cache.inverse_attributes(y)['ildj']
  
  ## Garbage Collection
  # Attributes remain cached until refs to both `x` and `y` are collected.
  x = None
  assert ildj is cache.inverse_attributes(y)['ildj']
  
  x, y = cache.inverse(y), None
  assert ildj is cache.forward_attributes(x)['ildj']
  
  # When both refs are collected, attributes are cleared.
  x = y = None
  assert (len(cache.weak_keys(direction='forward'))
          == len(cache.weak_keys(direction='inverse'))
          == 0)
  ```
  
  Args:
    input: The singular ordered argument passed to the wrapped function.
    fn_name: `str`, name of the directed function to which `input` is an arg
      (typically `'_forward'` or `'_inverse'`).
    **kwargs: Any auxiliary arguments passed to the function.
      These reflect shared context to the function, and are associated
      with both the input and output cache-keys.
  Returns:
    The dictionary of attributes associated with the transformation.
docstr_tok: ["Looks","up","user-defined","attributes","associated","with","this","argument",".","Attributes","are","dictionaries","that","store","arbitrary","information","about","the","transformation",";","for","example",",","its","log","Jacobian","determinant",".","Each","cache","lookup","will","also","return","the","corresponding","`","attributes","`","dictionary",",","which","the","user","may","populate","however","they","want",".","Attributes","are","``","bidirectional","''",",","such","that","`","cache.forward_attributes","(","x",")","`","will","return","the","same","dictionary","instance","as","`","cache.inverse_attributes","(","cache.forward","(","x",")",")","`",".","This","method","is","``","lazy","''",",","in","the","sense","that","it","does","n't","invoke","the","wrapped","transformation",".","Whether","`","attributes","`","or","`","__call__","`","are","invoked","first","does","not","affect","behavior",".","Examples",":","``","`","python","#","#","Basic","Usage","bijector","=","tfb.Exp","(",")","cache","=","BijectorCache","(","bijector=bijector",")","x","=","tf.random.normal","(",")","#","Compute","some","attribute","for","x",",","and","add","it","to","the","cache",".","ildj","=","-bijector.forward_log_det_jacobian","(","x",")","cache.forward_attributes","(","x",")","[","'ildj","'","]","=","ildj","#","Apply","the","forward","transformation",",","and","lookup","the","attribute","by","`","y","`",".","y","=","cache.forward","(","x",")","assert","ildj","is","cache.inverse_attributes","(","y",")","[","'ildj","'","]","#","#","Garbage","Collection","#","Attributes","remain","cached","until","refs","to","both","`","x","`","and","`","y","`","are","collected",".","x","=","None","assert","ildj","is","cache.inverse_attributes","(","y",")","[","'ildj","'","]","x",",","y","=","cache.inverse","(","y",")",",","None","assert","ildj","is","cache.forward_attributes","(","x",")","[","'ildj","'","]","#","When","both","refs","are","collected",",","attributes","are","cleared",".","x","=","y","=","None","assert","(","len","(","cache.weak_keys","(","direction='forward","'",")",")","==","len","(","cache.weak_keys","(","direction='inverse","'",")",")","==","0",")","``","`","Args",":","input",":","The","singular","ordered","argument","passed","to","the","wrapped","function",".","fn_name",":","`","str","`",",","name","of","the","directed","function","to","which","`","input","`","is","an","arg","(","typically","`","'_forward","'","`","or","`","'_inverse","'","`",")",".","*","*","kwargs",":","Any","auxiliary","arguments","passed","to","the","function",".","These","reflect","shared","context","to","the","function",",","and","are","associated","with","both","the","input","and","output","cache-keys",".","Returns",":","The","dictionary","of","attributes","associated","with","the","transformation","."]
code: def _attributes(self, input, fn_name, **kwargs):
      """Looks up user-defined attributes associated with this argument.
  
      Attributes are dictionaries that store arbitrary information about the
      transformation; for example, its log Jacobian determinant. Each cache lookup
      will also return the corresponding `attributes` dictionary, which the user
      may populate however they want. Attributes are "bidirectional", such that
      `cache.forward_attributes(x)` will return the same dictionary instance as
      `cache.inverse_attributes(cache.forward(x))`.
  
      This method is "lazy", in the sense that it doesn't invoke the wrapped
      transformation. Whether `attributes` or `__call__` are invoked first does
      not affect behavior.
  
      Examples:
  
      ```python
      ## Basic Usage
      bijector = tfb.Exp()
      cache = BijectorCache(bijector=bijector)
      x = tf.random.normal()
  
      # Compute some attribute for x, and add it to the cache.
      ildj = -bijector.forward_log_det_jacobian(x)
      cache.forward_attributes(x)['ildj'] = ildj
  
      # Apply the forward transformation, and lookup the attribute by `y`.
      y = cache.forward(x)
      assert ildj is cache.inverse_attributes(y)['ildj']
  
      ## Garbage Collection
      # Attributes remain cached until refs to both `x` and `y` are collected.
      x = None
      assert ildj is cache.inverse_attributes(y)['ildj']
  
      x, y = cache.inverse(y), None
      assert ildj is cache.forward_attributes(x)['ildj']
  
      # When both refs are collected, attributes are cleared.
      x = y = None
      assert (len(cache.weak_keys(direction='forward'))
              == len(cache.weak_keys(direction='inverse'))
              == 0)
      ```
  
      Args:
        input: The singular ordered argument passed to the wrapped function.
        fn_name: `str`, name of the directed function to which `input` is an arg
          (typically `'_forward'` or `'_inverse'`).
        **kwargs: Any auxiliary arguments passed to the function.
          These reflect shared context to the function, and are associated
          with both the input and output cache-keys.
      Returns:
        The dictionary of attributes associated with the transformation.
      """
      if input is None:
          raise ValueError("Input must not be None.")
      return self._get_or_create_edge(input, fn_name, kwargs).attributes
  
imports: import collections
  import weakref
  import numpy
  import tensorflow.compat.v2
  from tensorflow.python.util import nest
label_desc: Use image node_id 11 for calling the BijectorCache obj's underlying member method code with example usage: obj._attributes(input, fn_name) and returns: self