
    Sh                         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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                    t          |           dk    rdS | \  }}t          ||z             D ]b}|                    |          |                    |          }}|dk    s|dk    s	||z   dk    r dS ||z   dz
  t          ||v           k    r dS c|L|D ]I}|d         |                    |                   |d         |                    |                   k    r dS Jt          |          dk    rdS d | D             }	|	d         |z
  }
|	d         |z
  }t          |          }| d         | d         k    rdS |	d         |	d         k    rd	S || d         |d|         k    rd
S |d|         || d         k    rd
S || d         || d         k    rd
S |d|         |d|         k    rd
S t          |
          dk    st          |          dk    rd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                 ,    g | ]}t          |          S  )set).0xs     U/var/www/html/movieo_spanner_bot/venv/lib/python3.11/site-packages/opt_einsum/blas.py
<listcomp>zcan_blas.<locals>.<listcomp>W   s    ###qCFF###    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rss                r   r   r   
   sc   ^ 6{{au$Jk)** 
 
!!!$$k&7&7&:&:BFFQBGaKK55
 7Q;#a6k****55 +
  	 	Aay++,q	+:J:J1:M:M0NNNuu O
 ;1~ $#F###DQ+%Ia;&J	[		B ayF1Iu 
aDG		| 2#$$;ss+++v 
CRCK-	-	-v 
RCDD	[".	.	.v 
CRCK,	,	,v i..A

3z??a#7#7} vr   )N)__doc__typingr   r   r   r   opt_einsum.typingr   __all__strr   boolr   r   r   r   <module>r/      s    6 6 / / / / / / / / / / / / , , , , , ,, 15	p pIpp  p (5:&,-	p
 39p p p p p pr   