
    uki                    L   U d dl mZ d dlZd dlmZmZmZmZ d dl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 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j6                  e        ed      Z edee         Z ede      Z eZ!eZ"ejF                  Z# ejH                         Z$e%e$_&        de$_%         ejN                  ddddd      Z(e%e(_&        de(_%         ejN                  ddddd      Z)e%e)_&        de)_%        e	 dd	 	 	 ded       Z*edfd       Z+e	 dd	 	 	 dgd       Z,e	 dd	 	 	 dhd       Z-edid       Z.edjd       Z/edkd       Z0dkdZ1e	 dd	 	 	 dld       Z2 edee         Z3 ed e      Z4 ed!e      Z5e6e5ef   Z7ee7   Z8e6e5d"f   Z9e	 dd	 	 	 	 	 	 	 	 	 dmd#       Z:ednd$       Z;edd%	 	 	 	 	 	 	 dod&       Z<edpd'       Z=e	 	 	 	 dqd(       Z> ej~                  d)d*d+g      Z@e6 e@d, d-       eA e@d. d/       eB e@d0 d1        ed       e@d2 d3       iZCd4eDd5<    G d6 d7      ZEe eE       df	 	 	 	 	 	 	 drd8       ZF eE       f	 	 	 	 	 	 	 dsd9ZGe eE       dd:	 	 	 	 	 	 	 	 	 dtd;       ZHedd%dud<       ZI G d= d>      ZJe G d? d@e
j                               ZK e:eKdA dB        e	 dd	 	 	 dvdC       ZL	 dd	 	 	 dwdDZM	 	 	 	 	 	 	 	 dxdEZNdydFZO	 	 	 	 dzdGZP	 dd	 	 	 d{dHZQ	 dd	 	 	 	 	 	 	 d|dIZR	 	 	 	 	 	 d}dJZSdK ZTej                  ZUdeDdL<   ej                  ZVdeDdM<   ej                  ZWdeDdN<   ej                  ZXdeDdO<   eddPdQd~dR       ZYddSZZe	 dd	 	 	 	 	 	 	 ddT       Z[edndU       Z\e	 	 	 d	 	 	 	 	 	 	 	 	 ddV       Z] e[ej                  dW dX        dY Z_ e[ej                  e_dZ        edd[       Zae	 	 d	 	 	 	 	 	 	 dd\       Zbe	 	 d	 	 	 	 	 	 	 dd]       ZcecZdeddd^	 	 	 	 	 	 	 	 	 	 	 dd_       Zedd`Zf	 dd	 	 	 	 	 	 	 	 	 ddaZg G db dc      Zhy)    )annotationsN)CallableHashableIterableSequence)partial)AnyTypeVar)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_registryr	   c                .    t         j                  | |      S )z"Alias of :func:`jax.tree.flatten`.r   flattentreeis_leafs     M/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/_src/tree_util.pytree_flattenr$   J   s    
 
	!	!$	00    c                $    | j                  |      S )z$Alias of :func:`jax.tree.unflatten`.)	unflatten)treedefleavess     r#   tree_unflattenr*   R   s     
		6	""r%   c                4    t         j                  | |      d   S )z!Alias of :func:`jax.tree.leaves`.r   r   r    s     r#   tree_leavesr,   X       
 
	!	!$	0	33r%   c                4    t         j                  | |      d   S )z$Alias of :func:`jax.tree.structure`.   r   r    s     r#   tree_structurer0   `   r-   r%   c                H    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   treedef_tupler   list)treedefss    r#   r2   r2   h   s    . 
		.X	??r%   c                "    | j                         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_childrenr8      s    , 
			r%   c                     | 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
  r/   )	num_nodesr7   s    r#   treedef_is_leafr;      s    & 
		a	r%   c                B    | j                   dk(  xr | j                  dk(  S )Nr/   )r:   
num_leavesr7   s    r#   treedef_is_strict_leafr>      s#    			a		;G$6$6!$;;r%   c                    |t        j                  t        |       S t        |       }t	        ||      }t        |      t        |      k(  xr t        d t        ||d      D              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])
  c              3  *   K   | ]  \  }}||u   y wN ).0itemleafs      r#   	<genexpr>zall_leaves.<locals>.<genexpr>   s      -#t-s   Tstrict)r   
