
    BVhT                        d Z ddlZddlZddlmZ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 g dggZd	 Z ed
       G d dej(                               Z ed       G d de             Zdedededeeeeef      fdZdedededeeeeef      fdZdddej6                  fdedeej8                     deej8                     dededefdZy)z Library of TPU helper functions.    N)ListOptionalTuple)
tf_logging)Topology)numpy_compat)	tf_export)r   r   r   r   c                    i }t        | j                  d         D ]q  }t        | j                  d         D ]T  }| ||ddf   }|j                  |      }||vri ||<   |||   vrt               ||   |<   ||   |   j	                  |       V s i }|j                         D ]2  \  }}	i }
|	j                         D ]  \  }}t        |      |
|<    |
||<   4 |S )zDComputes a nested dict which maps task and logical core to replicas.r      N)rangeshapetask_ordinal_at_coordinatessetadditemssorted)core_assignmenttopologytask_and_cores_to_replicasreplicalogical_corecoordinatestask_idtask_to_sorted_replica_idtaskcore_to_replicascore_to_sorted_replicascorereplicass                W/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/tpu/device_assignment.py#_compute_task_and_cores_to_replicasr!       s$   !,,Q/0 	Ego33A67 E#G\1$<=k44[Ag	2	2.0"7+	7@	@<?E"7+L9 ),7;;GDE	E ! : @ @ B >d *002 7h&,X&6d#7 '>d#> 
#"    z tpu.experimental.DeviceOrderModec                       e Zd ZdZdZdZdZy)DeviceOrderModezFThe way of determining device orders when computing device assignment.r   r      N)__name__
__module____qualname____doc__AUTORINGMESH r"   r    r$   r$   9   s    N 
$	
$	
$r"   r$   z!tpu.experimental.DeviceAssignmentc                      e Zd ZdZdedej                  fdZedefd       Z	ede
fd       Zede
fd       Zedej                  fd	       Zd
e
de
defdZde
de
dee
   fdZdd
e
de
de
fdZ	 	 	 dd
e
de
dee   defdZ	 	 	 dd
e
de
dee   defdZedddej2                  fdedeej                     deej                     de
dedd fd       Zy)DeviceAssignmentzMapping from logical cores in a computation to the physical TPU topology.

  Prefer to use the `DeviceAssignment.build()` helper to construct a
  `DeviceAssignment`; it is easier if less flexible than constructing a
  `DeviceAssignment` directly.
  r   r   c                 &   t        |t              s#t        dj                  t	        |                  t        j                  |t        j                        }|| _	        |j                  dk7  rt        d|j                         |j                  d   | _        |j                  d   | _        |j                  d   |j                  k7  r%t        d|j                   d	|j                         || _        t!        | j                  |      | _        y
)a  Constructs a `DeviceAssignment` object.

    Args:
      topology: A `Topology` object that describes the physical TPU topology.
      core_assignment: A logical to physical core mapping, represented as a
        rank 3 numpy array. See the description of the `core_assignment`
        property for more details.

    Raises:
      ValueError: If `topology` is not `Topology` object.
      ValueError: If `core_assignment` is not a rank 3 numpy array.
    z*topology must be a Topology object, got {}dtype   z8core_assignment must be a rank 3 numpy array, got shape r   r   zAcore_assignment.shape[-1] must have size equal to topology rank (z), got core_assignment.shape=N)
