
    ukiݭ                    2   d Z ddlmZ ddlmZ ddlZddlmZmZ ddl	Z
ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZm Z m!Z!m"Z"m#Z#m$Z$m%Z% ddl&m'Z'm(Z( ddl)m*Z*m+Z+ eZ,e*e-cZ-Z.e+e/cZ/Z0 ejb                  e2        ejf                  d      Z4d e4_5        e4jm                   eejn                  e4             d e4_8        d Z9e9e4_:        ee;e<e'ejz                  f   Z>	 	 	 	 	 	 	 	 d_dZ? eej                  d      	 d`	 	 	 	 	 dad       ZA ejf                  d      ZBd eB_5        eBjm                   eejn                  eB             d  eB_8        d! ZCeCeB_:         eej                  d"      	 db	 	 	 	 	 	 	 	 	 dcd#       ZDd$ ZE eej                  d%      	 	 	 	 	 	 	 	 ddd&       ZF ejf                  d'      ZGd( eG_5        d)eG_H        eGjm                   eejn                  eG             	 	 	 	 	 	 	 	 ded*ZI	 	 	 	 	 	 dfd+ZJ	 	 	 	 	 	 dgd,ZKd- ZLdhd.ZMe4j                  eM       	 	 	 	 did/ZOeBj                  eO       	 	 	 	 did0ZPeGj                  eP        eej                  ej                  j                  ej                  j                  1      ZV	 	 	 	 djd2ZWdkd3ZXdld4ZYeYej                  e4<   dld5Z[e[ej                  eB<   dld6Z\e\ej                  eG<   dmd7Z]e]ej                  e4<   dmd8Z_e_ej                  eB<   dmd9Z`e`ej                  eG<   d: Zaeaej                  e4<   d; Zcecej                  eB<   d< Zdedej                  eG<   d= Zeeeej                  e4<   d> Zgegej                  eB<   d? Zhehej                  eG<   d@ Zieiej                  ej                  <   dA Zlelej                  ej                  <   dB Znenej                  ej                  <   dC Zpepej                  e4<   epej                  eB<   dD Zqeqej                  eG<   	 	 	 	 	 	 	 	 	 	 	 	 dndEZrdF Zsesej                  e4<   dG Zueuej                  eB<   dH Zvevej                  eG<    ejf                  dI      ZwdodJZxewjl                  dK        Zyewj                  dL        Z{ ej                  ew ej                  eydM             dN Z~dO Ze~ej                  ej                  <   eej                   ej                  <    ej                  ej                  dP         ej                  ej                  dQ        d`dRZ ejf                  dS      Zej                  dT        ZdU Z ej                  ee       dV Z ejf                  dW      Zej                  dX        ZdY Z ej                  ee       dZ Z ejf                  d[      Zej                  d\        Zd] Z ej                  ee       d^ Zeej                   e <   y)pzModule for state primitives.    )annotations)partialN)AnyUnion)ad_util)core)dispatch)dtypes)pretty_printer)traceback_util)	tree_util)ad)batching)mlir)partial_eval)lax)indexing)AbstractRefAbstractLinValAccumEffect
ReadEffect	TransformTransformedRefWriteEffect)Array	ArrayLike)safe_mapsafe_zipgetc                     yNT paramss    T/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/_src/state/primitives.py<lambda>r&   G           c                   | j                   S Nis_highref_avaltree_s      r%   r&   r&   J   s    8+;+; r(   c               (   t        j                  | j                        }t        j                  ||      }|r&t        | |d d       } |d   }|j                  | |      S  |j                  t        t        |j                  | j                               S N)r   typeof_refsr   tree_unflattenr   ref_get_to_lojax	raise_valmapref_get	lower_val)refr/   idxval_ty
transformss        r%   _get_to_lojaxr@   K   s    ;;syy!&''c2*
j"o
.C
R.C""3,,			3w(8(8(CD	EEr(   c                B   t        | t              r| j                  | j                  }}n| d}}t	        j
                  |      }t        |t              st        d| d| d      t        |j                  t        j                        s|j                  j                  s|dfS ||t        u rd}nt        |t              s|f}|s||fS |s#|r!t        |d   t        j                        r||fS t        j                  j                  || j                         }|g ||fS )Nr"   zCan only call `z` on a `Ref`: .r3   )
isinstancer   r<   r?   r   get_avalr   
ValueError
inner_avalShapedArrayr,   Ellipsistupler   	NDIndexerfrom_indices_shapeshape)ref_or_viewr=   function_namer<   r?   r.   
nd_indexers          r%   get_ref_and_transformsrP   X   s   
 ^,!oo{'='=C!2C]]3(	Hk	*
}o^C5J
KK
X(($*:*:
;!!))7N[C8O
Cc5!&C	
?	
:b>8;M;M N
?!!44S+:K:KL*	'
'J'	''r(   zjax.ref.get)repro_api_namec                    t        | |d      \  } }t        j                  |      \  }}t        j                  | g|d|iS )a  Read a value from an Ref.

  This is equivalent to ``ref[idx]`` for a NumPy-style indexer ``idx``.
  For more on mutable array refs, refer to the `Ref guide`_.

  Args:
    ref: a :class:`jax.ref.Ref` object.
    idx: a NumPy-style indexer

  Returns:
    A :class:`jax.Array` object (note, not a :class:`jax.ref.Ref`) containing
    the indexed elements of the mutable reference.

  Examples:
    >>> import jax
    >>> ref = jax.new_ref(jax.numpy.arange(5))
    >>> jax.ref.get(ref, slice(1, 3))
    Array([1, 2], dtype=int32)

    Equivalent operation via indexing syntax:

    >>> ref[1:3]
    Array([1, 2], dtype=int32)

    Use ``...`` to extract the full buffer:

    >>> ref[...]
    Array([0, 1, 2, 3, 4], dtype=int32)

  .. _Ref guide: https://docs.jax.dev/en/latest/array_refs.html
  r:   r/   )rP   r   tree_flattenget_pbind)r<   r=   r?   flat_transformsr/   s        r%   r:   r:   t   sE    H +3Y?/#z#00</4	C	5/	5	55r(   swapc                     yr!   r"   r#   s    r%   r&   r&      r'   r(   c                   | j                   S r*   r+   r-   s      r%   r&   r&      s    H,<,< r(   c          	        t        j                  | j                        }t        j                  |      }t        j                  ||      }|r't        | |d d       } |d   }|j                  | ||      S |j                  | j                        }|j                  |      }t        ||      D 	