all_leavesr   r3   r,   lenallzip)iterabler"   itemsr)   s       r#   rI   rI      si    * _-x88NE(Fv;#e*$  -'*5&'F- * r%   	_Children_AuxDataKeyEntry.c                    t         j                  | |||       t        j                  | |||       t        j                  | |||       t	        ||      t
        | <   y)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)nodetypeflatten_funcunflatten_funcflatten_with_keys_funcs       r#   register_pytree_noderZ      sd    R   n.D ""n.D !!n.D '|^D)Hr%   c                Z    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$   )rZ   opmethodcallerr*   )clss    r#   register_pytree_node_classr_   2  s%    X sBOON;S=O=OP	*r%   r"   c                    t        ||      \  }}|g|D cg c]  }|j                  |       c}z   }|j                   fdt        | D              S c c}w )zAlias of :func:`jax.tree.map`.c              3  (   K   | ]	  } |   y wrA   rB   rC   xsfs     r#   rF   ztree_map.<locals>.<genexpr>j  s     =b1b6=   )r$   flatten_up_tor'   rL   )re   r!   r"   restr)   r(   rrI   s   `       r#   tree_maprj   b  sY     !w//&'xTB7003BB*			=C,<=	== Cs   Ac                $    | j                  |      S )a  Build a treedef from a nested iterable structure

  DEPRECATED: Use :func:`jax.tree.unflatten` instead.

  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)
    >>> jax.tree_util.tree_unflatten(treedef, [10, 11, 12, 13])
    [(10, 11), {'a': 12, 'b': 13}]
  )from_iterable_tree)r(   rd   s     r#   
build_treerm   m  s    . 
	#	#B	''r%   c           
        t        |      \  }}|t        | j                  |      d         }|j                  }| j                  }|j                  ||z  k7  r"| j	                  |      }t        d| d|       t        |      }t        |      D 	
cg c]$  }	t        |      D 
cg c]  }
t        |       c}
& }}	}
t        | }t        t        t        |       |      }t        ||      S c c}
w c c}
}	w )z$Alias of :func:`jax.tree.transpose`.r   z	Mismatch
z
 != 
)r$   r0   rg   r=   compose	TypeErroriterrangenextrL   mapr   r*   )outer_treedefinner_treedefpytree_to_transposeflatr(   
inner_size
outer_sizeexpected_treedef	iter_flat___loltransposed_lolsubtreess                 r#   tree_transposer     s     23-$"=#>#>?R#STU#VWM''*''*J34$,,];
j	2B1CD
EE4j)=B:=N	79j 121tI2	# 	 9.7H(	x	00	 3	s   C2%C-7C2-C2rT   to_iter	from_iterc                
    | d fS rA   rB   rd   s    r#   <lambda>r     s
    b$Z r%   c                    t        |      S rA   tupler~   rd   s     r#   r   r     s
    uRy r%   c                
    | d fS rA   rB   r   s    r#   r   r     s
    RJ r%   c                    t        |      S rA   )r3   r   s     r#   r   r     s
    d2h r%   c                R    t        t        | j                                     d d d   S )N)r   sortedrN   r   s    r#   r   r     s    F6"((*+=$>tt$D r%   c                ,    t        t        | |            S rA   )dictrL   )keysrd   s     r#   r   r     s    $s4}*= r%   c                     y)N)rB   NrB   )zs    r#   r   r         r%   c                     y rA   rB   r   s     r#   r   r     r   r%   zdict[type[Any], _RegistryEntry]rU   c                      e Zd Zy)UnspecifiedN)__name__
__module____qualname__rB   r%   r#   r   r     s    r%   r   c                    t        |t              r!t        j                  | t	        ||            S t        j                  | t	        ||      |      S )z!Alias of :func:`jax.tree.reduce`.r`   )
isinstancer   	functoolsreducer,   )functionr!   initializerr"   s       r#   tree_reducer     sD     [)Hk$&HIIHk$&H+VVr%   c                    t        |       }|dk(  rt        |t              rt        d      |S |dk(  r| d   S |dz  }t	        | d | ||      }t	        | |d  ||      } |||      S )Nr   z?Must specify identity for parallel reduction of empty sequence.r/      )rJ   r   r   rp   _parallel_reduce)sequence	operationidentitylengthindexabs          r#   r   r     s    
 x=&q[(K(WXXO{A;aKE&5)9h?A%&)9h?AQ?r%   )r   r"   c               6    t        ||      }t        || |      S )z-Alias of :func:`jax.tree.reduce_associative`.r`   )r,   r   )r   r!   r   r"   r   s        r#   tree_reduce_associativer     s     w/(	(Ix	88r%   c               .    t        t        | |            S )zAlias of :func:`jax.tree.all`.r`   )rK   r,   r    s     r#   tree_allr     s     
[w/	00r%   c                  .    e Zd ZdZd Zd Zd Zd Zd Zy)_HashableCallableShimzGObject that delegates __call__, __hash__, and __eq__ to another object.c                    || _         y rA   fun)selfr   s     r#   __init__z_HashableCallableShim.__init__  s	    DHr%   c                &     | j                   |i |S rA   r   )r   argskws      r#   __call__z_HashableCallableShim.__call__  s    488T R  r%   c                ,    t        | j                        S rA   )hashr   r   s    r#   __hash__z_HashableCallableShim.__hash__  s    >r%   c                r    t        |t              r| j                  |j                  k(  S | j                  |k(  S rA   )r   r   r   r   others     r#   __eq__z_HashableCallableShim.__eq__  s/    %./XX""88ur%   c                "    d| j                   dS )Nz_HashableCallableShim()r   r   s    r#   __repr__z_HashableCallableShim.__repr__  s    #DHH<q11r%   N)	r   r   r   __doc__r   r   r   r   r   rB   r%   r#   r   r     s    O!
2r%   r   c                  "     e Zd ZdZ fdZ xZS )Partiala:  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
  JitTracer(~int32[])
  c                   t        |t        j                        rV|}t        |      }t	        |   | |g|i |}|j                  |_        |j                  |_        |j                  |_        |S t	        |   | |g|i |S rA   )	r   r   r   r   super__new__funcr   keywords)klassr   r   r   original_funcout	__class__s         r#   r   zPartial.__new__&  s     $	))*m"=1dGOE45$5"5c$$di$$di#,,dmjW_UD646266r%   )r   r   r   r   r   __classcell__)r   s   @r#   r   r     s    .`7 7r%   r   c                J    | j                   | j                  f| j                  fS rA   )r   r   r   )partial_s    r#   r   r   :  s    x}}h&7&78(--H r%   c                ,    t        | g|d   i |d   S Nr   r/   )r   )r   rd   s     r#   r   r   ;  s    WT3BqE3RU3 r%   c                R    t        | ||      }t        |      j                  |      S )z$Alias of :func:`jax.tree.broadcast`.r`   )broadcast_prefixr0   r'   )prefix_tree	full_treer"   broadcast_leavess       r#   tree_broadcastr   ?  s*    
 &k9gN			"	,	,-=	>>r%   c                    g d fd}	 t        || ||       S # t        $ r t        | |      ^}} |d      dw xY w)a  Broadcasts tree prefix leaves into the full set of leaves for a given full tree.

    Args:
      prefix_tree: a pytree that is a tree prefix of full_tree.
      full_tree: a pytree with the structure to broadcast the prefix leaves into.
      is_leaf: an optionally specified function that will be called at each
        flattening step for prefix_tree. It should return a boolean, with true
        stopping the traversal and the whole subtree being treated as a leaf,
        and false indicating the flattening should traverse the current object.

    Returns:
      A list of leaves matching the expected count for the full tree,
      with the leaf of each prefix tree being duplicated to match the count of
      its corresponding subtree.
  c                ,    t        |       j                  S rA   )r0   r=   )ts    r#   r   z"broadcast_prefix.<locals>.<lambda>\  s    *55 r%   c                :    j                  | g |      z        S rA   )extend)xsubtreer=   results     r#   r   z"broadcast_prefix.<locals>.<lambda>]  s    &--j6I0I"J r%   r`   zbroadcast_prefix prefix_treeN)rj   
