
    0Fie*                    V   d dl mZ d dlZd dlmZmZ d dlmZ d dlm	Z	 d dl
mZ d dlZ	 d dlZn# e$ r dZY nw xY w G d de          Z G d	 d
e	          Z G d de	          Zeej        nej        a	 da	 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 )    )annotationsN)IntEnumauto)uname)
NamedTuple)parsec                      e Zd Z e            Z	  e            Z	  e            Z	  e            Z	  e            Z	  e            Z	dS )	NVMLStateN)
__name__
__module____qualname__r   UNINITIALIZEDINITIALIZEDDISABLED_PYNVML_NOT_AVAILABLEDISABLED_CONFIGDISABLED_LIBRARY_NOT_FOUND DISABLED_WSL_INSUFFICIENT_DRIVER     <lib/python3.11/site-packages/distributed/diagnostics/nvml.pyr
   r
      sd        DFFM2$&&K-$(DFF!dffOX!%2'+tvv$VVr   r
   c                  :    e Zd ZU dZded<   dZded<   dZded<   dS )CudaDeviceInfoNzbytes | Noneuuidz
int | Nonedevice_index	mig_index)r   r   r   r   __annotations__r   r   r   r   r   r   r   !   sE         D#L#### I      r   r   c                  (    e Zd ZU ded<   dZded<   dS )CudaContextboolhas_contextNzCudaDeviceInfo | Nonedevice_info)r   r   r   r   r!   r   r   r   r   r   '   s/         )-K------r   r   z512.15c                 d    t           t          j        k    ot          t	          j                    k    S )z&Is pynvml initialized on this process?)
NVML_STATEr
   r   NVML_OWNER_PIDosgetpidr   r   r   is_initializedr'   ;   s     ..P>RY[[3PPr   c                 ,    dt                      j        v S )zCheck if we are in Windows Subsystem for Linux; some PyNVML queries are not supported there.
    Taken from https://www.scivision.dev/python-detect-wsl/
    zmicrosoft-standard)r   releaser   r   r   _in_wslr*   @   s      577?22r   c                    t           t          j        t          j        t          j        t          j        hv rdS t           t          j        k    rt          t          j	                    k    rdS t           t          j
        k    r-t          j                            d          st          j        a dS t           t          j        k    rt          t          j	                    k    st           t          j
        k    r	 t          j                     n9# t          j        t          j        t          j        f$ r t          j        a Y dS w xY wt'                      rVt)          t          j                                                              t)          t.                    k     rt          j        a dS ddlm}  t          j        a t          j	                    a |              dS t5          dt           dt          d          )zIdempotent (per-process) initialization of PyNVML

    Notes
    -----

    Modifies global variables NVML_STATE and NVML_OWNER_PIDNzdistributed.diagnostics.nvmlr   add_gpu_metricsz+Unhandled initialisation state (NVML_STATE=z, NVML_OWNER_PID=))r#   r
   r   r   r   r   r   r$   r%   r&   r   daskconfiggetpynvmlnvmlInitNVMLError_LibraryNotFoundNVMLError_DriverNotLoadedNVMLError_Unknownr*   parse_versionnvmlSystemGetDriverVersiondecodeMINIMUM_WSL_VERSIONdistributed.workerr-   RuntimeErrorr,   s    r   	init_oncer=   G   s    /!,2	   		y,	,	,29;;1N1N	y.	.	.t{&8 8	. .
i+++")++0M0M	y.	.	.	O,,$
 	 	 	
 #=JFF	 99 	-//6688
 
-../ / #CJF:::::: #.JY[[NOPzPPnPPP
 
 	
s   4D 2D>=D>c                 d    t                       t                      sdS t          j                    S )Nr   )r=   r'   r2   nvmlDeviceGetCountr   r   r   device_get_countr@   }   s-    KKK +q(***r   c            	     p   t                      } t          t          j        k    rt	          d          t          t          j        k    rt	          d          t          t          j        k    rt	          dt           d          t          t          j        k    rt	          d          | dk    rt	          d          	 t          t          t          t          j                            dd	                              d
                              }n# t           $ r d}Y nw xY wt#          j        |          S )Nz8NVML monitoring requires PyNVML and NVML to be installedz$PyNVML is installed, but NVML is notz3Outdated NVIDIA drivers for WSL, please upgrade to z	 or newerzKPyNVML monitoring disabled by 'distributed.diagnostics.nvml' config settingr   zNo GPUs availableCUDA_VISIBLE_DEVICES ,)r@   r#   r
   r   r<   r   r   r:   r   nextmapintr%   environr1   split
