
    &Vfl)                       U d Z ddlmZ ddlZddlZddlm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 dd	lmZ dd
lmZmZ ddlmZmZ ddlmZmZ g dZ ede          Z de!d<    ede          Z"de!d<    G d d          Z#	 ddl$m#Z# n# e%$ r Y nw xY w	 d8dddd9d Z&e&Z'd:d'Z(d;d+Z)d<d,Z*d=d2Z+d>d7Z,dS )?zIntegration with JAX.    )annotationsN)FunctionType)AnyCallable)	TypeAlias)Arraylax)dtypes)	ArrayLike)tree_flattentree_unflatten)
PyTreeSpecPyTreeTypeVar)safe_ziptotal_order_sorted)ArrayLikeTree	ArrayTree
tree_ravelr   r   r   c                  R    e Zd ZU dZded<   ded<   ded<   ddZddZddZddZdS )HashablePartialz1A hashable version of :class:`functools.partial`.r   funcztuple[Any, ...]argszdict[str, Any]kwargsFunctionType | HashablePartialr   returnNonec                H   t          |          st          d|d          t          |t                    r-|j        | _        |j        |z   | _        i |j        || _        dS t          |t                    r|| _        || _        || _        dS t          d|d          )z.Construct a :class:`HashablePartial` instance.zExpected a callable, got .zExpected a function, got N)callable	TypeError
isinstancer   r   r   r   r   )selfr   r   r   s       S/var/www/html/software/conda/lib/python3.11/site-packages/optree/integration/jax.py__init__zHashablePartial.__init__C   s    ~~ 	CAAAABBBdO,, 		C	DI	D(DI3T[3F3DKKKl++ 	CDIDI DKKKAAAABBB    otherobjectboolc                    t          |          t          u o9| j        j        |j        j        k    o| j        |j        k    o| j        |j        k    S N)typer   r   __code__r   r   )r"   r&   s     r#   __eq__zHashablePartial.__eq__S   sP    KK?* ,	"ej&99,	UZ', u|+		
r%   intc           
         t          | j        j        | j        t	          t          | j                                        d                     f          S )Nc                    | d         S )Nr    )kvs    r#   <lambda>z*HashablePartial.__hash__.<locals>.<lambda>`   s    RPQU r%   )key)hashr   r,   r   tupler   r   items)r"   s    r#   __hash__zHashablePartial.__hash__[   sQ    	"	():):)<)<BRBRSSSTT
 
 	