ValueErrorprefix_errors)r   r   r"   
add_leaveser~   r=   r   s         @@r#   r   r   I  s]    $ &5*J*8ZiA 
- 
 8K3ea!,-478s	     !Ac                D     g  fd} ||dt               ||       S )a;  Broadcasts tree prefix leaves into the full set of leaves for a given full treedef.

    Args:
      prefix_leaves: the leaves of a pytree that is a tree prefix
        of full_treedef.
      prefix_treedef: the PyTreeDef of a pytree that is a tree prefix of
        full_treedef.
      full_treedef: a PyTreeDef with the structure to broadcast the prefix
        leaves into.

    Returns:
      A list of leaves matching the expected count for the full tree,
      with each leaf of prefix tree being duplicated to match the count of
      its corresponding subtree.
  c                   t        |      r,||z
  dk(  sJ j                  
|| |j                  z         y t        |      rt        d      |j	                         }|j	                         }||k7  rt        d| d|       |}t        |j                         |j                         d      D ]-  \  }}	 | | |||j                  z   ||	       ||j                  z  }/ y )Nr/   z2`prefix_treedef` is not a prefix of `full_treedef`z	expected z, got TrG   )r>   r   r=   r   	node_datarL   r6   )broadcast_fn
leaf_startleaf_endprefix_treedefr(   prefix_node_datar   prefix_iprefix_child
tree_childprefix_leavesrets             r#   
_broadcastz;broadcast_flattened_prefix_with_treedef.<locals>._broadcast  s    n- #)))	jjz(3g6H6HHIg&KLL%//1!!#I9$9+V4D3EFGGH$'!7#3#3#5d%D * j<8l6M6M+M ,)))h*r%   r   )rJ   )r   r   full_treedefr   r   s   `   @r#   'broadcast_flattened_prefix_with_treedefr   g  s+    8 	#*4 ZC.M	*r%   c                b    t         j                  |       }|t        dt        |              |S )a  Flatten the given pytree node by one level.

  Args:
    tree: 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')
  can't tree-flatten type: )r   flatten_one_levelr   typer!   r   s     r#   r   r     s5    . 	**40#[
0d=
>>Jr%   c                b    t         j                  |       }|t        dt        |              |S )z6Flatten the given pytree node by one level, with keys.r   )r   flatten_one_level_with_keysr   r   r   s     r#   r  r    s5     	44T:#[
0d=
>>Jr%   c                0    t        t        d| ||            S NrB   )r3   _prefix_error)r   r   r"   s      r#   r   r     s     
mBY@	AAr%   c              #  <   K   t        d| ||      E d{    y7 w)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))))
  rB   N)_equality_errors)tree1tree2r"   s      r#   equality_errorsr	    s     & b%888s   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                     y)Nzpytree leafrB   )r~   s    r#   r   z+equality_errors_pytreedef.<locals>.<lambda>  r   r%   )r   LeafrB   )r   r   r	  r*   r=   )r  r  rE   s      r#   equality_errors_pytreedefr    sj    
 
