
    Vpf                    *	   d dl mZ d dlZd dlmZmZmZmZ d dlm	Z	 d dl
Z
d dlZd dlmZ d dlZd dlZd dlmZmZmZmZmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ  ed          Z ej        e             ed          Z! ede"e                   Z# ede          Z$eZ%ej&        Z& ej'                    Z'e(e'_)        de'_(         ej*        ddddd          Z+e(e+_)        de+_(         ej*        ddddd          Z,e(e,_)        de,_(        e	 ddd            Z-edd!            Z.e	 ddd#            Z/e	 ddd%            Z0edd(            Z1edd*            Z2edd,            Z3dd-Z4e	 ddd0            Z5 ed1ee                   Z6 ed2e          Z7edd:            Z8edd<            Z9edd=ddA            Z:eddC            Z;eddH            Z< ej=        dIdJdKg          Z>e? e>dL dM           e@ e>dN dO           eA e>dP dQ            e"d           e>dR dS           iZBdT ZC eD            ZEedd=ddW            ZFe	 dddY            ZFeeEdfddZ            ZFedd=dd[            ZG e8ejH        d\ d]            d^ ZI e8ejJ        eId_             G d` da          ZKe G db dcej                              ZL e8eLdd de            	 dddiZMddlZN	 dddnZO	 dddrZPddsZQdt ZRe e	du           G dv dw                                  ZSe e	du           G dx dy                                  ZTe e	du           G dz d{                                  ZUe e	du           G d| d}                                  ZVeeSeTeUeVf         ZW ed~e          ZXe?eXdf         ZYedd            ZZ G d de          Z[ddZ\i Z] e\e?d             e\e@d             e\eAd             e\ejJ        d             e\ejH        d            e	 ddd            Z^edd            Z_edd            Z`edd            Zae	 ddd            Zbe	 ddd            Zc	 dddZdedZe	 dddZfedd=dd            ZgddZh	 dddZidS )    )annotationsN)CallableHashableIterableSequence)	dataclass)partial)Any
NamedTupleTypeVarUnionoverload)traceback_util)pytree)safe_zip
set_module)unzip2zjax.tree_utilTTyp)boundHdefault_registryFT)enable_noneenable_tupleenable_namedtupleenable_listenable_dictnone_leaf_registrydispatch_registrytreer
   is_leafCallable[[Any], bool] | Nonereturntuple[list[Leaf], PyTreeDef]c                8    t                               | |          S )z"Alias of :func:`jax.tree.flatten`.r   flattenr    r!   s     R/var/www/html/nettyfy-visnx/env/lib/python3.11/site-packages/jax/_src/tree_util.pytree_flattenr*   I   s    
 
	!	!$	0	00    treedef	PyTreeDefleavesIterable[Leaf]c                ,    |                      |          S )z$Alias of :func:`jax.tree.unflatten`.)	unflatten)r,   r.   s     r)   tree_unflattenr2   Q   s     
		6	"	""r+   
list[Leaf]c                D    t                               | |          d         S )z!Alias of :func:`jax.tree.leaves`.r   r&   r(   s     r)   tree_leavesr5   W       
 
	!	!$	0	0	33r+   None | Callable[[Any], bool]c                D    t                               | |          d         S )z$Alias of :func:`jax.tree.structure`.   r&   r(   s     r)   tree_structurer:   _   r6   r+   treedefsIterable[PyTreeDef]c                P    t          j        t          t          |                     S )a  Makes a tuple treedef from an iterable of child treedefs.

  Args:
    treedefs: iterable of PyTree structures

  Returns:
    a single treedef representing a tuple of the structures

  Examples:
    >>> import jax
    >>> x = [1, 2, 3]
    >>> y = {'a': 4, 'b': 5}
    >>> x_tree = jax.tree.structure(x)
    >>> y_tree = jax.tree.structure(y)
    >>> xy_tree = jax.tree_util.treedef_tuple([x_tree, y_tree])
    >>> xy_tree == jax.tree.structure((x, y))
    True

  See Also:
    - :func:`jax.tree_util.treedef_children`
  )r   tupler   list)r;   s    r)   treedef_tupler@   g   s    . 
&X	7	77r+   list[PyTreeDef]c                *    |                                  S )a  Return a list of treedefs for immediate children

  Args:
    treedef: a single PyTreeDef

  Returns:
    a list of PyTreeDefs representing the children of treedef.

  Examples:
    >>> import jax
    >>> x = [(1, 2), 3, {'a': 4}]
    >>> treedef = jax.tree.structure(x)
    >>> jax.tree_util.treedef_children(treedef)
    [PyTreeDef((*, *)), PyTreeDef(*), PyTreeDef({'a': *})]
    >>> _ == [jax.tree.structure(vals) for vals in x]
    True

  See Also:
    - :func:`jax.tree_util.treedef_tuple`
  )childrenr,   s    r)   treedef_childrenrE      s    , 
				r+   boolc                    | j         dk    S )a  Return True if the treedef represents a leaf.

  Args:
    treedef: tree to check

  Returns:
    True if treedef is a leaf (i.e. has a single node); False otherwise.

  Examples:
    >>> import jax
    >>> tree1 = jax.tree.structure(1)
    >>> jax.tree_util.treedef_is_leaf(tree1)
    True
    >>> tree2 = jax.tree.structure([1, 2])
    >>> jax.tree_util.treedef_is_leaf(tree2)
    False
  r9   )	num_nodesrD   s    r)   treedef_is_leafrI      s    & 
	a	r+   c                .    | j         dk    o
| j        dk    S )Nr9   )rH   
num_leavesrD   s    r)   treedef_is_strict_leafrL      s    		a		;G$6!$;;r+   iterableIterable[Any]c                    |t          j        t          |           S t          |           }|t	          ||          k    S )a,  Tests whether all elements in the given iterable are all leaves.

  This function is useful in advanced cases, for example if a library allows
  arbitrary map operations on a flat iterable of leaves it may want to check
  if the result is still a flat iterable of leaves.

  Args:
    iterable: Iterable of leaves.

  Returns:
    A boolean indicating if all elements in the input are leaves.

  Examples:
    >>> import jax
    >>> tree = {"a": [1, 2, 3]}
    >>> assert all_leaves(jax.tree_util.tree_leaves(tree))
    >>> assert not all_leaves([tree])
  )r   