cg c]  \  }	}
t        |	||
       }}	}
 |j                  | S c c}
}	w r2   )r   r4   r5   r   r6   r   ref_swap_to_lojaxr;   zipref_swapr8   )r<   valr/   r=   
ref_val_tyr>   r?   lo_refslo_valslo_reflo_valoutss               r%   _swap_to_lojaxre      s    {{399%*;;s&''c2*
j"o
.C
R.C''S#66  +'S!''"
$NFF(63
' 
$$ 
$			4	  
$s   /Czjax.ref.swapc                    t        | d      rt        | j                  |      }t        | ||      \  } }t	        j
                  |      \  }}t        j                  | |g|d|iS )a  Update an array value inplace while returning the previous value.

  This is equivalent to ``ref[idx], prev = value, ref[idx]`` while returning
  ``prev``, for a NumPy-style indexer ``idx``.
  For more on mutable array refs, refer to the `Ref guide`_.

  Args:
    ref: a :class:`jax.ref.Ref` object. On return, the buffer will be
      mutated by this operation.
    idx: a NumPy-style indexer
    value: a :class:`jax.Array` object (note, not a :class:`jax.ref.Ref`)
      containing the values to set in the array.

  Returns:
    A :class:`jax.Array` containing the previous value at `idx`.

  Examples:
    >>> import jax
    >>> ref = jax.new_ref(jax.numpy.arange(5))
    >>> jax.ref.swap(ref, 3, 10)
    Array(3, dtype=int32)
    >>> ref
    Ref([ 0,  1,  2, 10,  4], dtype=int32)

    Equivalent operation via indexing syntax:

    >>> ref = jax.new_ref(jax.numpy.arange(5))
    >>> ref[3], prev = 10, ref[3]
    >>> prev
    Array(3, dtype=int32)
    >>> ref
    Ref([ 0,  1,  2, 10,  4], dtype=int32)

    Use ``...`` to swap the value of a scalar ref:

    >>> ref = jax.new_ref(jax.numpy.int32(5))
    >>> jax.ref.swap(ref, ..., 10)
    Array(5, dtype=int32)
    >>> ref
    Ref(10, dtype=int32)

  .. _Ref guide: https://docs.jax.dev/en/latest/array_refs.html
  dtyper/   )hasattr_maybe_implicit_castrg   rP   r   rS   swap_prU   )r<   r=   value_function_namer?   rV   r/   s          r%   r]   r]      sa    d S' E2E*3^D/#z#00</4	S%	=/	=	==r(   c                   t        j                  |      }t        |t         j                        s|S |j                  rRt        j                  | t        j                        r.t        j                  |j                  t        j                        sRt        j                  | t        j                        rDt        j                  |j                  t        j                        rt        j                  ||       S |S r*   )r   r4   rC   rG   	weak_typer
   
