
    &`iN                        d dl T d dlmZmZmZ d dlZd dlZd dlZd dlZd dl	Z	d dl
mZmZ  G d de          Z G d de          Z G d	 d
e          Z G d de          Z G d de          Z G d de          Z G d de          ZdZdZdZ G d de          Zi ej        dej        dej        dej        dej        dej        dej         dej!        dej"        d ej#        d!ej$        d"ej%        d#ej&        d$ej'        d%ej(        d&ej)        d'Z* G d( d)e          Z+ G d* d+e          Z,g d,Z- G d- d.e.          Z/ G d/ d0e          Z0 G d1 d2e.          Z1 G d3 d4e.          Z2 G d5 d6e.          Z3 G d7 d8e          Z4 G d9 d:e          Z5da6 e	j7                    Z8d a9 e:            Z;d; Z<d< Z=d= Z>d> Z?d? Z@d@ ZAdA ZBdB ZCdC ZDdD ZEdE ZFdF ZGdG ZHdfdIZIdfdJZJdK ZKdL ZLdM ZMdN ZNdO ZOdP ZPdQ ZQdR ZRdS ZSdT ZTdU ZUdV ZVdW ZWdX ZXdY ZYdZ ZZd[ Z[d\ Z\d] Z]d^e^d_e_d`e_fdaZ`db Zadc Zbdd Zcde ZddS )g    )*)joinrealpathisfileN)IntEnumautoc                       e Zd ZdS )ROCMLError_NotSupportedN__name__
__module____qualname__     }/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/ray/_private/thirdparty/pyamdsmi/pyamdsmi.pyr
   r
   $           Dr   r
   c                       e Zd ZdS )ROCMLError_FunctionNotFoundNr   r   r   r   r   r   (   r   r   r   c                       e Zd ZdS )ROCMLError_LibraryNotFoundNr   r   r   r   r   r   ,   r   r   r   c                       e Zd ZdS )ROCMLError_DriverNotLoadedNr   r   r   r   r   r   0   r   r   r   c                       e Zd ZdS )ROCMLError_UnknownNr   r   r   r   r   r   4   r   r   r   c                       e Zd ZdS )ROCMLError_UninitializedNr   r   r   r   r   r   8   r   r   r   c                   z    e Zd Z e            Z	  e            Z	  e            Z	  e            Z	  e            ZdS )
ROCMLStateN)	r   r   r   r   UNINITIALIZEDINITIALIZEDDISABLED_PYROCML_NOT_AVAILABLEDISABLED_CONFIGDISABLED_LIBRARY_NOT_FOUNDr   r   r   r   r   <   sU        DFFM3$&&K.%)TVV"dffOZ!%44r   r   zlibrocm_smi64.so       c                   R    e Zd ZdZdZdZdZdZdZdZ	dZ
d	ZeZd
ZdZdZdZdZdZdZdS )rsmi_status_tr                           	   
                   N)r   r   r   RSMI_STATUS_SUCCESSRSMI_STATUS_INVALID_ARGSRSMI_STATUS_NOT_SUPPORTEDRSMI_STATUS_FILE_ERRORRSMI_STATUS_PERMISSIONRSMI_STATUS_OUT_OF_RESOURCESRSMI_STATUS_INTERNAL_EXCEPTIONRSMI_STATUS_INPUT_OUT_OF_BOUNDSRSMI_STATUS_INIT_ERRORRSMI_INITIALIZATION_ERRORRSMI_STATUS_NOT_YET_IMPLEMENTEDRSMI_STATUS_NOT_FOUNDRSMI_STATUS_INSUFFICIENT_SIZERSMI_STATUS_INTERRUPTRSMI_STATUS_UNEXPECTED_SIZERSMI_STATUS_NO_DATARSMI_STATUS_UNKNOWN_ERRORr   r   r   r'   r'   P   sv        " #  #& %("&)#  6&)#$'!"% *r   r'   zOperation was successfulzInvalid arguments providedz!Not supported on the given systemzProblem accessing a filezPermission deniedz*Unable to acquire memory or other resourcez An internal exception was caughtz0Provided input is out of allowable or safe rangez)Error occurred during rsmi initializationz3Requested function is not implemented on this setupzItem searched for but not foundz Insufficient resources availablez#Interrupt occurred during executionzUnexpected amount of data readz!No data found for the given inputzUnknown error occurredc                       e Zd ZdZdS )rsmi_init_flags_tr(   N)r   r   r   RSMI_INIT_FLAG_ALL_GPUSr   r   r   rI   rI   y   s        !r   rI   c                   "    e Zd ZdZeZdZdZeZdS )rsmi_memory_type_tr   r(   r)   N)r   r   r   RSMI_MEM_TYPE_FIRSTRSMI_MEM_TYPE_VRAMRSMI_MEM_TYPE_VIS_VRAMRSMI_MEM_TYPE_GTTRSMI_MEM_TYPE_LASTr   r   r   rL   rL   }   s.        ,*r   rL   )VRAMVIS_VRAMGTTc                   $    e Zd ZdefdefdefgZdS )rsmi_retired_page_record_tpage_address	page_sizestatusN)r   r   r   c_uint64c_int_fields_r   r   r   rV   rV      s-        *h'5!#HHHr   rV   c                       e Zd ZdZeZeZdS )rsmi_sw_component_tr   N)r   r   r   RSMI_SW_COMP_FIRSTRSMI_SW_COMP_DRIVERRSMI_SW_COMP_LASTr   r   r   r^   r^      s"        ,+r   r^   c                   *    e Zd Zdefdefdeez  fgZdS )rsmi_frequencies_tnum_supportedcurrent	frequencyN)r   r   r   c_int32c_uint32rZ   RSMI_MAX_NUM_FREQUENCIESr\   r   r   r   rc   rc      s4         '*H%h)AABDHHHr   rc   c                   $    e Zd Zdefdeez  fgZdS )rsmi_pcie_bandwidth_ttransfer_ratelanesN)r   r   r   rc   rh   ri   r\   r   r   r   rk   rk      s-         "45(%==>@HHHr   rk   c                   0    e Zd ZdefdefdefdefdefgZdS )rsmi_process_info_t
process_idpasid
vram_usage
sdma_usagecu_occupancyN)r   r   r   rh   rZ   r\   r   r   r   ro   ro      s=        x((#x(x(*	,HHHr   ro   c                       e Zd ZdZdZdZdS )rsmi_xgmi_status_tr   r(   r)   N)r   r   r   RSMI_XGMI_STATUS_NO_ERRORSRSMI_XGMI_STATUS_ERROR RSMI_XGMI_STATUS_MULTIPLE_ERRORSr   r   r   rv   rv      s"        !"'($$$r   rv   c                   Z    e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
ZdZdZdZdZdZdZdZdZdZdS )rsmi_io_link_typer   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5            r6   N)r   r   r   RSMI_IOLINK_TYPE_UNDEFINEDRSMI_IOLINK_TYPE_HYPERTRANSPORTRSMI_IOLINK_TYPE_PCIEXPRESSRSMI_IOLINK_TYPE_AMBARSMI_IOLINK_TYPE_MIPIRSMI_IOLINK_TYPE_QPI_1_1RSMI_IOLINK_TYPE_RESERVED1RSMI_IOLINK_TYPE_RESERVED2RSMI_IOLINK_TYPE_RAPID_IORSMI_IOLINK_TYPE_INFINIBANDRSMI_IOLINK_TYPE_RESERVED3RSMI_IOLINK_TYPE_XGMIRSMI_IOLINK_TYPE_XGOPRSMI_IOLINK_TYPE_GZRSMI_IOLINK_TYPE_ETHERNET_RDMARSMI_IOLINK_TYPE_RDMA_OTHERRSMI_IOLINK_TYPE_OTHERRSMI_IOLINK_TYPE_NUMIOLINKTYPESRSMI_IOLINK_TYPE_SIZEr   r   r   r{   r{      s        &'&'#&'&'&'&'&'&'&'&'&(&(&(&(&("&(&(&(#&0r   r{   c                 t   | t           v rt           |          S t                                           	 t          d k    rt          	 t          t          |           t           | <   t           |          t                                           S # t          $ r t          w xY w# t                                           w xY w)N)	_rocml_get_function_ptr_cachelib_load_lockacquirerocm_libr   getattrreleaseAttributeErrorr   )names    r   _rocml_get_function_ptrr      s     ,,,,T22 t**	.29(D2I2I)$/06
 		  	. 	. 	.--	. 	s   B )B BB B7c                     t           dk    rt                                           	 t           dk    r	 t          j        dd         dk    rt          d          t                      } t                              |            t          |           a n# t          $ r t          d          w xY wt           dk    rt          d          t                                           dS # t                                           w xY wdS )z'Load ROCm library if not already loadedNr*   winz%Windows platform is not supported yetzROCm library not found)r   r   r   sysplatformr
   _find_lib_rocmcdllLoadLibraryCDLLOSErrorr   r   )path_librocms    r   _load_rocm_libraryr      s    4	$4	O|BQB'50056]^^^ (6'7'7((666#'#5#5 O O O45MNNNOt##45MNNN!!#####M!!####' s#   C# AB C# B++C# #C>c                      t           j                            dd          } t          | dt                     }t          |          r|ndS )zRsearch for librocm and returns path
    if search fails, returns empty string
    	ROCM_PATHz	/opt/rocmzlib/ )osenvirongetr   LIBROCM_NAMEr   )	rocm_pathrocm_lib_paths     r   r   r      sH     
{K88I$9<$9$9::M"=119==r9r   c                      d} 	 t          t          j        ddt          j                            } n# t          j        $ r Y nw xY wt          |           dk    S )zH Returns true if amdgpu is found in the list of initialized modules
    r   z+cat /sys/module/amdgpu/initstate |grep liveT)shellstderrr   )str
subprocesscheck_outputDEVNULLCalledProcessErrorlen)initializeds    r   _driver_initializedr     s~     K*12_gkt~  uG  H  H  H  I  I(   {as   .3 AAc                  ^   t                       t                      rEt                              d          } | dk    r$t	          j        d|            t          d          nt          d          t                                           t          dz  a	t          
                                 dS )zInitialize ROCm binding of SMIr   z ROCm SMI init returned value: %szROCm SMI initialization failedz ROCm driver initilization failedr(   N)r   r   r   	rsmi_initloggingdebugRuntimeErrorr   r   _rocm_lib_refcountr   )ret_inits    r   smi_initializer     s     ?%%a((q==M<hGGG?@@@  =>>> !r   c                     | t           j        k    rdt                      }t                              | t          |                     t          j        d|j        	                                           dS dS )z Returns true if RSMI call status is 0 (success)

    @param device: DRM device identifier
    @param my_ret: Return of RSMI call (rocm_smi_lib API)
    @param metric: Parameter of GPU currently being analyzed
    zROCm RSMI error: %sFT)
r'   r7   c_char_pr   rsmi_status_stringbyrefr   r   valuedecode)my_reterr_strs     r   rsmi_ret_okr   %  sb     222**##FE'NN;;;+W]-A-A-C-CDDDu4r   c                      t          t                                                     t                                           t
          dz  at                                           dS )z4leave the library loaded, but shutdown the interfacer(   N)r   r   rsmi_shut_downr   r   r   r   r   r   r   smi_shutdownr   4  sS    ''))*** !r   c                      t          d          } t                              t          j        | d          }t          |          r| j                                        ndS )z#returns ROCm kernerl driver versionr$   r   )create_string_bufferr   rsmi_version_str_getr^   r`   r   r   r   )ver_strrets     r   smi_get_kernel_versionr   ?  sR    "3''G

