Ë
    ~\;j  ã                   ó2   — d Z ddlZddlmZ ddgZd	d„Zd„ Zy)
z1
Determines if a contraction can use BLAS or not
é    Né   )ÚhelpersÚcan_blasÚtensor_blasc                 óÂ  — t        | «      dk7  ry| \  }}t        ||z   «      D ]P  }|j                  |«      |j                  |«      }}|dkD  s|dkD  s||z   dkD  r y||z   dz
  t        ||v «      k(  sŒP y |�8|D ]3  }|d   |j	                  |«         |d   |j	                  |«         k7  sŒ3 y t        |«      dk(  ry| D �	cg c]  }	t        |	«      ‘Œ }
}	|
d   |z
  }|
d   |z
  }t        |«      }| d   | d   k(  ry|
d   |
d   k(  ry|| d |d| k(  ry	|d| || d k(  ry	|| d || d k(  ry	|d| |d| k(  ry	t        |«      dk(  st        |«      dk(  ry
yc c}	w )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
    é   Fr   Nr   zOUTER/EINSUMÚDOTz
DOT/EINSUMÚGEMMzGEMV/EINSUMÚTDOT)ÚlenÚsetÚcountÚintÚfind)ÚinputsÚresultÚidx_removedÚshapesÚ
input_leftÚinput_rightÚcÚnlÚnrÚxÚsetsÚ	keep_leftÚ
keep_rightÚrss                 úXG:\00. PROJECTS\API\Inventory\templateJSON\kerjaOCR\Lib\site-packages\opt_einsum/blas.pyr   r      sá  € ôV ˆ6ƒ{�aÒØà$Ñ€J�ä�˜kÑ)Ö*ˆà×!Ñ! !Ó$ k×&7Ñ&7¸Ó&:ˆBˆØ�ŠF˜˜Qš B¨¡G¨a¢KÙð
 �‰7�Q‰;œ#˜a 6˜kÓ*Ó*Ùð +ð ÐÛˆAØ�a‰y˜Ÿ™¨Ó+Ñ,°°q±	¸+×:JÑ:JÈ1Ó:MÑ0NÓNÙð ô ˆ;Ó˜1ÒØñ #Ó#™F�qŒC��F˜F€DÐ#Ø�Q‘˜+Ñ%€IØ�a‘˜;Ñ&€JÜ	ˆ[Ó	€Bð ˆa�y�F˜1‘IÒØð 
ˆa‰�D˜‘GÒ	Øð �2�#�$Ð˜; s¨Ð+Ò+Øð 
�C�Rˆ˜K¨¨¨Ð-Ò	-Øð 
�R�C�DÐ	˜[¨"¨¨Ð.Ò	.Øð 
�C�Rˆ˜K¨¨Ð,Ò	,Øô ˆi‹.˜AÒ
¤3 z£?°aÒ#7Øð ùòG $s   ÃEc                 ó  ‡— t        |«      }t        |«      |z
  }t        |«      |z
  }i Št        || j                  «      D ]
  \  }}	|	‰|<   Œ t        ||j                  «      D ]
  \  }}	|	‰|<   Œ t        |«      }