isinstancer   
ValueErrorformattyper   
np_asarraynpint32	_topologyndimr   _num_replicas_num_cores_per_replica	mesh_rank_core_assignmentr!   _task_and_cores_to_replicas)selfr   r   s      r    __init__zDeviceAssignment.__init__N   s    h)CJJ
x.  "--oRXXNODNq  $$3$9$9#:< = = )..q1D"1"7"7":DR H$6$66%%& '##2#8#8"9;< <
 ,D'Jx()D$r"   returnc                     | j                   S )z-A `Topology` that describes the TPU topology.)r<   rC   s    r    r   zDeviceAssignment.topologys   s     >>r"   c                     | j                   S )z The number of cores per replica.)r?   rG   s    r    num_cores_per_replicaz&DeviceAssignment.num_cores_per_replicax   s     &&&r"   c                     | j                   S )z*The number of replicas of the computation.)r>   rG   s    r    num_replicaszDeviceAssignment.num_replicas}   s     r"   c                     | j                   S )zThe logical to physical core mapping.

    Returns:
      An integer numpy array of rank 3, with shape
      `[num_replicas, num_cores_per_replica, topology_rank]`. Maps
      (replica, logical core) pairs to physical topology coordinates.
    )rA   rG   s    r    r   z DeviceAssignment.core_assignment   s        r"   r   r   c                 <    t        | j                  ||ddf         S )z<Returns the physical topology coordinates of a logical core.N)tupler   )rC   r   r   s      r    r   zDeviceAssignment.coordinates   s    %%g|Q&>?@@r"   r   c                 x    	 | j                   |   |   S # t        $ r t        dj                  ||            w xY w)at  Lookup replica ids by task number and logical core.

    Args:
      task_id: TensorFlow task number.
      logical_core: An integer, identifying a logical core.
    Returns:
      A sorted list of the replicas that are attached to that task and
      logical_core.
    Raises:
      ValueError: If no replica exists in the task which contains the logical
      core.
    z?Can not find any replica in task: {} contains logical_core: {} )rB   KeyErrorr6   r7   )rC   r   r   s      r    lookup_replicasz DeviceAssignment.lookup_replicas   sH    )--g6|DD )
K
&,
') ))s    %9c                 \    | j                  ||      }| j                  j                  |      S )zAReturns the ordinal of the TPU device assigned to a logical core.)r   r<   !tpu_device_ordinal_at_coordinates)rC   r   r   r   s       r    tpu_ordinalzDeviceAssignment.tpu_ordinal   s)    ""7L9K>>;;KHHr"   Njobc                 `    | j                  ||      }| j                  j                  ||      S )z2Returns the CPU device attached to a logical core.rU   )r   r<   cpu_device_name_at_coordinatesrC   r   r   rU   r   s        r    host_devicezDeviceAssignment.host_device   0    
 ""7L9K>>88#8NNr"   c                 `    | j                  ||      }| j                  j                  ||      S )z>Returns the name of the TPU device assigned to a logical core.rW   )r   r<   tpu_device_name_at_coordinatesrY   s        r    
tpu_devicezDeviceAssignment.tpu_device   r[   r"   r   computation_shapecomputation_striderK   device_order_modec                 "    t        |||||      S )N)r   r_   r`   rK   ra   )device_assignment)clsr   r_   r`   rK   ra   s         r    buildzDeviceAssignment.build   s      +-!+ r"   )r   r   )r   r   N)r&   r'   r(   r)   r   r:   ndarrayrD   propertyr   intrI   rK   r   r   r   r   rQ   rT   r   strrZ   r^   classmethodr$   r*   re   r-   r"   r    r/   r/   E   s   #)x #)"** #)J    'S ' ' C   !rzz ! !A AC AE A)S ) )S	 )(I I IC I "#&''+OO #O  }O 14O !"%&&*OO"O smO 03O  1515+:+?+? ""**- #2::.	
  )  r"   r/   x_sizey_sizez_coordrE   c                 0   g }t        |dz        D ]Y  }t        d|       D ]  }|j                  |d|z  |f        t        | dz
  dd      D ]  }|j                  |d|z  dz   |f        [ t        |dz
  dd      D ]  }|j                  d||f        |S )a  Ring-order of a X by Y mesh, with a fixed Z coordinate.

  For example, in a 4x4 mesh, this returns the following order.
    0 -- 1 -- 2 -- 3
    |    |    |    |
    15-- 6 -- 5 -- 4
    |    |    |    |
    14-- 7 -- 8 -- 9
    |    |    |    |
    13-- 12-- 11-- 10

  Note that chip 0 is not included in the output.

  Args:
    x_size: An integer represents the mesh size in the x-dimension. Must be
      larger than 1.
    y_size: An integer represents the mesh size in the y-dimension. Must be
      larger than 1.
    z_coord: An integer represents the z-coordinate to use for the chips in the
      ring.

  Returns:
    A list of (x,y,z) triples in ring order.
  r%   r   r   r4   )r   append)rk   rl   rm   retijs         r    _open_ring_2drs      s    4 	#1 *a1f &	jj!QUG$%&6A:q"% *	jj!QUQY()**
 !Q#  aJJ1g 	*r"   z_sizec                    | dk(  r!|dk(  rt        |      D cg c]  }dd|f	 c}S | dk(  r!|dk(  rt        |      D cg c]  }d|df	 c}S |dk(  r!|dk(  rt        |       D cg c]  }|ddf	 c}S | dkD  r| dz  dk7  s|dkD  r|dz  dk7  s|dkD  re|dz  dk7  r]t        j                  d       g }t        |      D ]6  t        |      D ]&  |j                  fdt        |       D               ( 8 |S dg}|dk(  r|j                  t	        | |d             |S |dk(  r(dg}|j                  d t	        | |d      D               |S | dk(  r(dg}|j                  d t	        ||d      D               |S dg}t        d|      D ]C  }t	        | ||      }|dz  dk(  r|j                  |       *|j                  t        |             E t        |dz
  dd	      D ]  }|j                  dd|f        |S c c}w c c}w c c}w )