'
'(;(OQXZ]
^
^C%0%5%5=7=!!!2=r   c                     t                      }t                              | t          |                    }t	          |          r|j        ndS )z0returns device id of the device as 64bit integer)rZ   r   rsmi_dev_id_getr   r   r   devuidr   s      r   smi_get_device_idr   E  s?    
**C

"
"3c


3
3C#C((0399b0r   c                      t          d          } t                              t          |                     }t	          |          r| j        ndS )zreturns a list of GPU devices r   r   )rh   r   rsmi_num_monitor_devicesr   r   r   )
num_devicer   s     r   smi_get_device_countr   K  sC    !J

+
+E*,=,=
>
>C*3//7:R7r   c                     t          t                    }t                              | |t                    }t	          |          r|j                                        ndS )z returns the name of a GPU devicer   )r   RSMI_MAX_BUFFER_LENGTHr   rsmi_dev_name_getr   r   r   )r   seriesr   s      r   smi_get_device_namer   R  sN    !"899F

$
$S&2H
I
IC$/$4$4<6<   "<r   c                     t                      }t                              | t          |                    }t	          |          r|j        ndS )z0returns unique id of the device as 64bit integerr   )rZ   r   rsmi_dev_unique_id_getr   r   r   r   s      r   smi_get_device_unique_idr   Y  s?    
**C

)
)#uSzz
:
:C#C((0399b0r   c                     t                      }t                              | t          |                    }t	          |          r|j        ndS )z0returns GPU device busy percent of device_id devr   )rh   r   rsmi_dev_busy_percent_getr   r   r   r   busy_percentr   s      r   smi_get_device_utilizationr   _  sC    ::L

