
    9j                         d 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 erdd
lmZ ddZ G d d      ZdddZdddZddZ	 	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 d	 	 	 	 	 	 	 	 	 	 	 ddZy)zM
Python implementation of function wrapping functionality for functorch.dim.
    )annotationsN)AnyTYPE_CHECKING)tree_map   )DimEntry)EnableAllLayers)
TensorInfo)Callablec                    | S )z8Handle tensor conversion for torch function integration. )tensors    S/media/conek/DATA/Code/OCR/venv/lib/python3.12/site-packages/functorch/dim/_wrap.pyhandle_from_tensorr      s    M    c                  .    e Zd ZdZ	 d	 	 	 	 	 ddZddZy)WrappedOperatorzP
    This class wraps PyTorch operations to support first-class dimensions.
    c                2   || _         || _        t        |dd      | _        t        |dd       | _        || _        d| _        d| _        d| _        d| _	        d| _
        | j                  r/| j
                  r"| j                   d| j
                   d	| _        y y y )
N__name__ __doc__Fr   r   Tz
Argument 'z5' can be either an integer or a torchdim.Dim object.
)origwrapper_implementationgetattrnamedocdim_nameis_pointwise
dim_offsetkeepdim_offset
single_dimreduce)selfr   r   r   s       r   __init__zWrappedOperator.__init__    s     	&<#D*b1	4D1 ! 88((<>tuDH &8r   c                |     d fd}t        j                  | j                  dd        j                  |_        |S )z@Create a wrapped function that calls our wrapper implementation.c                 0     j                   g| i |S )N)r   )argskwargsr#   s     r   wrapped_funcz.WrappedOperator.function.<locals>.wrapped_func6   s     .4..tEdEfEEr   )r   r   )assignedupdated)r'   r   r(   r   returnr   )	functoolsupdate_wrapperr   r   r   )r#   r)   s   ` r   functionzWrappedOperator.function3   s:    	F 	  $))mR	
  $xxr   N)dim)r   r   r   r   r   str)r,   r   )r   
__module____qualname__r   r$   r/   r   r   r   r   r      s4    
 QVvv6>vJMv&r   r   c                    ddl m} t        | |      r|rt        d      t	        |       S t        | t
              r| }|dk\  r||z  }|dk\  rt	        |      S t	               S )z:Convert single dimension specification to DimEntry object.r   )Dimz8cannot preserve first-class dimensions with keepdim=Truer   )r   r5   
isinstance
ValueErrorr   int)r0   ndimkeepdimr5   is        r   	_wrap_dimr<   B   sb    #sWXX}	C	1fIA 1f{zr   c                    t        | ||      }g }|j                         s|j                  |       |S | D ]  }|j                  t        |||               |S )z<Convert dimension specification to list of DimEntry objects.)r<   is_noneappend)r0   r9   r:   deresultds         r   
_wrap_dimsrC   S   s\    	3g	&BF::<b M  	7AMM)AtW56	7Mr   c                   |st        d      |j                  | j                        }|:| j                  t	        |      k  r"| j                  dz   }|t	        |      k  r||   }|t        j                  |d   dd      s | j                  |i |S t        j                        5 }j                  t        d      |j                  j                  j                         t        |      }t        j                        |d<    | j                  |i |}|j                  |j                         cddd       S t        j                  |d         s | j                  |i |S d}| j"                  rZ|j                  d	      }	|	:| j$                  t	        |      k  r"| j$                  dz   }
|
t	        |      k  r||
   }	|	t'        |	      }j)                         }t+        |||      }g }dgt	        j                        z  }|D ]  }d}t-        j                        D ]  \  }}||k(  s|} n |tt-        j                        D ]'  \  }}t/        |d
      s|j1                  |      s%|} n |3j                  D cg c]  }t3        |       }}t        d| d|       d||<   |j5                  |        g | j"                  r7|s5t-        j                        D ]  \  }}||   rj5                  |        nj                  dd t	        |      dk(  r|d   }nt7        |      }t        |      }|j9                         }j:                  t        d      t        j:                        |d<   | j                  |v r||| j                  <   n-| j                  dz   }|t	        |      k  rt        |      }|||<    | j                  |i |}dfd}t=        ||      S # 1 sw Y   xY wc c}w )zJ
    This is the core method that handles dimension-aware operations.
    z%Expected at least one argument (self)Nr   r   TF)ensure_batchedensure_presentz%Expected batchedtensor to be non-Noner:   matcheszTensor with dimensions z does not contain zExpected tensor to be non-Nonec                    t        | t        j                        r#ddlm} |j	                  | j
                        S | S )Nr   )Tensor)r6   torchrI   r   from_positional