a  Ring-order of a X by Y by Z mesh.

  Constructs the 3d ring from 2d rings that are stacked in the Z dimension and
  joined in one corner.

  z == 0:
    0 -- 1 -- 2 -- 3
    |    |    |    |
    15 - 6 -- 5 -- 4
    |    |    |    |
    14 - 7 -- 8 -- 9
    |    |    |    |
    13 - 12 - 11 - 10
  z == 1:
    63 - 30 - 29 - 28
    |    |    |    |
    16 - 25 - 26 - 27
    |    |    |    |
    17 - 24 - 23 - 22
    |    |    |    |
    18 - 19 - 20 - 21
  z == 2:
    62 - 31 - 32 - 33
    |    |    |    |
    45 - 36 - 35 - 34
    |    |    |    |
    44 - 37 - 38 - 39
    |    |    |    |
    43 - 42 - 41 - 40
  z == 3:
    61 - 60 - 59 - 58
    |    |    |    |
    46 - 55 - 56 - 57
    |    |    |    |
    47 - 54 - 53 - 52
    |    |    |    |
    48 - 49 - 50 - 51

  Args:
    x_size: An integer represents the mesh size in the x-dimension. Must be
      larger than 1.
    y_size: An integer represents the mesh size in the y-dimension. Must be
      larger than 1.
    z_size: An integer represents the mesh size in the z-dimension. Must be
      larger than 1.  For example, in a 4x4x4 mesh, this returns the following
      order.

  Returns:
    A list of (x,y,z) triples in ring order.
  r   r   r%   zOdd dimensionc              3   (   K   | ]	  }|f  y wNr-   ).0xyzs     r    	<genexpr>z_ring_3d.<locals>.<genexpr>7  s     4Aq!94s   )r   r   r   c              3   .   K   | ]  \  }}}|||f  y wrw   r-   )rx   ry   r{   rz   s       r    r|   z_ring_3d.<locals>.<genexpr>C       KYaA1ayK   c              3   .   K   | ]  \  }}}|||f  y wrw   r-   )rx   rz   r{   ry   s       r    r|   z_ring_3d.<locals>.<genexpr>G  r~   r   r4   )r   loggingwarningextendrs   reversedro   )rk   rl   rt   rq   rp   rrz   r{   s         @@r    _ring_3dr      s#   l q[Vq[$V}-!Q1I--q[Vq[$V}-!Q1I--q[Vq[$V}-!Q1I-- qjVaZ1_&1**01*/vz?EzQOOO$
C6] 5V} 5!