,
,S%2E2E
F
FC!,S!1!19<r9r   rR   c                     t                               |          }t                      }t                              | |t          |                    }t          |          r|j        ndS )z-returns used memory of device_id dev in bytesr   )memory_type_lindexrZ   r   rsmi_dev_memory_usage_getr   r   r   )r   typetype_idxusedr   s        r   smi_get_device_memory_usedr   f  sT    ""4((H::D

,
,S(E$KK
H
HC$S))14::r1r   c                     t                               |          }t                      }t                              | |t          |                    }t          |          r|j        ndS )z.returns total memory of device_id dev in bytesr   )r   r   rZ   r   rsmi_dev_memory_total_getr   r   r   )r   r   r   totalr   s        r   smi_get_device_memory_totalr   n  sT    ""4((HJJE

,
,S(E%LL
I
IC%c**25;;2r   c                     t                      }t                              | t          |                    }t	          |          r|j        ndS )z:returns percentage of time any device memory is being usedr   )rh   r    rsmi_dev_memory_busy_percent_getr   r   r   r   s      r   smi_get_device_memory_busyr   v  sC    ::L

3
3C|9L9L
M
MC!,S!1!19<r9r   c                     t                      }t                      }t                              | t	          |          t	          |                    }t          |          r	|j        |fndS )z(returns info about reserved memory pagesr   )rh   rV   r   "rsmi_dev_memory_reserved_pages_getr   r   r   )r   	num_pagesrecordsr   s       r   $smi_get_device_memory_reserved_pagesr   }  s[    

