o
    ?e-                     @   s  d Z ddlmZmZm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 ddlmZ ddlmZ ddlmZ dededededejddfddZ		d+deee  dee deeej ef fddZedg dddddejfdeeeeef   dedeee  dee de dejfd d!Z!ed"g ddddejfdeeeef  ded#eee  dee de dejfd$d%Z"i Z#ed&g d		d+dejd'ee d(ee fd)d*Z$dS ),z%Utilities to help with mesh creation.    )ListOptionalTuple)loggingN)accelerator_util)api)config)layout)tpu_util)context)device)	array_ops)math_ops)	tf_exportnum_global_devicesnum_clients	client_iddevice_typemeshreturnc                 C   sT   t d|| t d| |  t d|  t d|  t d|  d S )NzThis is client %d of %d clientszNumber of global %s devices: %dzGlobal device IDs: %szLocal device IDs: %szLocal devices: %s)r   infoupperglobal_device_idslocal_device_idslocal_devicesr   r   r   r   r    r   d/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/dtensor/python/mesh_util.py_print_context!   s   r   devicesc                 C   s|   | du r|du r
d}t |} | |fS dd | D } |du r#| d j}| | d j kr:tdt|  d| | |fS )zHMakes device specs from local devices names or number of global devices.NCPUc                 S   s   g | ]}t j|qS r   )	tf_device
DeviceSpecZfrom_string.0dr   r   r   
<listcomp>8   s    z&_make_device_specs.<locals>.<listcomp>r   zConflicting devices z and device_type )r   r   r   r   
ValueErrorstr)r   r   r   r   r   _make_device_specs-   s   


r)   z experimental.dtensor.create_mesh)v1 	mesh_dims	mesh_nameuse_xla_spmdc                    s  t ||\}}tjt ddd  fdd|D }| du r&dt|fg} nt| dkr@| d d dkr@| d d t|f| d< d	d | D }d
d | D }t|t|krctdt| d| t	t|
|}t| }	tj|||	|||d}
tt|dd||
d |
S )a  Creates a single-client mesh.

  If both `mesh_dims` and `devices` are specified, they must match each otehr.
  As a special case, when all arguments are missing, this creates a 1D CPU mesh
  with an empty name, assigning all available devices to that dimension.

  Args:
    mesh_dims: A list of (dim_name, dim_size) tuples. Defaults to a single
      batch-parallel dimension called 'x' using all devices. As a special case,
      a single-element mesh_dims whose dim_size is -1 also uses all devices.
    mesh_name: Name of the created mesh. Defaults to ''.
    devices: String representations of devices to use. This is the device part
      of tf.DeviceSpec, e.g. 'CPU:0'. Defaults to all available logical devices.
    device_type: If `devices` is missing, the type of devices to use. Defaults
      to 'CPU'.
    use_xla_spmd: Boolean when True, will use XLA SPMD instead of
      DTensor SPMD.

  Returns:
    A single-client mesh created from specified or default arguments.
  r   ZjobZreplicataskc                       g | ]}  |qS r   Zmake_merged_specr#   Z
local_specr   r   r&   a       zcreate_mesh.<locals>.<listcomp>Nx   c                 S      g | ]}|d  qS )r   r   r#   r   r   r   r&   i       c                 S   r8   )r6   r   r#   r   r   r   r&   j   r9   zlength of devices (3) must be equal to total size of the mesh of shape 	dim_namesr   r   r   r-   r.   r   )r)   r!   r"   r   job_namelennpprodr'   arangereshaperaveltolistr	   Meshr   )r,   r-   r   r   r.   device_specsr<   shaper   r   r   r   r3   r   create_meshC   s>   rH   z,experimental.dtensor.create_distributed_meshr   c              	      s  t |  \}}t std|r)| dkr)|dur)td|  d|  dt||\}}| dv rtjt	 dt
 d	  fd
d|D }t|t  }t||krntdt| dt  d| d| t||}	t|	 }
t|t
  }|
