o
    i"J                     @  s   d dl mZ d dlmZmZ d dlmZmZmZm	Z	 d dl
Z
ddlmZmZ ddlmZ er4ddlmZ dBddZeG dd dZdCddZdDddZdEd"d#ZdFd&d'ZdGd-d.ZdHd1d2ZdId4d5ZdJd7d8ZdKd@dAZdS )L    )annotations)	dataclassfield)AnyOptionalTYPE_CHECKINGUnionN   )_match_levelsDimEntry)
TensorInfoDimlstlistitemr   returnOptional[int]c                 C  sL   t | D ]\}}t|trt|tr||kr|  S q||u r#|  S qdS )z
    Helper function to find index of item in list.

    For DimEntry objects, uses __eq__ comparison which properly handles
    both positional and Dim entries.

    Returns the index if found, None if not found.
    N)	enumerate
isinstancer   )r   r   i	list_item r   [/sda-disk/www/egybert/egybert_env/lib/python3.10/site-packages/functorch/dim/_getsetitem.py_safe_index   s   	r   c                   @  sb   e Zd ZU dZded< dZded< dZded< eedZ	d	ed
< eedZ
ded< dZded< dS )IndexingInfoFboolcan_call_originaladvanced_indexingNzOptional[torch.Tensor]self_tensor)default_factoryz	list[Any]flat_inputslist[DimEntry]result_levels
has_device)__name__
__module____qualname__r   __annotations__r   r   r   r   r!   r#   r$   r   r   r   r   r   #   s   
 r   objr   c                 C  s$   ddl m}m} || p|| S )z
    Check if an object has first-class dimensions.

    This function checks if the object is either a Dim or a functorch Tensor
    that has first-class dimensions, using the proper check_exact methods.
    r	   )r   Tensor) r   r*   check_exact)r)   r   r*   r   r   r   has_dims-   s   r-   szintsddimsnsznsdNonec                 C  s^  ddl m} d}t|D ]T\}}|js[t|d t|D ]}	||	 js/|d|d||	 |||	 j9 }q| | dkrPtdd |D }
|d|  d	|
 | | }||_| } n||j9 }q|| krvt|}
|d
|  d| d|
 dgt| }|}ttt|D ]}|||< ||| j9 }qtt|D ]}|	|| j |	||  qdS )zM
    Bind dimensions to size and calculate proper strides for dim packs.
    r	   DimensionBindErrorz1cannot infer the sizes of two dimensions at once  and r   c                 s  s     | ]}|j r
|jnd V  qdS )?N)is_boundsize).0dimr   r   r   	<genexpr>L   s    z%_bind_dims_to_size.<locals>.<genexpr>z>inferred dimension does not evenly fit into larger dimension: z vs z!Dimension sizes to do not match (z != z) when matching dimension pack N)
r+   r6   r   r9   rangelenr:   tuplereversedappend)r.   r0   r1   r2   r3   r6   rhs_prodr   r<   jtupinferred_sizenew_stridescurrent_strider   r   r   _bind_dims_to_size9   sD   
rI   r!   r@   c                 C  s   t | S N)r@   )r!   r   r   r   slice_to_tuplem   s   rK   indexindicesc                 C  s   t | tr||  dS t | tjr||  dS t| dr%t | ttfr,||  dS t | t	rkt
| dkr>||  dS | D ]#}t |tjtfs[t|ds[|du s[|d u s[t|rc||   dS q@||  dS ||  dS )NTF__iter__    .)r   r@   extendtorchr*   rB   hasattrstrbytesr   r?   slicer-   )rL   rM   r   r   r   r   extractIndicesq   s>   