issubdtypenpfloatingrg   integerr   convert_element_type)rg   rk   avals      r%   ri   ri      s    	U	$	D$**	+L
nn,R[[1

+RZZ0##E511	,r(   zjax.ref.setc                "    t        | ||d       y)a  Set a value in an Ref in-place.

  This is equivalent to ``ref[idx] = value`` for a NumPy-style indexer
  ``idx``. For more on mutable array refs, refer to the `Ref guide`_.

  Args:
    ref: a :class:`jax.ref.Ref` object. On return, the buffer will be
      mutated by this operation.
    idx: a NumPy-style indexer
    value: a :class:`jax.Array` object (note, not a :class:`jax.ref.Ref`)
      containing the values to set in the array.

  Returns:
    None

  Examples:
    >>> import jax
    >>> ref = jax.new_ref(jax.numpy.zeros(5))
    >>> jax.ref.set(ref, 1, 10.0)
    >>> ref
    Ref([ 0., 10.,  0.,  0.,  0.], dtype=float32)

    Equivalent operation via indexing syntax:

    >>> ref = jax.new_ref(jax.numpy.zeros(5))
    >>> ref[1] = 10.0
    >>> ref
    Ref([ 0., 10.,  0.,  0.,  0.], dtype=float32)

    Use ``...`` to set the value of a scalar ref:

    >>> ref = jax.new_ref(jax.numpy.int32(0))
    >>> ref[...] = 4
    >>> ref
    Ref(4, dtype=int32)

  .. _Ref guide: https://docs.jax.dev/en/latest/array_refs.html
  ref_set)rl   Nr]   )r<   r=   rk   s      r%   rv   rv   
  s    X 3U95r(   	addupdatec                     yr!   r"   r#   s    r%   r&   r&   E  r'   r(   Tc                    t        | |d      \  } }t        j                  |      \  }}t        j                  | |g|d|i y)a  Add to an element in an Ref in-place.

  This is analogous to ``ref[idx] += value`` for a NumPy array ``ref`` and
  NumPy-style indexer ``idx``. However, for an Ref ``ref``, executing
  ``ref[idx] += value`` actually performs a ``ref_get``, add, and ``ref_set``,
  so using this function can be more efficient under autodiff. For more on
  mutable array refs, refer to the `Ref guide`_.

  Args:
    ref: a :class:`jax.ref.Ref` object. On return, the buffer will be
      mutated by this operation.
    idx: a NumPy-style indexer
    x: a :class:`jax.Array` object (note, not a :class:`jax.ref.Ref`)
      containing the values to add at the specified indices.

  Returns:
    None

  Examples:
    >>> import jax
    >>> ref = jax.new_ref(jax.numpy.arange(5))
    >>> jax.ref.addupdate(ref, 2, 10)
    >>> ref
    Ref([ 0,  1, 12,  3,  4], dtype=int32)

    Equivalent operation via indexing syntax:

    >>> ref = jax.new_ref(jax.numpy.arange(5))
    >>> ref[2] += 10
    >>> ref
    Ref([ 0,  1, 12,  3,  4], dtype=int32)

    Use ``...`` to add to a scalar ref:

    >>> ref = jax.new_ref(jax.numpy.int32(2))
    >>> ref[...] += 10
    >>> ref
    Ref(12, dtype=int32)

  .. _Ref guide: https://docs.jax.dev/en/latest/array_refs.html
  ref_addupdater/   N)rP   r   rS   addupdate_prU   )r<   r=   xr?   rV   r/   s         r%   r{   r{   J  sF    \ +3_E/#z#00</437O7$7r(   c                >    |D ]  }|j                  |       }  | J | S r*   )transform_shape)rL   r?   	transforms      r%   _shape_after_transformingr     4      -i%%e,E-				,r(   c                >    |D ]  }|j                  |       }  | J | S r*   )transform_dtype)rg   r?   r   s      r%   _dtype_after_transformingr     r   r(   c                >    |D ]  }|j                  |       }  | J | S r*   )transform_sharding)shardingr?   r   s      r%   _sharding_after_transformingr     s2     6i++H5H6				/r(   c               4   t        j                  ||      }|r6| j                  j                  r  | j                  j                  | g|d|iS t        | t              st        d|  d      t        | j                  t        j                        rat        | j                  |      }t        | j                  |      }t        | j                  |      }| j                  j!                  |||      }n|rt        d      | j                  }|t#        d      hfS )Nr/   z%`get` must be called on `Ref` types: rB   )rL   rg   r   6Cannot index non-shaped array with nontrivial indices.r   )r   r6   rF   r,   ref_get_abstract_evalrC   r   rE   r   rG   r   rL   r   rg   r   r   updater   )r.   r/   argsr?   	out_shape	out_dtypeout_shardingout_avals           r%   _get_abstract_evalr     s    ''d3*H''//4844XPP4PP	Hk	*
<XJaH
II##T%5%56)(..*EI)(..*EI/0A0A:NL""))y< * AH OPP""H
Z]O	$$r(   c               4   t        j                  ||      }|r7| j                  j                  r! | j                  j                  | |g|d|iS t        | t              st        d|  d      t        |t              rt        d      t        | j                  t        j                        rt        |t        j                        sJ t        | j                  |      }t        | j                  |      }||j                  k7  r,t        d| j                   d| d|j                   d| d		      ||j                  k7  rt        d
| d|j                   d	      t        j                  ||      }n|rt        d      | j                  }|t        d      hfS )Nr/   z&`swap` must be called on `Ref` types: rB   zRCannot store a Ref into another Ref. Did you forget to load from it using `[...]`?z%Invalid shape for `swap`. Ref shape: . Expected shape: . Value shape: . Transforms: . z%Invalid dtype for `swap`. Ref dtype: z. Value dtype: r   r   )r   r6   rF   r,   ref_swap_abstract_evalrC   r   rE   r   rG   r   rL   r   rg   r   )r.   val_avalr/   r   r?   expected_out_shapeexpected_out_dtyper   s           r%   _swap_abstract_evalr     s    ''d3*H''//5855(.!.(,. . 
Hk	*
=hZqI
JJ+&
 E F F##T%5%56h 0 011128>>:N28>>:NX^^+ %%-^^$4 5**<)= >''/~~&6 7&&0\	5 6 6
 X^^+*+ ,"..)- 
  24FGHOPP""H
[^$	%%r(   c               ^   t        j                  ||      }t        | t              st	        d|  d      t        | j
                  t        j                        r9t        | j                  |      }t        | j                  |      }t        | j                  |      }t        |t        j                        sJ ||j                  k7  r,t	        d| j                   d| d|j                   d| d	      ||j                  k7  r&t	        d| j                   d|j                   d      |j                  j                  s |j                  j                  j                  rB||j                  k7  r3t	        d	| j                   d
|j                   d      |rt	        d      g t!        d      hfS )Nz+`addupdate` must be called on `Ref` types: rB   z*Invalid shape for `addupdate`. Ref shape: r   r   r   r   z*Invalid dtype for `addupdate`. Ref dtype: z0Invalid sharding for `addupdate`. Ref sharding: z. Value sharding: r   r   )r   r6   rC   r   rE   rF   r   rG   r   rL   r   rg   r   r   mesh_any_axis_explicitr   )r.   r   r/   r   r?   r   r   r   s           r%   _addupdate_abstract_evalr     s    ''d3*	Hk	*
B8*AN
OO##T%5%56)(..*EI)(..*EI/0A0A:NLh 0 0111HNN" ' (&K ("..) *#B	(  HNN" %%-^^$4 5''/~~&6b: ; ; 
			-	-						2	2))) ((0(9(9': ;**2*;*;)<B@ A A
 OPP	k!n	r(   )	intensity
foregroundc                    |st        j                  d      S t        j                  |D cg c]  }|j                  |        c}      S c c}w )Nz[...])pptextconcatpretty_print)contextr?   r   s      r%   _pp_transformsr     sC     
777	8BC9yg&C
 Cs   A