[	Jj4'41H#I	J6SUWY	Z	\$	v8H8H/HI'v8H8H/HI
K Kr%   c           	   #    K   t        t        ||            rt        t        ||            ry t        |      t        |      k7  r-| t        t        |            t        t        |            df y t	        |t
        t        f      r{t        |      t        |      k(  sJ t        |      t        |      k7  rK| t        |      j                   dt        |       t        |      j                   dt        |       df y t        |      \  }}t        |      \  }}t        |      }t        |      }t        |      t        |      }	}	 dj                  d t        |      j                  t        |	            D              }
t        |      t        |      k7  rh| t        |       dt        |       d	t        |      d
kD  rdnd t        |       dt        |       d	t        |      d
kD  rdnd d|
xr d|
 dz   f y ||k7  r%| t        |       d| t        |       d| df y ||	k(  sJ d| d|	        t        |||      D ]!  \  }}}t        g | ||||      E d {    # y #  d}
Y xY w7 w)Nr`   ztheir Python types differ of length zthe lengths do not match c              3  F   K   | ]  }t        |j                          y wrA   )reprkeyrC   ks     r#   rF   z#_equality_errors.<locals>.<genexpr>  s      EADK E   ! z with z childr/   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 )r>   r0   r   strr   r3   r   rJ   r   r   _child_keysjoinsetsymmetric_differencerL   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^B@AF 
"Xb
DHs48}.I
II
 T5M"8tBx
2w#b'R!!"+c"gY7R!!"+c"gY7') ) *2.+w*2.+wk"+k"+ _k"o7'88 EL55c'lCE ED 	[))2hZvc+./v;'!+e462hZvc+./v;'!+e461OFtfBOQ   2hZ-gY72hZ-gY746 6  
G	 N5gYeG9MN	w[9 =iaR
$

BG<<<=3D2 =s+   EI?9I4 C%I?,I=-I?4I:8I?SequenceKeyDictKey
GetAttrKeyFlattenedIndexKeyr  )simple	separatorc               T    |rt         nt        }|j                  t        ||             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.
    simple: If True, use a simplified string representation for keys. The
      simple representation of keys will be more compact than the default, but
      is ambiguous in some cases (for example "0" might refer to the first item
      in a list or a dictionary key for the integer 0 or string "0").
    separator: The separator to use to join string representations of the keys.

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

  Examples:
    >>> import jax
    >>> params = {'foo': {'bar': {'baz': 1, 'bat': [2, 3]}}}
    >>> for path, _ in jax.tree_util.tree_leaves_with_path(params):
    ...   print(jax.tree_util.keystr(path))
    ['foo']['bar']['bat'][0]
    ['foo']['bar']['bat'][1]
    ['foo']['bar']['baz']
    >>> for path, _ in jax.tree_util.tree_leaves_with_path(params):
    ...   print(jax.tree_util.keystr(path, simple=True, separator='/'))
    foo/bar/bat/0
    foo/bar/bat/1
    foo/bar/baz
  )_simple_entrystrr  r  rt   )r   r1  r2  str_fns       r#   keystrr6  5  s$    :  &3&	FD)	**r%   c                    | xt         d x\  n- xt        d x\  n xt        d x\  n xt        d x\  n  n}  t	        |       S 	 t	        |       S )N)idxr  )name)r-  r.  r/  r0  r  r9  s    r#   r4  r4  V  sB    
'

*

$

$	%
 Xo	
Xor%   c                4    |sfd}|}t        | ||       y)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                T     |       \  }}|D cg c]  \  }}|	 c}}|fS c c}}w rA   rB   )r!   key_childrenr(   r~   cflatten_with_keyss        r#   flatten_func_implz4register_pytree_with_keys.<locals>.flatten_func_impl  s/    /5lG()DAqa)722)s   $N)rZ   )rV   r?  rX   rW   r@  s    `   r#   register_pytree_with_keysrA  c  s'    x 
3 %Ln.?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)hasattrr\   r]   rA  r*   )r^   rW   s     r#   register_pytree_with_keys_classrE    sL    N *1n)Eboon%4  	2??34c6H6H 
*r%   c                |    щdu du k7  rt        ddd      t        j                         st        d d      t        j                         D cg c]*  }|j                  j                  dd      s|j                  , c}t        j                         D cg c]*  }|j                  j                  dd      r|j                  , c}J J t              t              t        j                         rt        j                         D ch c]  }|j                  s|j                   }} |j                  |  h |k7  r5d}|h z
  x}r	|d	| d
z  }h |z
  x}r	|d| dz  }t        |       fd}	fd}
