§
    AxÅjö%  ã                  ó>  — d Z ddlmZ ddlZddl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  e¦   «         Z eej                             d
d¦  «        ¦  «        Z eej                             dd¦  «        ¦  «        Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„ZdS )a1  
GPU fitness check system for worker startup validation.

Provides comprehensive GPU health checking using:
1. Native CUDA binary (gpu_test) for memory allocation testing
2. Python fallback using nvidia-smi if binary unavailable

Auto-registers when GPUs are detected, skips silently on CPU-only workers.
é    )ÚannotationsN)ÚPath)ÚAny©Úget_binary_pathé   )Úregister_fitness_check)ÚRunPodLoggerÚRUNPOD_GPU_TEST_TIMEOUTÚ30ÚRUNPOD_GPU_MAX_ERROR_MESSAGESÚ10ÚreturnúPath | Nonec                 ó    — t          d¦  «        S )zj
    Locate gpu_test binary in package.

    Returns:
        Path to binary if found, None otherwise
    Úgpu_testr   © ó    úYC:\Projects\Historical\venv\Lib\site-packages\runpod/serverless/modules/rp_gpu_fitness.pyÚ_get_gpu_test_binary_pathr      s   € õ ˜:Ñ&Ô&Ð&r   ÚoutputÚstrúdict[str, Any]c                ó–  ‡— |                       ¦   «                              d¦  «        }dddg i dœ}d}d}|D �]cŠ‰                      ¦   «         Š‰sŒ‰                     d¦  «        r8‰                     dd¦  «        d                               ¦   «         |d         d	<   n«‰                     d
¦  «        r8‰                     dd¦  «        d                               ¦   «         |d         d<   n^‰                     d¦  «        rId‰v rE	 t          ‰                     ¦   «         d         ¦  «        }||d<   n# t          t
          f$ r Y nw xY wd‰                     ¦   «         v r|dz  }t          ˆfd„dD ¦   «         ¦  «        r|d                              ‰¦  «         �Œe||d<   |dk    o||k    ot          |d         ¦  «        dk    |d<   |S )ag  
    Parse gpu_test binary output and detect success/failure.

    Looks for:
    - "GPU X memory allocation test passed." for success
    - Error patterns: "Failed", "error", "cannot" for failures
    - GPU count from "Found X GPUs:" line

    Args:
        output: Stdout from gpu_test binary

    Returns:
        Dict with keys:
        - success: bool - True if all GPUs passed tests
        - gpu_count: int - Number of GPUs that passed tests
        - found_gpus: int - Total GPUs found
        - errors: List[str] - Error messages from output
        - details: Dict - CUDA version, kernel version, etc
    ú
Fr   )ÚsuccessÚ	gpu_countÚ
found_gpusÚerrorsÚdetailszCUDA Driver Version:ú:r   r    Úcuda_versionzLinux Kernel Version:ÚkernelÚFoundÚGPUsr   zmemory allocation test passedc              3  óD   •K  — | ]}|‰                      ¦   «         v V — Œd S )N)Úlower)Ú.0ÚerrÚlines     €r   ú	<genexpr>z)_parse_gpu_test_output.<locals>.<genexpr>a   s0   øè è € ÐVÐV sˆs�d—j’j‘l”lÐ"ÐVÐVÐVÐVÐVÐVr   )ÚfailedÚerrorÚcannotÚunabler   r   r   )
ÚstripÚsplitÚ
startswithÚintÚ
IndexErrorÚ
ValueErrorr'   ÚanyÚappendÚlen)r   ÚlinesÚresultÚpassed_countr   r*   s        @r   Ú_parse_gpu_test_outputr<   (   s  ø€ ð( �LŠL‰NŒN× Ò  Ñ&Ô&€Eð ØØØØðð €Fð €LØ€Jàð *ñ *ˆØ�zŠz‰|Œ|ˆØð 	Øð �?Š?Ð1Ñ2Ô2ð 	Ø04·
²
¸3ÀÑ0BÔ0BÀ1Ô0E×0KÒ0KÑ0MÔ0MˆF�9Ô˜nÑ-Ð-Ø�_Š_Ð4Ñ5Ô5ð 		Ø*.¯*ª*°S¸!Ñ*<Ô*<¸QÔ*?×*EÒ*EÑ*GÔ*GˆF�9Ô˜hÑ'Ð'Ø�_Š_˜WÑ%Ô%ð 	¨&°D¨.¨.ðÝ  §¢¡¤¨a¤Ñ1Ô1�
Ø'1��|Ñ$Ð$øÝ¥
Ð+ð ð ð à�ðøøøð
 +¨d¯jªj©l¬lÐ:Ð:Ø˜AÑˆLõ ÐVÐVÐVÐVÐ.UÐVÑVÔVÑVÔVð 	*Ø�8Ô×#Ò# DÑ)Ô)Ð)ùà&€Fˆ;Ñà�qÒÐV˜\¨ZÒ7ÐV½CÀÀxÔ@PÑ<QÔ<QÐUVÒ<Vð ˆ9Ñð €Ms   Ä,D2Ä2EÅEc            	   ƒ  ó  K  — t          ¦   «         } | st          d¦  «        ‚t          j        | t          j        ¦  «        st          d| › �¦  «        ‚t                               d| › �¦  «         	 t          j	        t          | ¦  «        t          j        j        t          j        j        ¬¦  «        ƒ d{V —†}t          j        |                     ¦   «         t          ¬¦  «        ƒ d{V —†\  }}|                     dd¬	¦  «        }|                     dd¬	¦  «        }t                               d
