
    uki0                       d Z ddlmZ ddlZddlZddlmZ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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ej4                  Z G d
 de
j6                        Z e       Zd Zd Z	 	 	 	 ddZ ejB                  jD                  jG                  d      d d       Z$	 	 	 	 	 	 d!dZ%e 	 	 	 	 d"d       Z&	 	 	 	 	 	 	 	 d#dZ'e 	 	 	 	 d$d       Z(d Z)e 	 	 	 	 d%d       Z*d&dZ+e 	 	 	 	 d'd       Z,	 	 	 	 	 	 d(dZ-d)dZ.d*dZ/	 	 	 	 d+dZ0	 	 	 	 	 	 	 	 d,dZ1	 	 	 	 d-dZ2y# e$ r dZY w xY w).z)Colocated Python serialization utilities.    )annotationsN)CallableSequence)Any)api)	tree_util)
xla_bridge)
xla_clientc                      e Zd ZdZd Zy)_CommonObjectStatea  Tracks repeated objects within a single `_serialize()` or `_deserialize()`.

  It is common for `_serialize(x)` to be called with `x` being a nested
  container or capturing other objects in a closure, with many references
  pointing to only a few unique objects. The logic below
  (`_make_reduce_func_with_common_obj`) avoids duplicating object serialization
  by reducing a reference handle instead of the full object when an equal object
  is repeatedly seen.
  c                     d | _         d | _        y N)common_obj_index
common_obj)selfs    j/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/experimental/colocated_python/serialization.py__init__z_CommonObjectState.__init__4   s     48D )-DO    N)__name__
__module____qualname____doc__r    r   r   r   r   )   s    -r   r   c                    t         j                  J  || }t        t         j                        | k(  s%J d|  dt        t         j                         d       t         j                  j                  |       |S )zUnreduces a new common object.z	Expected z common objects, but got z_. This can happen if serialization and deserialization of objects happened in different orders.)_common_obj_stater   lenappend)common_obj_idunreduce_funcunreduce_argsobjs       r   *_wrapped_unreduce_func_with_new_common_objr"   B   s     
	%	%	11	1}%#	))	*m	; - !

**
+	, -FF	;
 %%c*	*r   c                L    t         j                  J t         j                  |    S )z4Unreduces a common object that has already appeared.)r   r   )r   s    r   /_wrapped_unreduce_func_with_existing_common_objr$   P   s%    		%	%	11	1		%	%m	44r   c                B     t        j                          fd       }|S )z:Wraps a reduce function to serialize a common object once.c                    t         j                  J t         j                  j                  |       }|B |       \  }}t        t         j                        }|t         j                  | <   t        |||ffS t
        |ffS r   )r   r   getr   r"   r$   )r!   r   unreduced_funcunreduced_argsreduce_funcs       r   wrapped_reduce_funcz>_make_reduce_func_with_common_obj.<locals>.wrapped_reduce_func[   s    --999%66::3?M'23'7$nn+<<=m0=((-7