c           
         t        t        j                  t        j                  t	        j
                  ||             t        | |      g            S r*   )
pp_ref_varr   r   r   r   pp_varr   )r   r<   r?   s      r%   pp_ref_transformsr     sA    	ii
''$++c7+
,
*
- 	
 r(   c           	     2   | j                   \  }| j                  ^}}t        j                  | j                  d   |      }t        j                  |g||j                        }t        j                  |t        j                  d      t        |||      g      S )Nr/   print_shapes <- )outvarsinvarsr   r6   r$   r   pp_varsr   r   r   r   r   )eqnr   settingsyr}   flat_idxr?   lhss           r%   _get_pp_ruler     s|    
{{"!,!h''

6(:HE*aS'0E0EF#	
BGGFO.w:FG
 r(   c                   | j                   \  }| j                  ^}}}t        j                  | j                  d   |      }t        |      t        j                  u r^~t        j                  t        |||      t        j                  d      t        j                  t        j                  ||            g      S t        |||      }t        j                  |g||j                        }t        j                  |t        j                  d      |t        j                  d      |t        j                  d      t        j                  t        j                  ||            g      S )Nr/   r   r   z, )r   r   r   r6   r$   typer   DropVarr   r   r   r   r   r   r   )	r   r   r   r   r}   vr   r?   x_is	            r%   _swap_pp_ruler     s   
{{"!JJ/!Q''

6(:HE*	!W 	
99'1j1

Aw'(   GQ

3CaS'0E0EFA99aRWWV_2774=ggdkk!W568 9 9r(   c           
     <   ~| j                   \   | j                  ^}}}t        j                  | j                  d   |      }t        j                  t        |||      t        j                  d      t        j                  t        j                  ||            g      S )Nr/   z += )r   r   r   r6   r$   r   r   r   r   r   r   )r   r   r   r}   r   r   r?   s          r%   _addupdate_pp_ruler   2  s|    
{{"JJ/!Q''

6(:HE*	J/ggfoggdkk!W%& 
 r(   c                &   | ^}}|^}}t        j                  |g|i |}t        |t        j                        r:t        j                  t        j                  |      j                               }||fS t        j                  |g|i |}||fS r*   )rT   rU   rC   r   Zeror   r4   to_tangent_aval)	primalstangentsr$   
ref_primalr=   ref_tangentr0   
out_primalout_tangents	            r%   _get_jvpr   A  s    *s/+zz*5s5f5*W\\*,,t{{:6FFHIK 
[	   **[939&9K	[	  r(   c                   | ^}}}|^}}}t        j                  ||g|i |}	t        |t        j                        rTt        |t        j                        r:t        j                  t        j                  |	      j                               }
|	|
fS |j                  j                  dk(  r:t        j                  t        j                  |	      j                               }
|	|
fS t        |t        j                        r"t        dt        j                  |       d      t        j                  |      }t        j                  ||g|i |}
|	|
fS )N
anselm_refzlperforming a set/swap operation with a differentiated value on a non-differentiated array reference of type zL. Move the array reference to be an argument of the differentiated function?)rj   rU   rC   r   r   r   r4   r   rt   kind	Exceptioninstantiate)r   r   r$   r   x_primalr=   r   	x_tangentr0   r   r   s              r%   	_swap_jvpr   L  s6   &*h'+y1{{:x@#@@*W\\*z)W\\/R,,t{{:6FFHIK 
[	   ,,,t{{:6FFHIK 
[	   +w||, OZ01 2JJ K K ##I.I++k9EsEfEK	[	  r(   c                    | ^}}}|^}}}t        j                  |      }|j                  j                  dk7  r4t	        j
                  ||g|i | t	        j
                  ||g|i | g g fS )Nr   )r   r   rt   r   r|   rU   )	r   r   r$   r   r   r=   r   r   r0   s	            r%   addupdate_jvp_ruler   _  s{    &*h'+y1!!),)l*Z:C:6:[)<c<V<	R-r(   c                    t        |       t        j                  urt        j                  || g|i | d gd gt        |      z  z   S r*   )r   r   r   r|   rU   len)gr<   r=   r$   s       r%   _get_transposer   k  sD    	!WGLL S!,c,V,
4&3s8#	##r(   c                    t        j                  |t        j                  |       g|i |}d |gd gt	        |      z  z   S r*   )rj   rU   r   r   r   )r   r<   r}   r=   r$   x_bars         r%   _swap_transposer   r  sA    
++c7..q1
BC
B6
B%
$#c(*	**r(   c                `    ~ ~t        j                  |g|i |}d |gd gt        |      z  z   S r*   )rT   rU   r   )cts_inr<   r}   r=   r$   r   s         r%   addupdate_transposer   x  s9    ajj%s%f%!
dVc#h&	&&r(   c                    |rNt        |       t        j                  ur3t        j                  |j                         j                  | g|i | y |j                  |        y r*   )r   r   r   r|   rU   instr<   accum)r   ref_r=   r$   s       r%   _get_transpose_fancyr     sC    T!WGLL(TYY[__a8#88JJqMr(   c                   |j                   t        |       t        j                  u ry |j                   Ft	        j
                  |j                         j                   t        j                  |       g|i | y t	        j
                  |j                         j                   t        j                  |       g|i |}|j                  |       y r*   )	r<   r   r   r   rj   rU   r   r   r   )r   r   r}   r=   r$   r   s         r%   _swap_transpose_fancyr     s    	XX$q'W\\1