all_leavesr   r?   r5   )rM   r!   lsts      r)   rP   rP      s=    * _-x888
x..C+c7++++r+   	_Children_AuxDatanodetypetype[T]flatten_func)Callable[[T], tuple[_Children, _AuxData]]unflatten_func"Callable[[_AuxData, _Children], T]Nonec                    t                               | ||           t                              | ||           t                              | ||           t	          ||          t
          | <   dS )aC
  Extends the set of types that are considered internal nodes in pytrees.

  See :ref:`example usage <pytrees>`.

  Args:
    nodetype: a Python type to register as a pytree.
    flatten_func: a function to be used during flattening, taking a value of
      type ``nodetype`` and returning a pair, with (1) an iterable for the
      children to be flattened recursively, and (2) some hashable auxiliary data
      to be stored in the treedef and to be passed to the ``unflatten_func``.
    unflatten_func: a function taking two arguments: the auxiliary data that was
      returned by ``flatten_func`` and stored in the treedef, and the
      unflattened children. The function should return an instance of
      ``nodetype``.

  See also:
    - :func:`~jax.tree_util.register_static`: simpler API for registering a static pytree.
    - :func:`~jax.tree_util.register_dataclass`: simpler API for registering a dataclass.
    - :func:`~jax.tree_util.register_pytree_with_keys`
    - :func:`~jax.tree_util.register_pytree_node_class`
    - :func:`~jax.tree_util.register_pytree_with_keys_class`

  Examples:
    First we'll define a custom type:

    >>> class MyContainer:
    ...   def __init__(self, size):
    ...     self.x = jnp.zeros(size)
    ...     self.y = jnp.ones(size)
    ...     self.size = size

    If we try using this in a JIT-compiled function, we'll get an error because JAX
    does not yet know how to handle this type:

    >>> m = MyContainer(size=5)
    >>> def f(m):
    ...   return m.x + m.y + jnp.arange(m.size)
    >>> jax.jit(f)(m)  # doctest: +IGNORE_EXCEPTION_DETAIL
    Traceback (most recent call last):
      ...
    TypeError: Cannot interpret value of type <class 'jax.tree_util.MyContainer'> as an abstract array; it does not have a dtype attribute

    In order to make our object recognized by JAX, we must register it as
    a pytree:

    >>> def flatten_func(obj):
    ...   children = (obj.x, obj.y)  # children must contain arrays & pytrees
    ...   aux_data = (obj.size,)  # aux_data must contain static, hashable data.
    ...   return (children, aux_data)
    ...
    >>> def unflatten_func(aux_data, children):
    ...   # Here we avoid `__init__` because it has extra logic we don't require:
    ...   obj = object.__new__(MyContainer)
    ...   obj.x, obj.y = children
    ...   obj.size, = aux_data
    ...   return obj
    ...
    >>> jax.tree_util.register_pytree_node(MyContainer, flatten_func, unflatten_func)

    Now with this defined, we can use instances of this type in JIT-compiled functions.

    >>> jax.jit(f)(m)
    Array([1., 2., 3., 4., 5.], dtype=float32)
  N)r   register_noder   r   _RegistryEntry	_registry)rT   rV   rX   s      r)   register_pytree_noder_      sg    H   <HHH""8\>JJJ!!(L.III&|^DD)Hr+   clsc                V    t          | t          j        d          | j                   | S )a  Extends the set of types that are considered internal nodes in pytrees.

  This function is a thin wrapper around ``register_pytree_node``, and provides
  a class-oriented interface.

  Args:
    cls: a type to register as a pytree

  Returns:
    The input class ``cls`` is returned unchanged after being added to JAX's pytree
    registry. This return value allows ``register_pytree_node_class`` to be used as
    a decorator.

  See also:
    - :func:`~jax.tree_util.register_static`: simpler API for registering a static pytree.
    - :func:`~jax.tree_util.register_dataclass`: simpler API for registering a dataclass.
    - :func:`~jax.tree_util.register_pytree_node`
    - :func:`~jax.tree_util.register_pytree_with_keys`
    - :func:`~jax.tree_util.register_pytree_with_keys_class`

  Examples:
    Here we'll define a custom container that will be compatible with :func:`jax.jit`
    and other JAX transformations:

    >>> import jax
    >>> @jax.tree_util.register_pytree_node_class
    ... class MyContainer:
    ...   def __init__(self, x, y):
    ...     self.x = x
    ...     self.y = y
    ...   def tree_flatten(self):
    ...     return ((self.x, self.y), None)
    ...   @classmethod
    ...   def tree_unflatten(cls, aux_data, children):
    ...     return cls(*children)
    ...
    >>> m = MyContainer(jnp.zeros(4), jnp.arange(4))
    >>> def f(m):
    ...   return m.x + 2 * m.y
    >>> jax.jit(f)(m)
    Array([0., 2., 4., 6.], dtype=float32)
  r*   )r_   opmethodcallerr2   )r`   s    r)   register_pytree_node_classrd     s)    X sBON;;S=OPPP	*r+   r!   fCallable[..., Any]restc                    t          ||          \  }|gfd|D             z   }                     fdt          | D                       S )zAlias of :func:`jax.tree.map`.c                :    g | ]}                     |          S  flatten_up_to.0rr,   s     r)   
<listcomp>ztree_map.<locals>.<listcomp>V  s'    BBB70033BBBr+   c              3  "   K   | ]	} | V  
d S Nrk   ro   xsrf   s     r)   	<genexpr>ztree_map.<locals>.<genexpr>W  s)      ==b11b6======r+   )r*   r1   zip)rf   r    r!   rh   r.   rP   r,   s   `     @r)   tree_maprx   O  sh     !w///&'xBBBBTBBBB*			====C,<===	=	==r+   ru   c                ,    |                      |          S )a  Build a treedef from a nested iterable structure

  Args:
    treedef: the PyTreeDef structure to build.
    xs: nested iterables matching the arity as the treedef

  Returns:
    object with structure defined by treedef

  See Also:
    - :func:`jax.tree.unflatten`

  Examples:
    >>> import jax
    >>> tree = [(1, 2), {'a': 3, 'b': 4}]
    >>> treedef = jax.tree.structure(tree)

    Both ``build_tree`` and :func:`jax.tree_util.tree_unflatten` can reconstruct
    the tree from new values, but ``build_tree`` takes these values in terms of
    a nested rather than flat structure:

    >>> jax.tree_util.build_tree(treedef, [[10, 11], [12, 13]])
    [(10, 11), {'a': 12, 'b': 13}]
    >>> jax.tree_util.tree_unflatten(treedef, [10, 11, 12, 13])
    [(10, 11), {'a': 12, 'b': 13}]
  )from_iterable_tree)r,   ru   s     r)   
build_treer{   Z  s    8 
	#	#B	'	''r+   outer_treedefinner_treedefPyTreeDef | Nonepytree_to_transposec                  
 t          |          \  }}|(t          |                     |          d                   }|j        
| j        }|j        
|z  k    r*|                     |          }t          d| d|           t          |          
fdt          |          D             }t          | }t          t          t          |           |          }	t          ||	          S )z$Alias of :func:`jax.tree.transpose`.Nr   z	Mismatch
z
 != 
