
    ȅiD                    f    S SK Jr  S SKJrJr  S SKrSSKJr  \(       a  SSKJ	r	J
r
   " S S5      rg)	    )annotations)AnyTYPE_CHECKINGN   )DimEntry)DimTensorc                  l    \ rS rSr% SrS\S'   S\S'   SS jrSS jrSS	 jrSS
 jr	      SS jr
Srg)EnableAllLayers   a,  
RAII-style context manager for enabling functorch vmap layers.
It manages the creation and cleanup of functorch dynamic layers.

This is probably one of the more algorithmically important parts of first
class dims. Intuitively, FCD can be thought of as another way of using
vmap, where you don't actually have to vmap at the top level, instead the
vmaps are implicitly determined by inspecting the bound dimensions on the
FCD tensors involved in a compute (this is similar to our concept of
non-lexical modes that we spent a long time talking about years ago). But
under the hood you still need to actually enable the vmap mode. So once
FCD has determined all of the dims we are batching over, it needs to
enable all those layers so functorch can actually apply the batching
rules. Therefore enable all layers!
intlevels_startz	list[Dim]levels_to_dimc                   SSK Jn  SU l        / U l        U HW  nUR	                  5       (       a  M  UR                  5       n[        XB5      (       d   eU R                  R                  U5        MY     U R                  R                  S S9  g)z
Initialize and push dynamic layers for all first-class dimensions.

Args:
    levels: List of dimension entries to create layers for
r   )r   r   c                    U R                   $ N)_level)ds    Z/home/james-whalen/.local/lib/python3.13/site-packages/functorch/dim/_enable_all_layers.py<lambda>*EnableAllLayers.__init__.<locals>.<lambda>6   s    ahh    )keyN)	 r   r   r   is_positionaldim
isinstanceappendsort)selflevelsr   lr   s        r   __init__EnableAllLayers.__init__"   sx     	A??$$EEG!!))))""))!,	  	$67r   c                    [        U R                  5       HI  u  pUR                  n[        R                  R
                  R                  US5      nUS:X  d  MC  X@l        MK     U $ )N	differentr   )	enumerater   sizetorch_C
_functorch_vmap_increment_nestingr   )r    ir   
batch_sizelevels        r   	__enter__EnableAllLayers.__enter__8   sR     2 23FAJHH''??
KXEAv$)!	 4
 r   c                   U R                   [        U R                  5      -   S-
  n[        [        U R                  5      5       HB  n[        R
                  R                  R                  5       nXdU-
  :X  a  M5   SXE-
   SU 35       e   g)z)Clean up dynamic layers in reverse order.r   zExpected layer z, got N)r   lenr   ranger)   r*   r+   _vmap_decrement_nesting)r    exc_typeexc_valexc_tb	to_remover-   poppeds          r   __exit__EnableAllLayers.__exit__A   s}    %%D,>,>(??!C	s4--./AXX((@@BF]* !)-vh?* 0r   c                p   / n[        UR                  5       * S5       H  nUR                  [        U5      5        M     Un[        R
                  R                  R                  U5      (       Ga!  [        R
                  R                  R                  U5      nUc   eX`R                  :  a%  X`R                  [        U R                  5      -   :  d   e[        U R                  X`R                  -
     5      n[        R
                  R                  R                  U5      nUc   eUR                  X5        [        R
                  R                  R                  U5      n[        R
                  R                  R                  U5      (       a  GM!  SSKJn	  U	" 5       n
XZl        Xl        X*l        X:l        U
$ )z
Create a Tensor from a batched tensor by unwrapping functorch layers.

Args:
    batchedtensor: Batched tensor from functorch operation
    has_device: Whether tensor has device info

Returns:
    Tensor with appropriate levels
r   r   )r	   )r4   r   r   r   r)   r*   r+   is_batchedtensormaybe_get_levelr   r3   r   maybe_get_bdiminsertget_unwrappedr   r	   _tensor_batchtensor_has_device_levels)r    batchedtensor
has_devicer!   r-   tensorr/   r   bdimr	   results              r   from_batchedEnableAllLayers.from_batchedJ   sg    "$))++Q/AMM(1+& 0 hh!!226::HH''77?E$$$---%:K:Kc""O ; 3   4--e6G6G.GHIC88&&55f=D###MM$$XX((66v>F hh!!226:: 	+'r   c                  ^ ^ [         R                  R                  R                  U5      (       d  gUn[	        [        [        T R                  5      5      5       H  mUc    g[        UU 4S jU 5       5      (       d  M%  [         R                  R                  R                  UT R                  T-   5        [         R                  R                  R                  U5      nM     g)z
Update the levels of a batched tensor in place.

This requires the _maybe_unsafe_set_level binding that we'll add to functorch.

Args:
    batchtensor: Batched tensor to update
    levels: New levels to set
Nc              3  X   >#    U  H  o[        TR                  T   5      :H  v   M!     g 7fr   )r   r   ).0r"   r-   r    s     r   	<genexpr>8EnableAllLayers.inplace_update_layers.<locals>.<genexpr>   s$     HA!3!3A!677s   '*)r)   r*   r+   r>   reversedr4   r3   r   any_maybe_unsafe_set_levelr   rB   )r    batchtensorr!   implr-   s   `   @r   inplace_update_layers%EnableAllLayers.inplace_update_layersq   s     xx""33K@@%D$6$6 789A|HHHH ##;;D$BSBSVWBWXxx**88> :r   )r   r   N)r!   list[DimEntry])returnr   )r6   r   r7   r   r8   r   r[   None)rG   torch.TensorrH   boolr[   r	   )rV   r]   r!   rZ   r[   r\   )__name__
__module____qualname____firstlineno____doc____annotations__r#   r0   r;   rL   rX   __static_attributes__ r   r   r   r      sG      8,%N?'?1??	?r   r   )
__future__r   typingr   r   r)   
_dim_entryr   r   r   r	   r   rf   r   r   <module>rj      s%    " %    }? }?r   