o
    iF                     @   s  d dl m  mZ d dlZd dlmZ d dlmZ d dl	m  m
  mZ dd Zd9ddZd	d
 Zdd Zd:ddZd;ddZd9ddZdd Zd<ddZdd Zdd Zd=d d!Zd"d# Zd<d$d%Zd<d&d'Zd(d) Zd>d+d,Zd-d. Zd/d0 Zd1d2 Zd3d4 Z G d5d6 d6Z!d7d8 Z"dS )?    N)partialuse_name_ofc                 C   s`   t | tjjjtjjjB rt| jS t | tt	B t
B tjB tjB tjB r&dS tdt|  d)N zObject of type z is not a tensor or scalar)
isinstancetracer	signature	classicalTensorConvertibleTensortupleshapeintfloatboolnpintegerfloatingbool_
ValueErrortype)xr   r   b/home/ubuntu/.local/lib/python3.10/site-packages/einx/_src/tracer/signature/classical/functions.py
_get_shape   s
   
$r      c                       t  fdd}|S )Nc                    sZ   t |  | fi |} dkrttjjj d}ndks J  fdd}t| |S )Nr   r   c                       t  fddtD S )Nc                 3   "    | ]}t jjj d V  qdS r   Nr   r   r	   r
   .0_originr   r   r   	<genexpr>        zBpreserve_shape.<locals>.inner.<locals>.<lambda>.<locals>.<genexpr>r   ranger%   num_outputsr   r*   r   <lambda>       z/preserve_shape.<locals>.inner.<locals>.<lambda>)r   r   r   r   r	   r
   cast)r   kwargsoutputr,   opr   r   inner   s   zpreserve_shape.<locals>.innerr   r3   r,   r4   r   r2   r   preserve_shape   s   r6   c                       t   fdd}|S )Nc                    s(    | |} t | tt jjj|d} | S Nr   r   r/   r   r   r	   r
   )r   r   r3   r   r   r4   #   s   
zset_shape.<locals>.innerr   r3   r4   r   r:   r   	set_shape"   s   r<   c                    r7   )Nc                    sF   t |  t fdd|D }| |} t| ttjjj|d} | S )Nc                 3       | ]} | V  qd S Nr   r"   ishape_inr   r   r&   0       z+transpose.<locals>.inner.<locals>.<genexpr>r   )r   r   r   r/   r   r   r	   r
   )r   axesr   r:   rA   r   r4   -   s
   
ztranspose.<locals>.innerr   r;   r   r:   r   	transpose,   s   rE   axis1axis2Fc                    s   t  fdd}|S )Nc                    sv  r| j d }| j d }n" |vrtd  d|vr%td d| }|}tt| }|dk r?|t|7 }|dk rI|t|7 }|dk s]|t|ks]|dk s]|t|krgtd| d| || || kr}td||  d	||  || }t|}|t||= |t||= || t	|}s ||i|B }| fi |} t
| tt
jjj|d
} | S )N   r   Missing required argument 'z' in diagonalr   z#Invalid axis indices for diagonal: z, z4Cannot take diagonal over axes of different length:  and r   )ndimr   poplistr   lenmaxminappendr   r   r/   r   r   r	   r
   )r   r0   rF   rG   rB   l	shape_outargname_axis1argname_axis2axis_always_lastr3   r   r   r4   9   s:   


(
zdiagonal.<locals>.innerr   )r3   rU   rV   rW   r4   r   rT   r   diagonal8   s   %rX   axiskeepdimsc                       t  fdd}|S )Nc                    s   t t| } |vs|  d u rt t| j}nt|  tr%|  g}n|  }|v r;| r;|D ]}d||< q3nt|ddD ]}||= qAt|}| fi |} t	| t
tjjj|d} | S )Nr   T)reverser   )rM   r   r)   rK   r   r   sortedr   r   r/   r   r   r	   r
   )r   r0   r   rD   aargname_axisargname_keepdimsr3   r   r   r4   c   s    
zreduce.<locals>.innerr   )r3   r`   ra   r4   r   r_   r   reduceb   s   rb   c                    r   )Nc                     s   d  | D ]@}t |drD d u r|j q|j}t t|k r*d   t t|k st|t k r>d| }t|t k s2t | q d u rMtd|  }dkr_ttjj	j
 d}ndkseJ  fdd}t||S )Nr   r   z>elementwise operation requires at least one tensor as argumentr   r   c                    r   )Nc                 3   r   r   r    r!   r$   r   r   r&      r'   z?elementwise.<locals>.inner.<locals>.<lambda>.<locals>.<genexpr>r(   r*   r+   r*   r   r-      r.   z,elementwise.<locals>.inner.<locals>.<lambda>)hasattrr   rN   r   maximumr   r   r   r   r	   r
   r/   )xsr^   shape2r   r1   r2   r   r   r4   |   s,   