I(**G

5
5c5;K;KUSZ^^
\
\C)4S)9)9AIOW%%rAr   c                     t                      }t                              | t          |                    }t	          |          r|ndS )zDreturns list of possible pcie bandwidths for the device in bytes/secr   )rk   r   rsmi_dev_pci_bandwidth_getr   r   )r   	bandwidthr   s      r   smi_get_device_pcie_bandwidthr    sA    %''I

-
-c53C3C
D
DC#C((099b0r   c                     t                      }t                              | t          |                    }t	          |          r|j        ndS )zreturns unique PCI ID of the device in 64bit Hex with format:
       BDFID = ((DOMAIN & 0xffffffff) << 32) | ((BUS & 0xff) << 8) |
                    ((DEVICE & 0x1f) <<3 ) | (FUNCTION & 0x7)
    r   )rZ   r   rsmi_dev_pci_id_getr   r   r   )r   bdfidr   s      r   smi_get_device_pci_idr    sA    
 JJE

&
&sE%LL
9
9C%c**25;;2r   c                     t                      }t                              | t          |                    }t	          |          r|j        ndS z0returns the NUMA node associated with the devicer   )rh   	reocm_librsmi_topo_numa_affinity_getr   r   r   r   	numa_noder   s      r   !smi_get_device_topo_numa_affinityr    sA    

I

/
/U95E5E
F
FC)#..69??B6r   c                 .   t                      }t                      }t                      }t                              | t          |          t          |          t          |                    }t	          |          r|j        |j        z   |j        z  ndS )z<returns measured pcie throughput for the device in bytes/secr   )rZ   r   rsmi_dev_pci_throughput_getr   r   r   )r   sentrecv
max_pkt_szr   s        r   smi_get_device_pcie_throughputr    su    ::D::DJ