rV   clsfunctypesargskwargsc                 C  s<   |d }|d }t ||t|}|jrtj||S t|S Nr   r	   )
getsetitemr-   r   rQ   r*   __getitem__invoke_getitem)rW   rX   rY   rZ   r[   selfrL   iinfor   r   r   getitem   s   rb   r`   rhsc                 C  sx  ddl m}m} t| |t| pt|}|jr"tjj	| || dS |
|dd}|r|jD ]J}| sxd}|jD ]}	|	 sK|	 | u rKd} nq9|sxg }
|jD ]}| ra|
|  qS|
|  qS|d| dt|
dq.|jdusJ d	t|j|j|j}n|}|jrt|j}|jdu rtd
tjj	|j|| dS |jdu rtd|j| dS )z2Set values in tensor using first-class dimensions.r	   )r6   r   NFTz"rhs of setitem contains dimension z, which is not in the dimension on the left ()z"Cannot match levels on None tensorzCannot setitem on None tensorzCannot copy to None tensor)r+   r6   r   r]   r-   r   rQ   _C
TensorBase__setitem__createlevelsis_positionalr#   r<   rB   positionr@   tensorr
   r   rK   r!   r   RuntimeErrorcopy_)r`   rL   rc   r6   r   ra   rhs_infolfoundresult_levelresult_dimsrlmatched_rhsrE   r   r   r   setitem   sT   





rv   ra   c                 C  sd   | j r| j}t| j}|d u rtd|| }n| j}|d u r#tdddlm} ||| j| j	S )NzCannot getitem on None tensorr	   )r*   )
r   r   rK   r!   rm   r+   r*   from_positionalr#   r$   )ra   r   rE   rtensorr*   r   r   r   r_      s   

r_   tensors_have_dimsc                   s*  ddl m} | }g }t|r|| nt||}|r#|s#tddS d}d d }g }	d fdd}
ddd}d}t|D ]N\}}t|rLd}|d7 }q=|du rU|
| q=t||rsd}|jsf|
| |}n|t	|j
7 }|	| q=|d u rzd}q=||rd}d}|d7 }q=|d7 }q=|rtddS t| dd}t	|j}||krtd| d| d|| } dkr|d ur|| ntd g| }|d   | | d d   }tt	|	d ddD ]+}|	| }|d u r dkr| kr||7 }|| }|d | |j
 ||d d   }qt||g g |S )Nr	   )DimListT)r   r   r   r/   r   r4   c                   s0    dkrddl m} |d  d|  |  d S )Nr{   r	   r5   z\at most one ... or unbound dimension list can exist in indexing list but found 2 at offsets r7   )r+   r6   )r   r6   expanding_objectr   r   check_expanding  s   z#getsetitem.<locals>.check_expandingsr   r   c                   s<   ddl m  t| ttfot| dkot fdd| D S )Nr	   r   r   c                 3      | ]}  |V  qd S rJ   r,   )r;   r   r   r   r   r=         z1getsetitem.<locals>.is_dimpack.<locals>.<genexpr>)r+   r   r   r@   r   r?   all)r   r   r   r   
