
    ,Vh              
          U d Z ddlZddlZddlZddlZddlmZmZ ddlm	Z	m
Z
mZmZmZmZmZ ddlmZ ddlmZmZ ddlmZ eeeeeeedf   f   eeef   f   Ze
eef   Zg d	Z ee      Ze
eee   f   ed
<   defdZdefdZ dede	fdZ!d#dZ"ejF                  	 d$dee   deeddf   fd       Z$dedee   fdZ%deddfdZ&dede	de	de	def
dZ'de	de	fdZ(de	de	fdZ)de	de	fdZ*d%d e	d!e	de	fd"Z+y)&z_A module for sharing intermediates between contractions.

Copyright (c) 2018 Uber Technologies
    N)Counterdefaultdict)AnyDict	GeneratorListOptionalTupleUnion)r   )alpha_canonicalizeparse_einsum_input)	ArrayType.)currently_sharingget_sharing_cacheshared_intermediatescount_cached_opstranspose_cache_wrapeinsum_cache_wrapto_backend_cache_wrap_SHARING_STACKreturnc                  6    t        j                         t        v S )z=Check if we are currently sharing a cache -- thread specific.)	threading	get_identr        B/home/dcms/DCMS/lib/python3.12/site-packages/opt_einsum/sharing.pyr   r   !   s     N22r   c                  >    t         t        j                            d   S )z8Return the most recent sharing cache -- thread specific.)r   r   r   r   r   r   r   r   &   s    )--/044r   cachec                 X    t         t        j                            j                  |        y N)r   r   r   appendr    s    r   _add_sharing_cacher%   +   s    9&&()007r   c                  |    t        j                         } t        |    j                          t        |    st        | = y y r"   )r   r   r   pop)tids    r   _remove_sharing_cacher)   /   s6    



C3#3 r   c              #   f   K   | i } t        |        	 |  t                y# t                w xY ww)a  Context in which contract intermediate results are shared.

    Note that intermediate computations will not be garbage collected until
    1. this context exits, and
    2. the yielded cache is garbage collected (if it was captured).

    **Parameters:**

    - **cache** - *(dict)* If specified, a user-stored dict in which intermediate results will be stored. This can be used to interleave sharing contexts.

    **Returns:**

    - **cache** - *(dict)* A dictionary in which sharing results are stored. If ignored,
        sharing results will be garbage collected when this context is
        exited. This dict can be passed to another context to resume
        sharing.
    N)r%   r)   r$   s    r   r   r   6   s1     * }u s   1" 1.1c                 B    t        d | j                         D              S )zrReturns a counter of the types of each op in the cache.
    This is useful for profiling to increase sharing.
    c              3   &   K   | ]	  }|d      yw)r   Nr   ).0keys     r   	<genexpr>z#count_cached_ops.<locals>.<genexpr>X   s     2c3q62   )r   keysr$   s    r   r   r   T   s     2UZZ\222r   tensorsc                  F    t               }| D ]  }||dt        |      f<    y)z{Save tensors in the cache to prevent their ids from being recycled.
    This is needed to prevent false cache lookups.
    tensorN)r   id)r2   r    r4   s      r   _save_tensorsr6   [   s.     E -&,h6
"#-r   r.   fnargskwargsc                 F    t               }| |v r||    S  ||i |}||| <   |S )zMemoize ``fn(*args, **kwargs)`` using the given ``key``.
    Results will be stored in the innermost ``cache`` yielded by
    :func:`shared_intermediates`.
    )r   )r.   r7   r8   r9   r    results         r   _memoizer<   d   s:    
 E
e|Sz  FE#JMr   	transposec                 D     t        j                         d fd	       }|S )zqDecorates a ``transpose()`` implementation to be memoized inside a
    :func:`shared_intermediates` context.
    c                     t               s | ||      S t        |        t        |      }d|t        |       |f}t	        || ||      S )Nbackendr=   )r   r6   tupler5   r<   )aaxesrA   r.   r=   s       r   cached_transposez.transpose_cache_wrap.<locals>.cached_transposev   sP     "Qg66 	aT{7BqE4/Y4AAr   )numpy	functoolswraps)r=   rE   s   ` r   r   r   q   s*    
 __YB  B r   	tensordotc                 D     t        j                         d fd	       }|S )zqDecorates a ``tensordot()`` implementation to be memoized inside a
    :func:`shared_intermediates` context.
    c                    t               s | |||      S t        | |       t        |t        j                        rjt        t        t        | j                                    t        | j                        |z
  d  t        t        t        |j                                    d | f}t        |d         t        |d         f}d|t        |       t        |      |f}t        || |||      S )Nr@   r      rJ   )r   r6   