t        j                   t              t                     t        j                   t              t                     t        j                   t              t                     t!        |
|	      t"         <    S c c}w c c}w c c}w )a  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:`pytrees-custom-pytree-nodes` 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: metadata field names: these are attributes which will be treated as
      :term:`static` when this pytree is passed to :func:`jax.jit`. ``meta_fields`` is
      optional only if ``nodetype`` is a dataclass, in which case individual fields can
      be marked static via :func:`dataclasses.field` (see examples below).
      Metadata fields *must* be static, hashable, immutable objects, as these objects
      are used to generate JIT cache keys. In particular, metadata fields cannot contain
      :class:`jax.Array` or :class:`numpy.ndarray` objects.
    data_fields: data field names: these are attributes which will be treated as non-static
      when this pytree is passed to :func:`jax.jit`. ``data_fields`` is optional only if
      ``nodetype`` is a dataclass, in which case fields are assumed data fields unless
      marked via :func:`dataclasses.field` (see examples below).
      Data 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 ``None`` is a valid data field, as JAX recognizes this as an empty pytree.

  Returns:
    The input class ``nodetype`` is returned unchanged after being added to JAX's
    pytree registry, so that :func:`register_dataclass` can be used as a decorator.

  Examples:
    In JAX v0.4.35 or older, you must specify ``data_fields`` and ``meta_fields``
    in order to use this decorator:

    >>> import jax
    >>> 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')

    Starting in JAX v0.4.36, the ``data_fields`` and ``meta_fields`` arguments are optional
    for :func:`~dataclasses.dataclass` inputs, with fields defaulting to ``data_fields``
    unless marked as static using `static` metadata in :func:`dataclasses.field`.

    >>> import jax
    >>> from dataclasses import dataclass, field
    ...
    >>> @jax.tree_util.register_dataclass
    ... @dataclass
    ... class MyStruct:
    ...   x: jax.Array  # defaults to non-static data field
    ...   y: jax.Array  # defaults to non-static data field
    ...   op: str = field(metadata=dict(static=True))  # marked as static meta field.
    ...
    >>> 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')

    Once this class is registered, it can be used with functions in :mod:`jax.tree` and
    :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, with ``data_fields`` being
    treated as dynamic arguments, and ``meta_fields`` being treated as static arguments:

    >>> @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)
  Nzqregister_dataclass: data_fields and meta_fields must both be specified when either is specified. Got data_fields=z meta_fields=.zlregister_dataclass: data_fields and meta_fields are required when nodetype is not a dataclass. Got nodetype=staticFz_data_fields and meta_fields must include all dataclass fields with ``init=True`` and only them.z Missing fields: z1. Add them to drop_fields to suppress this error.z Unexpected fields: c                    t        t        |             }t        t        |            }t        ||z         } di |S r  )r   rL   r   )metadata	meta_args	data_argskwargsdata_fieldsmeta_fieldsrV   s        r#   rX   z*register_dataclass.<locals>.unflatten_funch  sB    c+t,-Ic+t,-I)i'(Ffr%   c                ^     t         fdD              }t         fdD              }||fS )Nc              3  6   K   | ]  }t        |        y wrA   getattrrC   r:  r   s     r#   rF   z;register_dataclass.<locals>.flatten_func.<locals>.<genexpr>o       :dD!:   c              3  6   K   | ]  }t        |        y wrA   rS  rU  s     r#   rF   z;register_dataclass.<locals>.flatten_func.<locals>.<genexpr>p  rV  rW  r   )r   rJ  rK  rO  rP  s   `  r#   rW   z(register_dataclass.<locals>.flatten_funcn  s-    :k::D:k::D:r%   )rp   dataclassesis_dataclassfieldsmetadatagetr:  r   initdifference_updater   r   register_dataclass_noder3   r   r   rT   rU   )rV   rO  rP  drop_fieldsre   init_fieldsmsgmissing
unexpectedrX   rW   s   ```        r#   register_dataclassrf    sw   P K/t!45 E8C~^{nTUW X X##H- E;C+QH I I#.#5#5h#? ;a**..59 66 ;K#.#5#5h#? 7ajjnnXu5 66 7K 
	  	 		  	 
 k"+k"+h'#.#5#5h#?Ja166166JKJ!K!!;/##{#{2* 
  ">K">+">>	>	>y ) 	
 43{3kA	A	A%j\33sO
 **8T+5F[HYZ,,XtK7H${J[\++Hd;6GkIZ[&|^D)H	/];7 Ks   /H/'/H4#H95H9c                z     t         fd j                         D              t         j                               fS )Nc              3  >   K   | ]  }t        |      |   f  y wrA   r.  )rC   r  r   s     r#   rF   z<lambda>.<locals>.<genexpr>|  s     :Agaj!A$':   )r   r   )r   s   `r#   r   r   |  s'    u:::E!&&(OL r%   c                @    t        j                  t        | |            S rA   )collectionsOrderedDictr   )r   valuess     r#   r   r   }  s    00$1GH r%   c                p     t        t                     }t         fd|D               j                  |ffS )Nc              3  >   K   | ]  }t        |      |   f  y wrA   ri  )rC   r  ds     r#   rF   z1_flatten_defaultdict_with_keys.<locals>.<genexpr>  s     0a