4eFm4455 J 
# q[JJ}VVQ/0Jq[+CJJK-*JKKJq[+CJJK-*JKKJ 
#F affa(A1uz	jjm	jj! !Q# aJJ1ay	*Y .--s   G9 G>&Hr   r   r_   r`   rK   ra   c           	        2 t        | t              rt        |       } t        | t              st        dt	        |              t        | j                        2| j                  }|*t        j                  dg2z  t        j                        }n%t        j                  |t        j                        }|*t        j                  dg2z  t        j                        }n%t        j                  |t        j                        }|j                  2fk7  rt        d2 d|j                         |j                  2fk7  rt        d2 d|j                         t        |dk        rt        d	j                  |            t        |dk        rt        d
j                  |            ||z  }t        ||kD        rt        dj                  ||            ||z  }||z  }t        j                  |      }	||	kD  rt        dj                  ||	|||            d }
| j                   j"                  dk(  r:dg2z  }|dkD  r|}2}t%        2fdt'        |      D              D ]T  \  }}|2z   dz
  2z  }t)        t+        j,                  |d|z  z              }t/        ||      ||<    |
|||         }|dz  }V |dk(  r|dk(  sJ t        j0                  |2gdt        j                        }2dk(  xr, |d   |d   k(  xr t        j                  |      dk(  xr ||	k(  }|t2        j4                  k7  r3|t2        j6                  k(  r|st        d      |t2        j6                  k(  }|rg }t9        |d   |d   |d         }t9        |d   |d   |d         }t;        |      D ]  }||   \  }}}g }t;        t        j                  |            D ]O  }|||d   z     \  }}}||d   z  |z   } ||d   z  |z   }!||d   z  |z   }"||d   z  }#|j=                  | |!|"|#g       Q |j=                  |        nt;        |      D ]y  }|}$g }%t        j>                  |d   g|dd g      D ]  }&|%j=                  |$|&z         |$|&z  }$ t        j>                  |%dd |%d   gg      }'|'|z  }(|'|z  })|(|z  |)z   ||ddf<   { t;        2      D cg c]%  }t        j@                  d||   ||   z  ||         ' }*}t        j>                  t        jB                  |*ddiD cg c]  }|dt        jD                  f    c}d      }*|*jG                  d2f      }*|*|ddt        jD                  ddf   z   }nt        j                  |      dk(  sJ |t        j                  |      z  | jH                  | jJ                  z  k  sJ | jL                  }+g }t        j                  |      },t;        |      D ]d  }-g }.t;        |,      D ]A  }|-|,z  |z   }/|/| jJ                  z  }0|/| jJ                  z  }1|.j=                  |+|0|1ddf          C |j=                  |.       f tO        | |      S c c}w c c}w )a  Computes a device_assignment of a computation across a TPU topology.

  Attempts to choose a compact grid of cores for locality.

  Returns a `DeviceAssignment` that describes the cores in the topology assigned
  to each core of each replica.

  `computation_shape` and `computation_stride` values should be powers of 2 for
  optimal packing.

  Args:
    topology: A `Topology` object that describes the TPU cluster topology. To
      obtain a TPU topology, evaluate the `Tensor` returned by
      `initialize_system` using `Session.run`. Either a serialized
      `TopologyProto` or a `Topology` object may be passed. Note: you must
        evaluate the `Tensor` first; you cannot pass an unevaluated `Tensor`
        here.
    computation_shape: A rank 1 int32 numpy array with size equal to the
      topology rank, describing the shape of the computation's block of cores.
      If None, the `computation_shape` is `[1] * topology_rank`.
    computation_stride: A rank 1 int32 numpy array of size `topology_rank`,
      describing the inter-core spacing of the `computation_shape` cores in the
      TPU topology. If None, the `computation_stride` is `[1] * topology_rank`.
    num_replicas: The number of computation replicas to run. The replicas will
      be packed into the free spaces of the topology.
    device_order_mode: An enum of `DeviceOrderMode` class which indicates
      whether to assign devices to form rings or meshes, or let the library to
      choose.

  Returns:
    A DeviceAssignment object, which describes the mapping between the logical
    cores in each computation replica and the physical cores in the TPU
    topology.

  Raises:
    ValueError: If `topology` is not a valid `Topology` object.
    ValueError: If `computation_shape` or `computation_stride` are not 1D int32
      numpy arrays with shape [3] where all values are positive.
    ValueError: If computation's replicas cannot fit into the TPU topology.
  )