isinstancenumbersNumberlistrangelenshaperB   r5   r<   )xyrD   rA   r.   rJ   s        r   cached_tensordotz.tensordot_cache_wrap.<locals>.cached_tensordot   s     "Q499 	adGNN+U3qww<()#agg,*=*?@U3qww<()%40D T!W~uT!W~-7BqE2a5$6Y1dGDDr   )   rF   rG   )rJ   rW   s   ` r   tensordot_cache_wraprY      s*    
 __YE  E r   einsumc                 B     t        j                          fd       }|S )zoDecorates an ``einsum()`` implementation to be memoized inside a
    :func:`shared_intermediates` context.
    c            	         t               s | i |S |j                  dd      }| d   }t        |       \  }}}|j                  d      }t	        |  t        t        |t        t        |            d       }t        d |D              }dj                  d |D              }	t        |	d	z   |z         }
d
||
|f}t        ||g|d|iS )NrA   rF   r   ,c                     | d   S )NrM   r   )rU   s    r   <lambda>z:einsum_cache_wrap.<locals>.cached_einsum.<locals>.<lambda>   s
    1 r   )r.   c              3   &   K   | ]	  \  }}|  y wr"   r   )r-   _id_s      r   r/   z;einsum_cache_wrap.<locals>.cached_einsum.<locals>.<genexpr>   s     :fac:r0   c              3   &   K   | ]	  \  }}|  y wr"   r   )r-   input_ra   s      r   r/   z;einsum_cache_wrap.<locals>.cached_einsum.<locals>.<genexpr>   s     #FyvqF#Fr0   z->rZ   )r   r'   r   splitr6   sortedzipmapr5   rB   joinr   r<   )r8   r9   rA   equationinputsoutputoperands	canonicalcanonical_idscanonical_inputscanonical_equationr.   rZ   s               r   cached_einsumz(einsum_cache_wrap.<locals>.cached_einsum   s     "4*6** **Y07#5d#; c"x  3vs2x'89~N	:	::88#FI#FF/0@40G&0PQ!3]BVXJJ'JJr   rG   )rZ   rr   s   ` r   r   r      s*    
 __VK K* r   
to_backend	constantsc                       t        j                  t        |      S |r t        j                         d fd	       }|S t        j                          fd       }|S )zDecorates an ``to_backend()`` implementation to be memoized inside a
    :func:`shared_intermediates` context (e.g. ``to_cupy``, ``to_torch``).
    )rt   c                 z    t               s
 | |      S j                  t        |       |f}t        || |      S )N)constantr   __name__r5   r<   )arrayrw   r.   rs   s      r   cached_to_backendz0to_backend_cache_wrap.<locals>.cached_to_backend   s?    $&!%(;; %%r%y(:CCUXFFr   c                 p    t               s |       S j                  t        |       f}t        ||       S r"   rx   )rz   r.   rs   s     r   r{   z0to_backend_cache_wrap.<locals>.cached_to_backend   s9    $&!%(( %%r%y0CCU33r   )F)rH   partialr   rI   )rs   rt   r{   s   `  r   r   r      sl    
   !6)LL		$	G 
%	G&  
	$	4 
%	4 r   )r   Nr"   )NF),__doc__
contextlibrH   rO   r   collectionsr   r   typingr   r   r   r   r	   r
   r   CounterTypeopt_einsum.parserr   r   opt_einsum.typingr   strintCacheKeyType	CacheType__all__rQ   r   __annotations__boolr   r   r%   r)   contextmanagerr   r   r6   r<   r   rY   r   r   r   r   r   <module>r      s  
     , E E E ) D 'U3S%S/9:E#s(OKLy()	 .9->S$y/)* >34 3
59 5
8i 8C 8  !% I y$$%   :3I 3+c*: 3-I -$ -
, 
C 
 
s 
y 
C C &C C 0c c <c S S r   