AaD!0rj  )r   r   default_factory)rq  r   s   ` r#   _flatten_defaultdict_with_keysrs    s2    	vay	$	040	013D3Dd2K	KKr%   c                N    t        j                  | d   t        | d   |            S r   )rl  defaultdictr   )srn  s     r#   r   r     s"    k--adHQqT64JK r%   c                ,    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  rB   )objs    r#   r   z!register_static.<locals>.<lambda>  s
    S	 r%   c                    | S rA   rB   )ry  empty_iter_childrens     r#   r   z!register_static.<locals>.<lambda>  s    s r%   )rA  )r^   r   r'   s      r#   register_staticr|    s     @ "'2)C)4	*r%   c                F    }|sfd}t         j                  | |      S )z,Alias of :func:`jax.tree.flatten_with_path`.c                     |      S rA   rB   )r~   r   r"   s     r#   r   z(tree_flatten_with_path.<locals>.<lambda>  s    71: r%   )r   flatten_with_path)r!   r"   is_leaf_takes_pathis_leaf_with_kps    `  r#   tree_flatten_with_pathr    s*     8?/	 3-O		+	+D/	BBr%   c                "    t        | ||      d   S )z+Alias of :func:`jax.tree.leaves_with_path`.r   )r  )r!   r"   r  s      r#   tree_leaves_with_pathr    s     
 g/A	B1	EEr%   )r"   r  c                    t        |||      \  }}t        t        |       }||D cg c]  }|j                  |       c}z   }|j	                   fdt        | D              S c c}w )z(Alias of :func:`jax.tree.map_with_path`.c              3  (   K   | ]	  } |   y wrA   rB   rc   s     r#   rF   z%tree_map_with_path.<locals>.<genexpr>  s     Eb1b6Erf   )r  r3   rL   rg   r'   )	re   r!   r"   r  rh   keypath_leavesr(   ri   all_keypath_leavess	   `        r#   tree_map_with_pathr    sq     3
G'.' ^,-.%4(Pa)>)>q)A(PP			EC1C,DE	EE )Qs   A%c                j    t        t        |             rJ t        d t        |       d   D              S )Nc              3  &   K   | ]	  \  }}|  y wrA   rB   )rC   r  r~   s      r#   rF   z_child_keys.<locals>.<genexpr>  s     DTQqDs   r   )r>   r0   r   r  r   s    r#   r  r    s1    #N6$:;;	;	D8@CD	DDr%   c           	   #     	
K   t        t        |            ry t              t              k7  r
 fd y t              \  }t              \  
}t	              t	        
      
t              t              t        t        t        f      r-t              t              k7  r_t               fd y 	 t              j                  t                    	t              t        
      k7  r	
 fd y ||k7  rxt        |      t        |      t        j                  dj                  t        j                   j#                         j#                                     d       fd y k(  sJ d	 d
        t%        
      D ]   \  }}}t'        g  |||      E d {    " y #  d 	Y xY w7 w)Nr`   c                n    t        d|  t               d|  dt               dt               d
      S )Nz8pytree structure error: different types at key path
    %
At that key path, the prefix pytree  has a subtree of type
    zN
but at the same key path the full pytree has a subtree of different type
    rG  r   r6  r   )r:  r   key_pathr   s    r#   r   z_prefix_error.<locals>.<lambda>  sP    zF6(#$ %--1F 3+  )_Q ! r%   c                    t        dj                   d|  t               d|  dj                   dt               dt               d      S )Nz-pytree structure error: different lengths of z at key path
    r  z has a subtree of type r  zC, but the full pytree has a subtree of the same type but of length rG  )r   r   r6  rJ   )r:  r   r  r   tys    r#   r   z_prefix_error.<locals>.<lambda>  sf    9"++ Gvh'( )1156M[[MS%5$6 7::=i.9I	LM r%   c                6   t        d|  t               d|  dt               dt               ddj	                  d D               dt               ddj	                  d	 D               d
dz         S ddj	                  d D               z         S )NzMpytree structure error: different numbers of pytree children at key path
    r  r  z
with z child keys
    r  c              3  F   K   | ]  }t        |j                          y wrA   r  r  r  s     r#   rF   z2_prefix_error.<locals>.<lambda>.<locals>.<genexpr>  s     =qAEE
=r  zR
but at the same key path the full pytree has a subtree of the same type but with c              3  F   K   | ]  }t        |j                          y wrA   r  r  s     r#   rF   z2_prefix_error.<locals>.<lambda>.<locals>.<genexpr>  s     ;qAEE
;r  
r  z/so the symmetric difference on key sets is
    c              3  F   K   | ]  }t        |j                          y wrA   r  r  s     r#   rF   z2_prefix_error.<locals>.<lambda>.<locals>.<genexpr>  s     4!3quu:4r  )r   r6  r   rJ   r  )r:  r*  full_tree_childrenfull_tree_keysr  r   prefix_tree_childrenprefix_tree_keyss    r#   r   z_prefix_error.<locals>.<lambda>  s    	fVH%& '//3f 5K ! "()* +xx=,<==> ?/01 2xx;N;;<B	@ 2	89 ((4t4457	89 r%   r  z    )prefixc                f    t        d|  t               d|  dt               d d d       S )NzBpytree structure error: different pytree metadata at key path
    r  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
r  )r:  full_tree_meta_strr  metadata_diffr   prefix_tree_meta_strs    r#   r   z_prefix_error.<locals>.<lambda>'  sa    zF6(#$ %--1F 3+  !" #    !?	
 r%   z4equal pytree nodes gave differing prefix_tree_keys: r  )r>   r0   r   r   r   r  r   r3   rJ   r  r   r  textwrapindentr  difflibndiff
