o
    i                  	   @   s  U d Z ddlZddlmZmZmZ ddlmZ ddlm	Z
 ddlmZ ddlmZ ddlmZ dd	lmZ g d
ZddddddddZd/dedededefddZdejiZeeeef ef ed< zddlZejed< ejed< ejed< ejed< ejed< W n	 ey   Y nw d0dedededefd d!Zi Z eee!f ed"< dede!fd#d$Z"i Z#eee!f ed%< dede!fd&d'Z$ej%ej%ej%ej%e
j%d(Z&ej'ej'ej'ej'e
j'd(Z(d)d* Z%d+d, Z'dede!fd-d.Z)dS )1zHandles dispatching array operations to the correct backend library, as well
as converting arrays to backend formats and then potentially storing them as
constants.
    N)AnyDictTuple)cupy)jax)object_arrays)
tensorflow)theano)torch)get_func
has_einsumhas_tensordotbuild_expressionevaluate_constantshas_backendz
dask.arrayztheano.tensorzopt_einsum.backends.torchz	jax.numpyzautograd.numpyzmars.tensor)daskr	   r
   r   jaxlibautogradmarsfuncbackenddefaultreturnc                 C   sX   zt t||}|du rt|| W S t|| |W S  ty+   d}t||| w )zTry and import ``{backend}.{func}``.
    If library is installed and func is found, return the func;
    otherwise if default is provided, return default;
    otherwise raise an error.
    Nz{} doesn't seem to provide the function {} - see https://optimized-einsum.readthedocs.io/en/latest/backends.html for details on which functions are required for which contractions.)	importlibimport_module_aliasesgetgetattrAttributeErrorformat)r   r   r   lib	error_msg r"   R/mnt/sdb/aimis/docanh/lib/python3.10/site-packages/opt_einsum/backends/dispatch.py_import_func%   s   "r$   )einsumobject_cached_funcs)	tensordotnumpy)	transposer)   )r%   r)   )r(   r&   )r*   r&   r)   c                 C   s>   zt | |f W S  ty   t| ||}|t | |f< | Y S w )ziReturn ``{backend}.{func}``, e.g. ``numpy.einsum``,
    or a default func if provided. Cache result.
    )r'   KeyErrorr$   )r   r   r   fnr"   r"   r#   r   J   s   r   _has_einsumc                 C   X   zt |  W S  ty+   ztd|  dt | < W n ty$   dt | < Y nw t |   Y S w )zCCheck if ``{backend}.einsum`` exists, cache result for performance.r%   TF)r-   r+   r   r   r   r"   r"   r#   r   Z      

r   _has_tensordotc                 C   r.   )zFCheck if ``{backend}.tensordot`` exists, cache result for performance.r(   TF)r1   r+   r   r   r/   r"   r"   r#   r   k   r0   r   )r   r	   r   r
   r   c                 C      t |  ||S )zxBuild an expression, based on ``expr`` and initial arrays ``arrays``,
    that evaluates using backend ``backend``.
    )CONVERT_BACKENDSr   arraysexprr"   r"   r#   r         r   c                 C   r2   )zConvert constant arrays to the correct backend, and perform as much of
    the contraction of ``expr`` with these as possible.
    )EVAL_CONSTS_BACKENDSr4   r"   r"   r#   r      r7   r   c                 C   s   |   tv S )zChecks if the backend is known.)lowerr3   r/   r"   r"   r#   r      s   r   )N)r)   N)*__doc__r   typingr   r   r   opt_einsum.backendsr   _cupyr   _jaxr   r   _tensorflowr	   _theanor
   _torch__all__r   strr$   object_einsumr'   __annotations__r)   npr(   r*   r%   ModuleNotFoundErrorr   r-   boolr   r1   r   r   r3   r   r8   r   r"   r"   r"   r#   <module>   sf    



		