c                F    g | ]}fd t                    D             S )c                .    g | ]}t                    S rk   )next)ro   _	iter_flats     r)   rq   z-tree_transpose.<locals>.<listcomp>.<listcomp>  s    2221tI222r+   )range)ro   __
inner_sizer   s     r)   rq   z"tree_transpose.<locals>.<listcomp>  sC     	 	 	792222j 1 1222	 	 	r+   )r*   r:   rm   rK   compose	TypeErroriterr   rw   mapr	   r2   )r|   r}   r   flatr,   
outer_sizeexpected_treedefloltransposed_lolsubtreesr   r   s             @@r)   tree_transposer   y  s    233-$"=#>#>?R#S#STU#VWWM'*'*J344$,,];;
DDD2BDD
E
EE4jj)	 	 	 	 	=B:=N=N	 	 	# 9.77HH(	x	0	00r+   r]   to_iter	from_iterc                
    | d fS rs   rk   ru   s    r)   <lambda>r     s
    b$Z r+   c                     t          |          S rs   r>   r   ru   s     r)   r   r     s    uRyy r+   c                
    | d fS rs   rk   r   s    r)   r   r     s
    RJ r+   c                     t          |          S rs   )r?   r   s     r)   r   r     s    d2hh r+   c                p    t          t          |                                                     d d d         S )N)r   sorteditemsr   s    r)   r   r     s)    F6"((**+=+=$>$>ttt$D r+   c                <    t          t          | |                    S rs   )dictrw   )keysru   s     r)   r   r     s    $s4}}*=*= r+   c                    dS )N)rk   Nrk   )zs    r)   r   r     s     r+   c                    d S rs   rk   r   s     r)   r   r     s    4 r+   c                     t                               |          \  }}t           fd|          }|                    |          S )z0Replaces ``None`` in ``tree`` with ``sentinel``.c                    | n| S rs   rk   )xsentinels    r)   r   z _replace_nones.<locals>.<lambda>  s    QYA r+   )r   r'   r   r1   )r   r    r.   r,   s   `   r)   _replace_nonesr     sG    &..t44/&'5555v>>&			6	"	""r+   functionCallable[[T, Any], T]c                   d S rs   rk   )r   r    r!   s      r)   tree_reducer     	    
 Cr+   initializerc                    d S rs   rk   r   r    r   r!   s       r)   r   r     r   r+   c                    |t           u r$t          j        | t          ||                    S t          j        | t          ||          |          S )z!Alias of :func:`jax.tree.reduce`.re   )no_initializer	functoolsreducer5   r   s       r)   r   r     sQ     N""Hk$&H&H&HIIIHk$&H&H&H+VVVr+   c               >    t          t          | |                    S )zAlias of :func:`jax.tree.all`.re   )allr5   r(   s     r)   tree_allr     s     
[w///	0	00r+   c                    t          |                                           t          |                                           fS rs   )r>   valuesr   r   s    r)   r   r     s)    U188::affhh0 r+   c                F    t          j        t          | |                    S rs   )collectionsOrderedDictr   )r   r   s     r)   r   r     s    {.xf/E/EFF r+   c                     t          t                               }t           fd|D                        j        |ffS )Nc              3  (   K   | ]}|         V  d S rs   rk   )ro   kds     r)   rv   z'_flatten_defaultdict.<locals>.<genexpr>  s'      ""qt""""""r+   )r>   r   default_factory)r   r   s   ` r)   _flatten_defaultdictr     sF    	vayy		$	""""T"""	"	"Q%6$=	==r+   c                `    t          j        | d         t          | d         |                    S Nr   r9   )r   defaultdictr   )sr   s     r)   r   r     s%    K+AaD(1Q42H2HII r+   c                  0    e Zd ZdZd Zd Zd Zd Zd ZdS )_HashableCallableShimzGObject that delegates __call__, __hash__, and __eq__ to another object.c                    || _         d S rs   fun)selfr   s     r)   __init__z_HashableCallableShim.__init__  s    DHHHr+   c                     | j         |i |S rs   r   )r   argskws      r)   __call__z_HashableCallableShim.__call__  s    48T R   r+   c                *    t          | j                  S rs   )hashr   r   s    r)   __hash__z_HashableCallableShim.__hash__  s    >>r+   c                b    t          |t                    r| j        |j        k    S | j        |k    S rs   )
isinstancer   r   )r   others     r)   __eq__z_HashableCallableShim.__eq__  s1    %.// #X""8ur+   c                    d| j         dS )Nz_HashableCallableShim()r   r   s    r)   __repr__z_HashableCallableShim.__repr__  s    1DH1111r+   N)	__name__
__module____qualname____doc__r   r   r   r   r   rk   r+   r)   r   r     se        OO  ! ! !    
2 2 2 2 2r+   r   c                  "     e Zd ZdZ fdZ xZS )Partialam  A version of functools.partial that works in pytrees.

  Use it for partial function evaluation in a way that is compatible with JAX's
  transformations, e.g., ``Partial(func, *args, **kwargs)``.

  (You need to explicitly opt-in to this behavior because we didn't want to give
  functools.partial different semantics than normal function closures.)

  For example, here is a basic usage of ``Partial`` in a manner similar to
  ``functools.partial``:

  >>> import jax.numpy as jnp
  >>> add_one = Partial(jnp.add, 1)
  >>> add_one(2)
  Array(3, dtype=int32, weak_type=True)

  Pytree compatibility means that the resulting partial function can be passed
  as an argument within transformed JAX functions, which is not possible with a
  standard ``functools.partial`` function:

  >>> from jax import jit
  >>> @jit
  ... def call_func(f, *args):
  ...   return f(*args)
  ...
  >>> call_func(add_one, 2)
  Array(3, dtype=int32, weak_type=True)

  Passing zero arguments to ``Partial`` effectively wraps the original function,
  making it a valid argument in JAX transformed functions:

  >>> call_func(Partial(jnp.add), 1, 2)
  Array(3, dtype=int32, weak_type=True)

  Had we passed ``jnp.add`` to ``call_func`` directly, it would have resulted in
  a ``TypeError``.

  Note that if the result of ``Partial`` is used in the context where the
  value is traced, it results in all bound arguments being traced when passed
  to the partially-evaluated function:

  >>> print_zero = Partial(print, 0)
  >>> print_zero()
  0
  >>> call_func(print_zero)  # doctest:+ELLIPSIS
  Traced<ShapedArray(int32[], weak_type=True)>with<DynamicJaxprTrace...>
  c                   t          |t          j                  rU|}t          |          } t	                      j        | |g|R i |}|j        |_        |j        |_        |j        |_        |S  t	                      j        | |g|R i |S rs   )	r   r   r	   r   super__new__funcr   keywords)klassr   r   r   original_funcout	__class__s         r)   r   zPartial.__new__  s     $	)** 	7m"=11dEGGOE45$555"55c$di$di#,dmjUWW_UD646662666r+   )r   r   r   r   r   __classcell__)r   s   @r)   r   r     sC        . .`7 7 7 7 7 7 7 7 7r+   r   c                ,    | j         | j        f| j        fS rs   )r   r   r   )partial_s    r)   r   r   0  s    x}h&78(-H r+   c                :    t          | g|d         R i |d         S r   )r   )r   ru   s     r)   r   r   1  s&    WT3BqE333RU33 r+   prefix_tree	full_tree	list[Any]c                F    g d fd}t          || ||           S )Nc                *    t          |           j        S rs   )r:   rK   )ts    r)   r   z"broadcast_prefix.<locals>.<lambda>=  s    **5 r+   c                H                         | g |          z            S rs   )extend)r   subtreerK   results     r)   r   z"broadcast_prefix.<locals>.<lambda>>  s$    &--jj6I6I0I"J"J r+   re   )rx   )r   r   r!   
