o
    i$                     @   s~  d dl m  mZ d dlm  mZ ddlmZ d dl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Zdd	lmZmZ dd
lmZ ddlmZ ddlmZ dd Zdae Zdd Zdd Zd)ddZedde_dd Ze e_dd Z e e _dd Z!e!dd Z"e#dd e" e!d!d" Z$e#dd#e$ e!d$d% Z%e#dd&e% d'd( Z&e#dde& dS )*    N   )api)partial)registry)Backend)ImportBackendError   )_make_iskwarg_unsupported_op) _make_doc_adapt_numpylike_reduce)%_make_doc_adapt_numpylike_elementwise)_make_doc_adapt_with_vmapc                  C   sH   dd l } tdd | jdd d D }|dk r"td| j dd S )	Nr   c                 s       | ]}t |V  qd S Nint).0i r   Q/home/ubuntu/.local/lib/python3.10/site-packages/einx/_src/frontend/impl/torch.py	<genexpr>       z,_raise_on_invalid_version.<locals>.<genexpr>.r   )r   r   z=einx with PyTorch requires PyTorch version >= 2.2, but found z*. einx functions are disabled for PyTorch.)torchtuple__version__splitr   )r   versionr   r   r   _raise_on_invalid_version   s
   "r   Fc                  C   st   t s8t* t s&dd l} ddlm} |D ]}| j| qda W d    d S W d    d S 1 s1w   Y  d S d S )Nr   )opsT)_has_allowed_in_graph_has_allowed_in_graph_lockr   einx._src.frontend.opsr   compilerallow_in_graph)r   r   opr   r   r   _allow_ops_in_graph   s   "r&   c                     s   t jjd t jj jt jj j	t jj
 jt jj jt j t j g} dd l  fdd}dd }| t jj||dS )Nr   r   c                    s   t |  jS r   )
