o
    i9:j                      @  s   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r8dd
lmZ d7ddZG dd dZd8d9ddZd8d:ddZd;d"d#Z					d<d=d.d/Z	0	d>d?d5d6ZdS )@zM
Python implementation of function wrapping functionality for functorch.dim.
    )annotationsN)AnyTYPE_CHECKING)tree_map   )DimEntry)EnableAllLayers)
TensorInfo)Callabletensortorch.Tensorreturnc                 C  s   | S )z8Handle tensor conversion for torch function integration. )r   r   r   Z/home/nk/hobo-godmode/plappi-mvp/.venv/lib/python3.10/site-packages/functorch/dim/_wrap.pyhandle_from_tensor   s   r   c                   @  s(   e Zd ZdZ	dddd	ZdddZdS )WrappedOperatorzP
    This class wraps PyTorch operations to support first-class dimensions.
    dimorigr
   wrapper_implementationdim_namestrc                 C  sz   || _ || _t|dd| _t|dd | _|| _d| _d| _d| _d| _	d| _
| jr9| jr;| j d| j d	| _d S d S d S )
N__name__ __doc__Fr   r   Tz
Argument 'z5' can be either an integer or a torchdim.Dim object.
)r   r   getattrnamedocr   is_pointwise
dim_offsetkeepdim_offset
single_dimreduce)selfr   r   r   r   r   r   __init__    s   zWrappedOperator.__init__r   c                   s.   d fdd}t j| jddd	  j|_|S )z@Create a wrapped function that calls our wrapper implementation.argsr   kwargsr   c                    s    j  g| R i |S )N)r   )r$   r%   r"   r   r   wrapped_func6   s   z.WrappedOperator.function.<locals>.wrapped_func)r   r   )assignedupdatedN)r$   r   r%   r   r   r   )	functoolsupdate_wrapperr   r   r   )r"   r'   r   r&   r   function3   s   
zWrappedOperator.functionN)r   )r   r
   r   r
   r   r   )r   r
   )r   
__module____qualname__r   r#   r,   r   r   r   r   r      s
    r   Fr   r   ndimintkeepdimboolr   c                 C  s^   ddl m} t| |r|rtdt| S t| tr,| }|dkr(||8 }|dks t|S t S )z:Convert single dimension specification to DimEntry object.r   )Dimz8cannot preserve first-class dimensions with keepdim=Truer   )r   r3   
isinstance
ValueErrorr   r0   )r   r/   r1   r3   ir   r   r   	_wrap_dimB   s   

r7   list[DimEntry]c                 C  sF   t | ||}g }| s|| |S | D ]}|t ||| q|S )z<Convert dimension specification to list of DimEntry objects.)r7   is_noneappend)r   r/   r1   deresultdr   r   r   
_wrap_dimsS   s   
r>   wrapperr$   r%   c                   sV  |st d|| j}|du r&| jt|k r&| jd }|t|k r&|| }|du r~tj|d ddd  s>| j|i |S t j	3} j
du rMtd| j
 j	 t|}t j
|d< | j|i |}|| jW  d   S 1 syw   Y  t|d   s| j|i |S d}| jr|d	}	|	du r| jt|k r| jd }
|
t|k r||
 }	|	durt|	}  }t|||}g }dgt j	 }|D ]U}d}t j	D ]\}}||kr|} nq|du rt j	D ]\}}t|d
r||r|} nq|du rdd  j	D }t d| d| d||< || qg | jrF|sFt j	D ]\}}|| sC| q5n j	dd t|dkrY|d }nt|}t|}| } jdu rotdt j|d< | j|v r||| j< n| jd }|t|k rt|}|||< | j|i |}d fdd}t||S )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-Noner1   matchesc                 S  s   g | ]}t |qS r   )r   ).0levelr   r   r   
<listcomp>   s    z&patched_dim_method.<locals>.<listcomp>zTensor with dimensions z does not contain zExpected tensor to be non-Noneobjr   r   c                   s,   t | tjrddlm} ||  jS | S )Nr   )Tensor)r4   torchrG   r   from_positional
has_device)rF   rG   info
new_levelsr   r   wrap_result   s   z'patched_dim_method.<locals>.wrap_result)rF   r   r   r   )r5   getr   r   lenr	   creater   r   levelsbatchedtensorAssertionErrorinplace_update_layerslistr   from_batchedrJ   r!   r   r2   r/   r>   	enumeratehasattrrB   r:   tuplecopyr   r   )r?   r$   r%   dim_argdim_idxguardnew_argsr<   r1   keepdim_argkeepdim_idxr/   dimsdim_indicesseenr=   midxr6   rD   
level_strs
py_indices
new_kwargsrN   r   rK   r   patched_dim_method_   s   

 









ri   r   r
   r   
int | Noner   r   
str | Noner    bool | Noner!   c                 C  sT   |pd}t | t|}|dur||_|dur||_|dur||_|dur&||_| 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)
    r   N)r   ri   r   r   r    r!   r,   )r   r   r   r   r    r!   r?   r   r   r   _wrap   s   rm   r   functypesrZ   dict | Nonec                 C  s(   |du ri }ddl m} |||||S )z@
    Handle __torch_function__ calls for wrapped operators.
    Nr   )_Tensor)r   rq   __torch_function__)r?   rn   ro   r$   r%   rq   r   r   r   call_torch_function   s   
rs   )r   r   r   r   )F)r   r   r/   r0   r1   r2   r   r   )r   r   r/   r0   r1   r2   r   r8   )r?   r   r$   r   r%   r   r   r   )NNNNN)r   r
   r   rj   r   rj   r   rk   r    rl   r!   rl   r   r
   )r   N)r?   r   rn   r
   ro   rZ   r$   rZ   r%   rp   r   r   )r   
__future__r   r*   typingr   r   rH   torch.utils._pytreer   
_dim_entryr   _enable_all_layersr   _tensor_infor	   collections.abcr
   r   r   r7   r>   ri   rm   rs   r   r   r   r   <module>   s2    
'
|'