add_leavesrK   r   s       @@r)   broadcast_prefixr   6  s@     &55*JJJJJ*
:{Iw????	-r+   r   tuple[Iterable[Any], Hashable]c                |    t                               |           }|t          dt          |                      |S )a  Flatten the given pytree node by one level.

  Args:
    pytree: A valid pytree node, either built-in or registered via
      :func:`register_pytree_node` or related functions.

  Returns:
    A pair of the pytrees flattened children and its hashable metadata.

  Raises:
    ValueError: If the given pytree is not a built-in or registered container
    via ``register_pytree_node`` or ``register_pytree_with_keys``.

  Examples:
    >>> import jax
    >>> from jax._src.tree_util import flatten_one_level
    >>> flattened, meta = flatten_one_level({'a': [1, 2], 'b': {'c': 3}})
    >>> flattened
    ([1, 2], {'c': 3})
    >>> meta
    ('a', 'b')
  Nzcan't tree-flatten type: )r   flatten_one_level
ValueErrortype)r   r   s     r)   r  r  D  s>    . 	**622#[
?f??
@
@@Jr+   !list[Callable[[str], ValueError]]c                @    t          t          d| ||                    S Nrk   )r?   _prefix_error)r   r   r!   s      r)   prefix_errorsr
  c  s      
mBY@@	A	AAr+   tree1tree2'Iterable[tuple[KeyPath, str, str, str]]c              #  :   K   t          d| ||          E d{V  dS )a  Helper to describe structural differences between two pytrees.

  Args:
    tree1, tree2: pytrees known to have different structure.

  Usage:

    raise Exception(
        "Value 1 and value 2 must have the same pytree structure, but they have "
        "the following structural differences:
" +
        ("
".join(
           f"   - {keystr(path)} is a {thing1} in value 1 and a {thing2} in "
           f" value 2, so {explanation}.
"
           for path, thing1, thing2, explanation
           in equality_errors(val1, val2))))
  rk   N)_equality_errors)r  r  r!   s      r)   equality_errorsr  j  s4      & b%88888888888r+   c           	           t          dt           ft          d                     ddi                       }t          t          | |g| j        z            t          ||g|j        z                      S )z0Like `equality_errors` but invoked on PyTreeDef.LeafMetac                    dS )Nzpytree leafrk   )r   s    r)   r   z+equality_errors_pytreedef.<locals>.<lambda>  s    = r+   )r   Leafrk   )r  r   r  r2   rK   )r  r  leafs      r)   equality_errors_pytreedefr    s    
 
[	Jj4'41H1H#I#I#I	J	J6SUWY	Z	Z	\	\$	v8H/HII'v8H/HII
K 
K Kr+   c           	   #  P  K   t          t          ||                    r t          t          ||                    rd S t          |          t          |          k    r>| t          t          |                    t          t          |                    dfV  d S t	          |t
          t          f          rt          |          t          |          k    sJ t          |          t          |          k    rR| t          |          j         dt          |           t          |          j         dt          |           dfV  d S t          |          \  }}t          |          \  }}t          |          }t          |          }t          |          t          |          }	}	 d                    d t          |                              t          |	                    D                       }
n	#  d}
Y nxY wt          |          t          |          k    r| t          |           dt          |           d	t          |          d
k    rdnd t          |           dt          |           d	t          |          d
k    rdnd d|
od|
 dz   fV  d S ||k    r.| t          |           d| t          |           d| dfV  d S ||	k    sJ d| d|	             t          |||          D ]#\  }}}t          g | |R |||          E d {V  $d S )Nre   ztheir Python types differ of length zthe lengths do not match c              3  >   K   | ]}t          |j                  V  d S rs   )reprkeyro   r   s     r)   rv   z#_equality_errors.<locals>.<genexpr>  sB       E EADKK E E E E E Er+    z with z childr9   renz$the numbers of children do not matchz., with the symmetric difference of key sets: {}z with pytree metadata z'the pytree node metadata does not matchz-equal pytree nodes gave different tree keys:  and )rL   r:   r  strr   r?   r>   lenr   r  _child_keysjoinsetsymmetric_differencerw   r  )patht1t2r!   t1_childrent1_metat2_childrent2_metat1_keyst2_keysdiffr   c1c2s                 r)   r  r    s     ^B@@@AA K^B@@@AAKDJF 
