o
    ¨i eD  ã                   @   s  d Z ddlZddl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œZd#dd„ZejejejejejejdœZd$dd„Zi Zdd„ Zi Z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!d"„ Z dS )%z¦
Handles dispatching array operations to the correct backend library, as well
as converting arrays to backend formats and then potentially storing them as
constants.
é    Né   )Úobject_arrays)Úcupy)Újax)Ú
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   ÚautogradÚmarsc                 C   sX   zt  t ||¡¡}|du rt|| ƒW S t|| |ƒW S  ty+   d}t| || ¡ƒ‚w )z½Try 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)ÚfuncÚbackendÚdefaultÚlibÚ	error_msg© r   úK/var/www/myenv/lib/python3.10/site-packages/opt_einsum/backends/dispatch.pyÚ_import_func   s   "ür    ))Ú	tensordotÚnumpy)Ú	transposer"   )Úeinsumr"   )r!   Úobject)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.
    )Ú_cached_funcsÚKeyErrorr    )r   r   r   Úfnr   r   r   r	   <   s   ýr	   c                 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 )zHCheck if ``{backend}.einsum`` exists, cache result for performance.
    r$   TF)Ú_has_einsumr'   r	   r   ©r   r   r   r   r
   L   ó   

ÿùr
   c                 C   r)   )zKCheck if ``{backend}.tensordot`` exists, cache result for performance.
    r!   TF)Ú_has_tensordotr'   r	   r   r+   r   r   r   r   ^   r,   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   r.   )zƒConvert constant arrays to the correct backend, and perform as much of
    the contraction of ``expr`` with these as possible.
    )ÚEVAL_CONSTS_BACKENDSr0   r   r   r   r   ‡   r3   r   c                 C   s   |   ¡ tv S )z$Checks if the backend is known.
    )Úlowerr/   r+   r   r   r   r   Ž   s   r   )N)r"   N)!Ú__doc__r   r"   Ú r   r   Ú_cupyr   Ú_jaxr   Ú_tensorflowr   Ú_theanor   Ú_torchÚ__all__r   r    r!   r#   r$   Úobject_einsumr&   r	   r*   r
   r-   r   r   r/   r   r4   r   r   r   r   r   Ú<module>   sZ    ú

ù
û	û	