.
.sE$KKteT^N_N_
`
`C;Fs;K;KSDJ#z'777QSSr   c                     t                      }t                              | t          |                    }t	          |          r|j        ndS )z(return PCIe replay counter of the devicer   )rZ   r   rsmi_dev_pci_replay_counter_getr   r   r   )r   counterr   s      r   !smi_get_device_pci_replay_counterr    s?    jjG

2
23g
G
GC',,47=="4r   c                     t          t                    }t                              | t	          |          t                    }t          |          r|j                                        ndS )z+returns the compute partition of the devicer   )r   r   r   rsmi_dev_compute_partition_getr   r   r   r   r   	partitionr   s      r    smi_get_device_compute_partitionr    sV    $%;<<I

1
1#uY7G7GI_
`
`C'23'7'7?9?!!###R?r   c                 V    t                               | |          }t          |          S )z5modifies the compute partition of the selected device)r   rsmi_dev_compute_partition_setr   r  s      r    smi_set_device_compute_partitionr!    s%    

1
1#y
A
ACsr   c                 T    t                               |           }t          |          S )zFreverts the compute partition of the selected device to its boot state)r    rsmi_dev_compute_partition_resetr   r   r   s     r   "smi_reset_device_compute_partitionr%    s#    

3
3C
8
8Csr   c                     t          t                    }t                              | t	          |          t                    }t          |          r|j                                        ndS )z*returns the memory partition of the devicer   )r   r   r   rsmi_dev_memory_partition_getr   r   r   r   r  s      r   smi_get_device_memory_partitionr(    sV    $%;<<I

0
0eI6F6FH^
_
_C'23'7'7?9?!!###R?r   c                 V    t                               | |          }t          |          S )z4modifies the memory partition of the selected device)r   rsmi_dev_memory_partition_setr   r  s      r   smi_set_device_memory_partitionr+    s%    

0
0i
@
@Csr   c                 T    t                               |           }t          |          S )zEreverts the memory partition of the selected device to its boot state)r   rsmi_dev_memory_partition_resetr   r$  s     r   !smi_reset_device_memory_partitionr.    s#    

2
23
7
7Csr   c                     t                      }t                              | t          |                    }t	          |          r|j        ndS r
  )rh   r   rsmi_topo_get_numa_node_numberr   r   r   r  s      r   $smi_get_device_topo_numa_node_numberr1    sA    

I

1
1#uY7G7G
H
HC)#..69??B6r   c                     t                      }t                              | |t          |                    }t	          |          r|j        ndS )z2returns the weight of the link between two devicesr   )rZ   r   rsmi_topo_get_link_weightr   r   r   )dev_srcdev_dstweightr   s       r   smi_get_device_topo_link_weightr7    sA    ZZF

,
,WguV}}
M
MC&s++36<<3r   c                 .   t          | |          d         dk    s
J d            t                      }t                      }t                              | |t	          |          t	          |                    }t          |          r|j        |j        fndS )zreturns the minimum and maximum io link bandwidth between two devices
    API works if src and dst are connected via XGMI and are 1 hop away.
    r   r(   zDevices must be 1 hop awayr   )smi_get_device_link_typerZ   r   rsmi_minmax_bandwidth_getr   r   r   )r4  r5  min_bandwidthmax_bandwidthr   s        r   smi_get_device_minmax_bandwidthr=    s     $GW55a8A===?[===JJMJJM

,
,Wgu]?S?SUZ[hUiUi
j
jC9DS9I9IQM!455rQr   c                     t                      }t                      }t                              | |t	          |          t	          |                    }t          |          r|j        |j        fndS )z9returns the hops and the type of link between two devicesr   )rZ   r{   r   rsmi_topo_get_link_typer   r   r   )r4  r5  hops	link_typer   s        r   r9  r9    s_    ::D!##I