"XXb
DHHs488}}.I
IIII
F T5M"" 88tBxx
2ww#b''R!77c"gg77R!77c"gg77') ) ) ) f*2..+w*2..+wk""+k""+ __k"oo7'88 E ELL55c'llCCE E E E EDDDDD[))))2hh 6 6c+.. 6 6;''!++ee6 62hh 6 6c+.. 6 6;''!++ee6 61OOtOOOQ    F 2hh77g772hh77g7746 6 6 6 F 
G			MgMMGMM 
		w[99 = =iaR
$


BG<<<<<<<<<<= =s   0AG= =H)frozenc                  $    e Zd ZU dZded<   d ZdS )SequenceKeyDStruct for use with :func:`jax.tree_util.register_pytree_with_keys`.intidxc                    d| j         dS N[])r9  r   s    r)   __str__zSequenceKey.__str__      txr+   Nr   r   r   r   __annotations__r>  rk   r+   r)   r6  r6    s7          ML
(((    r+   r6  c                  $    e Zd ZU dZded<   d ZdS )DictKeyr7  r   r  c                    d| j         dS r;  r  r   s    r)   r>  zDictKey.__str__  r?  r+   Nr@  rk   r+   r)   rC  rC    s7          ML---    r+   rC  c                  $    e Zd ZU dZded<   d ZdS )
GetAttrKeyr7  r"  namec                    d| j          S )N.rH  r   s    r)   r>  zGetAttrKey.__str__  s    ty??r+   Nr@  rk   r+   r)   rG  rG    s7          ML)))    r+   rG  c                  $    e Zd ZU dZded<   d ZdS )FlattenedIndexKeyr7  r8  r  c                    d| j          dS )Nz[<flat index z>]rE  r   s    r)   r>  zFlattenedIndexKey.__str__  s    '48''''r+   Nr@  rk   r+   r)   rM  rM    s7          ML
(((( ( ( ( (r+   rM  KeyEntry.r   KeyPathc                @    d                     d | D                       S )a=  Helper to pretty-print a tuple of keys.

  Args:
    keys: A tuple of ``KeyEntry`` or any class that can be converted to string.

  Returns:
    A string that joins all string representations of the keys.

  Examples:
    >>> import jax
    >>> keys = (0, 1, 'a', 'b')
    >>> jax.tree_util.keystr(keys)
    '01ab'
  r  c                ,    g | ]}t          |          S rk   )r"  r  s     r)   rq   zkeystr.<locals>.<listcomp>  s    '''Q#a&&'''r+   )r%  )r   s    r)   keystrrS    s%      
''$'''	(	((r+   c                  $    e Zd ZU ded<   ded<   dS )_RegistryWithKeypathsEntryrg   flatten_with_keysrX   N)r   r   r   rA  rk   r+   r)   rU  rU    s*         ''''$$$$$$r+   rU  tyhandler#Callable[[T], tuple[KeyEntry, ...]]c                |      fd} t           v r*t          |t                     j                  t           <   d S d S )Nc                    t                                        |           \  }}t          t           |           |                    |fS rs   )r^   r   r?   rw   )ru   rC   r,   rX  rW  s      r)   rV  z-_register_keypaths.<locals>.flatten_with_keys  sD    !"--b11HgGGBKK**++W44r+   )r^   rU  r   _registry_with_keypaths)rW  rX  rV  s   `` r)   _register_keypathsr]    s[    5 5 5 5 5 5 9__"<9R=2# #B _r+   c                h    t          d t          t          |                     D                       S )Nc              3  4   K   | ]}t          |          V  d S rs   r6  ro   is     r)   rv   z<lambda>.<locals>.<genexpr>  s(      CCqKNNCCCCCCr+   r>   r   r#  r   s    r)   r   r     s)    eCCE#b''NNCCCCC r+   c                h    t          d t          t          |                     D                       S )Nc              3  4   K   | ]}t          |          V  d S rs   r`  ra  s     r)   rv   z<lambda>.<locals>.<genexpr>  s(      BBa;q>>BBBBBBr+   rc  r   s    r)   r   r     s)    UBB5R>>BBBBB r+   c                N    t          d t          |           D                       S )Nc              3  4   K   | ]}t          |          V  d S rs   rC  r  s     r)   rv   z<lambda>.<locals>.<genexpr>  s(      )I)I'!**)I)I)I)I)I)Ir+   )r>   r   r   s    r)   r   r     s#    E)I)IfRjj)I)I)I$I$I r+   c                X    t          d |                                 D                       S )Nc              3  4   K   | ]}t          |          V  d S rs   rh  r  s     r)   rv   z<lambda>.<locals>.<genexpr>  (      ,J,JAWQZZ,J,J,J,J,J,Jr+   r>   r   r   s    r)   r   r     %    u,J,J,J,J,J'J'J r+   c                X    t          d |                                 D                       S )Nc              3  4   K   | ]}t          |          V  d S rs   rh  r  s     r)   rv   z<lambda>.<locals>.<genexpr>  rk  r+   rl  r   s    r)   r   r     rm  r+   rV  >Callable[[T], tuple[Iterable[tuple[KeyEntry, Any]], _AuxData]]&Callable[[_AuxData, Iterable[Any]], T]4None | Callable[[T], tuple[Iterable[Any], _AuxData]]c                l    |sfd}|}t          | ||           t          |          t          | <   dS )a	  Extends the set of types that are considered internal nodes in pytrees.

  This is a more powerful alternative to ``register_pytree_node`` that allows
  you to access each pytree leaf's key path when flattening and tree-mapping.

  Args:
    nodetype: a Python type to treat as an internal pytree node.
    flatten_with_keys: a function to be used during flattening, taking a value
      of type ``nodetype`` and returning a pair, with (1) an iterable for tuples
      of each key path and its child, and (2) some hashable auxiliary data to be
      stored in the treedef and to be passed to the ``unflatten_func``.
    unflatten_func: a function taking two arguments: the auxiliary data that was
      returned by ``flatten_func`` and stored in the treedef, and the
      unflattened children. The function should return an instance of
      ``nodetype``.
    flatten_func: an optional function similar to ``flatten_with_keys``, but
      returns only children and auxiliary data. It must return the children
      in the same order as ``flatten_with_keys``, and return the same aux data.
      This argument is optional and only needed for faster traversal when
      calling functions without keys like ``tree_map`` and ``tree_flatten``.

  Examples:
    First we'll define a custom type:

    >>> class MyContainer:
    ...   def __init__(self, size):
    ...     self.x = jnp.zeros(size)
    ...     self.y = jnp.ones(size)
    ...     self.size = size

    Now register it using a key-aware flatten function:

    >>> from jax.tree_util import register_pytree_with_keys_class, GetAttrKey
    >>> def flatten_with_keys(obj):
    ...   children = [(GetAttrKey('x'), obj.x),
    ...               (GetAttrKey('y'), obj.y)]  # children must contain arrays & pytrees
    ...   aux_data = (obj.size,)  # aux_data must contain static, hashable data.
    ...   return children, aux_data
    ...
    >>> def unflatten(aux_data, children):
    ...   # Here we avoid `__init__` because it has extra logic we don't require:
    ...   obj = object.__new__(MyContainer)
    ...   obj.x, obj.y = children
    ...   obj.size, = aux_data
    ...   return obj
    ...
    >>> jax.tree_util.register_pytree_node(MyContainer, flatten_with_keys, unflatten)

    Now this can be used with functions like :func:`~jax.tree_util.tree_flatten_with_path`:

    >>> m = MyContainer(4)
    >>> leaves, treedef = jax.tree_util.tree_flatten_with_path(m)
  c                <     |           \  }}d |D             |fS )Nc                    g | ]\  }}|S rk   rk   )ro   r   cs      r)   rq   zHregister_pytree_with_keys.<locals>.flatten_func_impl.<locals>.<listcomp>e  s    )))DAqa)))r+   rk   )r    key_childrenr,   rV  s      r)   flatten_func_implz4register_pytree_with_keys.<locals>.flatten_func_implc  s1    //55lG))L)))722r+   N)r_   rU  r\  )rT   rV  rX   rV   rx  s    `   r)   register_pytree_with_keysry  "  s`    @ 
 %3 3 3 3 3 %Lx~>>>&@' '(###r+   c                    t          | d          rt          j        d          nd}t          | t          j        d          | j        |           | S )ao  Extends the set of types that are considered internal nodes in pytrees.

  This function is similar to ``register_pytree_node_class``, but requires a
  class that defines how it could be flattened with keys.

  It is a thin wrapper around ``register_pytree_with_keys``, and
  provides a class-oriented interface:

  Args:
    cls: a type to register as a pytree

  Returns:
    The input class ``cls`` is returned unchanged after being added to JAX's pytree
    registry. This return value allows ``register_pytree_node_class`` to be used as
    a decorator.

  See also:
    - :func:`~jax.tree_util.register_static`: simpler API for registering a static pytree.
    - :func:`~jax.tree_util.register_dataclass`: simpler API for registering a dataclass.
    - :func:`~jax.tree_util.register_pytree_node`
    - :func:`~jax.tree_util.register_pytree_with_keys`
    - :func:`~jax.tree_util.register_pytree_node_class`

  Examples:
    >>> from jax.tree_util import register_pytree_with_keys_class, GetAttrKey
    >>> @register_pytree_with_keys_class
    ... class Special:
    ...   def __init__(self, x, y):
    ...     self.x = x
    ...     self.y = y
    ...   def tree_flatten_with_keys(self):
    ...     return (((GetAttrKey('x'), self.x), (GetAttrKey('y'), self.y)), None)
    ...   @classmethod
    ...   def tree_unflatten(cls, aux_data, children):
    ...     return cls(*children)
  r*   Ntree_flatten_with_keys)hasattrrb   rc   ry  r2   )r`   rV   s     r)   register_pytree_with_keys_classr}  n  s^    N *1n)E)EObon%%%4  	2?344c6H   
*r+   data_fieldsSequence[str]meta_fieldsc                    t                    t                    fd} fd}fd}t                               t                    t                               t                               t                    t                               t
                               t                    t                               t          ||          t           <   t          ||          t           <    S )aK  Extends the set of types that are considered internal nodes in pytrees.

  This differs from ``register_pytree_with_keys_class`` in that the C++
  registries use the optimized C++ dataclass builtin instead of the argument
  functions.

  See :ref:`extending-pytrees` for more information about registering pytrees.

  Args:
    nodetype: a Python type to treat as an internal pytree node. This is assumed
      to have the semantics of a :obj:`~dataclasses.dataclass`: namely, class
      attributes represent the whole of the object state, and can be passed
      as keywords to the class constructor to create a copy of the object.
      All defined attributes should be listed among ``meta_fields`` or ``data_fields``.
    meta_fields: auxiliary data field names. These fields *must* contain static,
      hashable, immutable objects, as these objects are used to generate JIT cache
      keys. In particular, ``meta_fields`` cannot contain :class:`jax.Array` or
      :class:`numpy.ndarray` objects.
    data_fields: data field names. These fields *must* be JAX-compatible objects
      such as arrays (:class:`jax.Array` or :class:`numpy.ndarray`), scalars, or
      pytrees whose leaves are arrays or scalars. Note that ``data_fields`` may be
      ``None``, as this is recognized by JAX as an empty pytree.

  Returns:
    The input class ``nodetype`` is returned unchanged after being added to JAX's
    pytree registry. This return value allows ``register_dataclass`` to be partially
    evaluated and used as a decorator as in the example below.

  Examples:
    >>> from dataclasses import dataclass
    >>> from functools import partial
    >>>
    >>> @partial(jax.tree_util.register_dataclass,
    ...          data_fields=['x', 'y'],
    ...          meta_fields=['op'])
    ... @dataclass
    ... class MyStruct:
    ...   x: jax.Array
    ...   y: jax.Array
    ...   op: str
    ...
    >>> m = MyStruct(x=jnp.ones(3), y=jnp.arange(3), op='add')
    >>> m
    MyStruct(x=Array([1., 1., 1.], dtype=float32), y=Array([0, 1, 2], dtype=int32), op='add')

    Now that this class is registered, it can be used with functions in :mod:`jax.tree_util`:

    >>> leaves, treedef = jax.tree.flatten(m)
    >>> leaves
    [Array([1., 1., 1.], dtype=float32), Array([0, 1, 2], dtype=int32)]
    >>> treedef
    PyTreeDef(CustomNode(MyStruct[('add',)], [*, *]))
    >>> jax.tree.unflatten(treedef, leaves)
    MyStruct(x=Array([1., 1., 1.], dtype=float32), y=Array([0, 1, 2], dtype=int32), op='add')

    In particular, this registration allows ``m`` to be passed seamlessly through code
    wrapped in :func:`jax.jit` and other JAX transformations:

    >>> @jax.jit
    ... def compiled_func(m):
    ...   if m.op == 'add':
    ...     return m.x + m.y
    ...   else:
    ...     raise ValueError(f"{m.op=}")
    ...
    >>> compiled_func(m)
    Array([1., 2., 3.], dtype=float32)
  c                z     t           fdD                       }t           fdD                       }||fS )Nc              3  8   K   | ]}t          |          V  d S rs   getattrro   rH  r   s     r)   rv   z@register_dataclass.<locals>.flatten_with_keys.<locals>.<genexpr>  -      ::dD!!::::::r+   c              3  V   K   | ]#}t          |          t          |          fV  $d S rs   rG  r  r  s     r)   rv   z@register_dataclass.<locals>.flatten_with_keys.<locals>.<genexpr>  s:      NN$*T""GAt$4$45NNNNNNr+   r   r   metadatar~  r  s   `  r)   rV  z-register_dataclass.<locals>.flatten_with_keys  sR    ::::k:::::DNNNN+NNNNND:r+   c                    t          t          |                     }t          t          |                    }t          ||z             } di |S r  )r>   rw   r   )r  r  	meta_args	data_argskwargsr~  r  rT   s        r)   rX   z*register_dataclass.<locals>.unflatten_func  sY    c+t,,--Ic+t,,--I)i'((F8fr+   c                z     t           fdD                       }t           fdD                       }||fS )Nc              3  8   K   | ]}t          |          V  d S rs   r  r  s     r)   rv   z;register_dataclass.<locals>.flatten_func.<locals>.<genexpr>  r  r+   c              3  8   K   | ]}t          |          V  d S rs   r  r  s     r)   rv   z;register_dataclass.<locals>.flatten_func.<locals>.<genexpr>  r  r+   r   r  s   `  r)   rV   z(register_dataclass.<locals>.flatten_func  sR    ::::k:::::D::::k:::::D:r+   )