:9 9 9 =}>NNNr   )	functoolswraps)r*   r+   s   ` r   !_make_reduce_func_with_common_objr.   V   s*    
 ??;
O  
O 
r   )max_sizec            
     R   i } t        j                         d   j                  j                         D ]Z  }|j                  dk(  s|j
                  | v r+t        d|j
                   d| |j
                      d|       || |j
                  <   \ | r| S t        j                         j                         D ]o  }|j                         D ]Z  }|j                  dk(  s|j
                  | v r+t        d|j
                   d| |j
                      d|       || |j
                  <   \ q | S )z4Returns a map from a device id to a matching device.r   cpuzMultiple CPU devices with id z found: z and )	xblocal_devicesclient_get_all_devicesdevice_kindid
ValueErrorbackendsvalues)cpu_device_mapdbackends      r   _get_cpu_device_mapr>   k   s@    +-. a ''88: a}}	
	+ADD6 2qtt$%U1#/
 	
 nQTT  %%' !g%%' !	
%	44>!-addV 4 &'uQC1   !qtt!! 
r   c                J    | j                  |      }|t        d| d      |S )z.Returns a CPU device with the given device ID.zInvalid device ID z,. Device list must contain only CPU devices.)r'   r8   )r;   	device_idr<   s      r   _lookup_cpu_devicerA      s>     #!Y

YK ( 	  
(r   c                     t        j                  d t        g      | j                        }t        || j
                  | j                  ffS )Nc                    | j                   S r   )r7   )r<   s    r   <lambda>z_reduce_mesh.<locals>.<lambda>   s
    144 r   )otypes)np	vectorizeintdevices_unreduce_mesh
axis_names
axis_types)meshmesh_device_idss     r   _reduce_meshrO      s;     ?BLL>t||L/	/4??DOOL	LLr   c                    t               } t        j                  t        j                  t
        |            |       }t        j                  j                  |||      S r   )	r>   rF   rG   r,   partialrA   jaxshardingMesh)rN   rK   rL   r;   mesh_devicess        r   rJ   rJ      sR     '(.*N;, 
		<Z	@@r   c                    t        | j                  t        j                  j                        sJ d       t        | j                        }t        || j                  | j                  ffS )NzOnly Mesh is supported)	
isinstancerM   rR   rS   rT   rO   _unreduce_named_shardingspecmemory_kind)rS   reduced_meshs     r   _reduce_named_shardingr\      sY     
HMM3<<#4#4	5O7OO	5hmm,,	!HMM8#7#7$9 
9 9r   c                H     | d   | d    }t        j                  |||      S )Nr      rZ   )rR   NamedSharding)r[   rY   rZ   rM   s       r   rX   rX      s+    	a,q/	*$			4;	??r   c                P    | D cg c]  }|j                    }}t        |ffS c c}w r   )r7   _unreduce_device_list)device_listr<   
device_idss      r   _reduce_device_listre      s-     *****		-- +s   #c                    t               } t        j                  t        j                  t
        |            |       }t        t        |            S r   )r>   rF   rG   r,   rQ   rA   
DeviceListtuple)rd   r;   rI   s      r   rb   rb      s?    &(.OBLL**+=~NO'	E'N	##r   c                n    t         | j                  j                         j                  | j                  ffS r   ) _unreduce_single_device_sharding
device_setpopr7   rZ   )rS   s    r   _reduce_single_device_shardingrm      s7     
*"", 
 r   c                p    t               }t        ||       }t        j                  j	                  ||      S )Nr_   )r>   rA   rR   rS   SingleDeviceSharding)r@   rZ   r;   devices       r   rj   rj      s2     '(.ni8&		*	*6{	*	KKr   c                   t         t        d       G d dt         j                        }t        j                  J d       i t        _        	 t        j                         5 } ||      j                  |        |j                         cddd       dt        _        S # 1 sw Y   nxY w	 dt        _        y# dt        _        w xY w)a  Serializes callables and input/output spec objects.

  DO NOT USE THIS FUNCTION EXCEPT FOR THE INTERNAL IMPLEMENTATION OF
  colocated_python.

  This module contains utility functions used internally for implementiong
  `colocated_python` when it ships callables and input/output specs through
  IFRT. The pickled data is produced and consumed in an ephermeral fashion
  without any persistence, and it does not expect any version compatibility
  (which cloudpickle does not guarantee). Furthermore, serialization and
  deserialization is expected to be done on machine(s) that are controlled by a
  single tenant, which allows unpickling done during deserialization to be
  trusted.

  Raises:
    ModuleNotFoundError: If cloudpickle is not available.
  NNo module named "cloudpickle"c                      e Zd Z ej                  ej                  j                  eiej                  j                  e
ieeiej                  j                  eiej                   j"                        ZeZy)"_serialize.<locals>._CustomPicklerN)r   r   r   collectionsChainMaprR   rS   rT   rO   r`   r\   rg   re   ro   rm   cloudpickleCloudPicklerdispatch_tabledispatchr   r   r   _CustomPicklerrt      sk    )[))			L)		#	#%;<	()		*	*,JK  //N Hr   r{   z'_serialize() expects no recursive calls)	rw   ModuleNotFoundErrorPicklerr   r   ioBytesIOdumpgetvalue)r!   r{   files      r   
_serializer      s    $ 
=
>>{**  
	+	+	3 1/1	3')$.	 T$]]_  *.&	   *.&&s$   B7 "'B		B7 B'#B7 7Cc                    t         t        d      t        j                  J d       g t        _        	 t        j                  |       dt        _        S # dt        _        w xY w)zDeserializes callables and input/output spec objects.

  DO NOT USE THIS FUNCTION EXCEPT FOR THE INTERNAL IMPLEMENTATION OF
  colocated_python. See serialize() for details.

  Raises:
    ModuleNotFoundError: If cloudpickle is not available.
  Nrr   z)_deserialize() expects no recursive calls)rw   r|   r   r   loads)