isinstanceTensortensorr   r   r   is_supported_tensor8   s   z0_get_backend_kwargs.<locals>.is_supported_tensorc                 S   s   t dd | jD S )Nc                 s   r   r   r   )r   xr   r   r   r   <   r   z9_get_backend_kwargs.<locals>.get_shape.<locals>.<genexpr>)r   shaper)   r   r   r   	get_shape;   s   z&_get_backend_kwargs.<locals>.get_shape)optimizationsr#   r,   r/   )tracer	signaturepythonimport_	optimizer	classicalSkipReshapereshapeSkipTransposepermuteSkipBroadcastTobroadcast_toSkipConcatenatecatInlineGraphSkipCastr   r#   )r0   r,   r/   r   r+   r   _get_backend_kwargs+   s   	rA   c                 C   s   t   t| }t }tj }tjj||j	d}tj
||j	d}tjj| } tjj| ||jd} tj| |} |j| } tjj| |jd} tjj| ||dd} t| tjdi t d} dd l}|j|  | S )N
get_deviceexpected_type	bijective)iskwargel_opimplicit_outputbackendr   r   )r   r	   adapterTorchDeviceStackr1   r2   r   classical_from_torchr   rC   vmap_from_torchr3   constantdecomposednamedtensor_from_vmapr%   r(   &namedtensor_from_decomposednamedtensornamedtensornamedtensor_calltensorfactoryeinx_from_namedtensorr   typesSimpleNamespacerA   r#   r$   )r%   r2   rG   device_stackr   r6   vmapr   r   r   adapt_with_vmapA   s    
rZ   r   z``torch.vmap``c                 C   s   t   t| fdd}t }tj }tjj||j	d}tjj
| } tjj| |jd} tj| |} |j| } tjj| |jd} tjj| |d} t| tjdi t d} dd l}|j|  | S )	Nc                 S   s   | dko|| S )Naxisr   )namerG   r   r   r   <lambda>`   s    z(adapt_numpylike_reduce.<locals>.<lambda>rB   rD   rG   rJ   r   r   )r   r	   rL   rM   r1   r2   r   rN   r   rC   r3   rP   $decomposednamedtensor_from_classicalreducer(   rR   r%   rS   rT   rU   r   rV   rW   rA   r#   r$   r%   rG   rX   r   r6   r   r   r   adapt_numpylike_reduce^   s   
rb   c                 C   s   t   t| }t }tj }tjj||j	d}tjj
| } tjj| ||jd} tj| |} |j| } tjj| |jd} tjj| |d} t| tjdi t d} dd l}|j|  | S )NrB   rD   r^   rJ   r   r   )r   r	   rL   rM   r1   r2   r   rN   r   rC   r3   rP   r_   elementwiser(   rR   r%   rS   rT   rU   r   rV   rW   rA   r#   r$   ra   r   r   r   adapt_numpylike_elementwisez   s   
rd   c                    s    fdd}|S )Nc                     s   t   t  t } tj }tjj|| j	d} ||| \}}tj
||}| j|}tjj||jd}tj|}td||ddt S )NrB   rD   r   r\   priorityr   )r   r&   rL   rM   r1   r2   r   rN   r   rC   rR   rS   rT   r(   rU   r   rA   )rX   r   r6   decomposednamedtensor_opsr\   namedtensor_opseinx_opscreater   r   
new_create   s   
z$_backend_creator.<locals>.new_creater   )rl   rm   r   rk   r   _backend_creator   s   rn   c                    s    fddt jjD  fddt jjD B  fddt jjD B  fddt jjD B  fddt jjD B t j t j	 dB }|dfS )	Nc                    "   i | ]}|t jt | qS r   )rL   r_   rc   getattrr   r\   r6   r   r   
<dictcomp>      " z,create_backend_numpylike.<locals>.<dictcomp>c                        i | ]}|t jt |qS r   )rL   r_   r`   rp   rq   rr   r   r   rs           c                    ru   r   )rL   r_   preserve_shaperp   rq   rr   r   r   rs      rv   c                    ro   r   )rL   r_   argfindrp   rq   rr   r   r   rs      rt   c                    ro   r   )rL   r_   update_at_ravelledrp   rq   rr   r   r   rs      rt   )get_atdottorch.numpylike)
rL   r   rc   r`   rw   rx   	update_atr_   get_at_ravelledr{   )r   r6   rX   rh   r   rr   r   create_backend_numpylike   s   

r   r|   c                 C   sF   t j| |jd}t j|t j|t j|t j|d}|dfS )NrB   )idsummultiplyr{   torch.einsum)rL   einsum_from_torchrC   !decomposednamedtensor_from_einsumr   r   r   r{   )r   r6   rX   einsumrh   r   r   r   create_backend_einsum   s   



r   r   c                    sf   t j|jdt j d} fddt jjD dtdd|iB dd t jjD B }|dfS )NrB   a  get_at is not supported by the torch.vmap backend. As of testing this, torch.vmap is not compatible with scalar indexing operations and raises the following error:
"vmap: It looks like you're calling .item() on a Tensor. We don't support vmap over calling .item() on a Tensor, please try to rewrite what you're doing with other operations. If error is occurring somewhere inside PyTorch internals, please file a bug report."
Please use another PyTorch backend for this operation.c              
      s*   i | ]}|t jj| jd  dqS )T)rE   allow_squeeze_unsqueezer6   )rL   rQ   r%   r(   rq   r6   elementary_opsr   rY   r   r   rs      s    z'create_backend_vmap.<locals>.<dictcomp>rz   
torch.vmapc                 S   s   i | ]}|t |d qS )r   )r
   rq   r   r   r   rs      s    )rL   rO   rC   elementary_from_classicalr   allr
   r}   )r   r6   rX   get_at_error_messagerh   r   r   r   create_backend_vmap   s   	r   r   c                  C   s8   t  j} t j}| d|d iB }td|dddt S )Nr{   r   r   rf   r   )r   r   r   r   rA   )einx_ops_numpylikeeinx_ops_einsumrj   r   r   r   create_backend   s   r   r   )'einx._src.tracer_srcr1   einx._src.adapterrL   r   rV   inspect	functoolsr   rK   r   r   einx._src.frontend.errorsr   	threading_utilr	   r
   _docsr   r   r   r   r    Lockr!   r&   rA   rZ   __doc__rb   rd   rn   r   register_on_importr   r   r   r   r   r   r   <module>   sL    