splitlinesrL   r  )r  r   r   r"   prefix_tree_metafull_tree_metar  r"  r#  r*  r  r  r  r  r  r  r  r  s   ```      @@@@@@@@@r#   r  r    s     N;HI
 
+$y/)! ! 
 ,=[+I(('8'C$n34/0 -y). dE]+
;3y>)bM M !"77N8KLd  C(:$;;9 9 9  '/0^,OO		MM.99;,779;	< 	M
   
^	+ 1;~.01	+ ')=?QR 5iaR^x^^R4445]d\ 5s+   CG&#G 6CG&G$G&G!G&c                      e Zd ZdZddZddZddZ	 	 	 	 	 	 	 	 	 	 ddZddZddZ	e
d        Zdd	Ze
dd
       ZddZddZd Zd Zd Zd Zy)FlatTreea  A FlatTree stores a treedef and a flat list of values. It's meant to be
  isomorphic to the corresponding pytree but we can map over it more easily.
  Compared to `tree_map`, FlatTree.map has these benefits:
    1. It doesn't touch user flatten/unflatten code (which shouldn't have side
       effects but sometimes does in practice).
    2. It can be faster, because it skips the recursive traversal.
    3. It actually obeys the functor rules. For example,
       `flat_tree.map(lambda x: (f(x), g(x))).unzip2()[0]` will give
       the same result as `flat_tree.map(f)`, whereas in the `tree_map` version
       the tuple-returning function would change the tree structure and `unzip`
       wouldn't be able to recover it.
  c                j    t        |t        j                        sJ || _        t	        |      | _        y rA   )r   r   	PyTreeDefr!   r   vals)r   r  r(   s      r#   r   zFlatTree.__init__L  s*    gv//000DIdDIr%   c                    g }| j                   D ]  }|j                   ||              t        || j                        S rA   r  appendr  r!   )r   re   ans_valsr   s       r#   rt   zFlatTree.mapQ  s;    HYY ooadHdii((r%   c                    t        |       }t        |      |k(  sJ g }t        | j                  |j                        D ]  \  }}|j                   |||              t	        || j
                        S rA   rJ   rL   r  r  r  r!   )r   re   r#  nr  x1x2s          r#   map2zFlatTree.map2W  se    D	Ar7a<<Hdii) !BooaBi !Hdii((r%   c                   t        |       }t        |      |k(  rt        |      |k(  sJ g }t        | j                  |j                  |j                        D ]  \  }}}|j                   ||||             ! t	        || j
                        S rA   r  )	r   re   r#  t3r  r  r  r  x3s	            r#   map3zFlatTree.map3`  sz    D	Ar7a<CGqL((H$))RWWbgg6 %
BooaBm$%Hdii((r%   c                    J rA   rB   )r   r#  s     r#   rL   zFlatTree.zipi  s    5r%   c                    g }g }| j                   D ]'  \  }}|j                  |       |j                  |       ) t        || j                        t        || j                        fS rA   r  )r   yszsyr   s        r#   r   zFlatTree.unzip2l  s\    	B	B		 1iiliil B		"HR$;;;r%   c                x   t        | t              r| S t        | t              rkg }g }| D ]M  }t        j                  |      }|j	                  |j
                         |j                  |j                         O t        |t        |            S t        | t              r| i k(  rt        j                  i       S J J rA   )r   r  r   packr   r  r  r!   r2   r   r   )r!   r  trees
child_treechilds        r#   r  zFlatTree.packv  s     $!k	D%	 de !*j)EJJUZZ ! dM%011	D$		##uUr%   c                    t        | j                        }g }d}|D ];  }||j                  z   }|j                  t	        | j
                  || |             |}= t        |      S )Nr   )r8   r!   r=   r  r  r  r   )r   r  r6   offsetr!   
new_offsets         r#   unpackzFlatTree.unpack  sh     TYY'EHF DOO+joohtyy
;TBCf ?r%   c                $    t        t        |        S rA   )r  r$   )r!   s    r#   r   zFlatTree.flatten  s    \$'((r%   c                B    t        | j                  | j                        S rA   )r*   r!   r  r   s    r#   r'   zFlatTree.unflatten  s    $))TYY//r%   c                .    t        || j                        S rA   )r  r!   )r   new_valss     r#   update_from_listzFlatTree.update_from_list  s    Hdii((r%   c                .    | j                   j                  S rA   )r!   r=   r   s    r#   __len__zFlatTree.__len__  s    99r%   c                6    | j                   j                         S rA   )r  __iter__r   s    r#   r  zFlatTree.__iter__  s    99r%   c                    t        |t              xr4 | j                  |j                  k(  xr | j                  |j                  k(  S rA   )r   r  r  r!   r   s     r#   r   zFlatTree.__eq__  s;    uh' (		UZZ'(		UZZ')r%   c                D    t        | j                  | j                  f      S rA   )r   r  r!   r   s    r#   r   zFlatTree.__hash__  s    DII&''r%   N)r  r   r(   r  )re   r   returnr  )r   r  re   r   r#  r  r  r  )
r   r  re   r   r#  r  r  r  r  r  )r#  r  r  r  )r   r  r  ztuple[FlatTree, FlatTree])r   r  r  ztuple[FlatTree, ...])r!   PyTreer  r  )r  r  )r  r3   r  r  )r   r   r   r   r   rt   r  r  rL   r   staticmethodr  r  r   r'   r  r  r  r   r   rB   r%   r#   r  r  ?  s    
)))))$,)19)>F)<  ,
 ) )0)  )