has_device)objrI   info
new_levelss     r   wrap_resultz'patched_dim_method.<locals>.wrap_result   s2    c5<<( ))#z4??KK
r   )rM   r   r,   r   )r7   getr   r   lenr
   creater   r	   levelsbatchedtensorAssertionErrorinplace_update_layerslistr   from_batchedrL   r"   r    boolr9   rC   	enumeratehasattrrG   r1   r?   tuplecopyr   r   )wrapperr'   r(   dim_argdim_idxguardnew_argsrA   r:   keepdim_argkeepdim_idxr9   dimsdim_indicesseenrB   midxr;   level
level_strs
py_indices
new_kwargsrP   rN   rO   s                          @@r   patched_dim_methodrn   _   s    @AA jj))*G7--D	9$$q(SY7mG   aeT7<<000T[[) 	?U!!)$%LMM''(:(:DKKHDzH,T-?-?@HQK!W\\86v6F%%fdoo>	? 	? T!W%Dw||T,V,, G~~jj+7#9#9CI#E!0014KSY&";/";'G 99;DgtW-D  K7S%%D !!$++. 	HAuz	
 <%dkk2 55),q1AD
 |6:kkBUc%jB
B -j\9KA3O  T
4 +!0 J~~g!$++. 	)HAu7!!%(	) [[^
 ;1%a.
;'
 DzHJ{{=>>$T[[1HQK :%'1
7##$$$q(S]"H~H *HW W\\82z2F K((E	? 	?` Cs   -BO9P9Pc                    |xs d}t        | t        |      }|||_        |||_        |||_        |||_        |j                         S )a  
    Wrap a PyTorch function to support first-class dimensions.

    Args:
        orig: Original function to wrap
        dim_offset: Offset for dimension argument (default: 0)
        keepdim_offset: Offset for keepdim argument (default: 1)
        dim_name: Name of dimension parameter (default: "dim")
        single_dim: Whether function takes single dimension (default: False)
        reduce: Whether function reduces dimensions (default: True)
    r0   )r   rn   r   r    r!   r"   r/   )r   r   r    r   r!   r"   r_   s          r   _wraprp      sc    &  5Hd$6AG'!!/'r   c                >    |i }ddl m} |j                  ||||      S )z@
    Handle __torch_function__ calls for wrapped operators.
    r   )_Tensor)r   rr   __torch_function__)r_   functypesr'   r(   rr   s         r   call_torch_functionrv      s,     ~  %%dE4@@r   )r   torch.Tensorr,   rw   )F)r0   r   r9   r8   r:   rZ   r,   r   )r0   r   r9   r8   r:   rZ   r,   zlist[DimEntry])r_   r   r'   r   r(   r   r,   r   )NNNNN)r   r   r   
int | Noner    rx   r   z
str | Noner!   bool | Noner"   ry   r,   r   )r   N)r_   r   rt   r   ru   r]   r'   r]   r(   zdict | Noner,   r   )r   
__future__r   r-   typingr   r   rJ   torch.utils._pytreer   
_dim_entryr   _enable_all_layersr	   _tensor_infor
   collections.abcr   r   r   r<   rC   rn   rp   rv   r   r   r   <module>r      s    #  %  (   / $ (
$ $N"	w)x "!%" 
     	 
      N AA
A A 	A
 A 	Ar   