|› �¦  «         |rt                               d|› �¦  «         t#          |¦  «        }|d         sGd}|d         r.|dd                     |d         dt&          …         ¦  «        › �z  }t)          |¦  «        ‚t                               d|d         › d|d                              dd¦  «        › d�¦  «         |S # t          j        $ rH |                     ¦   «          |                     ¦   «         ƒ d{V —† t)          dt          › d�¦  «        d‚t          $ r ‚ t
          $ r ‚ t4          $ r}t)          d|› �¦  «        |‚d}~ww xY w)zÇ
    Execute gpu_test binary and parse output.

    Returns:
        Parsed result dict from _parse_gpu_test_output

    Raises:
        RuntimeError: If binary execution fails or GPUs unhealthy
    z$gpu_test binary not found in packagez gpu_test binary not executable: zRunning gpu_test binary: )ÚstdoutÚstderrN)Útimeoutzutf-8Úreplace)r   zgpu_test output:
zgpu_test stderr:
r   z!GPU memory allocation test failedr   z: z; zGPU binary test passed: r   z GPU(s) healthy (CUDA r    r"   Úunknownú)z GPU test binary timed out after Úsz"GPU test binary execution failed: )r   ÚFileNotFoundErrorÚosÚaccessÚX_OKÚPermissionErrorÚlogÚdebugÚasyncioÚcreate_subprocess_execr   Ú
subprocessÚPIPEÚwait_forÚcommunicateÚTIMEOUT_SECONDSÚdecoder<   ÚjoinÚMAX_ERROR_MESSAGESÚRuntimeErrorÚinfoÚgetÚTimeoutErrorÚkillÚwaitÚ	Exception)	Úbinary_pathÚprocessr>   r?   r   Úerror_outputr:   Ú	error_msgÚexcs	            r   Ú_run_gpu_test_binaryrb   l   s  è è € õ ,Ñ-Ô-€Kàð HÝÐ FÑGÔGÐGåŒ9�[¥"¤'Ñ*Ô*ð PÝÐNÀÐNÐNÑOÔOÐOå‡I‚IÐ7¨+Ð7Ð7Ñ8Ô8Ð8ð0PåÔ6Ý�ÑÔÝÔ%Ô*ÝÔ%Ô*ð
ñ 
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ˆõ  'Ô/Ø×ÒÑ!Ô!­?ð 
ñ  
ô  
ð 
ð 
ð 
ð 
ð 
ð 
‰ˆ�ð —’˜w¨y�Ñ9Ô9ˆØ—}’} W°Y�}Ñ?Ô?ˆå�	Š	Ð/ vÐ/Ð/Ñ0Ô0Ð0àð 	;Ý�IŠIÐ9¨<Ð9Ð9Ñ:Ô:Ð:õ (¨Ñ/Ô/ˆð �iÔ ð 	*Ø;ˆIØ�hÔð UØÐT $§)¢)¨F°8Ô,<Ð=PÕ>PÐ=PÔ,QÑ"RÔ"RÐTÐTÑT�	Ý˜yÑ)Ô)Ð)å�ŠðI v¨kÔ':ð Ið IØ˜IÔ&×*Ò*¨>¸9ÑEÔEðIð Ið Iñ	
ô 	
ð 	
ð
 ˆøåÔð ð ð Ø�Š‰ŒˆØ�lŠl‰nŒnÐÐÐÐÐÐÐÝØA­ÐAÐAÐAñ