(r%   r  rA   )r!   r	   r"   Callable[[Any], bool] | Noner  ztuple[list[Leaf], PyTreeDef])r(   r  r)   zIterable[Leaf]r  r	   )r!   r	   r"   r  r  z
list[Leaf])r!   r	   r"   zNone | Callable[[Any], bool]r  r  )r4   zIterable[PyTreeDef]r  r  )r(   r  r  zlist[PyTreeDef])r(   r  r  bool)rM   zIterable[Any]r"   r  r  r  )
rV   type[T]rW   z)Callable[[T], tuple[_Children, _AuxData]]rX   z"Callable[[_AuxData, _Children], T]rY   z3Callable[[T], tuple[KeyLeafPairs, _AuxData]] | Noner  None)r^   r   r  r   )
re   Callable[..., Any]r!   r	   rh   r	   r"   r  r  r	   )r(   r  rd   r	   r  r	   )ru   r  rv   zPyTreeDef | Nonerw   r	   r  r	   )
r   zCallable[[T, Any], T]r!   r	   r   T | Unspecifiedr"   r  r  r   )r   zlist[T]r   Callable[[T, T], T]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  	list[Any])r   r  r   r  r   r  r  r  )r!   r	   r  ztuple[Iterable[Any], Hashable])r!   r	   r  z&tuple[Iterable[KeyLeafPair], Hashable])r   r	   r   r	   r"   r  r  z!list[Callable[[str], ValueError]])r  r	   r  r	   r"   r  r  'Iterable[tuple[KeyPath, str, str, str]])r  r  r  r  r  r  )r   KeyPathr1  r  r2  r  r  r  )r  rQ   r  r  )rV   r  r?  z5Callable[[T], tuple[Iterable[KeyLeafPair], _AuxData]]rX   z&Callable[[_AuxData, Iterable[Any]], T]rW   z4None | Callable[[T], tuple[Iterable[Any], _AuxData]])NNrB   )
rV   r   rO  Sequence[str] | NonerP  r  ra  zSequence[str]r  r   )r^   type[H]r  r  )NF)r!   r	   r"   Callable[..., bool] | Noner  r  r  z+tuple[list[tuple[KeyPath, Any]], PyTreeDef])r!   r	   r"   r  r  r  r  zlist[tuple[KeyPath, Any]])re   r  r!   r	   rh   r	   r"   r  r  r  r  r	   )r   r	   r  r  )
r  r  r   r	   r   r	   r"   r  r  z%Iterable[Callable[[str], ValueError]])i
__future__r   rl  collections.abcr   r   r   r   rY  r  r   r   operatorr\   r  typingr	   r
   jax._srcr   jax._src.libr   jax._src.utilr   r   r   exportregister_exclusion__file__r   r   r   r   r  r  r  r   r   r   PyTreeRegistryr   r   r$   r*   r,   r0   r2   r8   r;   r>   rI   rO   rP   rQ   r   KeyLeafPairKeyLeafPairsr  rZ   r_   rj   rm   r   
namedtuplerT   r3   r   rU   __annotations__r   r   r   r   r   r   r   r   r   r   r   r  r   r	  r  r  r-  r.  r/  r0  r6  r4  rA  rE  rf  rm  rs  ru  r|  r  r  generate_key_pathsr  r  r  r  rB   r%   r#   <module>r     s`   #  B B        #  .   
O	$ ! ! !( +CLe49%Cx 
		*6**,  '  .   +V**DD$(  !)  2   *F))44$(   (  0   9=16121 1 # #
 8<4544 4  8<454@I4 4 @ @2  0    ,< 7;4@D < Kx}5	:X.:S)HcM"$
#
  	QEQE;QE 7QE
 	<QE 
QE QEh , ,^  6:>>> 3> ?B> > ( (2 1(+1031 1. (''(89k:RS	>/1HI..0F
G.D=?J35GH.	*    0;}8<WW,W 6W BCW W !,"  	& 
 !,,0	9"	9
	9 		9
 *	9 	9 	9 CG 1 1
2 2* @7i @7 @7F H3 ;??8?? ? >B:#<::: : 	:|>
+ ;?B7B8B EI999%A9,9*KKK@K6=r %%S %~~ ##
C #11 3 1 ,1B + +@
 
 LP	CCLC ;C I	C CL , ,^  )-(,!#	\\%\ &\ 	\
 	\ \~ LHL "K " "J 59$C
C2CC 1C C 59$F
F2FF F F +  
 +/$FF
F F (	F
 F 	F F E -1	^5^5^5 ^5 *	^5
 +^5Dp( p(r%   