serializeds    r   _deserializer     sa     
=
>>		%	%	- 313	-!#(Z(#' 4 s   A A"c                4   t         j                  j                  t        |       d      }t         j                  j	                  |t         j                  j                               }t        j                  dt        j                  j                         |      S )z(Makes output specs for serialized specs.xr   )shapedtyperS   )rR   rS   rT   rh   r`   PartitionSpecr   ShapeDtypeStructrF   dtypesStringDType)rI   rM   replicated_shardings      r    _make_specs_for_serialized_specsr     so     
		5>6	2$22
CLL&&( 
		bii++-8K
 r   c                v   t        t        j                  d      st        d      t	        | |f      }t        j                  |      j                  d      }t        j                  |t        j                  j                               }|j                  }t        j                  j                  t        |      d      }t        j                  j                  |t        j                  j!                               }|D 	cg c]  }	t        j"                  ||	       }
}	t        j$                  |
|d      S c c}	w )zSerializes the output specs into a jax.Array of string type.

  DO NOT USE THIS FUNCTION EXCEPT FOR THE INTERNAL IMPLEMENTATION OF
  colocated_python. See serialize() for details.
  r   zSerializing Colocated Python requires StringDType. Please use numpy to 2.0.0 or later, or explicitly provide an output spec function.ascii)r   r   r   )arraysrS   r   )hasattrrF   r   	TypeErrorr   base64	b64encodedecodearrayr   addressable_device_listrR   rS   rT   rh   r`   r   
device_put$make_array_from_single_device_arrays)specs_treedefspecs_leavesrI   s_bytess_str
s_np_arrayaddressable_devicesrM   r   rp   
out_arrayss              r   _serialize_specsr   (  s	    
M	*
	  |45'


7
#
*
*7
3%xxRYY%:%:%<=*  77			5!45v	>$22
CLL&&(
 8K-3cnnZ(*  
	1	1"
 s   ?D6c                    | j                   d   j                  }t        j                  |j	                         j                  d            }t        |      S )zDeserializes the specs from the serialized specs.

  DO NOT USE THIS FUNCTION EXCEPT FOR THE INTERNAL IMPLEMENTATION OF
  colocated_python. See serialize() for details.
  r   r   )addressable_shardsdatar   	b64decodeitemencoder   )serialized_specs
data_arrayr   s      r   _deserialize_specsr   Q  sG      2215::*			*//+227;	<$	d	r   )r*    Callable[[Any], tuple[Any, Any]]returnr   )r   dict[int, jax.Device])r;   r   r@   rH   r   z
jax.Device)rM   jax.sharding.Meshr   z,tuple[Callable[..., jax.sharding.Mesh], Any])rN   z
np.ndarrayrK   r   rL   r   r   r   )rS   zjax.sharding.NamedShardingr   z5tuple[Callable[..., jax.sharding.NamedSharding], Any])rc   rg   r   z%tuple[Callable[..., DeviceList], Any])rd   zSequence[int]r   rg   )rS   !jax.sharding.SingleDeviceShardingr   z<tuple[Callable[..., jax.sharding.SingleDeviceSharding], Any])r@   rH   rZ   z
str | Noner   r   )r!   r   r   bytes)r   r   r   r   )rI   rg   r   zapi.ShapeDtypeStruct)r   ztree_util.PyTreeDefr   z tuple[api.ShapeDtypeStruct, ...]rI   rg   r   	jax.Array)r   r   r   z<tuple[tree_util.PyTreeDef, tuple[api.ShapeDtypeStruct, ...]])3r   
__future__r   r   ru   collections.abcr   r   r,   r~   	threadingtypingr   rw   ImportErrorrR   jax._srcr   r   r	   r2   jax._src.libr
   xcnumpyrF   rg   localr   r   r"   r$   r.   _srcutilcacher>   rA   rO   rJ   r\   rX   re   rb   rm   rj   r   r   r   r   r   r   r   r   <module>r      s)   0 "   .  	      % ) ]]
- -, '( 51%* d# $D
)
69

 #M
M1M #MAA-0A>AAA #9(9:9 #9@
 #..*. #.$ #/A #LL!+L&L'.T(*


&&&2& & 	&R

A
k	  +s   D3 3D>=D>