r>   r   register_dataclass_noder?   r   r   r]   r^   rU  r\  )rT   r~  r  rV  rX   rV   s   ```   r)   register_dataclassr    s0   V k""+k""+     
           
 **8T+5F5F[HYHYZZZ,,XtK7H7H${J[J[\\\++Hd;6G6GkIZIZ[[[&|^DD)H&@' '(# 
/r+   type[H]c                4    d }d }t          | ||           | S )a   Registers `cls` as a pytree with no leaves.

  Instances are treated as static by :func:`jax.jit`, :func:`jax.pmap`, etc. This can
  be an alternative to labeling inputs as static using ``jit``'s ``static_argnums``
  and ``static_argnames`` kwargs, ``pmap``'s ``static_broadcasted_argnums``, etc.

  Args:
    cls: type to be registered as static. Must be hashable, as defined in
      https://docs.python.org/3/glossary.html#term-hashable.

  Returns:
    The input class ``cls`` is returned unchanged after being added to JAX's
    pytree registry. This allows ``register_static`` to be used as a decorator.

  Examples:
    >>> import jax
    >>> @jax.tree_util.register_static
    ... class StaticStr(str):
    ...   pass

    This static string can now be used directly in :func:`jax.jit`-compiled
    functions, without marking the variable static using ``static_argnums``:

    >>> @jax.jit
    ... def f(x, y, s):
    ...   return x + y if s == 'add' else x - y
    ...
    >>> f(1, 2, StaticStr('add'))
    Array(3, dtype=int32, weak_type=True)
  c                
    d| fS r  rk   )objs    r)   r   z!register_static.<locals>.<lambda>&  s
    S	 r+   c                    | S rs   rk   )r  empty_iter_childrens     r)   r   z!register_static.<locals>.<lambda>'  s    s r+   )ry  )r`   r'   r1   s      r)   register_staticr    s,    @ "!'22)C)444	*r+   +tuple[list[tuple[KeyPath, Any]], PyTreeDef]c                L    t          | |          \  }}t          | |          |fS )a  Flattens a pytree like ``tree_flatten``, but also returns each leaf's key path.

  Args:
    tree: a pytree to flatten. If it contains a custom type, it must be
      registered with ``register_pytree_with_keys``.
  Returns:
    A pair which the first element is a list of key-leaf pairs, each of
    which contains a leaf and its key path. The second element is a treedef
    representing the structure of the flattened tree.
  )r*   _generate_key_paths)r    r!   r   tree_defs       r)   tree_flatten_with_pathr  ,  s,     T7+++!X	T7	+	+X	55r+   list[tuple[KeyPath, Any]]c                "    t          | |          S )a  Gets the leaves of a pytree like ``tree_leaves`` and returns each leaf's key path.

  Args:
    tree: a pytree. If it contains a custom type, it must be registered with
      ``register_pytree_with_keys``.
  Returns:
    A list of key-leaf pairs, each of which contains a leaf and its key path.

  See Also:
    - :func:`jax.tree_util.tree_leaves`
    - :func:`jax.tree_util.tree_flatten_with_path`
  )r  r(   s     r)   tree_leaves_with_pathr  >  s      
