o
    i                     @   sp   d Z ddlmZmZmZmZ ddlmZ dgZ	ddee	 de	ded	eeee
  df d
ee	ef f
ddZdS )z0Determines if a contraction can use BLAS or not.    )ListSequenceTupleUnion)ArrayIndexTypecan_blasNinputsresultidx_removedshapesreturnc                 C   s  t | dkrdS | \}}t|| D ]-}||||}}|dks-|dks-|| dkr0 dS || d t||v kr? dS q|dur^|D ]}|d || |d || kr] dS qFt |dkrfdS dd | D }	|	d | }
|	d | }t |}| d | d krd	S |	d |	d krd
S || d |d| krdS |d| || d krdS || d || d krdS |d| |d| krdS t |
dkst |dkrdS dS )a  Checks if we can use a BLAS call.

    Parameters
    ----------
    inputs : list of str
        Specifies the subscripts for summation.
    result : str
        Resulting summation.
    idx_removed : set
        Indices that are removed in the summation
    shapes : sequence of tuple[int], optional
        If given, check also that none of the indices are broadcast dimensions.

    Returns:
    -------
    type : str or bool
        The type of BLAS call to be used or False if none.

    Notes:
    -----
    We assume several operations are not efficient such as a transposed
    DDOT, therefore 'ijk,jki->' should prefer einsum. These return the blas
    type appended with "/EINSUM" to differentiate when they can still be done
    with tensordot if required, e.g. when a backend has no einsum.

    Examples:
    --------
    >>> can_blas(['ij', 'jk'], 'ik', set('j'))
    'GEMM'

    >>> can_blas(['ijj', 'jk'], 'ik', set('j'))
    False

    >>> can_blas(['ab', 'cd'], 'abcd', set())
    'OUTER/EINSUM'

    >>> # looks like GEMM but actually 'j' is broadcast:
    >>> can_blas(['ij', 'jk'], 'ik', set('j'), shapes=[(4, 1), (5, 6)])
    False
       F   Nr   zOUTER/EINSUMc                 S   s   g | ]}t |qS  )set).0xr   r   E/mnt/sdb/aimis/docanh/lib/python3.10/site-packages/opt_einsum/blas.py
<listcomp>W   s    zcan_blas.<locals>.<listcomp>DOTz
DOT/EINSUMGEMMzGEMV/EINSUMTDOT)lenr   countintfind)r   r	   r
   r   
input_leftinput_rightcnlnrsets	keep_left
keep_rightrsr   r   r   r   
   sH   /$)N)__doc__typingr   r   r   r   opt_einsum.typingr   __all__strr   boolr   r   r   r   r   <module>   s     