is_dimpack  s   
zgetsetitem.<locals>.is_dimpackF.z	at least z/ indices were supplied but the tensor only has z dimensionsr   r/   r   r4   )r   r   r   r   )r+   rz   r-   rB   rV   r   r   r   r9   r?   _dimsr   rh   ri   
ValueErrorbind_lenrU   r>   getsetitem_flat)r`   rL   ry   rz   can_call_original_getitem
input_listis_sequencedims_indexedunbound_dim_listdimlistsr~   r   has_dimpacks_or_noner   r   	self_info
total_dimsexpanding_dims	no_slicesidxdlr   r|   r   r]      s~   


	







$r]   r   r   r   keysr"   valuesr   c                   s  ddl m  g g d%fddg g d d&fd
dd'fddg 
g 	| jd u r6td| j | j d(	
fdd|d d  d)	
fdd}d* 	
f
dd}t| jD ]I\}}t||}	|	d ur||||	  qp|	 r|  st
d  | qpd }
dd  |||
 qp|  |  | qp|  rֈ
r| jd u rtd| j
	| j }n| j}g g }dd}d)fdd}tD ]\}}| d urd }|  | jD ]}||vr|| qq |rf|}t|}|d us+J d!| d"| dkr@t
d |< t| qd }d |< t| t|gdd |< t||vrb|t| |  q|t
d krod }t|ts|td qdkrt|D ]	}| q|rttD ]4}| d ur̈| j}|d usJ d#| jsd ur|j}t|| j||< qd}tttD ]}| 	 r|d7 }t| |< qtd||| jd$S )+Nr	   r   r<   r   r   r4   c                   s>   t  | }|d ur|  d7  < d S  |  d d S )Nr	   )r   rB   )r<   r   )	seen_dimsseen_dims_nusesr   r   add_dimw  s
   

z getsetitem_flat.<locals>.add_dimhandlec                   s     |   d  d S rJ   rB   )r   )r!   tensor_inputsr   r   append_flat_handle  s   
z+getsetitem_flat.<locals>.append_flat_handletir   c                   s4    d   |  | jr d u r| j d S d S d S rJ   )rB   r$   rl   )r   )device_holding_tensorr!   r   r   r   append_tensor_input  s
   


z,getsetitem_flat.<locals>.append_tensor_inputz%Cannot get size/stride on None tensorr   r/   c                   s(    r |    |   d S d S rJ   r   )r   )r   r3   r2   r0   r.   r   r   append_size  s   z$getsetitem_flat.<locals>.append_sizec                     s\   r(d d u r, t d  d d dd  r*d d u sd S d S d S d S r\   )rU   rB   r   )r   input_itr3   r2   r   r   parse_nones  s   

 z$getsetitem_flat.<locals>.parse_nonesargc                   s     |r|}|jdkr	|  |_| |  | d S t|dd}|rB|  | |jD ]}| s?|  q3d S rut|t	t
frut fdd|D rut
|}|D ]
}| | q\t	|  |  | d S |  | d S )Nr{   Fc                 3  r   rJ   r   )r;   dr   r   r   r=     r   z7getsetitem_flat.<locals>.append_item.<locals>.<genexpr>)r,   _sizer:   r   rh   ri   rj   r<   r   r@   r   r   rI   )r   r   r   infoleveldim_pack)
r   r   r   r   r   r   r3   r2   r0   r.   r   r   append_item  s6   



$
z$getsetitem_flat.<locals>.append_itemr   zCannot restride None tensorr{   Fc                     s,   dkr
t  d S t  krdd S d S )Nr{   r   )r?   r   )r#   tensor_insert_pointr   r   mark_tensor_index  s
   z*getsetitem_flat.<locals>.mark_tensor_indexTzDim z not found in seen_dimsz(TensorInfo should have valid tensor data)r   r   r   r!   r#   r$   )r<   r   r   r4   )r   r   r   r4   )r   r   r   r4   r   )r   r4   )r   r/   r   r   r   r4   )r+   r   rl   rm   r:   strider   ri   r   rj   rU   r<   
as_stridedstorage_offsetrB   r,   r   r   
_get_ranger   r/   rA   insertr>   r?   r$   todevicer
   r   )r   r   r   r   r   r   r   r   r   r   r   r   index_levelsrequires_getindexr   inpr   dim_idxtseen_positionalsr   )r   r   r   r   r   r   r!   r   r   r3   r2   r#   r0   r   r   r.   r   r   r   r   j  s   	


 !









r   )r   r   r   r   r   r   )r)   r   r   r   )r.   r/   r0   r/   r1   r   r2   r   r3   r   r   r4   )r!   r   r   r@   )rL   r   rM   r   r   r   )rW   r   rX   r   rY   r   rZ   r   r[   r   r   r   )r`   r   rL   r   rc   r   r   r4   )ra   r   r   r   )r`   r   rL   r   ry   r   r   r   )r   r   r   r   r   r"   r   r   r   r   r   r   )
__future__r   dataclassesr   r   typingr   r   r   r   rQ   
_dim_entryr
   r   _tensor_infor   r+   r   r   r   r-   rI   rK   rV   rb   rv   r_   r]   r   r   r   r   r   <module>   s(    

	

4

(

@
r