
    uki                       d Z ddl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
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 ddlmZ  ej,                  ddd      Z G d d      Z e       Ze
j4                  j6                  j9                  d      	 	 	 	 	 	 dd       Z	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 ddZy)z+Colocated Python object API implementation.    )annotations)CallableN)Any)api_util)config)	tree_util)api_boundary)wraps)func)obj_backend@jax_experimental_colocated_python_object_use_weakrefs_at_backendFzUnstable in-development feature that switches the colocated-python implementation to internally use reference counting for destructing objects at the colocated backend, instead of invoking an explicit delete-object function from the frontend.)helpc                  0    e Zd ZdZddZddZd	dZd
dZy)_InstanceRegistryzRegistry of object instances.c                D    t        j                         | _        i | _        y N)	threadingLock_lock_storageselfs    `/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/experimental/colocated_python/obj.py__init__z_InstanceRegistry.__init__3   s    !DJ02DM    c                    t        j                  d      }| j                  5  || j                  vsJ t	               | j                  |<   ddd       |S # 1 sw Y   |S xY w)zBReturns a new unique identifier for an instance on the controller.?   N)randomgetrandbitsr   r   setr   uids     r   new_instancez_InstanceRegistry.new_instance7   sY    


R
 C	 !%%%5dmmC! J! Js   (AAc                t    | j                   5  | j                  |xx   |z  cc<   ddd       y# 1 sw Y   yxY w)z/Updates the set of devices on which it is live.N)r   r   )r   r"   
device_sets      r   update_devicesz _InstanceRegistry.update_devices?   s2    	 '
mmCJ&' ' 's   .7c                |    | j                   5  | j                  j                  |      cddd       S # 1 sw Y   yxY w)zHRemoves the instance and returns the set of devices on which it is live.N)r   r   popr!   s     r   pop_instancez_InstanceRegistry.pop_instanceD   s0    	 $]]s#$ $ $s   2;NreturnNone)r+   int)r"   r-   r%   set[jax.Device]r+   r,   )r"   r-   r+   r.   )__name__
__module____qualname____doc__r   r#   r&   r)    r   r   r   r   0   s    %3'
$r   r   i   )max_sizec                p    t               }|D ]  }||j                  z  } t        j                  | |       y)z6Caching version of _InstanceRegistry.update_devices().N)r    r%   SINGLETON_INSTANCE_REGISTRYr&   )r"   	shardingsr%   shardings       r   _update_instance_devicesr9   M   s:    
 u* &h(%%%J&,,S*=r   c	                      G  fdd      }	|j                   |	       |t        j                              }
fd |
      }|S )Nc                  6    e Zd Zd Zd Z fdZfdZy)+_make_method.<locals>.MethodCallerAtBackendc                6    t        j                         | _        y r   )r   r   r   r   s    r   r   z4_make_method.<locals>.MethodCallerAtBackend.__init__f   s    >>#djr   c                    t        |       dfS )Nr3   )typer   s    r   
__reduce__z6_make_method.<locals>.MethodCallerAtBackend.__reduce__i   s    $Z^r   c                    d fd}t         j                  j                  |      }r |       | _        y || _        y )Nc                 F     i rdd l } | j                        S S )Nr   )weakrefref)rC   cls	init_argsinit_kwargsnew_objuse_weakrefss    r   initializerzL_make_method.<locals>.MethodCallerAtBackend._first_call.<locals>.initializerq   s,    y0K0
W%
%r   )r   SINGLETON_OBJECT_STOREget_or_createobj)	r   rJ   	retrievedrH   rE   rF   rG   r"   rI   s	      @r   _first_callz7_make_method.<locals>.MethodCallerAtBackend._first_calll   sF     g  44BB
{i 
;r   c                    | j                   5  t        | d      s| j                          d d d         t        | j                        |i |S # 1 sw Y   %xY w)NrM   )r   hasattrrO   getattrrM   )r   argskwargsmethod_names      r   __call__z4_make_method.<locals>.MethodCallerAtBackend.__call__   sT    :: tU#



 ,WTXX{+T<V<< s   AAN)r/   r0   r1   r   r@   rO   rV   )rE   rF   rG   rU   r"   rI   s   r   MethodCallerAtBackendr<   d   s    $ .=r   rW   c                d     t          fd       } fd} t              |      }||_        |S )Nc                     t        j                  | |f      }t        d |D              }|rt        |        | i |}|s3t        j                  |      }t        d |D              }t        |       |S )Nc              3  Z   K   | ]#  }t        j                  |      j                   % y wr   r   	_get_specr8   .0xs     r   	<genexpr>zT_make_method.<locals>.make_method_wrapper.<locals>.method_wrapper.<locals>.<genexpr>   s$      $;)*$..

$
$$;   )+c              3  Z   K   | ]#  }t        j                  |      j                   % y wr   r[   r]   s     r   r`   zT_make_method.<locals>.make_method_wrapper.<locals>.method_wrapper.<locals>.<genexpr>   s$      (?+,DNN1&&(?ra   )r   tree_leavestupler9   )	rS   rT   args_leavesargs_shardings_leavesresultresult_leavesresult_shardings_leavescallabler"   s	          r   method_wrapperzA_make_method.<locals>.make_method_wrapper.<locals>.method_wrapper   s     ))4.9k# $;.9$; ;	 &;<((f #!--f5"' (?0=(? #? &=>mr   c                 4      j                   | i |      S r   )
specialize)rS   rT   rj   make_method_wrappers     r   rm   z=_make_method.<locals>.make_method_wrapper.<locals>.specialize   s!     !4!4!4d!Ef!EFFr   )r	   r
   rm   )rj   rk   rm   rn   original_methodr"   s   `  r   rn   z)_make_method.<locals>.make_method_wrapper   s<     ,G ,U?+N;N *Nr   )make_callabler   fun_signature)rE   cls_sourceinfor"   rF   rG   rU   ro   
