o
    EiL                     @   s  d dl Z d dlmZ ddlmZ d dlZd dlmZm	Z	 d dl
mZ dddddZe jd	d
 ddddddZe jddddZdd Ze jje jdd
 dddddede jdedede	e jedf dedejde jfddZee_e jjddddede jde	e jedf dedejde jfd d!Ze jjddddede jde	e jedf dedejde jfd"d#Ze jjddddede jde	e jedf dedejde jfd$d%Ze jjddddede jde	e jedf dedejde jfd&d'ZdS )(    N)partial   )util)CallableUnion)opbackendc                    sv   d usJ | r|d }|dd }|d }	n
|d }|dd  }dd t ||D }g }
|D ]Z\}}}}dd | D }||v rG||nd }|d u r\|dksSJ |
|||f q/dd | D }||= tjjj|}t	|D ]}|
|t
d f| |f  ||f qtq/t|
|jksJ |
} fdd	tfd
d|D }| r|	|}	| s|||S ||||	S )Nr   r   c                 S   s"   g | ]\}\}}}||||fqS  r
   ).0tensorcoordinate_axis_name
expr_coordndimr
   r
   J/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/einx/op/index.py
<listcomp>   s    
z_index.<locals>.<listcomp>c                 S   s"   g | ]}t |tjjjr|jqS r
   
isinstanceeinxexprstage3Axisnamer   axisr
   r
   r   r      
    c                 S   s    g | ]}t |tjjjr|qS r
   )r   r   r   r   r   r   r
   r
   r   r   $   s     c                    s   t j|| d dd S )NF)	broadcastr   r   )r   transpose_broadcast)r   r   )r   expr_commonr
   r   	transpose1   s
   
z_index.<locals>.transposec                 3   s     | ]\}}} ||V  qd S Nr
   )r   r   r   r   )r   r
   r   	<genexpr>6   s    
z_index.<locals>.<genexpr>)zipallindexappendr   r   r   Listmayberangeslicelenr   tuple)updatelayoutexpr_update_innerr   r   r   tensors	tensor_intensor_coordinatestensor_updatelayout2tensor_coordr   r   r   
axis_namesr   axesir
   )r   r   r   r   _index	   sV   



r8   c                    s    fddS )Nc                    s"    | fdd|D |fi |S )Nc                       g | ]} |qS r
   r
   r   xtr
   r   r   E       .<lambda>.<locals>.<lambda>.<locals>.<listcomp>r
   )exprs_in
tensors_inexpr_outkwargscr=   r
   r   <lambda>D   s
    <lambda>.<locals>.<lambda>r
   r=   rE   r
   rD   r   rF   D       rF   )tracec             	      s  t | t |krtdt |  dt | | d D ]}t|tjjjr0|jr0|jdkr0tdqt	| |g D ]}|
 D ]}t|tjjjrLtdq>q8|sb|
 D ]}tjj|ratdqT|rdd	 | d d
 D }| d
 
 D ]}	t|	tjjjr|	j|vrtd|	j qudd  fddt|| D } |}| d }
|r| dd
 n| dd  }|r| d
 }g }d}|D ]R}dd |
 D }t |dkrtdt | d| dt |dkr|d jnd}t |dkr|d jr|d jdkr|d jnd }|||f ||7 }qdd	 |

 D t |kr1td| dt  |rHdd	 |
 D }t |dkrHtddd	 |

 D t fddfdd|D }|rotjj|nd }fddtjj|}|rtjj|}|rfddtjj|}dd fd d|D }|r|nd }d!d t||D }|r|d |d fg }t|d"d# d$d
 fd%dd 
 D }d&d	 |D }|D ].\}}}|
 D ]#}	t|	tjjjr|	j|kr|	j|vr||	j ||	 qqtjjj|}ntjjt|gd }ttr6t tt|||| d't|
g| |rP|gng  } tj| ||gd( d)\}}t |dkrot |dksqJ |d |d fS )*N	Expected z input tensors, got r   r   9First expression cannot contain unnamed axes with value 1zConcatenation not allowedz1Brackets in the output expression are not allowedc                 S   s0   h | ]}|  D ]}t|tjjjr|jqqS r
   )r#   r   r   r   r   r   r   )r   rootr   r
   r
   r   	<setcomp>X   s    zindex_stage3.<locals>.<setcomp>r	   z\Update expression cannot contain axes that are not in the coordinate or tensor expressions: c                 S   s   | dkrdS | S )Nget_at	embeddingr
   )sr
   r
   r   get_namef   s   zindex_stage3.<locals>.get_namec              
      s8   g | ]\}}t jj||j ttd qS ))r   init)r   tracercall_factoryshaper   
_op_to_str)r   r   r   )r   rR   r   r
   r   r   l   s    z index_stage3.<locals>.<listcomp>c                 S   s.   g | ]}t |tjjjrtjj|r|qS r
   )r   r   r   r   r   	is_markedr   r   r
   r
   r   r      s    zCExpected at most one coordinate axis in coordinate expression, got z in ''c                 S   0   h | ]}t |tjjjrtjj|r|jqS r
   r   r   r   r   r   rX   r   rY   r
   r
   r   rN          z marked axes in tensor, got c                 S   r[   r
   r\   rY   r
   r
   r   rN      r]   z,Update expression cannot contain marked axesc                 S   "   h | ]}t |tjjjr|jqS r
   r   rY   r
   r
   r   rN      r   c                    sR   t | tjjjr#| jvr%tjj| s' | j tjj| 	 S d S d S d S r    )
