o
    Nrf#                     @  sn   d dl mZ d dlZd dlmZmZmZ d dlm	Z	 dZ
ee
Zdd Zdd	 Ze	edd
ddddZdS )    )annotationsN)asarray	blockwiseeinsum_lookup)derived_from4abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZc                  O  s^   | d}| d}| d}tt| d }||g| R d|i|}||jd|  S )N
subscriptsncontract_indskernel_dtyper   dtype   )popr   dispatchtypeZreshapeshape)operandskwargsr   r	   r   einsumchunk r   _/var/www/html/software/conda/envs/catlas/lib/python3.10/site-packages/dask/array/einsumfuncs.pychunk_einsum   s   


r   c                 C  s  t | dkr
tdt| d tr9| d dd}dd | dd D } |D ]}|d	v r-q&|tvr7td
| q&nt| }g }g }tt | d D ]}||	d ||	d qIt |rd|d nd}dd |D } d}t |d }t
|D ])\}	}
|
D ]}|tu r|d7 }qt|tr|t| 7 }qtd|	|kr|d7 }qy|dur|d7 }|D ]}|tu r|d7 }qt|tr|t| 7 }qtdd|v sd|v r|ddkp|ddk}|s|ddkrtdd|v r|dddddd}ttt| }d|}d}d|v r!|d\}}|d}d}n|d}d}t
|D ]g\}	}
d|
v r|
ddksE|
ddkrItd| |	 jdkrTd}nt| |	 jd}|t |
d 8 }||krk|}|dk rttd|dkr|
dd||	< q,|| d }|
d|||	< q,d|}|dkrd}n|| d }|r|d|d| 7 }n>d}|dd}tt|D ]}|tvrtd
| ||dkr||7 }qdtt|t| }|d| | 7 }d|v r|d\}}n+|}|dd}d}tt|D ]}|tvrtd
| ||dkr*||7 }q|D ]}||vr;td| q.t |dt | krMtd||| fS )a  
    A reproduction of numpy's _parse_einsum_input()
    which in itself is a reproduction of
    c side einsum parsing in python.

    Returns
    -------
    input_strings : str
        Parsed input strings
    output_string : str
        Parsed output string
    operands : list of array_like
        The operands to use in the numpy contraction
    Examples
    --------
    The operand list is simplified to reduce printing:
    >> a = np.random.rand(4, 4)
    >> b = np.random.rand(4, 4, 4)
    >> __parse_einsum_input(('...a,...a->...', a, b))
    ('za,xza', 'xz', [a, b])
    >> __parse_einsum_input((a, [Ellipsis, 0], b, [Ellipsis, 0]))
    ('za,xza', 'xz', [a, b])
    r   zNo input operands  c                 S     g | ]}t |qS r   r   .0or   r   r   
<listcomp>9       z&parse_einsum_input.<locals>.<listcomp>r   Nz.,->z#Character %s is not a valid symbol.   c                 S  r   r   r   )r   vr   r   r   r    K   r!   z...z=For this input type lists must contain either int or Ellipsis,->->z%Subscripts can only contain one '->'..TF   zInvalid Ellipses.r   zEllipses lengths do not match.z/Output character %s did not appear in the inputzDNumber of einsum subscripts must be equal to the number of operands.)len
ValueError
isinstancestrreplaceeinsum_symbols_setlistrangeappendr   	enumerateEllipsisinteinsum_symbols	TypeErrorcountsetjoinsplitr   maxndimsorted)r   r   sZtmp_operandsZoperand_listZsubscript_list_Zoutput_listlastnumsubinvalidusedZunusedZellipse_indslongestZ	input_tmpZ
output_subZsplit_subscriptsZout_subZellipse_countZrep_indsZout_ellipseZoutput_subscriptZtmp_subscriptsZnormal_indsZinput_subscriptscharr   r   r   parse_einsum_input   s   









 









rI   F)r   optimizesplit_everyc              	   O  s   | }t |\}}}d||f}	| du rtjdd |D  } |dur7dd |D }
tj|	g|
R d|i\}}dd |d	D }d
d |D }|t| }t|}tt	t
|t
| gdd t||D R dd |D | |	|||d|}|dkrt|}|jtt||| |dS |S )a  Dask added an additional keyword-only argument ``split_every``.

    split_every: int >= 2 or dict(axis: int), optional
        Determines the depth of the recursive aggregation.
        Defaults to ``None`` which would let dask heuristically
        decide a good default.
    r&   Nc                 S  s   g | ]}|j qS r   )r   r   r   r   r   r           zeinsum.<locals>.<listcomp>Fc                 S  s$   g | ]}t j|jd |jdqS )r   )r   )npZbroadcast_tor   r   r   r   r   r   r   r       s   $ rJ   c                 S  r   r   )tuple)r   ir   r   r   r       r!   r%   c                 S  s   h | ]	}|D ]}|qqS r   r   )r   rO   ar   r   r   	<setcomp>   s    zeinsum.<locals>.<setcomp>c                 s  s    | ]
}|D ]}|V  qqd S )Nr   )r   ZaprP   r   r   r   	<genexpr>   s    zeinsum.<locals>.<genexpr>c                 S  s   i | ]}|d qS r   r   )r   indr   r   r   
<dictcomp>   rL   zeinsum.<locals>.<dictcomp>)Zadjust_chunksr   r   r
   r	   rJ   r   )ZaxisrK   )rI   r;   rM   Zresult_typeZeinsum_pathr<   r:   r+   r   r   rN   zipsumr1   r2   )r   rJ   rK   r   r   Zeinsum_dtypeZinputsZoutputsopsr   Zfake_opsrA   Zall_indsZcontract_indsr	   resultsizer   r   r   r      sB   
r   )
__future__r   numpyrM   Zdask.array.corer   r   r   Z
dask.utilsr   r7   r:   r0   r   rI   r   r   r   r   r   <module>   s     +