func_makerrI   rW   rj   rk   rn   s   ` ````` `   @r   _make_methodrt   X   sS    #= #= #=L %%_-(> 'x0.	r   c                h      G  fdd      } j                   |_          j                  |_        |S )Nc                  R    e Zd Z eW  j                        d fd       ZfdZy) wrap_class.<locals>.WrappedClassc                p   t         j                         x}| _        t        j                  |      | _        t        j                  | _        t              D ]]  }t        |      }t        j                  |      s%|dv r*t        |||||| j
                  | j                  	      }t        | ||       _ y )N)r   __del__r@   __reduce_ex__)r6   r#   _colocated_python_uidr   _CachedColocatedFunctionMakerrs   _USE_WEAKREFSvaluerI   dirrR   inspect
isfunctionrt   setattr)	r   rF   rG   r"   	attr_nameoriginal_membermethodrE   rr   s	          r   r   z)wrap_class.<locals>.WrappedClass.__init__   s     &
2
2
4cD& ::3?do'--d3x ))!#y1!!/2

 NN
OO

 	i(1)r   c                    | ` | j                  ry | j                  t        j	                        }|rCdfd}t        j                  |d       }|j                  t        |d             } |        y y )Nc                 D    t         j                  j                          y r   )r   rK   remove)r"   s   r   remove_objectz?wrap_class.<locals>.WrappedClass.__del__.<locals>.remove_object   s    

,
,
3
3C
8r   c                    | j                   S r   )id)devices    r   <lambda>z:wrap_class.<locals>.WrappedClass.__del__.<locals>.<lambda>   s
    vyy r   )key)devicesr*   )	rs   rI   r{   r6   r)   r   rp   rm   sorted)r   r   r   
destructorr"   rr   s       @r   ry   z(wrap_class.<locals>.WrappedClass.__del__   s    
/			&&c+88=g		9 ''


  **7(@A + 

 	 
r   Nr*   )r/   r0   r1   r
   r   ry   )rE   rr   s   r   WrappedClassrw      s$    
3<<) )@r   r   )r/   r2   )rE   rr   r   s   `` r   
wrap_classr      s.    6 6p ,,,,	r   )r"   r-   r7   z!tuple[jax.sharding.Sharding, ...]r+   r,   )rE   type[object]rr   
str | Noner"   r-   rF   ztuple[Any, ...]rG   zdict[str, Any]rU   strro   zCallable[..., Any]rs   z"func._CachedColocatedFunctionMakerrI   bool)rE   r   rr   r   r+   r   ) r2   
__future__r   collections.abcr   r   r   r   typingr   jaxjax._srcr   r   r   jax._src.traceback_utilr	   jax._src.utilr
   !jax.experimental.colocated_pythonr   r   
bool_stater}   r   r6   _srcutilcacher9   rt   r   r3   r   r   <module>r      s/   2 " $     
    0  2 9
 "!!F		5		$ $4 01  d#>	>:>	> $>Z	ZZ 
Z 	Z
  Z Z (Z 3Z Zz>	>> >r   