zelementwise.<locals>.innerr   r5   r   r2   r   elementwise{   s   rh   c                    s    fdd}|S )Nc                    s   | j |j krtd| j  d|j  | j dk s|j dk r(td| j  d|j  tt| jd d |jd d | jd |jd f } | |} t| ttj	j
j|d} | S )NzImatmul requires input tensors to have the same number of dimensions, got rJ   rH   zAmatmul requires input tensors to have at least 2 dimensions, got r   )rK   r   r   r   re   r   r   r/   r   r   r	   r
   )r   yr   r:   r   r   matmul   s   8
zmatmul.<locals>.matmulr   )r3   rl   r   r:   r   rl      s   rl   c                    r   )Nc                    s    |v r	|  }nd }|d u r|j }nB|}|dk r|| j7 }|dk s'|| jkr2td| d| j t|dr=t|j }nd}t| j d | | t| j |d d   }| |fi |} t| ttjj	j
|d} | S )Nr   axis & out of bounds for array of dimension r   r   r   r   )r   rK   r   rd   r   r   r/   r   r   r	   r
   )r   indicesr0   rY   r   rG   indices_shaper`   r3   r   r   r4      s"   


,ztake.<locals>.innerr   r3   r`   r4   r   rq   r   take   s   rs   c                    s,   t  tjs
tdt  fdd}|S )Nzop must be Tracerc                    s   t jj|  | g||S r>   )r   r   pythoncall_inplace)r   argsr0   r:   r   r   r4      s   zinplace.<locals>.inner)r   r   Tracerr   r   r;   r   r:   r   inplace   s
   rx   c                  C   s   dd } | S )Nc                 S   sR  t |trt|| jkrtdt| d| j dt| j}g }|D ]R}t |tjt	B s?t |t
jjjt
jjjB rF|jdkrF|dd  }q#|td ksT|td d dkrb||d  |dd  }q#|d u rl|d q#tdt| dt|t| }n| jdkrtd	| j d
t|j}t
jj| |}t
|tt
jjj|d}|S )NzNumber of indices (z%) must match the rank of the tensor ()r   r   rj   z	Key type z not supportedz0Single index only supported for 1D tensors, got zD tensorr   )r   r   rN   rK   r   rM   r   r   r   r   r   r   r	   r
   r   slicerQ   NotImplementedErrorr   rt   getitemr/   r   )tensorkeyin_shaper   kr   r   r   r   r|      s0   




zgetitem.<locals>.getitemr   )r|   r   r   r   r|      s   r|   c                    s"    d u r	t jjj  fdd}|S )Nc                    s,   | j } | g|R i |} t| |} | S r>   )_tracer_typer   r/   )r   rv   r0   tracer_typer:   r   r   setitem   s   zsetitem.<locals>.setitem)r   r   rt   r   )r3   r   r   r:   r   r      s   
r   c                    r7   )Nc                    s:   | f} | g|R i |}t |tt jjj|d}|S r8   r9   )nrv   r0   r   r   r:   r   r   r4     s   zarange.<locals>.innerr   r;   r   r:   r   arange  s   r   c                    r   )Nc                    s   |v r	|  nd  dk r | d j 7   dk s! | d j kr.td  d| d j  t| d j}t fdd| D | < t|}| fi |}t|ttj	j
j|d}|S )Nr   rm   rn   c                 3   s    | ]}|j   V  qd S r>   r   )r"   r   rY   r   r   r&     s    z-concatenate.<locals>.inner.<locals>.<genexpr>r   )rK   r   rM   r   sumr   r   r/   r   r   r	   r
   )rf   r0   r   r   rq   r   r   r4     s   
