o
    *ѹg`O                     @   sp  d dl Z d dlmZ ddlmZ ddlmZ ddlm	Z	mZ ej
Z
d dlZd dlmZ eejZdd	 Zd
d Zdd Zdd Zdd Zdd Zd9ddZdd ZG dd dZG dd deeZG dd deeZi Zeefdd Zd!d" Z d#d$ Z!d%d& Z"e# Z$d'd( Z%d)d* Z&	,d:d-d.Z'd/d0 Z(e)dZ*e j+j,Z-G d1d2 d2Z.d3d4 Z/d;d5d6Z0e j+j1Z2d<d7d8Z1dS )=    Ndim   )op_properties)_enable_layers)tree_flattentree_map)reducec                 C   s   t tj| dS Nr   )r	   operatormul)x r   [/Users/admin/.pyenv/versions/3.10.0/lib/python3.10/site-packages/functorch/dim/reference.pyprod   s   r   c                 C   s:   ddl m} t| |r|rJ d| S | dkr| | S | S )Nr   Dimz8cannot preserve first-class dimensions with keepdim=Truer    r   
isinstance)dNkeepdimr   r   r   r   	_wrap_dim   s   
r   c                    sV   ddl m} t| |tfrtt|  fS |rJ d|  t fdd| D S )Nr   r   z.expected a single dimension or int but found: c                 3   s    | ]	}t | V  qd S N)r   ).0r   r   r   r   r   	<genexpr>.       z_dims.<locals>.<genexpr>)r   r   r   intltupler   )r   r   r   
single_dimr   r   r   r   _dims(   s
   r"   c              	   C   s   ddl m} tdd t|D }t|dkrH|d \}}tdd |D }| | dkr?tdd |D }|d|  d	| | | }	|	|_d S t|dkratd
d |D }|d| d| tdd |D }
| |
kr~|d|  d|
 d| d| d S )Nr   )DimensionMismatchErrorc                 s   s"    | ]\}}|j s||fV  qd S r   )is_bound)r   irr   r   r   r   4   s     z%_bind_dims_to_size.<locals>.<genexpr>r   c                 s   s    | ]	}|j r|jV  qd S r   )r$   sizer   r&   r   r   r   r   7   r   c                 s   $    | ]}|j s	d nt|jV  qdS ?Nr$   strr'   r(   r   r   r   r   9      " z>inferred dimension does not evenly fit into larger dimension:  vs c                 s   r)   r*   r,   r(   r   r   r   r   @   r.   z1cannot infer the size of two dimensions at once: z with sizes c                 s       | ]}|j V  qd S r   r'   r(   r   r   r   r   E       z!Dimension sizes to do not match (z != z) when matching z to )r   r#   tuple	enumeratelenr   r'   )Zlhs_sizerhsZ	lhs_debugr#   Z	not_boundidxr   Z
rhs_so_farZrhs_sZnew_sizeZrhs_sizer   r   r   _bind_dims_to_size1   s.   
r8   c                 C   sB   ddl m} t| |r| jt| j| jfS | tt| j ddfS )Nr   _Tensorr   T)	r   r:   r   _tensorllist_levels_has_devicerangendim)inpr:   r   r   r   _tensor_levelsL   s   
rB   c           	   	   C   s   g }g }d}|   }|D ]%}z||}|| |||  W q ty1   |d d}Y qw |ttt|krA| j| } |rH| j| } | S )NFr   T)	r'   indexappend
ValueErrorlistr?   r5   permuteview)	vZfrom_levelsZ	to_levelsrH   rG   requires_viewr'   tr7   r   r   r   _match_levelsU   s$   




rL   Fc           	      C   s   ddl m} | jt| j}}z||}W n  ty6   |s  d}|j|jg| R  }|	dd Y nw d}t
|D ]}t|| trR||  d8  < |d7 }q=| d ||< |||| j|fS )Nr   )Tensorr   )r   rM   r;   r<   r=   rC   rE   expandr'   insertr?   r   r   from_positionalr>   )	selfr   
expand_dimrM   ptensorlevelsr7   Zidx_batchedr%   r   r   r   _positional_no_permutel   s&   rU   c                 C   s>   ddl m} t| |t||krdS t| |r| |u S | |kS )Nr   r   Fr   )abr   r   r   r   seq   s   
rX   c                   @   s   e Zd Zdd Zdd ZdS )isinc                 C   s   | D ]
}t ||r dS qdS )NTF)rX   )rQ   itemr   r   r   r   __contains__   s
   
zisin.__contains__c                 C   s(   t | D ]\}}t||r|  S qtr   )r4   rX   rE   )rQ   rZ   r%   r   r   r   r   rC      s
   
z
isin.indexN)__name__
__module____qualname__r[   rC   r   r   r   r   rY      s    rY   c                   @      e Zd ZdS )r<   Nr\   r]   r^   r   r   r   r   r<          r<   c                   @   r_   )r    Nr`   r   r   r   r   r       ra   r    c                    s<  ddl mm m ddlm} |tjju r3|\}}t|r3t|r3|j	dkr3|j	dkr3|||S t
 }t||f\}	}
