o
    Ei,                     @   s   d dl Z ddlmZ d dlZd dl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 jfddZee_dS )    N   )util)Unionc                    s   d fdd	S )Nc                    s    | fdd|D |S )Nc                       g | ]} |qS  r   .0xtr   H/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/einx/op/dot.py
<listcomp>
       .<lambda>.<locals>.<lambda>.<locals>.<listcomp>r   )exprs_in
tensors_inexpr_outbackendcr   r   r   <lambda>	   s    <lambda>.<locals>.<lambda>Nr   r   r   r   r   r   r   	   s    r   )tracec                    s@  t |g D ]}| D ]}t|tjjjrtdqq| D ]}t|tjjjr/tdq!dd | D }D ]5}| D ].}t|tjjj	ro|j
|v}	tjj|}
|	rc|
sctd| d|	so|
rotd| dqAq;d	d | D fd
d fddtt|D } |}tj| d\}t|gd }tdd D sJ tjj|sJ i fddfdddd D dfddD d fddtjj|D  } j|g|R  }tjjfddtjj|D }tj||| dd } ||j}||fS )NzConcatenation not allowedz-Brackets in the output expression not allowedc                 S   "   h | ]}t |tjjjr|jqS r   
isinstanceeinxexprstage3Axisnamer   ar   r   r   	<setcomp>      " zdot_stage3.<locals>.<setcomp>zReduced axis z must be markedzMarked axis z# cannot appear in output expressionc                 S   r   r   r   r#   r   r   r   r%   !   r&   c                    s    fddt D g }g }g }t   D ]7\}}tfdd| D }tfdd| D }|r?|s?|| q|rI|sI|| q|| qt|t|t|dS )Nc                    s<   h | ]\}}|  D ]}| kr
t|tjjjr
|jq
qS r   )allr   r   r   r    r!   r"   )r   iexpr_inr$   )idxr   r   r%   $   s    z/dot_stage3.<locals>.get_fans.<locals>.<setcomp>c                 3   *    | ]}t |tjjjo|j v V  qd S r   r   r#   )other_input_axis_namesr   r   	<genexpr>.   
    
z/dot_stage3.<locals>.get_fans.<locals>.<genexpr>c                 3   r+   r   r   r#   )output_axis_namesr   r   r-   2   r.   )in_axisout_axis
batch_axis)	enumerateanyr'   appendtuple)r*   r0   r1   r2   r(   childany_in_other_inputany_in_output)r   r/   )r*   r,   r   get_fans#   s,   
zdot_stage3.<locals>.get_fansc                    s<   g | ]\}\}}t jj||j fi |d ddqS )weightdot)r"   init)r   tracercall_factoryshape)r   r(   tensorr   )r   r:   r   r   r   B   s    
zdot_stage3.<locals>.<listcomp>r   r   c                 s   s    | ]
}t jj|V  qd S r   )r   r   r    is_flatr   r   r   r   r   r-   M   s    zdot_stage3.<locals>.<genexpr>c                    s`   |  v r |  S t tdt  }t|tdkr*tdtdtd d  d| | < |S )Nr$   zzOnly supports up to r   z unique input axes)chrordlen
ValueError)keyv)einsum_variablesr   r   get_einsum_variableS   s    z'dot_stage3.<locals>.get_einsum_variablec                    s   d  fdd| D S )N c                 3   s    | ]} |j V  qd S r   r"   r#   rM   r   r   r-   ^   s    z0dot_stage3.<locals>.to_einsum.<locals>.<genexpr>)join)axesrP   r   r   	to_einsum]   s   zdot_stage3.<locals>.to_einsumc                 S   s&   h | ]}t jj|D ]}|jqqS r   )r   r   r    get_axesr"   )r   r   r$   r   r   r   r%   `   s   & ,c                 3   s"    | ]} t jj|V  qd S r   )r   r   r    rT   rD   )rS   r   r   r-   c   s     z->c                    s   g | ]	}|j  v r|qS r   rO   r#   input_axis_namesr   r   r   e   s    c                    s   g | ]}|j  v r| qS r   )r"   __deepcopy__r#   rV   r   r   r   k   s
    
)listr'   r   r   r   r    ConcatenationrI   Markerr!   r"   	is_markedr3   zipall_to_tensorr   flattenrC   rQ   rT   einsumListtranspose_broadcastreshaper@   )r   r   r   r   rootr   out_axis_namesr)   axisis_reduced_axisr\   expr_out_flat
einsum_strrA   r   )r   rL   r   rM   r:   rW   r/   rS   r   
dot_stage3   sf   



rj   T)csec             	      s  t jj| |\} }t jj| }t|d dkrt|dkr|d d |d d fD ]$}| D ]}t	|t jjj
rN|jdkrNt jj|rNtd| q1q+t }g }|d d |d d fD ]M}| D ]F}t	|t jjjrt jj|r|j|vr||j | }	|}
|
jd urt	|
t jjjrt jjj|	|
jd}	|
j}
|
jd us||	 qgqat jj|}t jjt jjt jj|d d |gt jjt jj|d d gg}t|d t|krtdt|d  dt| t|d dkrtdt|d  t jjd	d
 t|d |D t j|d d g dd
 | D  |ddd t|d d  }|d d |d }}tdd |D sddd | D   fdd