r%   c                >     | j         g | j        |R i | j        |S r*   )r   r   r   )r"   r   r   s      r#   __call__zHashablePartial.__call__d   s0    tyD$)DdDDDdkDVDDDr%   N)r   r   r   r   r   r   r   r   )r&   r'   r   r(   )r   r.   )r   r   r   r   r   r   )	__name__
__module____qualname____doc____annotations__r$   r-   r8   r:   r1   r%   r#   r   r   <   s         ;;C C C C 
 
 
 

 
 
 
E E E E E Er%   r   )r   F )none_is_leaf	namespacetreeis_leafCallable[[Any], bool] | NonerA   r(   rB   strr   *tuple[Array, Callable[[Array], ArrayTree]]c                   t          | |||          \  }}t          |          \  }}|t          t          ||          fS )a
  Ravel (flatten) a pytree of arrays down to a 1D array.

    >>> tree = {
    ...     'layer1': {
    ...         'weight': jnp.arange(0, 6, dtype=jnp.float32).reshape((2, 3)),
    ...         'bias': jnp.arange(6, 8, dtype=jnp.float32).reshape((2,)),
    ...     },
    ...     'layer2': {
    ...         'weight': jnp.arange(8, 10, dtype=jnp.float32).reshape((1, 2)),
    ...         'bias': jnp.arange(10, 11, dtype=jnp.float32).reshape((1,))
    ...     },
    ... }
    >>> tree
    {'layer1': {'weight': Array([[0., 1., 2.],
                                 [3., 4., 5.]], dtype=float32),
                'bias': Array([6., 7.], dtype=float32)},
     'layer2': {'weight': Array([[8., 9.]], dtype=float32),
                'bias': Array([10.], dtype=float32)}}
    >>> flat, unravel_func = tree_ravel(tree)
    >>> flat
    Array([ 6.,  7.,  0.,  1.,  2.,  3.,  4.,  5., 10.,  8.,  9.], dtype=float32)
    >>> unravel_func(flat)
    {'layer1': {'weight': Array([[0., 1., 2.],
                                 [3., 4., 5.]], dtype=float32),
                'bias': Array([6., 7.], dtype=float32)},
     'layer2': {'weight': Array([[8., 9.]], dtype=float32),
                'bias': Array([10.], dtype=float32)}}

    Args:
        tree (pytree): a pytree of arrays and scalars to ravel.
        is_leaf (callable, optional): An optionally specified function that will be called at each
            flattening step. It should return a boolean, with :data:`True` stopping the traversal
            and the whole subtree being treated as a leaf, and :data:`False` indicating the
            flattening should traverse the current object.
        none_is_leaf (bool, optional): Whether to treat :data:`None` as a leaf. If :data:`False`,
            :data:`None` is a non-leaf node with arity 0. Thus :data:`None` is contained in the
            treespec rather than in the leaves list and :data:`None` will be remain in the result
            pytree. (default: :data:`False`)
        namespace (str, optional): The registry namespace used for custom pytree node types.
            (default: :const:`''`, i.e., the global namespace)

    Returns:
        A pair ``(array, unravel_func)`` where the first element is a 1D array representing the
        flattened and concatenated leaf values, with ``dtype`` determined by promoting the
        ``dtype``\s of leaf values, and the second element is a callable for unflattening a 1D array
        of the same length back to a pytree of the same structure as the input ``tree``. If the
        input pytree is empty (i.e. has no leaves) then as a convention a 1D empty array of the
        default dtype is returned in the first component of the output.
    )rD   rA   rB   )r   _ravel_leavesr   _tree_unravel)rC   rD   rA   rB   leavestreespecflatunravel_flats           r#   r   r   o   sU    p $!	  FH 'v..D,,GGGGr%   rL   r   rN   "Callable[[Array], list[ArrayLike]]rM   r   c                4    t          |  ||                    S r*   )r   )rL   rN   rM   s      r#   rJ   rJ      s    
 (LL$6$6777r%   rK   list[ArrayLike]0tuple[Array, Callable[[Array], list[ArrayLike]]]c                H   | st          j        g           t          fS t          d | D                       }t	          j        | t          d | D                       }t          d | D                       }t          t          j        |                    }t          fd|D                       r6t          j	        d | D                       }|t          t          ||          fS t          j	        fd| D                       }|t          t          |||          fS )Nc              3  >   K   | ]}t          j        |          V  d S r*   )r
   dtype.0leafs     r#   	<genexpr>z _ravel_leaves.<locals>.<genexpr>   s,      >>tT**>>>>>>r%   c              3  >   K   | ]}t          j        |          V  d S r*   )jnpsizerV   s     r#   rY   z _ravel_leaves.<locals>.<genexpr>   s*      44T#(4..444444r%   c              3  >   K   | ]}t          j        |          V  d S r*   )r[   shaperV   s     r#   rY   z _ravel_leaves.<locals>.<genexpr>   s*      66t39T??666666r%   c              3  $   K   | ]
}|k    V  d S r*   r1   )rW   dtto_dtypes     r#   rY   z _ravel_leaves.<locals>.<genexpr>   s'      
0
0b2>
0
0
0
0
0
0r%   c                6    g | ]}t          j        |          S r1   )r[   ravelrV   s     r#   
<listcomp>z!_ravel_leaves.<locals>.<listcomp>   s     "F"F"Ft39T??"F"F"Fr%   c                ^    g | ])}t          j        t          j        |                    *S r1   )r[   rc   r	   convert_element_type)rW   rX   ra   s     r#   rd   z!_ravel_leaves.<locals>.<listcomp>   s0    PPP3+D(;;	<	<PPPr%   )r[   array_unravel_emptyr6   r
   result_type	itertools