serializedz)`topology` is not a Topology object; got Nr   r1   z#computation_shape must have shape [z]; got z$computation_stride must have shape [z<computation_shape must be positive; got computation_shape={}z>computation_stride must be positive; got computation_stride={}z>computation footprint {} does not fit in TPU topology shape {}zprequested {} replicas but only {} replicas with shape {} and computation_stride {} fit in a TPU mesh of shape {}c                     | |z   dz
  |z  S )Nr   r-   )nms     r    ceil_of_ratioz(device_assignment.<locals>.ceil_of_ratio  s    EAI!r"   r   c              3   8   K   | ]  \  }}||d z   z  f  yw)r   Nr-   )rx   rq   ry   topology_ranks      r    r|   z$device_assignment.<locals>.<genexpr>  s-      D%1 Q- 79 Ds   g      ?r4      zdevice_order_mode=DeviceOrderMode.RING is not compatible with the 3D tiling current topology.  Try setting device_order_mode=DeviceOrderMode.AUTOr%   indexingij.)axis)r   )(r5   bytesr   r6   r8   len
mesh_shaper:   arrayr;   r   r9   r   anyr7   prodmissing_devicessizer   	enumeraterh   mathceilminfullr$   r*   r+   r   r   ro   concatenatearangemeshgridnewaxisreshape	num_tasksnum_tpus_per_taskdevice_coordinatesr/   )3r   r_   r`   rK   ra   r   computation_footprintblock_countsreplica_countsmax_replicasr   replica_shaperemaining_replicasremaining_dimsry   nirq   target_sizereplica_offsetsenable_3d_tiling
assignment
inner_ring
outer_ringr   outer_xouter_youter_zper_replica_assignmentindexinner_xinner_yinner_zpxpypzpitposdimreplica_posouterinnerindicesr   devices_per_replicarindexreplica_assignment
logical_idr   devicer   s3                                                     @r    rc   rc   W  s   ` % 8,H	Hh	'

3DN3CD  h))*-""*!}!4BHHE$// 1#"5RXXF%00"((  00

-m_ = &&'	)  -!11

.}o >!''(	* 
 		Q	
FMM	    		a	 
HOO	 ! !
 ,.@@		+,
HOO!:	/0 0
 44,"44.(,L 
	>>Df,(9;M?  ""a'C-'Ma'$n"  D)2>)BD E %!R-!#}4$))$6~9M$NOP{A.a*+=}Q?OP!  1$1)<<< gg|];RrxxPO 	 	)"B/	)GG&'1,	) L(	  O000	o22	2;K5
 	

 +o.B.BBj-a02CA2F-a02jM!,mA.>)!,.j <( 
2'$.w$7!'!#277#456 	:E&0*R.1H&I
#'7G*1--7"*1--7"*1--7"z"~%"
 
'
'RR(8
9	: 	01
2 <( L'>>M"$5#6cr8J"KL 	C
**QW

)!	 nnc!"gAx%89 1100&+.C&Ce&K
#L$ 5:-4H/0 ))A(+.@.CC&q)+g  '){{G'Kd'K
L!1S"**_
Lg ] 34g_Q

A-=>>j 77%&!+++"'' &0083M3MMN N N "44J''"34% 	,,- G%11E9
X777h888!!"4T61_"EFG *+	, 
(J	??E
 Ms   *Y%Y*)r)   enumr   typingr   r   r   numpyr:   tensorflow.python.platformr   r   tensorflow.python.tpu.topologyr   tensorflow.python.utilr    tensorflow.python.util.tf_exportr	   SINGLE_CORE_ASSIGNMENTr!   IntEnumr$   objectr/   rh   rs   r   r*   rf   rc   r-   r"   r    <module>r      s_   '   ( (  < 3 / 6 (.) #2 -.dll  / ./Cv C 0CL"# "s ""#'c3m(<#="JcS c# cc!%S#"67cP /3/3)8)=)=h@h@

+h@ !,h@ 	h@
 'h@ h@r"   