t	        j
                  |‰«      }t	        j
                  |‰«      }t	        j
                  |‰«      }||z   }|D ]  }	|j                  |	d«      }Œ ||k(  r4t        j                  | j                  «       |j                  «       «      }�n…||
 d |d|
 k(  r8t        j                  | j                  ||«      |j                  ||«      «      }�nA|d|
 ||
 d k(  rKt        j                  | j                  ||«      j                  |j                  ||«      j                  «      }nê||
 d ||
 d k(  rAt        j                  | j                  ||«      |j                  ||«      j                  «      }nœ|d|
 |d|
 k(  rAt        j                  | j                  ||«      j                  |j                  ||«      «      }nPd\  }}|D ],  }	||j                  |	«      fz  }||j                  |	«      fz  }Œ. t        j                  | |||f¬«      }t        ˆfd„|D «       «      }|j                  |k7  r+t        |«      dkD  r||_        nt        j                  |«      }||k7  rt        j                   |dz   |z   |«      }|S )a  
    Computes the dot product between two tensors, attempts to use np.dot and
    then tensordot if that fails.

    Parameters
    ----------
    view_left : array_like
        The left hand view
    input_left : str
        Indices of the left view
    view_right : array_like
        The right hand view
    input_right : str
        Indices of the right view
    index_result : str
        The resulting indices
    idx_removed : set
        Indices removed in the contraction

    Returns
    -------
    type : array
        The resulting BLAS operation.

    Notes
    -----
    Interior function for tensor BLAS.

    This function will attempt to use `np.dot` by the iterating through the
    four possible transpose cases. If this fails all inner and matrix-vector
    operations will be handed off to einsum while all matrix-matrix operations will
    first copy the data, perform the DGEMM, and then copy the data to the required
    order.

    Examples
    --------

    >>> a = np.random.rand(4, 4)
    >>> b = np.random.rand(4, 4)
    >>> tmp = tensor_blas(a, 'ij', b, 'jk', 'ik', set('j'))
    >>> np.allclose(tmp, np.dot(a, b))

    Ú N)© r"   )Úaxesc              3   ó(   •K  — | ]	  }‰|   –— Œ y ­w©Nr"   )Ú.0r   Údimension_dicts     €r   Ú	<genexpr>ztensor_blas.<locals>.<genexpr>é   s   øè ø€ ÐB±M¨q˜¨Õ*±Mùs   ƒr   z->)r   ÚzipÚshaper   r   Úcompute_size_by_dictÚreplaceÚnpÚdotÚravelÚreshapeÚTr   Ú	tensordotÚtupleÚsqueezeÚeinsum)Ú	view_leftr   Ú
view_rightr   Úindex_resultr   r   r   ÚiÚsr   Údim_leftÚ	dim_rightÚdim_removedÚtensor_resultÚnew_viewÚleft_posÚ	right_posÚtensor_shaper'   s                      @r   r   r   {   s   ø€ ôZ �kÓ"€KÜ�J“ +Ñ-€IÜ�[Ó! KÑ/€Jð €NÜ�J 	§¡Ö0‰ˆˆ1Øˆ�qÒð 1ä�K ×!1Ñ!1Ö2‰ˆˆ1Øˆ�qÒð 3ô" 
ˆ[Ó	€BÜ×+Ñ+¨I°~ÓF€HÜ×,Ñ,¨Z¸ÓH€IÜ×.Ñ.¨{¸NÓK€KØ Ñ,€MÛˆØ%×-Ñ-¨a°Ó4‰ð ð
 �[Ò Ü—6‘6˜)Ÿ/™/Ó+¨Z×-=Ñ-=Ó-?Ó@Šð 
�R�C�DÐ	˜[¨¨"Ð-Ò	-Ü—6‘6˜)×+Ñ+¨H°kÓBÀJ×DVÑDVÐWbÐdmÓDnÓoŠð 
�C�Rˆ˜K¨¨¨Ð-Ò	-Ü—6‘6˜)×+Ñ+¨K¸ÓB×DÑDÀj×FXÑFXÐYbÐdoÓFp×FrÑFrÓs‰ð 
�R�C�DÐ	˜[¨"¨¨Ð.Ò	.Ü—6‘6˜)×+Ñ+¨H°kÓBÀJ×DVÑDVÐW`ÐbmÓDn×DpÑDpÓq‰ð 
�C�Rˆ˜K¨¨Ð,Ò	,Ü—6‘6˜)×+Ñ+¨K¸ÓB×DÑDÀj×FXÑFXÐYdÐfoÓFpÓq‰ð
 %Ñˆ�)ÛˆAØ˜Ÿ™¨Ó+Ð.Ñ.ˆHØ˜+×*Ñ*¨1Ó-Ð0Ñ0‰Ið ô —<‘< 	¨:¸XÀyÐ<QÔRˆô ÓB±MÓBÓB€LØ‡~�~˜Ò%Üˆ}Ó Ò!Ø)ˆH�Nä—z‘z (Ó+ˆHà˜Ò$Ü—9‘9˜]¨TÑ1°LÑ@À(ÓKˆà€Oó    r%   )Ú__doc__Únumpyr-   r!   r   Ú__all__r   r   r"   rC   r   Ú<module>rG      s)   ðñó å à�}Ð
%€óló^xrC   