|D }||fS )Nr   r      z0Cannot mark unnamed non-trivial axes, but found )ellipsis_idz	Expected z input tensor(s), got z&Expected 1 output expression, but got c                 S   s   g | ]\}}t j||qS r   )r   r   Equation)r   r)   tensor_shaper   r   r   r      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   rn   npasarraynewaxis)r   krK   r   r   r   r      s    "F)rk   
cse_concatc                 s   s,    | ]}|  D ]
}tjj|V  qqd S r   )r'   r   r   r    r\   )r   r)   r   r   r   r   r-      s   * zparse.<locals>.<genexpr>c                 S   r   r   r   )r   rf   r   r   r   r%      s
    zparse.<locals>.<setcomp>c                    s$   g | ]}t jj| fd dqS )c                    s   t | tjjjo| j vS r   r   )r   axes_names_outr   r   r      s    
z"parse.<locals>.<listcomp>.<lambda>)r   r   r    mark)r   r)   rx   r   r   r      s    
) r   opr   !_clean_description_and_parametersr   stage1parse_oprH   r'   r   UnnamedAxisvaluer\   rI   set	NamedAxisr"   addrX   parentEllipsisrm   r5   ra   OpArgsdemarksolver]   rn   itemsr4   )descriptionrk   tensor_shapes
parametersr{   rd   r   namesexpr_in2expr2r   exprsr   r   r   rx   r   parsez   s   
	




 	
	r   c                    s   d d fdd
S )NrB   c                   s$    | gfdd|D R i |S )Nc                    r   r   r   r   r
   r   r   r      r   r   r   )r   r   tensorskwargsr   r   r   r      s    r   r   r   r   r   r   r      r   )r   rk   r   r   r   rk   r   returnc          	      O   s@   t | gdd |D R d|i|\}}t||||d\}}|S )a  Computes a general dot-product of the input tensors.

    The following shorthand notation is supported:

    * When no brackets are found, brackets are placed implicitly around all axes that do not
      appear in the output.

      Example: ``a b, b c -> a c`` expands to ``a [b], [b] c -> a c``

    * When given two input tensors, the expression of the second input is determined implicitly
      from the marked axes in the input and output expression.

      Example: ``a [b] -> a [c]`` expands to ``a b, b c -> a c``

      Axes marked multiple times appear only once in the implicit second input expression.

      Example: ``[a b] -> [a c]`` expands to ``a b, a b c -> a c``

    The function additionally passes the ``in_axes``, ``out_axes`` and ``batch_axes`` arguments
    to tensor factories that can be used to determine the fan-in and fan-out of a neural network
    layer and initialize weights accordingly (see e.g. `jax.nn.initializers.lecun_normal
    <https://jax.readthedocs.io/en/latest/_autosummary/jax.nn.initializers.lecun_normal.html#jax.nn.initializers.lecun_normal>`_)

    Args:
        description: Description string for the operation in einx notation.
        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 dot-product operation if ``graph=False``, otherwise the graph
        representation of the operation.

    Examples:
        Compute an inner product between two vectors:

        >>> a, b = np.random.uniform(size=(10,)), np.random.uniform(size=(10,))
        >>> einx.dot("a, a ->", a, b).shape
        ()

        Compute a matrix-vector product:

        >>> a, b = np.random.uniform(size=(10, 10)), np.random.uniform(size=(10,))
        >>> einx.dot("a b, b -> a", a, b).shape
        (10,)
        >>> einx.dot("a [b] -> a", a, b).shape
        (10,)
        >>> einx.dot("a [b->]", a, b).shape
        (10,)

        Compute a vector-matrix product:

        >>> a, b = np.random.uniform(size=(10,)), np.random.uniform(size=(10, 10))
        >>> einx.dot("a, a b -> b", a, b).shape
        (10,)
        >>> einx.dot("[a] -> [b]", a, b).shape
        (10,)
        >>> einx.dot("[a->b]", a, b).shape
        (10,)

        Multiply a tensor with a weight matrix:

        >>> x, w = (
        ...     np.random.uniform(size=(4, 16, 16, 64)),
        ...     np.random.uniform(
        ...         size=(
        ...             64,
        ...             32,
        ...         )
        ...     ),
        ... )
        >>> einx.dot("b... [c1->c2]", x, w).shape
        (4, 16, 16, 32)
    c                 S   s   g | ]}t j|qS r   )r   r>   	get_shape)r   rA   r   r   r   r   3  s    zdot.<locals>.<listcomp>rk   rB   )r   rj   )	r   r   rk   r   r   r   r   rA   _exprr   r   r   r<      s   \
r<   r   )r   rN   r   numpyrr   typingr   numpy.typingnptjitrj   	lru_cacher   traceback_utilfilterstrTensorBackendbool	ArrayLiker<   r   r   r   r   <module>   s>    m[
]