*
*7GU4[[%PYJZJZ
[
[C,7,<,<DDJ	(("Dr   c                     t                      }t                              | |t          |                    }t	          |          r|j        ndS )z.returns true if two devices are p2p accessibler   )c_boolr   rsmi_is_P2P_accessibler   r   r   )r4  r5  
accessibler   s       r   smi_is_device_p2p_accessiblerF    sE    J

)
)'7E*<M<M
N
NC*3//7:R7r   c                     t                      } t                              dt          |                     }t	          |          r| j        dz   }t          |z              t                              t                    t          |                     }t	          |          r fdt          | j                  D             ng S g S )z9returns list of process ids running compute on the systemNr1   c                 *    g | ]}|         j         S r   )rp   ).0i	proc_infos     r   
<listcomp>z2smi_get_device_compute_process.<locals>.<listcomp>  s     HHHA	!'HHHr   )rh   r   rsmi_compute_process_info_getr   r   r   ro   range)	num_procsr   buff_szret2rK  s       @r   smi_get_device_compute_processrR    s    

I

0
0uY7G7G
H
HC3 /B&(7255	55eI6F6FiHXHXYYLWX\L]L]eHHHHy1G1GHHHHcee	r   	device_idproc_idsreturnc                     g }|D ]]}t                      }t                              || t          |                    }t	          |          r|                    |           ^|S )a&  Returns list of process info running compute on the specified device by process IDs.

    Args:
        device_id: The device index to query
        proc_ids: List of process IDs to get info for

    Returns:
        List of process info structures for the specified device and process IDs
    )ro   r   'rsmi_compute_process_info_by_device_getr   r   append)rS  rT  
proc_infosproc_idrK  r   s         r   &smi_get_compute_process_info_by_devicer[    so     J ) )'))	>>w	SXYbScScdds 	)i(((r   c                     t                      }t                              | dt          |                    }t	          |          r
|j        dz  ndS )z&returns average power of device_id devr   gư>r   )rh   r   rsmi_dev_power_ave_getr   r   r   )r   powerr   s      r   smi_get_device_average_powerr_    sG    JJE

)
)#q%,,
?
?C!,S!1!195;r9r   c                     t                      }t                              | t          |                    }t	          |          r|j        ndS )z&returns XGMI error status for a devicer   )rv   r   rsmi_dev_xgmi_error_statusr   r   r   )r   rY   r   s      r    smi_get_device_xgmi_error_statusrb  '  sA    !!F

-
-c5==
A
AC&s++36<<3r   c                 T    t                               |           }t          |          S )z%resets XGMI error status for a device)r   rsmi_dev_xgmi_error_resetr   r$  s     r   smi_reset_device_xgmi_errorre  .  s#    

,
,S
1
1Csr   c                     t                      }t                              | t          |                    }t	          |          r|j        ndS )z!returns XGMI hive ID for a devicer   )rZ   r   rsmi_dev_xgmi_hive_id_getr   r   r   )r   hive_idr   s      r   smi_get_device_xgmi_hive_idri  4  s?    jjG

,
,S%..
A
AC',,47=="4r   )rR   )ectypesos.pathr   r   r   r   r   r   r   	threadingenumr   r   	Exceptionr
   r   r   r   r   r   r   r   r   ri   r[   r'   r7   r8   r9   r:   r;   r<   r=   r>   r@   rA   rB   rC   rD   rE   rF   rG   rsmi_status_verbose_err_outrI   rL   r   	StructurerV   r^   rc   rk   ro   rv   r{   r   Lockr   r   dictr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r!  r%  r(  r+  r.  r1  r7  r=  r9  rF  rR  intlistr[  r_  rb  re  ri  r   r   r   <module>ru     s/  0     * * * * * * * * * * 				      



            
	 	 	 	 	i 	 	 		 	 	 	 	) 	 	 		 	 	 	 	 	 	 		 	 	 	 	 	 	 		 	 	 	 	 	 	 		 	 	 	 	y 	 	 	
5 
5 
5 
5 
5 
5 
5 
5 "   + + + + +E + + +*%'A*,H +-P (*D	
 (*= .0\ 02T 13e +-X 13h ')J /1S ')N -/O %'J  +-E! (" " " " " " " "+ + + + + + + + ,++# # # # # # # #, , , , ,% , , ,D D D D D D D D@ @ @ @ @I @ @ @
, , , , ,) , , ,) ) ) ) ) ) ) )1 1 1 1 1 1 1 1. 	    !%      *$ $ $4: : :       &    > > >1 1 18 8 8= = =1 1 1: : :2 2 2 23 3 3 3: : :B B B1 1 13 3 37 7 7T T T5 5 5@ @ @    @ @ @    7 7 74 4 4R R RE E E8 8 8  c T d    $: : :4 4 4  5 5 5 5 5r   