zconcatenate.<locals>.innerr   rr   r   rq   r   concatenate  s   r   c                    r[   )Nc           	         s@  |v r	| }nd}|dk r|| j 7 }|dk s|| j kr(td| d| j  t|trQ| j| | }|| | jd krKtd| j|  d| d|g| }n!rpdgt| | j| g   fddtt d	 D }n|}g |D ]}t| j}t|||< t	| qv| |fi |}t
|fd
d}|S )Nr   rm   rn   z2array split does not result in an equal division: z % z != 0c                    s    g | ]} |d    |  qS rc   r   r?   )ro   r   r   
<listcomp>7  s     z(split.<locals>.inner.<locals>.<listcomp>r   c                    s    fddD S )Nc                    s   g | ]}t jjj |d qS )r   r    r"   r   r*   r   r   r   B  s    z:split.<locals>.inner.<locals>.<lambda>.<locals>.<listcomp>r   r*   )shapesr*   r   r-   B      z&split.<locals>.inner.<locals>.<lambda>)rK   r   r   r   r   rM   r)   rN   rQ   r   r   r/   )	r   arg1r0   rY   section_lengthlengthslengthr   rf   r`   
cumulativer3   )ro   r   r   r4   $  s0   


 
zsplit.<locals>.innerr   )r3   r   r`   r4   r   r   r   split#  s    r   c                    r7   )Nc                    sV   | j dks
|j dkrtd| j  d|j  d | |} t| ttjjjdd} | S )Nr   z"dot only supports 1D tensors, got zD and Dr   r   )rK   r   r   r/   r   r   r	   r
   )r   rk   r:   r   r   r4   I  s
   
zdot.<locals>.innerr   r;   r   r:   r   dotH  s   r   rD   c                    r   )Nc                    s  |v r	| }nt d dt|tr(tt j|  jtt|n)t|ttB rJt|dkrJ|\ttrAgttrIgnt d| ttkrgt dt dt dd  fd	d
D fdd
D fdd
t jD }fdd
tjD }t fdd
|D fdd
|D  } fi |}t	|t
tjjj|d}|S )NrI   z' in tensordotrH   z%Invalid axes argument for tensordot: zAxes lengths do not match: z != c                 S   s,   | dk r| |7 } | dk s| |krt d| S )Nr   zInvalid axis index in tensordot)r   )rY   rK   r   r   r   canonicalize_axisk  s
   z3tensordot.<locals>.inner.<locals>.canonicalize_axisc                       g | ]}| j qS r   rK   r"   rY   )r^   r   r   r   r   r      z,tensordot.<locals>.inner.<locals>.<listcomp>c                    r   r   r   r   )br   r   r   r   s  r   c                       g | ]}| vr|qS r   r   r?   )axes_ar   r   r   u  r   c                    r   r   r   r?   )axes_br   r   r   v  r   c                       g | ]} j | qS r   r   r?   )r^   r   r   r   w      c                    r   r   r   r?   )r   r   r   r   w  r   r   )r   r   r   rM   r)   rK   r   rN   r   r/   r   r   r	   r
   )r^   r   r0   rD   a_remainb_remainr   r   argname_axesr3   )r^   r   r   r   r   r   r4   V  s2   



(ztensordot.<locals>.innerr   )r3   r   r4   r   r   r   	tensordotU  s   &r   c                    r7   )Nc              	      s`  |  dd  d}t|t|kr tdt| dt| i  tt||ddD ]U\}\}}| dd	}t|t|jkrUtdt| d
t|j d| dt||jddD ]"\}}| v r{ | |krztd| d |  d| q]| |< q]q+|  dd  dd	}t fdd|D }	| g|R  }
t	
|
tt	jjj|	d}
|
S )Nz->r   ,	Expected z tensors, got Fstrict  z axes, got z for z-th (zero-based) input tensorz Got conflicting values for axis z: rJ   rj   c                 3   r=   r>   r   r   valuesr   r   r&     rC   z(einsum.<locals>.inner.<locals>.<genexpr>r   )r   rN   r   	enumeratezipstripreplacer   r   r   r/   r   r   r	   r
   )