accumulateallconcatenater   _unravel_leaves_single_dtype_unravel_leaves)rK   from_dtypessizesshapesindicesraveledra   s         @r#   rI   rI      sG     /	"~..>>v>>>>>K!;/H44V44444E66v66666FI(//00G

0
0
0
0K
0
0
000 
 /"F"Fv"F"F"FGG8'6JJ
 	
 oPPPPPPP G 	&+xPP r%   c                    t          j        |           dk    r(t          dd dt          j        |            d          g S )N)r   0The unravel function expected an array of shape , got shape r   )r[   r^   
ValueError)rM   s    r#   rh   rh      sY    
y$,t , ,4, , ,
 
 	

 Ir%   rs   tuple[int, ...]rr   tuple[tuple[int, ...]]list[Array]c                   t          j        |          | d         fk    r/t          d| d         f dt          j        |           d          t          j        || d d                   }d t	          ||          D             S )Nrv   rw   r   c                >    g | ]\  }}|                     |          S r1   )reshape)rW   chunkr^   s      r#   rd   z0_unravel_leaves_single_dtype.<locals>.<listcomp>   s(    NNN\UEEMM%  NNNr%   )r[   r^   rx   splitr   )rs   rr   rM   chunkss       r#   rn   rn      s    
 y72;.((,~ , ,4, , ,
 
 	

 YtWSbS\**FNNXff5M5MNNNNr%   rp   tuple[jnp.dtype, ...]ra   	jnp.dtypec                   t          j        |          | d         fk    r/t          d| d         f dt          j        |           d          t          j        |          }||k    rt          d| d| d          t          j        || d d                   }t          j                    5  t          j        d           d t          |||          D             cd d d            S # 1 swxY w Y   d S )	Nr}   rv   rw   r   z0The unravel function expected an array of dtype z, got dtype ignorec                f    g | ].\  }}}t          j        |                    |          |          /S r1   )r	   rf   r   )rW   r   r^   rU   s       r#   rd   z#_unravel_leaves.<locals>.<listcomp>  sG     
 
 
#ue $U]]5%9%95AA
 
 
r%   )
r[   r^   rx   r
   rU   r   warningscatch_warningssimplefilterr   )rs   rr   rp   ra   rM   array_dtyper   s          r#   ro   ro      sx    y72;.((,~ , ,4, , ,
 
 	
 ,t$$Kh(x ( ($( ( (
 
 	

 YtWSbS\**F		 	"	" 
 
h'''
 
'/'L'L
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
s   //C++C/2C/r*   )
rC   r   rD   rE   rA   r(   rB   rF   r   rG   )rL   r   rN   rO   rM   r   r   r   )rK   rQ   r   rR   )rM   r   r   rQ   )rs   ry   rr   rz   rM   r   r   r{   )rs   ry   rr   rz   rp   r   ra   r   rM   r   r   r{   )-r>   
__future__r   rj   r   typesr   typingr   r   typing_extensionsr   	jax.numpynumpyr[   jaxr   r	   jax._srcr
   
jax.typingr   
optree.opsr   r   optree.typingr   r   optree.utilsr   r   __all__r   r?   r   r   jax._src.utilImportErrorr   ravel_pytreerJ   rI   rh   rn   ro   r1   r%   r#   <module>r      sp  @    " " " " " "                            ' ' ' ' ' '                                 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 5 5 5 5 5 5 5 5 7
6
6 )=)DD D D D D$}[%88	 8 8 8 8)E )E )E )E )E )E )E )EX	------- 	 	 	D	 -1?H ?H ?H ?H ?H ?H ?HD 8 8 8 8   @   O O O O
 
 
 
 
 
s   B BB