xx
KK		!4!4Q!7H#HHKK		)<)<Q)?P#PPEGGENr(   c                    |j                   Pt        |t        j                        r5t	        j
                  |j                   g|i |}|j                  |       y y y r*   )r<   rC   r   	GradAccumrT   rU   r   )r   r   r}   r=   r$   r   s         r%   addupdate_transpose_fancyr     sH    	XXjBLL9JJtxx0#00EGGEN :r(   c                f    ~ |\  }|\  }|j                   \  }|s|gng }|r	d |dgdg|fS ||dgdg|fS )NTF)r   )saveableunks_ininst_inr   unkr   invarress           r%   _array_ref_partial_eval_customr     sV    	$#
%$::&%#tftfc))eWtfc))r(   c                    |\  }|\  }|Pt        j                  || j                  d| j                        }t        j
                  j                  |||      dfS t        j
                  j                  |||      |fS )Nr   memory_spacer   )r   	broadcastsizeexplicit_mesh_axisr   ref_prU   )	axis_datavals_indims_inr   r   r^   dimval2s           r%   _array_ref_batchedr     st    	$#	$#[c9>>1'::<D::??4l?FII::??3\?EsJJr(   c                T    |\  }|\  }t         j                  j                  |      |fS r*   )r   freeze_prU   )r   r   r   r<   r   s        r%   _freeze_batchedr    s*    	$#	$#			C	 #	%%r(   c                   ~ |^}}|^}}|j                   ^}}|sJ t        ||      D 	cg c]
  \  }}	|	r	| }
}}	|r	d |dgdg|
fS |j                   d   j                  j                  dk(  r	|d dgdg|
fS ||dgdg|
fS c c}	}w )NTr   r   F)r   r\   rt   r   r   r   r   r   ref_unkr0   ref_instval_varsr   r   r   s              r%   _state_partial_eval_customr	    s    +'A(W,!h	/h0=wq$=#=tftfc))
zz!},.ugw++eWtfc)) 	>s
   
B B c                    ~ |^}}|^}}|j                   ^}}|sJ t        ||      D 	cg c]
  \  }}	|	r	| }
}}	|rd |g g |
fS ||g g |
fS c c}	}w r*   )r   r\   r  s              r%   _addupdate_partial_eval_customr    sv    +'A(W,!h	/h0=wq$=#=b"c!!RS  	 	>s
   
AAc           	        | j                   }|j                   }g }|g| j                  }	t        ||      D ]  \  }
}|rst        |
t        j
                        rst        t        j                  |
            dk(  }|r|j                  |
       Y|j                  }|t        j                  u r|j                  |
       t        d|
       t        |
d      sJ |
j                  sM|t        j                  ur)|
j                  |fk(  sJ t!        j"                  |
|	d      }
|j                  |
       |t        j                  u rCt%        t'        dt)        j*                  |
      dz               }t!        j"                  |
|	|      }
nt        j,                  |
|d      }
|j                  |
       }|t        j                  urvt        |
t        j
                        s\t        |
d      sJ |
j                  rBt%        t'        dt)        j*                  |
      dz               }t!        j"                  |
|	|      }
|j                  |
        |t        j                  ura| j                  r+t!        j.                  t)        j0                  d      |	d      }nt	        j
                  d|      }d}	|j3                  ||       t	        j4                  t%        |      ||	d	      S )
a  Converts a batched indexer into an unbatched one.

  This function handles the complexity of `vmap`-style batching where either the
  `ref` being indexed, the indexer, or both may have batched dimensions. The
  goal is to produce a new indexer that acts as if applied in a batched context,
  but without actual batching, enabling downstream code to process it as usual.

  If any index in `indexer` is batched, all array indexers are normalized. If
  the array indexer contains a batched dimension, the dimension is moved to the
  front (axis 0). If the array indexer not batched, it is broadcasted to include
  a batch dimension at the front. This is to guarantee that all array indexers
  are still of the same shape.

  Slices are passed through unchanged unless they contain dynamic elements and
  are themselves batched, which is currently unsupported.

  If `ref` is batched (`ref_dim` is not `NotMapped`), we simulate per-example
  indexing by inserting a new iota array at the position corresponding to
  `ref_dim` in the indexer.

  It is worth noting that if the array indexers in the original indexer are
  contiguous, but become non-contiguous in the new indexer due to the insertion
  of the iota, the dimensions corresponding to the array indexers will be moved
  to the front in the indexing result. The batched dimension will be at axis 0,
  while the dimensions corresponding to the array indexers in the original
  indexer will start from axis 1. This behavior would cause a mismatch between
  the original indexer and the new indexer. Callers must take this behavior into
  account and properly transpose the arrays involved to avoid this mismatch.

  Args:
    indexer: An `NDIndexer` that indexes into `ref`.
    dims: A pytree with the same structure as `indexer`, indicating which
      dimension (if any) is batched for each array indexer.
    axis_size: Size of the batch dimension.
    ref_shape: Shape of `ref`.
    ref_dim: The dimension of `ref` that is batched (if any).
    idx_is_batched: Whether any index in the `indexer` is batched.
  r   z9No support for vmapping over nontrivial slices just yet: rL   )r      int32r"   T)validate)indicesint_indexer_shaper\   rC   r   Slicer   r   tree_leavesappendstartr   