ô 
àð	õ ð ð ð ØÝð ð ð ØÝð Pð Pð PÝÐEÀÐEÐEÑFÔFÈCÐOøøøøðPøøøs   Á1FG: Ç:A3JÉ-J Ê JÚNonec                 óN  — t                                d¦  «         	 t          j        ddgdddd¬¦  «        } | j        dk    rt          d	| j        › �¦  «        ‚d
„ | j                             d¦  «        D ¦   «         }t          |¦  «        }|dk    rt          d¦  «        ‚t            
                    d|› d�¦  «         dS # t          $ r t          d¦  «        d‚t          j        $ r t          d¦  «        d‚t
          $ r ‚ t          $ r}t          d|› �¦  «        |‚d}~ww xY w)a  
    Python fallback for GPU testing using nvidia-smi.

    Less comprehensive than binary (doesn't test memory allocation) but validates
    basic GPU availability by checking GPU count.

    Raises:
        RuntimeError: If GPUs not available or unhealthy
    z!Running Python GPU fallback checkú
nvidia-smiz--list-gpusTé
   F©Úcapture_outputÚtextr@   Úcheckr   znvidia-smi --list-gpus failed: c                ó:   — g | ]}|                      ¦   «         ¯|‘ŒS r   )r0   )r(   r*   s     r   ú
<listcomp>z*_run_gpu_test_fallback.<locals>.<listcomp>Ì   s%   € ÐPÐPÐP˜dÀ4Ç:Â:Á<Ä<ÐP�TÐPÐPÐPr   r   zNo GPUs detected by nvidia-smizGPU fallback check passed: z5 GPU(s) detected (Note: Memory allocation NOT tested)z7nvidia-smi not found. Cannot validate GPU availability.Nznvidia-smi timed outz"nvidia-smi fallback check failed: )rJ   rK   rN   ÚrunÚ
returncoderV   r?   r>   r1   r8   rW   rE   ÚTimeoutExpiredr\   )r:   Ú	gpu_linesr   Úes       r   Ú_run_gpu_test_fallbackrr   ³   s‘  € õ ‡I‚IÐ1Ñ2Ô2Ð2ð!Lå”Ø˜=Ð)ØØØØð
ñ 
ô 
ˆð Ô Ò!Ð!ÝÐPÀÄÐPÐPÑQÔQÐQàPÐP f¤m×&9Ò&9¸$Ñ&?Ô&?ÐPÑPÔPˆ	Ý˜	‘N”Nˆ	à˜Š>ˆ>ÝÐ?Ñ@Ô@Ð@å�Šð3¨)ð 3ð 3ð 3ñ	
ô 	
ð 	
ð 	
ð 	
øõ
 ð ð ð ÝØEñ
ô 
àð	õ Ô$ð =ð =ð =ÝÐ1Ñ2Ô2¸Ð<Ýð ð ð ØÝð Lð Lð LÝÐCÀÐCÐCÑDÔDÈ!ÐKøøøøðLøøøs   œB#C ÃAD$ÄDÄD$c               ƒ  ó@  K  — d} d}	 t          ¦   «         ƒ d{V —† dS # t          $ r)}t                               d|› �¦  «         |}Y d}~nld}~wt          $ r)}t                               d|› �¦  «         |}Y d}~n;d}~wt
          $ r+}t                               d|› �¦  «         d} |}Y d}~nd}~ww xY wt                               d¦  «         	 t          ¦   «          dS # t
          $ r0}| rt          d|› d	|› �¦  «        |‚t          d
