
    ukiQ                    x   d Z ddlmZ ddlZddlmZmZ ddlmZ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Ze	 	 	 	 dd
       Ze	 	 	 	 dd       Zd Z ej*                  dd      	 	 	 	 dd       Z ej*                  dd      	 	 	 	 dd       Z ej*                  dd      dd       ZddZddZy)zColocated Python top-level API.    )annotationsN)Anyoverload)CallableSequence)api_util)util)make_callable)
wrap_classc                     y N devices_or_meshs    `/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/experimental/colocated_python/api.pycolocated_cpu_devicesr               c                     y r   r   r   s    r   r   r   %   r   r   c                    t        | t        j                  j                        rt	        |       S t        | t
              st        |       } 	 t        |       S # t        t        f$ r t        |       cY S w xY w)a  Finds devices or a mesh that has CPU devices colocated with the given devices or mesh.

  An accelerator device often accompanies a CPU device that is on the same host.
  Furthermore, when a single host has multiple accelerator devices, there can be
  multiple CPU devices, each of which is associated with one of the accelerator
  devices with a 1:1 correspondence.

  This function finds the colocated CPU devices for the given devices or mesh.
  When the input is a mesh, the returned value is another mesh that has the same
  shape as the input mesh but has colocated CPU devices. If an input device is
  already a CPU device, it is returned as-is.

  It preserves ordering. The output CPU device at index i is associated with the
  input accelerator device at index i.

  Args:
    devices_or_mesh: A tuple of devices or a mesh.

  Returns:
    A tuple of devices or a mesh that has the colocated CPU devices.
  )

isinstancejaxshardingMesh_colocated_cpu_mesh_cachedtuple_colocated_cpu_devices_cached
ValueErrorAttributeError5_colocated_cpu_devices_cached_fallback_to_cpu_backendr   s    r   r   r   ,   sk    , !2!23%o66	OU	+O,O(99
n	% @ s   
A A43A4i   F)max_sizetrace_context_in_keyc           	        t        j                  t              }| d   j                  j	                         D ]0  }|j
                  dk(  s||j                     j                  |       2 |st        d      g }| D ]a  }||j                     }|st        d| d      t        |      dkD  rt        d| dt        |       d	|       |j                  |d          c |S )
Nr   cpuzNo CPU devices foundzDevice z has no colocated devices   z$Ambiguous colocated devices; device z has z colocated devices: f)
collectionsdefaultdictlistclient_get_all_devicesdevice_kindcolocation_idappendr   len)devicescpu_devices_by_colocation_iddevicer   matchess        r   r   r   O   s    "-!8!8!>
!!224 HfU""6#7#78??GH 
&
+
,, 	-f*6+?+?@G(ABCC	W	0 9'l^0	;    ,	- 
r   c                   | d   j                   dk(  r:| d   j                  j                         D cg c]  }|j                   dk(  r| }}nt        j                  d      }t        t        j                               D ci c]  \  }}|j                  | }}}| d t        t        |      t        |              }|D cg c]  }|||j                         c}S c c}w c c}}w c c}w )Nr   r$   )backend)	r+   r)   r*   r   r/   	enumerateidminr.   )r/   dcpu_backend_devicesir1   device_index_mapavailable_devicess          r   r    r    h   s     QZu$ '.aj&7&7&H&H&J 6mmu4  6 6
 ++e44=ckkm4LMyq&fiilMMKC(;$<c'l KL;L
67*14401
 6 N
s   CC#C)c                   t        t        | j                  j                              }t        j
                  j                  t        j                  |      j                  | j                        | j                  | j                        S )zSReturns a CPU mesh that is similar to the given mesh but has colocated CPU devices.)
axis_types)r   r   r/   flatr   r   r   nparrayreshape
axis_sizes
axis_namesr>   )meshflat_cpu_devicess     r   r   r      sd     +51B1B+CD			hh ((9
oo 
 
 r   c                h    t        | t        j                  |       t        j                  |             S )a1  Executes the given Python function on the same devices as the arguments.

  The returned colocated Python callable lets the user run a serializable Python
  function on the same devices as the arguments, potentially on remote hosts.

  Python callable implements `specialize` and `__call__` methods. See their
  docstrings for details and https://docs.jax.dev/en/latest/notebooks/colocated-python.html
  for examples.

  Args:
    fun: An original function to wrap as an I/O callable.

  Returns:
    Colocated Python callable with no initial specialization.
  )r
   r   fun_sourceinfofun_signature)funs    r   colocated_pythonrK      s.      
	8""3')?)?)D
 r   c                @    t        | t        j                  |             S )a  Creates a wrapper class that executes the given Python class methods on the same devices as the arguments.

  The wrapper class exposes the returned type's methods, and can be instantiated
  on JAX. An actual object will be instantiated on the host of the devices of
  the arguments' when a method of the wrapper instance is called for the first
  time.

  The actual object will persist while the wrapper object is alive, and will be
  destroyed asynchronously when the wrapper object is destroyed. Note that if
  the wrapper object is destroyed immediately without any method call, actual
  objects will not be created.

  Args:
    cls: The class to wrap as a colocated Python object.

  Returns:
    Wrapper class.
  )r   r   rH   )clss    r   colocated_python_classrN      s    & 
C005	66r   )r   Sequence[jax.Device]returnrO   )r   jax.sharding.MeshrP   rQ   )r/   ztuple[jax.Device, ...]rP   rO   )rE   rQ   rP   rQ   )rJ   zCallable[..., Any])rM   type[object]rP   rR   )__doc__
__future__r   r&   typingr   r   collections.abcr   r   r   jax._srcr   r	   &jax.experimental.colocated_python.funcr
   %jax.experimental.colocated_python.objr   numpyr@   r   cacher   r    r   rK   rN   r   r   r   <module>r\      s   & "    . 
   @ <  
) 
 
& 
 F T6# 70 T6# 7, T6
 7
*7r   