d |	D ]}t|r^|jrO|j|jD ]}||vr]|| qRqBfdd|tv rt
 t
 }g }t|	D ]<\}}t|rt|\}}}t|r|jsd ur|jjd}||	|< |D ]}|vr| q|||f qv|D ]\}}t|	| ||	|< q|
|	\}}||i |} fdd	}t||S  fd
d	}t|( td|  |
fdd|	D \}}||i |}t||W  d    S 1 sw   Y  d S )Nr   )r:   rM   
TensorLike)DelayedMulTensorr   c                    s4   t |  r| j}d ur| js|jjd}|S | S )Ndevice)r   _batchtensorr>   tore   )rK   r&   )r:   device_holding_tensorr   r   unwrap   s   
z"__torch_function__.<locals>.unwraprd   c                    s    t | r | d uS | S r   )r   rP   rK   )rM   rb   rh   result_levelsr   r   wrap   s
   

z __torch_function__.<locals>.wrapc                    s   t | r | d uS | S r   )r   from_batchedrj   )rM   rb   rh   r   r   rl         
zbatch_tensor for c                 3   s    | ]} |V  qd S r   r   )r   f)ri   r   r   r      s    z%__torch_function__.<locals>.<genexpr>)r   r:   rM   rb   Zdelayed_mul_tensorrc   torch__mul__r   r@   r<   r   r>   rf   dimsrD   	pointwiser4   rB   rg   re   rL   r   r   print)rQ   origclsargskwargsrc   lhsr6   Zall_dimsZ	flat_argsZ	unflattenro   r   Z
arg_levels	to_expandr%   rS   rT   _lresultrl   r   )rM   rb   r:   rh   rk   ri   r   __torch_function__   sv   







&r~   c                 G   s  ddl m}m} | jt| j}}t }g }d}| j}	|D ]T}
t|
tr4|	|
 |	dd |
D  qt|
|rE|
|
 |
|
j qt|
tr^t|
|	d}
|
|
 |
||
 q|	|
 |
tdd |
D  d}qttt|}t|}t|D ]:\}}
z||
}W n ty } ztd| j d	|
 |d }~ww || }||= ||= ||d
 ||| q|j| }d
}tt|d ddD ]}t|| tr|d7 }| ||< q|||| j}|r|jg || t|d  R  }|S )Nr   )r   rM   Fc                 s   r0   r   r1   r   er   r   r   r      r2   zpositional.<locals>.<genexpr>c                 s   r0   r   r1   r   r   r   r   r   
  r2   Tztensor of dimensions z does not contain dim r   )r   r   rM   r;   r<   r=   r@   r   DimListextendrD   r'   r   r   r   rF   r?   r5   r4   rC   rE   DimensionBindErrorrr   rO   rG   rP   r>   Zreshape)rQ   rr   r   rM   rS   rT   Z	flat_dimsrH   Z
needs_viewr@   r   rG   Znflatr%   r7   r   pseenr}   r   r   r   
positional   sb   