T7	+	++r+   c                >    t          t          d| |                    S r  )r?   _generate_key_paths_r(   s     r)   generate_key_pathsr  R  s     
"2tW55	6	66r+   key_pathIterable[tuple[KeyPath, Any]]c              #    K   |r |          r| fV  d S t                               t                              }|r>|                              \  }}|D ]!\  }}t	          g | |R ||          E d {V  "d S t
                                        }|| fV  d S t          t                    rbt          d          rR|d         t                    k    r9fdj
        D             }|D ]!\  }}t	          g | |R ||          E d {V  "d S t          |d                   D ]0\  }	}t          |	          }t	          g | |R ||          E d {V  1d S )N_fieldsr9   c                N    g | ]!}t          |          t          |          f"S rk   r  )ro   r   r    s     r)   rq   z(_generate_key_paths_.<locals>.<listcomp>q  s.    LLL!Z]]GD!$4$45LLLr+   r   )r\  getr  rV  r  r   r  r   r>   r|  r  	enumeraterM  )
r  r    r!   key_handlerrw  r   r   rv  r   rb  s
    `        r)   r  r  Z  s     
   
D.
F'++DJJ77+ !33D99OL! B B1%nn!nnaAAAAAAAAAA
F		+	+D	1	1$	\
D.
Fu '$	":": 
1gdLLLLt|LLLL B B1%nn!nnaAAAAAAAAAA
FQ   @ @da!A#NhNNNAw??????????@ @r+   c                    t          ||          \  }t          t          |           }|fd|D             z   }                     fdt          | D                       S )a4  Maps a multi-input function over pytree key path and args to produce a new pytree.

  This is a more powerful alternative of ``tree_map`` that can take the key path
  of each leaf as input argument as well.

  Args:
    f: function that takes ``2 + len(rest)`` arguments, aka. the key path and
      each corresponding leaves of the pytrees.
    tree: a pytree to be mapped over, with each leaf's key path as the first
      positional argument and the leaf itself as the second argument to ``f``.
    *rest: a tuple of pytrees, each of which has the same structure as ``tree``
      or has ``tree`` as a prefix.

  Returns:
    A new pytree with the same structure as ``tree`` but with the value at each
    leaf given by ``f(kp, x, *xs)`` where ``kp`` is the key path of the leaf at
    the corresponding leaf in ``tree``, ``x`` is the leaf value and ``xs`` is
    the tuple of values at corresponding nodes in ``rest``.

  See Also:
    - :func:`jax.tree_util.tree_map`
    - :func:`jax.tree_util.tree_flatten_with_path`
    - :func:`jax.tree_util.tree_leaves_with_path`
  c                :    g | ]}                     |          S rk   rl   rn   s     r)   rq   z&tree_map_with_path.<locals>.<listcomp>  s'    (P(P(Pa)>)>q)A)A(P(P(Pr+   c              3  "   K   | ]	} | V  
d S rs   rk   rt   s     r)   rv   z%tree_map_with_path.<locals>.<genexpr>  s)      EEb11b6EEEEEEr+   )r  r?   rw   r1   )rf   r    r!   rh   keypath_leavesall_keypath_leavesr,   s   `     @r)   tree_map_with_pathr  {  s{    : 34AA.'^,--.%(P(P(P(P4(P(P(PP			EEEEC1C,DEEE	E	EEr+   c                   t          t          |                     rJ t                              t	          |                     }|r2t          d |                    |           d         D                       S t          | t
                    r.t          | d          rt          d | j	        D                       S t          t          t          |                               }t          d t          |          D                       S )Nc              3      K   | ]	\  }}|V  
d S rs   rk   )ro   r   r   s      r)   rv   z_child_keys.<locals>.<genexpr>  s&      DDtq!DDDDDDr+   r   r  c              3  4   K   | ]}t          |          V  d S rs   )rG  )ro   r   s     r)   rv   z_child_keys.<locals>.<genexpr>  s(      771A777777r+   c              3  4   K   | ]}t          |          V  d S rs   )rM  ra  s     r)   rv   z_child_keys.<locals>.<genexpr>  s+      CC!"1%%CCCCCCr+   )rL   r:   r\  r  r  r>   rV  r   r|  r  r#  rE   r   )r   rX  num_childrens      r)   r$  r$    s    #N6$:$:;;;;;#''V55' DDDw88@@CDDDDDD&%   DWVY%?%? D77777777'v(>(>??@@LCCu\/B/BCCCCCCr+   %Iterable[Callable[[str], ValueError]]c           	   #     	
K   t          t          |                    rd S t                    t                    k    r fdV  d S t                    \  }t                    \  
}t	                    t	          
          
t                    t                    t          t          t          f          r<t                    t                    k    rt                     fdV  d S ni	 t                    
                    t                              	n	#  d 	Y nxY wt                    t          
          k    r	
 fdV  d S ||k    rt          |          t          |          t          j        d                    t          j                                                                                            d           fdV  d S k    sJ d	 d
             t%          
          D ]"\  }}}t'          g  |R ||          E d {V  #d S )Nre   c           
         t          dt                     dt                     dt                     d                    |                     S )Nz>pytree structure error: different types at key path
    {name}F
At that key path, the prefix pytree {name} has a subtree of type
    zN
but at the same key path the full pytree has a subtree of different type
    rJ  rK  r  rS  r  format)rH  r   r  r   s    r)   r   z_prefix_error.<locals>.<lambda>  sm    z H%%    +   
 )__     
 !'D 1 13 3 r+   c                    t          dj         dt                     dj         dt                     dt                     d                    |                     S )Nz-pytree structure error: different lengths of z at key path
    {name}zB