||t|  }tj||	||||d}t|t t
 || |S | dkrtj||||d}tt|t t
 || |S td| d)a  Creates a distributed mesh.

  This is similar to `create_mesh`, but with a different set of arguments to
  create a mesh that spans evenly across a multi-client DTensor cluster.

  For CPU and GPU meshes, users can choose to use fewer local devices than what
  is available `local_devices`.

  For TPU, only meshes that uses all TPU cores is supported by the DTensor
  runtime.

  Args:
    mesh_dims: A list of (dim_name, dim_size) tuples.
    mesh_name: Name of the created mesh. Defaults to ''.
    local_devices: String representations of devices to use. This is the device
      part of tf.DeviceSpec, e.g. 'CPU:0'. Defaults to all available local
      logical devices.
    device_type: Type of device to build the mesh for. Defaults to 'CPU'.
      Supported values are 'CPU', 'GPU', 'TPU'.6
    use_xla_spmd: Boolean when True, will use XLA SPMD instead of
      DTensor SPMD.

  Returns:
    A mesh that spans evenly across all DTensor clients in the cluster.
  zYAccelerators are uninitialized, please run dtensor.initialize_accelerator_system() first.ZTPUNzDo not specify devices for z- meshes. Using a partial list of devices for z is not supported.)r    ZGPUr   r/   c                    r1   r   r2   r#   r3   r   r   r&      r4   z+create_distributed_mesh.<locals>.<listcomp>zGlobal number of devices (z per client * z clients = r:   r;   )Zmesh_dim_namesZ
mesh_shaper-   r.   zDevice type z is not CPU, GPU or TPU)zipr   Zis_initializedr'   r   r)   r!   r"   r   r=   r   r>   r   r?   r@   rA   rB   rC   rD   r	   rE   r   r
   Zcreate_tpu_meshr   )r,   r-   r   r   r.   r<   rG   rF   r   r   Z	flattenedZ	start_idxr   r   r   r3   r   create_distributed_mesh   st    
rJ   zexperimental.dtensor.barrierbarrier_nametimeout_in_msc                 C   s   |du rd}t d| t  tddgt|   }t	|g| 
  t| j| }t|}|| jkr@td|| jt  t jrj|du rOd}t|d}|d t|< | d	| }t || t d
| dS )a  Runs a barrier on the mesh.

  Upon returning from the barrier, all operations run before the barrier
  would have completed across all clients. Currently we allocate a fully
  sharded tensor with mesh shape and run an all_reduce on it.

  Example:

  A barrier can be used before application exit to ensure completion of pending
  ops.

  ```python

  x = [1, 2, 3]
  x = dtensor.relayout(x, dtensor.Layout.batch_sharded(mesh, 'batch', 1))
  dtensor.barrier(mesh)

  # At this point all devices on all clients in the mesh have completed
  # operations before the barrier. Therefore it is OK to tear down the clients.
  sys.exit()
  ```

  Args:
    mesh: The mesh to run the barrier on.
    barrier_name: The name of the barrier. Mainly used for logging purpose.
    timeout_in_ms: The timeout of the barrier in ms. If omitted, blocks
      indefinitely till the barrier is reached from all clients.
  Nz	(barrier)zentering barrier before op: %sg      ?r6   zMGlobal barrier produced wrong mesh size : {0} while mesh has actualsize : {1}i \&r   :z8finished running barrier across all clients after op: %s)r   r   r   Z
async_waitr   rB   r>   rG   r   packZnum_local_devicesr	   ZLayoutr<   r   Z
reduce_sumsizer'   formatZcoordination_service_BARRIER_DICT
setdefaultZwait_at_barrier)r   rK   rL   	componentZonesZ	mesh_sizeZ	num_callsZ
barrier_idr   r   r   barrier   s2    



rT   )NN)%__doc__typingr   r   r   Zabslr   numpyr?   Ztensorflow.dtensor.pythonr   r   r   r	   r
   Ztensorflow.python.eagerr   Ztensorflow.python.frameworkr   r!   Ztensorflow.python.opsr   r   Z tensorflow.python.util.tf_exportr   intr(   rE   r   r"   r)   ZUSE_XLA_SPMDboolrH   rJ   rQ   rT   r   r   r   r   <module>   s   





>
b

