o
    EiS                     @   s   d dl Z ddlmZ d dlZd dlmZmZ d dlmZ	 e j
dd dddd	Ze jd
dddZe jje j
dd ddd
ddede jdee jedf dede	jdee jee jdf f fddZee_dS )    N   )util)UnionTuplec                    s   d fdd	S )Nc                    s    | fdd|D |S )Nc                       g | ]} |qS  r   .0xtr   N/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/einx/op/rearrange.py
<listcomp>
       .<lambda>.<locals>.<lambda>.<locals>.<listcomp>r   )exprs_in
tensors_in	exprs_outbackendcr   r   r   <lambda>	   s    <lambda>.<locals>.<lambda>Nr   r   r   r   r   r   r   	   s    r   )tracec                    s\  t t krtdt  dt  tdd tt| D r-tdt d fddtD  jd	d
tj d\t|}t	dd D sZJ t	dd |D seJ t t |kr|tdt  dt | dt
|}fdd|D fdd|D  fddt|D }tj||| d}||fS )N	Expected z input tensor(s), got c                 s   s.    | ]}|  D ]}t|tjjjV  qqd S r   )all
isinstanceeinxexprstage3Marker)r	   rootr    r   r   r   	<genexpr>   s    z#rearrange_stage3.<locals>.<genexpr>zMarker 'z' is not allowedc              	      s(   g | ]\}}t jj||j d ddqS )	embedding	rearrange)nameinit)r   tracercall_factoryshape)r	   tensorr    r   r   r   r      s    z$rearrange_stage3.<locals>.<listcomp>T)convert_scalarsr-   c                 s       | ]
}t jj|V  qd S r   r   r    r!   is_flatr	   r    r   r   r   r$   !       c                 s   r/   r   r0   r2   r   r   r   r$   "   r3   zGot different number of input (z) and output expressions (z) (after flattening)c                       g | ]} | qS r   r   r	   i)r   r   r   r   +   r   c                    r4   r   r   r5   )r   r   r   r   ,   r   c                    s(   g | ]\}}}t j||| d d qS )r-   r   )r   transpose_broadcast)r	   expr_inr,   expr_outr-   r   r   r   /   s    )len
ValueErroranylistr    zipall_to_tensorr   flattenr   
assignment	unflatten)r   r   r   r   exprs_out_flatindicestensorsr   )r   r   r   r   rearrange_stage3   s8   



rF   Tcsec                O   s   t jj| |\} }t jj| }t|d t|kr+tdt|d  dt| t jj	dd t
|d |D dd |d D  dd | D  |d	d t|d t|d   }|d t|d  |t|d d  }}||fS )
Nr   r   z input tensors, but got c                 S   s   g | ]\}}t j||qS r   r   r    Equation)r	   r8   tensor_shaper   r   r   r   F   s    zparse.<locals>.<listcomp>c                 S      g | ]}t j|qS r   rI   )r	   r9   r   r   r   r   J       r   c                 S   s4   g | ]\}}t jj|t|d tjf dddqS ).N)depth1depth2)r   r    rJ   npasarraynewaxis)r	   kvr   r   r   r   K   s    "rG   )r   opr   !_clean_description_and_parametersr    stage1parse_opr:   r;   solver>   items)descriptionrH   tensor_shapes
parametersrU   exprsr   r   r   r   r   parse:   s,    	*r_   c                    s   d d fdd
S )Nr-   c                   s$    | gfdd|D R i |S )Nc                    r   r   r   r   r   r   r   r   Y   r   r   r   )r[   r   rE   kwargsr   r   r   r   X   s    r   r   r   r   r   r   r   X   r   )r   rH   r[   rE   r   rH   r]   return.c                O   sT   t | gdd |D R d|i|\}}t||||d\}}t|dkr(|d S |S )a  Rearranges the input tensors to match the output expressions.

    Args:
        description: Description string for the operation in einx notation. Must not contain
            brackets.
        tensors: Input tensors or tensor factories matching the description string.
        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 rearrange operation if ``graph=False``, otherwise the graph
        representation of the operation.

    Examples:
        Transpose the row and column axes of a batch of images:

        >>> x = np.random.uniform(size=(4, 64, 48, 3))
        >>> einx.rearrange("b h w c -> b w h c", x).shape
        (4, 48, 64, 3,)

        Insert new axis (repeats elements along the new axis):

        >>> x = np.random.uniform(size=(10, 10))
        >>> einx.rearrange("a b -> a c b", x, c=100).shape
        (10, 100, 10,)

        Concatenate two tensors along the first axis:

        >>> a, b = (
        ...     np.random.uniform(size=(10, 10)),
        ...     np.random.uniform(size=(20, 10)),
        ... )
        >>> einx.rearrange("a b, c b -> (a + c) b", a, b).shape
        (30, 10,)

        Split a tensor:

        >>> x = np.random.uniform(size=(10, 2))
        >>> a, b = einx.rearrange("a (1 + 1) -> a, a", x)
        >>> a.shape, b.shape
        ((10,), (10,))

        Swap the first and last third of a tensor along a given axis:

        >>> x = np.arange(6)
        >>> einx.rearrange("(b + c + d) -> (d + c + b)", x, b=2, c=2)
        array([4, 5, 2, 3, 0, 1])
    c                 S   rL   r   )r   r)   	get_shape)r	   r,   r   r   r   r      rM   zrearrange.<locals>.<listcomp>rH   r-   r   r   )r_   rF   r:   )r[   r   rH   rE   r]   r   r   r   r   r   r&   V   s   B
r&   r   )r    r   numpyrP   typingr   r   numpy.typingnptjitrF   	lru_cacher_   traceback_utilfilterstrTensorBackendbool	ArrayLiker&   r   r   r   r   <module>   s>    -
C