
    qiD                    \    d dl mZ d dlmZmZ d dlZddlmZ erddlm	Z	m
Z
  G d d      Zy)	    )annotations)AnyTYPE_CHECKINGN   )DimEntry)DimTensorc                  Z    e Zd ZU dZded<   ded<   ddZddZddZdd	Z	 	 	 	 	 	 dd
Z	y)EnableAllLayersa`  
    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                   ddl m} d| _        g | _        |D ]L  }|j	                         r|j                         }t        ||      sJ | j                  j                  |       N | j                  j                  d        y)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                    | j                   S N)_level)ds    f/home/ubuntu/crypto_trading_bot/.venv/lib/python3.12/site-packages/functorch/dim/_enable_all_layers.py<lambda>z*EnableAllLayers.__init__.<locals>.<lambda>6   s
    ahh     )keyN)	 r   r   r   is_positionaldim
isinstanceappendsort)selflevelsr   lr   s        r   __init__zEnableAllLayers.__init__"   sy     	 	-A??$EEG!!S)))""))!,		- 	$67r   c                    t        | j                        D ]H  \  }}|j                  }t        j                  j
                  j                  |d      }|dk(  sB|| _        J | S )N	differentr   )	enumerater   sizetorch_C
_functorch_vmap_increment_nestingr   )r   ir   
batch_sizelevels        r   	__enter__zEnableAllLayers.__enter__8   s[     2 23 	*FAsJHH''??
KXEAv$)!		*
 r   c                   | j                   t        | j                        z   dz
  }t        t        | j                              D ]B  }t        j
                  j                  j                         }|||z
  k(  r4J d||z
   d|         y)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__zEnableAllLayers.__exit__A   s    %%D,>,>(??!C	s4--./ 	AXX((@@BFY]* !)a-vh?*	r   c                ^   g }t        |j                          d      D ]  }|j                  t        |              |}t        j
                  j                  j                  |      rt        j
                  j                  j                  |      }|J || j                  k\  r%|| j                  t        | j                        z   k  sJ t        | j                  || j                  z
           }t        j
                  j                  j                  |      }|J |j                  ||       t        j
                  j                  j                  |      }t        j
                  j                  j                  |      rddlm}	  |	       }
||
_        ||
_        ||
_        ||
_        |
S )a  
        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	   )r0   r   r   r   r&   r'   r(   is_batchedtensormaybe_get_levelr   r/   r   maybe_get_bdiminsertget_unwrappedr   r	   _tensor_batchtensor_has_device_levels)r   batchedtensor
has_devicer   r*   tensorr,   r   bdimr	   results              r   from_batchedzEnableAllLayers.from_batchedJ   sv    "$))++Q/ 	'AMM(1+&	' hh!!226:HH''77?E$$$D---%$:K:Kc""O ; 3   4--ed6G6G.GHIC88&&55f=D###MM$$XX((66v>F hh!!226: 	+'r   c                    t         j                  j                  j                  |      sy|}t	        t        t         j                                    D ]|  | yt         fd|D              st         j                  j                  j                  | j                  z          t         j                  j                  j                  |      }~ y)a   
        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  T   K   | ]  }|t        j                           k(   ! y wr   )r   r   ).0r    r*   r   s     r   	<genexpr>z8EnableAllLayers.inplace_update_layers.<locals>.<genexpr>   s&     HA1!3!3A!677Hs   %()r&   r'   r(   r9   reversedr0   r/   r   any_maybe_unsafe_set_levelr   r=   )r   batchtensorr   implr*   s   `   @r   inplace_update_layersz%EnableAllLayers.inplace_update_layersq   s     xx""33K@%D$6$6 789 	?A|HHH ##;;D$BSBSVWBWXxx**88>	?r   N)r   list[DimEntry])returnr   )r2   r   r3   r   r4   r   rS   None)rB   torch.TensorrC   boolrS   r	   )rO   rU   r   rR   rS   rT   )
__name__
__module____qualname____doc____annotations__r!   r-   r7   rG   rQ    r   r   r   r      sG      8,%N?'?1??	?r   r   )
__future__r   typingr   r   r&   
_dim_entryr   r   r   r	   r   r\   r   r   <module>r`      s%    " %    }? }?r   