ValueErrorr2   nvmlDeviceGetHandleByIndex)countgpu_idxs     r   _pynvml_handlesrN      s:   EY<<<UVVV	y;	;	;ABBB	yA	A	A.". . .
 
 	
 
y0	0	0
 
 	
 
!.///	C(>CCII#NNOO GG  	 	 	GGG	 0999s   >AD D! D!c                    t                       t          t          d          rt          j        |           }nt          j        |           }t          d |D                       S )a)  Check whether the current process is same as that of handle

    Parameters
    ----------
    handle : pyvnml.nvml.LP_struct_c_nvmlDevice_t
        NVML handle to CUDA device

    Returns
    -------
    out : bool
        Whether the device handle has a CUDA context on the running process.
    'nvmlDeviceGetComputeRunningProcesses_v2c              3  N   K   | ] }t          j                    |j        k    V  !d S N)r%   r&   pid).0procs     r   	<genexpr>z+_running_process_matches.<locals>.<genexpr>   s/      EE4ry{{dh&EEEEEEr   )r=   hasattrr2   rP   $nvmlDeviceGetComputeRunningProcessesany)handlerunning_processess     r   _running_process_matchesr\      sd     KKKv@AA P"J6RR"GOOEE3DEEEEEEr   c            
        t                       t                      r\t          t                                D ]?} t	          j        |           }	 t	          j        |          \  }}n!# t          j        $ r t          j        }Y nw xY w|t          j	        k    rt          t	          j
        |                    D ]v}	 t	          j        ||          }n# t          j        $ r Y *w xY wt          |          r9t	          j        |          }t          dt!          || |                    c c S wt          |          r6t	          j        |          }t          dt!          ||                     c S At          d          S )aK  Check whether the current process already has a CUDA context created.

    Returns
    -------
    out : CudaContext
        Object containing information as to whether the current process has a CUDA
        context created, and in the positive case containing also information about
        the device the context belongs to.
    T)r   r   r   )r    r!   r   r   F)r    )r=   r'   ranger@   r2   rK   nvmlDeviceGetMigModeNVMLError_NotSupportedNVML_DEVICE_MIG_DISABLENVML_DEVICE_MIG_ENABLEnvmlDeviceGetMaxMigDeviceCount#nvmlDeviceGetMigDeviceHandleByIndexNVMLError_NotFoundr\   nvmlDeviceGetUUIDr   r   )indexrZ   mig_current_modemig_pending_moder   
mig_handler   s          r   has_cuda_contextrl      s    KKK +--.. 	 	E6u==FB5;5PQW5X5X2 "2"20 B B B#)#A   B6#@@@!&v'LV'T'T!U!U  I!%+%O"I& &

 "4 ! ! ! ! 0