$r   c                 C   s*   ddl m} | D ]
}t||r dS qd S )Nr   r   Tr   )inputr   r%   r   r   r   _contains_dim'  s   
r   c                 G   sR   t |s| tjjd | g|R S |}dd |D dg| j  }| j| } | | S )Nc                 S   s   g | ]}|j qS r   r1   r   r   r   r   r   
<listcomp>3  s    zexpand.<locals>.<listcomp>r   )r   r~   rp   rM   rN   r@   )rQ   sizesrr   r   r   r   rN   /  s   
rN   c                 C   s    t ||kr
|| S || |S r   )r5   get)nameoffsetrw   rx   defaultr   r   r   _getarg;  s   r   c                 C   s$   t ||kr|||< d S ||| < d S r   )r5   )r   r   rw   rx   valuer   r   r   	_patchargA  s   r   r   Tc              	      s4   ddl m mm  f	dd}|S )Nr   )r   rM   rb   c           	         s  t ||t}|tu sr@t|s@tj  td
  
jg|R i |jW  d    S 1 s;w   Y  rJt d	||dnd}j	t
j}t|jj|}tfdd|D  ry|sy fddtD nt dkr d	  t|}t||  fd
d}t td
  
|g|R i |}t||W  d    S 1 sw   Y  d S )Nzdim fallback batch_tensor for r   Fc                 3   s    | ]}  |V  qd S r   rC   r   )rT   r   r   r   Z  s    z$_wrap.<locals>.fn.<locals>.<genexpr>c                    s   g | ]
\}}| vr|qS r   r   )r   r%   r|   )dim_indicesr   r   r   \  s    z%_wrap.<locals>.fn.<locals>.<listcomp>r   r   c                    s   t | r | jS | S r   )r   rP   r>   rj   )rM   rb   
new_levelsrQ   r   r   rl   g  rn   z_wrap.<locals>.fn.<locals>.wrapzdim used batch_tensor for )r   _not_presentr   r   rr   rt   rm   rf   r>   r;   r<   r=   r"   r@   r3   r4   r5   rF   r   r   )	rQ   rw   rx   r   r   rK   rr   rl   r&   	r   rM   rb   dim_name
dim_offsetkeepdim_offsetru   r	   r!   )r   rT   r   rQ   r   fnM  s8    
$z_wrap.<locals>.fn)r   r   rM   rb   )ru   r   r   r   r!   r	   r   r   r   r   _wrapH  s   $r   c                 O   s:   ddl m} ttj| }t|| t|g|R i | d S )Nr   r9   )r   r:   getattrrp   rM   setattrr   )r   rw   rx   r:   ru   r   r   r   _deft  s   "r   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )dim_trackerc                 C   s   t  | _g | _d S r   )r<   rr   count)rQ   r   r   r   __init__  s   
zdim_tracker.__init__c                 C   s*   || j vr| j | | jd d S d S r
   )rr   rD   r   rQ   r   r   r   r   record  s   
zdim_tracker.recordc                 C   s   | j | j| S r   )r   rr   rC   r   r   r   r   __getitem__  s   zdim_tracker.__getitem__N)r\   r]   r^   r   r   r   r   r   r   r   r     s    r   c           *         s  ddl m m}m}m}m}m} t|| o(t|tt	f o(t||o'|j
dk }|r>t|  r9 td | |fS t| |S t|tsG|g}nt	|}d}d }	g }
t|D ]D\}}|du set||rw|jsw|	d urud| d|	 }|||}	t||r||jrt|nd7 }|
| qU|d ur|dur|d7 }qU| j
}||krtd| d| d	|	d ur|| }||	 }|du rtg| ||	|	d < n|| t|
D ]}|| |||d < qd}d
}|  }g }t  fdd}||  g }t|D ]s\}}|d u rt||< |d d}q|| }t||r)||_| || nBt|tt	frb|rbt|d |rb|D ]}| q>t||d|  |dd |D  d}|| n	|| || |d7 }q|rx| j| } t|D ]}|| |||d < q|t|  r| jt	| j}}t|fdd|D }| j}d}n| |}}|j
t| }d}g }g }d } i }!d
}"t|D ]T\}}#t|#|r|# dkrt||< ||# qt|#|rd}"| d u rt|} t|#\}$}}%||!|< |$||< |D ]}&|&|vr||& qd}"|d q| d ur(||| | < |!  D ]\}}t!|| ||||< q,|"rEt||}'n|}'d}(|dkrV|dg|  tt|D ]\}})t|)t"rp|(|d| < |(d8 }(q\|#|'||S )Nr   )r:   r   r   r   rM   rb   r   .z\at most one ... or unbound dimension list can exist in indexing list but found 2 at offsets z and z	at least z/ indices were supplied but the tensor only has z dimensions.Fc                    s(   t |  sd S | jD ]}| q
d S r   )r   rr   r   )rK   r   )r:   	dims_seenr   r   add_dims  s
   