r   r   r   r   r   r   rX   addMarker__deepcopy__r   )new_marked_axis_namestensor_axis_namesr
   r   replace   s   
zindex_stage3.<locals>.replacec                    s   g | ]
}t jj| qS r
   )r   r   r   re   rY   )re   r
   r   r      s    c                    F   t | tjjjr| j v rtjj| s!tjj|  S d S d S d S r    	r   r   r   r   r   r   rX   r`   ra   rb   )rc   r
   r   re         
c                    rf   r    rg   rb   )marked_tensor_axis_namesr
   r   re      rh   c                 S   s   t jj| } t| gd S )Nr   )r   r   r   
get_markedr   flattenrb   r
   r
   r   to_inner   s   zindex_stage3.<locals>.to_innerc                    r9   r
   r
   rY   )rl   r
   r   r      r>   c                 S   s   g | ]\}\}}|||fqS r
   r
   )r   r   r   r   r
   r
   r   r      s    
c                 S   s   t | d jS )Nr   )r*   rV   )r;   r
   r
   r   rF      rI   zindex_stage3.<locals>.<lambda>)keyc                    s.   g | ]}t |tjjjr|j d  ks|qS )r   r   r   )longestr
   r   r      s    c                 S   s   h | ]}|j qS r
   )r   r   r
   r
   r   rN      s    )r   r,   r-   r   r.   r   T)r   flatr   ) r*   
ValueErrorr   r   r   r   r   
is_unnamedvaluelistr#   ConcatenationrX   r   r"   all_to_tensorr%   setre   sortedr_   r&   r'   rj   r   rk   strgetattrr   r8   rJ   vmap_stage3)r@   rA   rB   r,   r   r   r   rM   r5   r   expr_tensorexprs_coordinatesexpr_updater-   
total_ndimr   marked_coordinate_axesr   r   marked_update_axis_namesexprs_coordinates_innerr.   r3   all_axes
axes_names_r   tensors_out	exprs_outr
   )	r   rR   rn   ri   rc   r   re   rd   rl   r   index_stage3C   s   




	




	
 r   T)csec                   s  t jj| |\} }t jj| }t|dkr3r/t jj|d t jj	|d d gg}nt
dt|d t krMt
dt|d  dt  t|d dkr`t
dt|d   fdd}t jjd	d
 t|d  D t j|d d g dd
 | D  ||dd t|d d  }|d t|d  |t|d  }}	rdd |d  D }