not_mappedNotImplementedErrorrh   rL   r   broadcast_in_dimrI   rangerp   ndimmoveaxisbroadcasted_iotarg   insertrJ   )indexerdims	axis_size	ref_shaperef_dimidx_is_batchedr  indices_dimsnew_indicesnew_integer_indexer_shaper=   r   is_static_slice
bcast_dims	batch_idxs                  r%   _batch_indexerr*    s   \ OO',46+(E7+D+DEg|, +hc3 
C	( i33C89Q>


S
!
ii(%%%


S
!#I#OQ Q
 sG$$$yy+++99,,,&&s,EtLC


S
!H'''uQq(89:J&&s,E'13C ##Ca0C


S
!	++	+#x~~.g&
&&YYuQq(89:J&&s,E&02CW+X H'''  &&
((7
6;i ..I.i"$w	*			K)%>
 r(   c          	     "   t        | |      D ch c]&  \  }}|t        j                  ur|j                  |   ( c}}\  | ^}|^}t	        j
                  ||      }|st        j                  g|d|ifS t	        j
                  ||      }t        d |D              t        |      dkD  rt        d      t        fdt        ||      D              }	t	        j                  |	      \  }
}t        j                  |d         \  }}}t        t!        j"                  t!        j$                  t!        j&                  |      d         dk(              }t        |d   j(                        }t        j                  |	d         \  }}}t        t!        j"                  t!        j$                  t!        j&                  |      d         dk(              }t        j                  g|
d|i}|xr | }|r|r|j+                  d      }|	d   j(                  }t        |      }t-        t/        t        |j                                    }|d   g||||z    |d| |||z   d  }t1        j2                  ||      }d}||fS t        j                  urI|r|sd}||fS |j+                  d      }||fS t5        t!        j6                  |d              }|z
  }||fS d}t        |      r|j+                  d      }|}||fS c c}}w )Nr/   c              3  @   K   | ]  }|t         j                  u  y wr*   r   r  .0i_dims     r%   	<genexpr>z_get_vmap.<locals>.<genexpr>K  #      3  H$7$77 3   r  .Batching with multiple indexers not supported.c           	   3  X   K   | ]!  \  }}t        ||j                         # y wr*   )r*  rL   )r/  r  r  r   r#  r<   r"  s      r%   r1  z_get_vmap.<locals>.<genexpr>Q  s6      H&$ &gtY"%))WnF Hs   '*r   T)r\   r   r  rL   r   r6   rT   rU   anyr   r  rI   rS   r   unpack_ndindexerboolrp   alldiffwherer  indexlistr  r   	transposeintsum)batched_argsbatched_dimsr/   r}   d	flat_idxsflat_idx_dimsindexersindexers_dimsnew_indexersflat_indexersis_int_indexingr0   int_indexers_contiguouswill_add_int_batcheris_new_int_indexingnew_int_indexers_contiguousoutshould_transposeoriginal_posarray_indexer_shapearray_indexer_lentranspose_orderout_bdimint_indexers_before_ref_dimr   r#  r<   r"  s                            @@@@r%   	_get_vmaprW  A  sI   '*<'F 1tq!H/// 
 1*) /#	('M%%dI6(	::c1I1D17::**4?- 3$13 3.]Q
N
OO  H*-h*FH H, "..|<-"33HQK@/1a ffRWWRXXo.q12a78
 hqk;;<&77QHq! $ffRWWRXX12156!;<! 	

322T2#- 655 ."((.L&q/;;/05SYY01O	*+<\+I	J 
,	- 
*<78	9	O --_
-CH* 
h' h)))	&( 
h )..t4( 
h '*"&&1DXg1N*O&P#88 
h h	_	&,,T2	hM1s   +Lc          	         |^}}|^}}t        j                  ||      }t        j                  ||      }	t        j                  u}
|t        j                  u}t	        d |D              |
s"t        dt        j                         d      |sL|
r.|s,t        j                  | j                   j                        }t        j                  |g|d|ifS t        |      dkD  rt        d      t         fdt!        ||	      D              }t        j"                  |      \  }}t%        j&                  |d         \  }}}t)        t+        j,                  t+        j.                  t+        j0                  |      d         dk(              }t%        j&                  |d         \  }}}t)        t+        j,                  t+        j.                  t+        j0                  |      d         dk(              }|sd}n	 |j3                  d	      dz   }|s1|
srDt        j                  | j                  | j                        }nt        j6                  |||      }d }|r|s|j3                  d	      }|d   j8                  }t        |      }t;        t=        t        |j>                                    }|d   g|d|z   d|z   |dz
  z    |dd|z    |d|z   |dz
  z   d  }|jA                  |      }t+        jB                  |      }t        j                  |g|d|i}||jA                  |      }||fS # t4        $ r }Y 5w xY w)
Nc              3  @   K   | ]  }|t         j                  u  y wr*   r-  r.  s     r%   r1  z_swap_vmap.<locals>.<genexpr>  r2  r3  z[performing a set/swap operation with vmapped value on an unbatched array reference of type E. Move the array reference to be an argument to the vmapped function?r/   r  r4  c           	   3  l   K   | ]+  \  }}t        ||j                  j                         - y wr*   r*  r   rL   r/  r  r  r   r#  r<   r"  s      r%   r1  z_swap_vmap.<locals>.<genexpr>  :      H&$ &gtY^^"%))WnF H   14r   T)"r   r6   r   r  r6  r   r   r4   r   r   r   rj   rU   r   r  rI   r\   rS   r   r7  r8  rp   r9  r:  r;  r<  rE   r  r  r=  r  rL   r>  argsort)r   rA  rB  r/   r^   rD  val_dimrE  rF  rG  ref_is_batchedval_is_batchedrH  rI  rJ  r0   rK  rM  rN  batched_dim_in_resulttranspose_order_inversedrQ  rR  rS  rT  rO  r#  r<   r"  s   `                         @@@r%   
_swap_vmaprf    s{   %#sY%1"'7]%%dI6(**4?-("5"55.("5"55. 3$13 3. 

 <<@KK<L;M N   ! ! 
nsINNG(;;=c;;sC7)7$7@@]Q
N
OO H*-h*FH H, "..|<-"33HQK@/1a ffRWWRXXo.q12a78 '77QHq! $ffRWWRXX12156!;<! 
%&177=A 
sINN4I(;;=c 

C*?
@C! %@"((.L&q/;;/05SYY01O	<<:KA:M(N	O 
1\>	* 
!L.+<Q+>?@	A	O --
(C!zz/:C8}848#
 )