zt__getitem__.<locals>.add_dimsTzoffset c                 s   r0   r   r1   r   r   r   r   r     r2   zt__getitem__.<locals>.<genexpr>c                    s"   g | ]}t |trt n|qS r   )r   r   next)r   r|   )input_itr   r   r     s   " z t__getitem__.<locals>.<listcomp>r   )$r   r:   r   r   r   rM   rb   r   r3   rF   r@   r~   _orig_getitemr4   r$   r5   rD   
IndexErrorno_sliceZbind_lenreversedr'   r   r   r8   r   rH   r;   r=   iterr>   rB   itemsrL   r   rP   )*rQ   r   r   r   r   rM   rb   Z	is_simpleZdims_indexedZexpanding_objectZdimlistsr%   smsgr@   Zexpanding_ndimsobjrJ   r'   Z
view_sizesr   Z	dim_packsr7   szr   Zptensor_selfrT   Zflat_inputsZ
has_deviceZto_padrk   Zindex_levelsZtensor_insert_pointrz   Zrequires_getindexrA   rS   r{   r|   r}   Znext_positionalr&   r   )r:   r   r   r   t__getitem__  s   







&









r   c           
      C   s   t |trt| ||||S d }|d urt||dd\}}g }| D ]!}t||dd\}}|d ur=||kr=|||}n|}|| q#tj|||d}	|	||d f||fS )NT)rR   )outr   )r   r   rp   stackrC   rU   Zmove_dimrD   )
ZtensorsZnew_dimr   r   rC   ZptensorsrK   ptpiprr   r   r   r   B  s   
r   c              	      s  ddl m}m} t|tstdd |D r&t |rtdt| | dS t |r>t| |s7J d  t|  \}  | 	 }d}g }g }t
|D ]\}	}
|
jr`||
j	 ||
j	7 }qM|d ||	 qM|r||ksJ d	| d
| d| d|| }| t|  }|D ]&}t||}||| _	|||< ||8 }q||ksJ d| d
| d| dt fddt|t| | dD S )Nr   )r:   r   c                 s   s    | ]}t |tV  qd S r   )r   r   )r   rK   r   r   r   r   Z  s    

zsplit.<locals>.<genexpr>zKwhen dim is specified as a Dim object, split sizes must also be dimensions.r   zTensor does not have dimension r   z,result dimensions are larger than original: r/   z ()z)result dimensions do not match original: c                 3   s     | ]\}}|  |V  qd S r   r   )r   r   rK   r   r   r   r     s
    

)r   r:   r   r   r   anyrE   _orig_splitrU   r'   r4   r$   rD   r5   minr3   zip)rQ   Zsplit_size_or_sectionsr   r:   r   r'   Ztotal_bound_sizeunboundr   r%   r   Zremaining_size
chunk_sizeur   r   r   r   splitW  sR   






r   )F)r   r   r   FT)r   N)r   )3rp   Zfunctorch._Cr   Z_Cr   r   Zbatch_tensorr   r   r   r   r   	functoolsr	   setrs   r   r   r"   r8   rB   rL   rU   rX   rY   rF   r<   r3   r    Z
empty_dictclassmethodr~   r   r   rN   objectr   r   r   r   r   slicer   rM   r   r   r   r   r   r   r   r   r   r   r   <module>   sP   
		
O2	
, 
5