dd |	 D }|
|st
d|
|  ||	fS )Nr   r   z2Operation string must contain an output expressionrK   z input tensors, but got z&Expected 1 output expression, but got c                    sR  | d   D ]}t|tjjjr |jdkr tjj|r tdqdd | d   D }t	|}g }| dt	  }rB|d d }|D ]R}dd | d   D }t	|dkr`tdt	| t	|dkrt|d tjjj
r~|tjj
|d j qD|tjj|d j qD|tjjd qDtjtjjj|t|ggS )	Nr   r   rL   c                 S   8   g | ]}t |tjjjtjjjfrtjj|r|qS r
   r   r   r   stage2	NamedAxisUnnamedAxisrX   rY   r
   r
   r   r   +      z/parse.<locals>.after_stage2.<locals>.<listcomp>r	   c                 S   r   r
   r   rY   r
   r
   r   r   9  r   z<Expected at most one marked axis per coordinate tensor, got )r#   r   r   r   r   r   rr   rX   rp   r*   r   r%   stage1r   Equationrt   r'   npasarray)exprs1exprs2r   tensor_marked_axesr   concat_thiscoord_exprsr   tensor_shapesr,   r
   r   after_stage2#  sJ   


zparse.<locals>.after_stage2c                 S   s   g | ]\}}t j||qS r
   )r   r   r   )r   expr_intensor_shaper
   r
   r   r   U  s    zparse.<locals>.<listcomp>c                 S   s4   g | ]\}}t jj|t|d tjf dddqS ).N)depth1depth2)r   r   r   r   r   newaxis)r   kvr
   r
   r   r   Z  s    ")r   r   c                 S   r^   r
   r   r   r
   r
   r   rN   e  r   zparse.<locals>.<setcomp>c                 S   r^   r
   r   r   r
   r
   r   rN   h  s   " zIOutput expression does not contain all axes from first input expression: )r   r   r   !_clean_description_and_parametersr   r   parse_opr*   OpArgsrp   solver"   r   itemsr#   issubset)descriptionr,   r   r   
parametersr   r   exprsr@   rB   axes_inaxes_outr
   r   r   parse  sX    1	&

r   c                 C   s&   t j| }|d uotdd |D S )Nc                 s   s    | ]}|d kV  qdS )r   Nr
   )r   rQ   r
   r
   r   r!   t      z"_has_zero_shape.<locals>.<genexpr>)r   rT   	get_shapeany)r   rV   r
   r
   r   _has_zero_shaper  s   r   c                    s   d d fdd
S )N)r   c                   s$    | gfdd|D R i |S )Nc                    r9   r
   r
   r:   r<   r
   r   r   z  r>   r?   r
   )r   r   r/   rC   rD   r
   r   rF   y  s    rG   r
   rH   r
   rD   r   rF   y  r>   )r   r   r   r/   r   r,   r   r   r   returnc          
      O   sl   |rt dd |dd D r|d S t| gdd |D R ||d|\}}t||||||d	\}	}|	S )
a>  Updates and/ or returns values from a tensor at the given coordinates.

    * If ``update`` is True: The first tensor receives updates, the last tensor contains the
      updates, and all other tensors represent the coordinates. If the output expression is
      not given, it is assumed to be equal to the first input expression.

    * If ``update`` is False, values are retrieved from the first tensor and the remaining tensors
      contain the coordinates.

    Using multiple coordinate expressions will yield the same output as concatenating
    the coordinate expressions along the coordinate axis first.

    Args:
        description: Description string for the operation in einx notation.
        *tensors: Tensors that the operation will be applied to.
        op: The update/gather function. If ``op`` is a string, retrieves the attribute of
            ``backend`` with the same name.
        update: Whether to update the tensor or return values from the tensor.
        backend: Backend to use for all operations. If None, determines the backend from the
            input tensors. Defaults to None.
        cse: Whether to apply common subexpression elimination to the expressions. Defaults
            to True.
        graph: Whether to return the graph representation of the operation instead of computing
            the result. Defaults to False.
        **parameters: Additional parameters that specify values for single axes, e.g. ``a=4``.

    Returns:
        The result of the update/ gather operation if ``graph=False``, otherwise the graph
        representation of the operation.

    Examples:
        Get values from a batch of images (different indices per image):

        >>> tensor = np.random.uniform(size=(4, 128, 128, 3))
        >>> coordinates = np.ones((4, 100, 2))
        >>> einx.get_at("b [h w] c, b p [2] -> b p c", tensor, coordinates).shape
        (4, 100, 3)

        >>> tensor = np.random.uniform(size=(4, 128, 128, 3))
        >>> coordinates_x = np.ones((4, 100), "int32")
        >>> coordinates_y = np.ones((4, 100), "int32")
        >>> einx.get_at(
        ...     "b [h w] c, b p, b p -> b p c",
        ...     tensor,
        ...     coordinates_x,
        ...     coordinates_y,
        ... ).shape
        (4, 100, 3)

        Set values in a batch of images (same indices per image):

        >>> tensor = np.random.uniform(size=(4, 128, 128, 3))
        >>> coordinates = np.ones((100, 2), "int32")
        >>> updates = np.random.uniform(size=(100, 3))
        >>> einx.set_at(
        ...     "b [h w] c, p [2], p c -> b [h w] c", tensor, coordinates, updates
        ... ).shape
        (4, 128, 128, 3)

        >>> tensor = np.random.uniform(size=(4, 128, 128, 3))
        >>> coordinates_x = np.ones((100,), "int32")
        >>> coordinates_y = np.ones((100,), "int32")
        >>> updates = np.random.uniform(size=(100, 3))
        >>> einx.set_at(
        ...     "b [h w] c, p, p, p c -> b [h w] c",
        ...     tensor,
        ...     coordinates_x,
        ...     coordinates_y,
        ...     updates,
        ... ).shape
        (4, 128, 128, 3)
    c                 s   s    | ]}t |V  qd S r    )r   r   r   r
   r
   r   r!     r   zindex.<locals>.<genexpr>r   Nr   c                 S   s   g | ]}t j|qS r
   )r   rT   r   r   r
   r
   r   r     s    zindex.<locals>.<listcomp>)r,   r   )r   r,   r   )r   r   r   )
r   r   r,   r   r   r/   r   r@   rB   r   r
   r
   r   r$   w  s    W

r$   c                O       t | g|R dd||d|S )zNSpecialization of :func:`einx.index` with ``op="get_at"`` and ``update=False``rO   Fr   r,   r   r   r$   r   r   r   r/   r   r
   r
   r   rO        	rO   c                O   r   )zMSpecialization of :func:`einx.index` with ``op="set_at"`` and ``update=True``set_atTr   r   r   r
   r
   r   r     r   r   c                O   r   )zMSpecialization of :func:`einx.index` with ``op="add_at"`` and ``update=True``add_atTr   r   r   r
   r
   r   r     r   r   c                O   r   )zRSpecialization of :func:`einx.index` with ``op="subtract_at"`` and ``update=True``subtract_atTr   r   r   r
   r
   r   r     r   r   )r   	functoolsr    r   numpyr   typingr   r   numpy.typingnptr8   jitr   	lru_cacher   r   traceback_utilfilterrx   TensorboolBackend	ArrayLiker$   rO   r   r   r   r
   r
   r
   r   <module>   s    : Ee
a