;; %7
CC*(,(6%)) ) )          " ,F33 !3F;;D&$($25$Q$Q$Q      5))))s$   A))BB>CC&%C&c                   t                       	 t          |           }t          j        |          }t          j        |          }ns# t
          $ rf t          | t                    r| nt          | d          }t          j        |          }t          j	        |          }t          j        |          }Y nw xY wt          ||          S )a`  Get both device index and UUID from device index or UUID

    Parameters
    ----------
    device : int, bytes or str
        An ``int`` with the index of a GPU, or ``bytes`` or ``str`` with the UUID
        of a CUDA (either GPU or MIG) device.

    Returns
    -------
    out : CudaDeviceInfo
        Object containing information about the device.

    Examples
    --------
    >>> get_device_index_and_uuid(0)  # doctest: +SKIP
    {'device-index': 0, 'uuid': b'GPU-e1006a74-5836-264f-5c26-53d19d212dfe'}

    >>> get_device_index_and_uuid('GPU-e1006a74-5836-264f-5c26-53d19d212dfe')  # doctest: +SKIP
    {'device-index': 0, 'uuid': b'GPU-e1006a74-5836-264f-5c26-53d19d212dfe'}

    >>> get_device_index_and_uuid('MIG-7feb6df5-eccf-5faa-ab00-9a441867e237')  # doctest: +SKIP
    {'device-index': 0, 'uuid': b'MIG-7feb6df5-eccf-5faa-ab00-9a441867e237'}
    utf-8r^   )r=   rG   r2   rK   rg   rJ   
isinstancebytesnvmlDeviceGetHandleByUUIDnvmlDeviceGetIndexr   )devicer   device_handler   uuid_handles        r   get_device_index_and_uuidrv      s    2 KKK
56{{9,GG'66 5 5 5#FE22Nvvfg8N8N 6t<<0=='445 t,????s   7A A-B87B8c                Z   t                       	 t          |           }t          j        |          }nK# t          $ r> t          | t                    r| nt          | d          }t          j        |          }Y nw xY w	 t          j        |          S # t          j	        $ r ddgcY S w xY w)aX  Get MIG mode for a device index or UUID

    Parameters
    ----------
    device: int, bytes or str
        An ``int`` with the index of a GPU, or ``bytes`` or ``str`` with the UUID
        of a CUDA (either GPU or MIG) device.

    Returns
    -------
    out : list
        A ``list`` with two integers ``[current_mode, pending_mode]``.
    rn   r   )
r=   rG   r2   rK   rJ   ro   rp   rq   r`   ra   )rs   r   rZ   r   s       r   get_device_mig_moderx     s     KKK86{{2<@@ 8 8 8#FE22Nvvfg8N8N1$778*6222(   1vs"   #4 AA<;A< B B*)B*c                b    	 t          j        |           j        S # t           j        $ r Y d S w xY wrR   )r2   nvmlDeviceGetUtilizationRatesgpura   hs    r   _get_utilizationr~   (  s@    3A66::(   tt    ..c                b    	 t          j        |           j        S # t           j        $ r Y d S w xY wrR   )r2   nvmlDeviceGetMemoryInfousedra   r|   s    r   _get_memory_usedr   /  s@    -a0055(   ttr   c                b    	 t          j        |           j        S # t           j        $ r Y d S w xY wrR   )r2   r   totalra   r|   s    r   _get_memory_totalr   6  s@    -a0066(   ttr   c                    	 t          j        |                                           S # t          $ r t          j        |           cY S t           j        $ r Y d S w xY wrR   )r2   nvmlDeviceGetNamer9   AttributeErrorra   r|   s    r   	_get_namer   =  sr    '**11333 + + +'*****(   tts   %( AAAc                 \    t                      } t          |           t          |           dS )N)utilizationzmemory-used)rN   r~   r   r|   s    r   	real_timer   F  s2    A'**'**  r   c                 \    t                      } t          |           t          |           dS )N)zmemory-totalname)rN   r   r   r|   s    r   one_timer   N  s0    A)!,,!  r   )'
__future__r   r%   enumr   r   platformr   typingr   packaging.versionr   r7   r/   r2   ImportErrorr
   r   r   r   r   r#   r$   r:   r'   r*   r=   r@   rN   r\   rl   rv   rx   r~   r   r   r   r   r   r   r   r   <module>r      sX   " " " " " " 				                     4 4 4 4 4 4 MMMM   FFFW W W W W W W W! ! ! ! !Z ! ! !. . . . .* . . . ~ ++		  
 # = Q Q Q
3 3 33
 3
 3
l+ + +: : ::F F F*** ** **Z&@ &@ &@R  6              s   / 99