At that key path, the prefix pytree {name} has a subtree of type r  zC, but the full pytree has a subtree of the same type but of length rJ  rK  )r  r   rS  r#  r  )rH  r   r  r   rW  s    r)   r   z_prefix_error.<locals>.<lambda>  s    L"+ L L))L L [L L &)%5%5L L ;>i..	L L L
 6t6  r+   c                   t          dt                     dt                     dt                     dd                    d D                        dt                     dd                    d D                        d	                    | 
          dn!dd                    d D                        z             S )NzSpytree structure error: different numbers of pytree children at key path
    {name}r  z
with z child keys
    r  c              3  >   K   | ]}t          |j                  V  d S rs   r"  r  r  s     r)   rv   z2_prefix_error.<locals>.<lambda>.<locals>.<genexpr>  s*      ==qAE

======r+   zR
but at the same key path the full pytree has a subtree of the same type but with c              3  >   K   | ]}t          |j                  V  d S rs   r  r  s     r)   rv   z2_prefix_error.<locals>.<lambda>.<locals>.<genexpr>  s*      ;;qAE

;;;;;;r+   
rK  r  z/so the symmetric difference on key sets is
    c              3  >   K   | ]}t          |j                  V  d S rs   r  r  s     r)   rv   z2_prefix_error.<locals>.<lambda>.<locals>.<genexpr>  s*      44!3qu::444444r+   )r  rS  r  r#  r%  r  )rH  r1  full_tree_childrenfull_tree_keysr  r   prefix_tree_childrenprefix_tree_keyss    r)   r   z_prefix_error.<locals>.<lambda>  s&   	@h''	@ 	@ K  	@ 	@ ())		@ 	@
 xx==,<=====	@ 	@ /00	@ 	@ xx;;N;;;;;	@ 	@ 	@ 
T		227((44t444447 7	89 9 r+   r  z    )prefixc                    t          dt                     dt                     d d d 
                    |                     S )NzHpytree structure error: different pytree metadata at key path
    {name}r  z
with metadata
    z_
but at the same key path the full pytree has a subtree of the same type but with metadata
    z6
so the diff in the metadata at these pytree nodes is
rK  r  )rH  full_tree_meta_strr  metadata_diffr   prefix_tree_meta_strs    r)   r   z_prefix_error.<locals>.<lambda>  s    z
H%%
 
 +
 

 "
 
  
 
 

 
  T**, , r+   z4equal pytree nodes gave differing prefix_tree_keys: r!  )rL   r:   r  r  r>   r$  r   r?   r#  r&  r'  r"  textwrapindentr%  difflibndiff
splitlinesrw   r	  )r  r   r   r!   prefix_tree_metafull_tree_metar   r)  r*  r1  r  r  r  r  r  r  r  rW  s   ```      @@@@@@@@@r)   r	  r	    sa      N;HHHII 
F 
+$y//))3 3 3 3 3 3 3 3 3 F
 ,=[+I+I(('8'C'C$n344/00 --y)). dE]++  
;3y>>))b          f *!""77N8K8KLLddddd
  C(:$;$;;;9 9 9 9 9 9 9 9 9 9 9 9 9 f ''/00^,,O		M.99;;,7799; ;	< 	< 	  M
, , , , , , , , , , , F 
^	+	+	+00 0-0 0 
,	+	+ ')=?QRR 5 5iaR^x^^^R44444444445 5s   /E E	rs   )r    r
   r!   r"   r#   r$   )r,   r-   r.   r/   r#   r
   )r    r
   r!   r"   r#   r3   )r    r
   r!   r7   r#   r-   )r;   r<   r#   r-   )r,   r-   r#   rA   )r,   r-   r#   rF   )rM   rN   r!   r"   r#   rF   )rT   rU   rV   rW   rX   rY   r#   rZ   )r`   r   r#   r   )
rf   rg   r    r
   rh   r
   r!   r"   r#   r
   )r,   r-   ru   r
   r#   r
   )r|   r-   r}   r~   r   r
   r#   r
   )r   r   r    r
   r!   r"   r#   r   )
r   r   r    r
   r   r   r!   r"   r#   r   )
r   r   r    r
   r   r
   r!   r"   r#   r   )r    r
   r!   r"   r#   rF   )r   r
   r   r
   r!   r"   r#   r   )r   r
   r#   r  )r   r
   r   r
   r!   r"   r#   r  )r  r
   r  r
   r!   r"   r#   r  )r  r-   r  r-   r#   r  )r   rP  )rW  rU   rX  rY  r#   rZ   )rT   rU   rV  rp  rX   rq  rV   rr  )rT   r   r~  r  r  r  r#   r   )r`   r  r#   r  )r    r
   r!   r"   r#   r  )r    r
   r!   r"   r#   r  )r  rP  r    r
   r!   r"   r#   r  )r   r
   r#   rP  )
r  rP  r   r
   r   r
   r!   r"   r#   r  )j
__future__r   r   collections.abcr   r   r   r   dataclassesr   r  r   r	   operatorrb   r  typingr
   r   r   r   r   jax._srcr   jax._src.libr   jax._src.utilr   r   r   exportregister_exclusion__file__r   r  r   r   r  r-   r   r   r   PyTreeRegistryr   r   r*   r2   r5   r:   r@   rE   rI   rL   rP   rR   rS   r_   rd   rx   r{   r   
namedtupler]   r>   r?   r   r^   r   objectr   r   r   r   r   r   r   r   r   r  r
  r  r  r  r6  rC  rG  rM  BuiltInKeyEntryrO  rP  rS  rU  r]  r\  ry  r}  r  r  r  r  r  r  r  r  r$  r	  rk   r+   r)   <module>r     sF   # " " " " "     B B B B B B B B B B B B ! ! ! ! ! !                 < < < < < < < < < < < < < < # # # # # #       . . . . . . . .             
O	$	$ ! !( + + +GCLLge49%%%GCx   
	*6*,,  '  .   +V*DD$( ( (  !)  2   *F)44$( ( (   (  0   9=1 1 1 1 1 # # # #
 8<4 4 4 4 4  8<4 4 4 4 4 8 8 8 82    0        ,< < < < 7;, , , , ,6 GKx}555	7:X... FE FE FE FER , , , ,^  6:> > > > > > ( ( ( (< 1 1 1 1. ('(89k:RSS	>>//1H1HII....0F0F
G
G..DD==? ?DJJ335G5GHH	# # #  
 9=     
 
 9=    
  $28<W W W W W CG 1 1 1 1 1 1
  00FFH H H
> > >  IIK K K2 2 2 2 2 2 2 2* @7 @7 @7 @7 @7i @7 @7 @7F  HH33   >B
 
 
 
 
   @ ;?B B B B B EI9 9 9 9 9*K K K K6= 6= 6=r 
$         
$         
$         
$( ( ( ( ( ( (  ( Wj:KKL7:X...
#
 ) ) ) )$% % % % % % % %
	 	 	 	    	CC    
B
B    4II J J J  JJ    JJ  
  	H H H H HV , , , ,^ d d d dN " " " "J 7;6 6 6 6 6" 7;, , , , ,( 8<7 7 7 7 7 )  -1@ @ @ @ @B  @DF F F F F FD
D 
D 
D 
D" -1	`5 `5 `5 `5 `5 `5 `5r+   