|› �¦  «        |‚d}~ww xY w)a$  
    Comprehensive GPU health check (internal implementation).

    Execution strategy:
    1. Try binary test if available
    2. Fall back to Python check if binary fails/missing
    3. Raise RuntimeError if all methods fail

    Raises:
        RuntimeError: If GPU health check fails
    FNzGPU binary not found: zGPU binary not executable: zGPU binary check failed: Tz$Attempting Python GPU fallback checkz&GPU health check failed. Binary test: z. Fallback test: zDGPU health check failed (binary disabled/missing, fallback failed): )	rb   rE   rJ   rK   rI   r\   Úwarnrr   rV   )Úbinary_attemptedÚbinary_errorra   Úfallback_excs       r   Ú_check_gpu_healthrx   ã   s½  è è € ð ÐØ€LðÝ"Ñ$Ô$Ð$Ð$Ð$Ð$Ð$Ð$Ð$ØˆøÝð ð ð Ý�	Š	Ð0¨3Ð0Ð0Ñ1Ô1Ð1ØˆˆˆˆˆˆøøøøÝð ð ð Ý�	Š	Ð5°Ð5Ð5Ñ6Ô6Ð6ØˆˆˆˆˆˆøøøøÝð ð ð Ý�ŠÐ2¨SÐ2Ð2Ñ3Ô3Ð3ØÐØˆˆˆˆˆˆøøøøðøøøõ ‡I‚IÐ4Ñ5Ô5Ð5ð ÝÑ Ô Ð ØˆøÝð  ð  ð  àð 
	 Ýð1Ø ,ð1ð 1à".ð1ð 1ñô ð  ð	 õ ð4Ø%1ð4ð 4ñô ð  ð øøøøð øøøsD   ˆ ž
B5¨AÁB5ÁA=Á=B5Â
!B0Â0B5ÃC# Ã#
DÃ-+DÄDc                 óô  — t           j                             dd¦  «                             ¦   «         dk    rt                               d¦  «         dS d} 	 t          j        dgddd	d¬
¦  «        }|j        dk    od|j	        v } n+# t          t          j        f$ r d} Y nt          $ r d} Y nw xY w| r,t                               d¦  «         t          d„ ¦   «         }dS t                               d¦  «         dS )ak  
    Auto-register GPU fitness check if GPUs are detected.

    This function is called during rp_fitness module initialization.
    It detects GPU presence via nvidia-smi and registers the check if found.
    On CPU-only workers, the check is skipped silently.

    Environment variables:
    - RUNPOD_SKIP_GPU_CHECK: Set to "true" to skip auto-registration
    ÚRUNPOD_SKIP_GPU_CHECKÚ Útruez<GPU fitness check auto-registration disabled via environmentNFre   Té   rg   r   z
NVIDIA-SMIz5GPU detected, registering automatic GPU fitness checkc               “  ó2   K  — t          ¦   «         ƒ d{V —† dS )z-Automatic GPU memory allocation health check.N)rx   r   r   r   Ú_gpu_health_checkz2auto_register_gpu_check.<locals>._gpu_health_check9  s,   è è € õ $Ñ%Ô%Ð%Ð%Ð%Ð%Ð%Ð%Ð%Ð%Ð%r   z8No GPU detected, skipping GPU fitness check registration)rF   ÚenvironrX   r'   rJ   rK   rN   rm   rn   r>   rE   ro   r\   r	   )Úhas_gpur:   r   s      r   Úauto_register_gpu_checkr‚     s8  € õ 
„z‡~‚~Ð-¨rÑ2Ô2×8Ò8Ñ:Ô:¸fÒDÐDÝ�	Š	ÐPÑQÔQÐQØˆð €GðÝ”ØˆNØØØØð
ñ 
ô 
ˆð Ô# qÒ(ÐJ¨\¸V¼]Ð-JˆˆøÝ�zÔ8Ð9ð ð ð ØˆˆˆÝð ð ð àˆˆˆðøøøð ð NÝ�	Š	ÐIÑJÔJÐJå	ð	&ð 	&ñ 
 Ô	ð	&ð 	&ð 	&õ 	�	Š	ÐLÑMÔMÐMÐMÐMs   Á.B ÂB-ÂB-Â,B-)r   r   )r   r   r   r   )r   r   )r   rc   )Ú__doc__Ú
__future__r   rL   rF   rN   Úpathlibr   Útypingr   Úrunpod._binary_helpersr   Ú
rp_fitnessr	   Ú	rp_loggerr
   rJ   r3   r€   rX   rR   rU   r   r<   rb   rr   rx   r‚   r   r   r   ú<module>rŠ      s…  ððð ð #Ð "Ð "Ð "Ð "Ð "à €€€Ø 	€	€	€	Ø Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð à 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø .Ð .Ð .Ð .Ð .Ð .Ø #Ð #Ð #Ð #Ð #Ð #à€l�n„n€ð �#�b”j—n’nÐ%>ÀÑEÔEÑFÔF€Ø�S˜œŸšÐ(GÈÑNÔNÑOÔOÐ ð'ð 'ð 'ð 'ðAð Að Að AðHDPð DPð DPð DPðN-Lð -Lð -Lð -Lð`/ ð / ð / ð / ðd)Nð )Nð )Nð )Nð )Nð )Nr   