--0
1C	#	##K  &%&s   M MMc          	     $    |^}}|^}}t        j                  ||      }t        j                  ||      }	t        j                  u}
|t        j                  u}t	        d |D              |
s"t        dt        j                         d      |s9|k7  rt        j                   ||      }t        j                  |g|d|ig fS t        |      dkD  rt        d      t         fdt        ||	      D              }t        j                  |      \  }}t!        j"                  |d         \  }}}t%        t'        j(                  t'        j*                  t'        j,                  |      d         dk(              }t!        j"                  |d         \  }}}t%        t'        j(                  t'        j*                  t'        j,                  |      d         dk(              }|sd}n	 |j/                  d	      }|s1|
srDt        j2                  | j4                  | j6                        }nt        j8                  |||      }|r|s|j/                  d	      }|d   j:                  }t        |      }t=        t?        t        |j@                                    }|d   g|d|z   d|z   |dz
  z    |dd|z    |d|z   |dz
  z   d  }|jC                  |      }t        j                  |g|d|ig fS # t0        $ r }Y 	w xY w)
Nc              3  @   K   | ]  }|t         j                  u  y wr*   r-  r.  s     r%   r1  z"_addupdate_vmap.<locals>.<genexpr>  r2  r3  z]performing an addupdate operation with vmapped value on an unbatched array reference of type rZ  r/   r  r4  c           	   3  l   K   | ]+  \  }}t        ||j                  j                         - y wr*   r\  r]  s      r%   r1  z"_addupdate_vmap.<locals>.<genexpr>  r^  r_  r   T)"r   r6   r   r  r6  r   r   r4   
matchaxis2r|   rU   r   r  rI   r\   rS   r   r7  r8  rp   r9  r:  r;  r<  rE   r   r   r   r  r  r=  r  rL   r>  )r   rA  rB  r/   r^   rD  ra  rE  rF  rG  rb  rc  rH  rI  rJ  r0   rK  rM  rN  rd  rQ  rR  rS  rT  r#  r<   r"  s   `                       @@@r%   _addupdate_vmaprk    s?   %#sY%1"'7]%%dI6(**4?-("5"55.("5"55. 3$13 3. 

 <<@KK<L;M N   ! ! 
'	7GSAcC<y<t<b@@]Q
N
OO  H*-h*FH H, "..|<-"33HQK@/1a ffRWWRXXo.q12a78 '77QHq! $ffRWWRXX12156!;<! 
%&177= 
sINN4I(;;=c 

C*?
@C %@"((.L&q/;;/05SYY01O	<<:KA:M(N	O 
1\>	* 
!L.+<Q+>?@	A	O --
(C			#s	>]	>	>	BB5  &%&s   4L   LLbroadcast_toc                    ddl m} |j                  |       } | j                  |k(  r| S t        j                  | |      S )zBroadcasts an array to a new shape.

  Args:
    a: The array to broadcast.
    shape: The desired shape to broadcast to.

  Returns:
    An array of shape ``shape``.

  See Also:
    :func:`jax.numpy.broadcast_to`
  r   N)rL   )	jax.numpynumpyasarrayrL   broadcast_to_prU   arL   jnps      r%   rl  rl  .  s;     	kk!n!WWH			Qe		,,r(   c               2    dd l m} |j                  | |      S )Nr   )rn  ro  rl  rr  s      r%   _broadcast_to_implrv  A  s    			!U	##r(   c               B    t        j                  || j                        S r*   )r   rG   rg   )rt   rL   s     r%   _broadcast_to_abstract_evalrx  F  s    			%	,,r(   Fc               d   | |c\  }\  }t         j                  j                  |||      }t        |      t        j
                  u rEt	        j                  |j                        }t         j                  j                  |||      }||fS t         j                  j                  |||      }||fS Nr   )r   r   rU   r   r   r   zeros_like_avalrt   )	r   r   r   r   init_valinit_dot