subscriptstensorsexprsr@   exprr}   rY   valueexpr_outrS   r   r:   r   r   r4     s(   &
zeinsum.<locals>.innerr   r;   r   r:   r   einsum  s   r   c                 C   s   g }d }t | |ddD ]?\}}t|}|d urE|dk r!|t|7 }|dk s+|t|kr/td|d u r8|| }n
||| krBtd||= || q||fS )NFr   r   Invalid axis index in vmapzInconsistent axis sizes in vmap)r   rM   rN   r   rQ   )rD   shapes_outershapes_innerr   rY   shape_outershape_innerr   r   r   _to_shapes_inner  s    
r   c                 C   s~   g }t | |ddD ]3\}}t|}|d ur7|dk r!|t|d 7 }|dk s-|t|d kr1td||| || q	|S )NFr   r   r   r   )r   rM   rN   r   insertrQ   )rD   r   r   r   rY   r   r   r   r   r   _to_shapes_outer  s   r   c                    s   t  d fdd	}|S )Nr   c                    sz   t  ttjB r f t ttjB rft  ts$tdt  t ts2tdt  fdd}|S )Nz+Expected in_axes to be a tuple or int, got z,Expected out_axes to be a tuple or int, got c                     sP  t | t krtdt  dt |  dd | D }t|\}}dd |D }| }t|tjjjsPt|trEt	dd |D sPtdt
t| t||}t|tjr_|g}d	d |D }t|| |t d
krvnd t d
krnd d|  } t d
krt| ttjjj d dS t|  fddS )Nr   z$ arguments in vmapped function, got c                 S      g | ]}|j qS r   r   r"   tr   r   r   r     r   zRvmap.<locals>.vmap_with_shapes.<locals>.vmapped_op_with_shapes.<locals>.<listcomp>c                 S   s   g | ]
}t jjd |qS r>   r    r   r   r   r   r     r.   c                 s   s     | ]}t |tjjjV  qd S r>   )r   r   r   r	   r
   r   r   r   r   r&     s    zQvmap.<locals>.vmap_with_shapes.<locals>.vmapped_op_with_shapes.<locals>.<genexpr>zEExpected vmapped function to return a tensor or tuple of tensor, got c                 S   r   r   r   r   r   r   r   r     r   r   r   )in_axesout_axesr   c                    s   t  fddD S )Nc                 3   s"    | ]}t jjj |d V  qdS r   r    r   r*   r   r   r&     r'   zcvmap.<locals>.vmap_with_shapes.<locals>.vmapped_op_with_shapes.<locals>.<lambda>.<locals>.<genexpr>)r   r*   out_shapes_outerr*   r   r-     r   zPvmap.<locals>.vmap_with_shapes.<locals>.vmapped_op_with_shapes.<locals>.<lambda>)rN   r   r   r   r   r   r	   r
   r   allpytreemapr   Graphrw   r   r/   r   )r   in_shapes_outerin_shapes_innervmapped_axis_lenin_tracers_innerout_tracers_innergraphout_shapes_inner)r   r3   original_vmapr   r   r   vmapped_op_with_shapes  s.   4z>vmap.<locals>.vmap_with_shapes.<locals>.vmapped_op_with_shapes)r   r   r   r   r   r   r   )r3   r   r   r   r   )r   r3   r   r   vmap_with_shapes  s   

"zvmap.<locals>.vmap_with_shapes)r   r   r   )r   r   r   r   r   vmap  s   .r   c                   @   s   e Zd Zdd ZdS )atc                 C   s4   || _ || _t| d| _t| d| _t| d| _d S )Nsetaddsubtract)_x_indices_at_updaterr   r   r   )selfr   ro   r   r   r   __init__  s
   zat.__init__N)__name__
__module____qualname__r   r   r   r   r   r     s    r   c                    s   t   fdd}|S )Nc                    s<   t jjt jjjdj  | }t |jj}|S )Nr   )r   r   rt   getattrr   r   r/   r   )updatesr   r3   r   r   r   r4     s   (z_at_updater.<locals>.innerr   )r   r3   r4   r   r   r   r     s   r   rc   )rF   rG   F)rY   rZ   r   r>   )rD   )#einx._src.tracer_srcr   numpyr   	functoolsr   einx._src.util.functoolsr   einx._src.util.pytreeutilr   r   r6   r<   rE   rX   rb   rh   rl   rs   rx   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s8    
	


*


#

%
+3	