primal_outzerotangent_outs	            r%   _ref_jvpr  P  s    $h+8{zzxlN*	(^w||#""8==1D**//$\/MK 
[	   **//(D/QK	[	  r(   c               j    | \  }t         j                  j                  |      }fd}|dd |fS )Nr   c                r    t        j                  |      }t        j                  j	                  |      S rz  )r   r   r   r   rU   )r0   x_dotr  r   r   s      r%   mut_linz_ref_lin.<locals>.mut_lin]  s,    u%D::??4l?FFr(   T)r   r   rU   )nzsr}   r   r   nzx_refr  s     ``   r%   _ref_linr  Z  s9    #"
**//!,T/
B%G 
dG	##r(   c                ,    t        j                  |       S r*   )r   freezer   r0   s     r%   r&   r&   e  s    dkk!n r(   c                @    t         j                  j                  |       S r*   )r   accum_grad_in_ref_prU   r  s     r%   r&   r&   f  s    1I1I1N1Nq1Q r(   c                0    t         j                  | |      S )Ntyr   )create_linear_prU   r  s     r%   create_linearr  j  s    			,		??r(   r  c                d    t        | t        j                        st        |       t	        | |      S r*   rC   r   rG   r  r   r  s     r%   _create_linear_abstract_evalr  n  s*    	B((	)1DR1H+H	L	))r(   c                    | j                   \  }t        j                  dg t        j                  |      g      j                  S )NCreateBufferoperandsresult_types)	avals_outr   custom_callaval_to_ir_typeresults)ctxr   s     r%   _lower_create_linearr  s  s>    mm)(			((23
 G	r(   c                ,    t         j                  |       S r*   )pin_prU   r}   s    r%   pinr  }  s    	Ar(   r  c                b    t        | t        j                        st        |       t	        |       S r*   r  rt   s    r%   _pin_abstract_evalr    s(    	D$**	+3Ft3L-L		r(   c                    | j                   \  }t        j                  dt        j                  |g      t        j                  |      g      j
                  S )NPinr  r  r   r  flatten_ir_valuesr  r  r  x_opr   s      r%   
_lower_pinr    sK    mm)(			%%tf-((23
 G	r(   c                ,    t         j                  |       S r*   )unpin_prU   r  s    r%   unpinr    s    	ar(   r  c                P    t        | t              st        |       | j                  S r*   )rC   r   	TypeErrorrF   r  s    r%   _unpin_abstract_evalr    s    	D.	)4+@	r(   c                    | j                   \  }t        j                  dt        j                  |g      t        j                  |      g      j
                  S )NUnpinr  r  r  s      r%   _lower_unpinr    sK    mm)(			%%tf-((23
 G	r(   c                    t         j                  j                  j                  | j                  t        j
                  | j                        | j                        S )N)r   )r   ir
MemRefTyper   rL   dtype_to_ir_typerg   r   )rs  s    r%   _linval_to_mlir_typer    sB    					)>)>qww)G-.^^ 
  
= =r(   )rM   r   r=   $Indexer | tuple[Indexer, ...] | NonerN   strreturnz!tuple[Any, tuple[Transform, ...]]r*   )r<   core.Ref | TransformedRefr=   r  r  Array | HijaxTyperw   )
r<   r  r=   r  rk   ArrayLike | HijaxTyperl   r  r  r  )r<   r  r=   r  rk   r  r  None)r<   r  r=   r  r}   r  r  r  )rL   tuple[int | Array, ...]r?   tuple[Transform, ...]r  r  )rg   r   r?   r  r  r   )r.   r   )r.   r   r   zcore.AbstractValuer   r   )r   core.JaxprPpContextr?   r  )r   r  )r  zpp.Doc)r   	list[Any]r   r  r$   r   )r  indexing.NDIndexerr   r?  r!  tuple[int, ...]r"  zint | batching.NotMappedr#  r8  r  r  )rs  r   rL   r  r  r   )__doc__
__future__r   	functoolsr   typestypingr   r   ro  rp   jax._srcr   r   r	   r
   r   r   r   r   jax._src.interpretersr   r   r   r   pejax._src.laxr   jax._src.stater   jax._src.state.typesr   r   r   r   r   r   r   jax._src.typingr   r   jax._src.utilr   r   	HijaxTyper9   
unsafe_mapr\   
unsafe_zipregister_exclusion__file__	PrimitiverT   is_effectfuldef_implapply_primitiver,   r@   to_lojaxr?  sliceEllipsisTypeIndexerrP   api_boundaryr:   rj   re   r]   ri   rv   r|   multiple_resultsr{   r   r   r   r   def_effectful_abstract_evalr   r   color	IntensityNORMALColorGREENr   r   r   r   pp_eqn_rulesr   r   r   primitive_jvpsr   r   r   primitive_transposesr   r   r   fancy_transposesr   r   r   partial_eval_jaxpr_custom_rulesr   r   fancy_primitive_batchersr  r  r	  r  r*  rW  primitive_batchersrf  rk  rq  rl  rv  def_abstract_evalrx  register_lowering	lower_funr  r  primitive_linearizationsdefjvpr  r  r  r  r  r  r  r  r  r  r  r  r  r  ir_type_handlersr"   r(   r%   <module>r     s   # "         ) #  $ * & 4  #   - , 	 CZCZ ! ! !( + 	u(  wx//7 8;F 
UE5#5#55
6((	-( ( '	(8 		$	$]C 15%6	"%6	-%6 %6 D%6p 
	)  00&9 :<! ! 		$	$^D
 %	5>	"5>	-5> !5> 	5>
 5> E5>t
 		$	$]C+6	"+6	-+6 !+6 
	+6 D+6r dnn[). #    WX55{C D08	"08	-08 08 
	08l"0E1%$  ! !"4 5"&"4"&""&F  " "#6 7!'9!$'!D  ' '(@ A RXX)<)<HHNN,
 % (  % 9( *  & 
 "4  + ! $  % !" &  &  "4  + $
 "0   + #2   '
 (;   $
 2  E  4  F  $=  K  	* 2P " "4:: .	K 1C ! !$** -& 4C ! !$-- 0* -G " "5 )-G " "6 *
! 3Q " "; /hh h 	h
 &h h hTGP &/  E "P$b -7 ! !& )ECL 2A ! !+ .  /-& $ $ !!- "-   NDNN#5u=!$ !)  $** *2  DJJ ' 			$--4 5 			$
"
"$Q R@ $..1""* #*   (< =u    uj )
$..
!    w -= )=  n %r(   