a
    d                     @   s   d dl 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 d dlm	Z	 d dl
mZ d dlmZ d dlmZ e eZG dd de	Zed	d
dZdS )    N)Optional)ClusterEnvironment)_IS_WINDOWS)rank_zero_warn)PossibleUserWarningc                       s6  e Zd ZdZd)eeej dd fddZe	eddd	Z
e	edd
dZe	edddZeedddZeee dddZeee dddZedddZeddddZedddZeddddZedddZedd d!Zeeed"d#d$Zeddd%d&Zeddd'd(Z  ZS )*SLURMEnvironmenta  Cluster environment for training on a cluster managed by SLURM.

    Args:
        auto_requeue: Whether automatic job resubmission is enabled or not. How and under which conditions a job gets
            rescheduled gets determined by the owner of this plugin.
        requeue_signal: The signal that SLURM will send to indicate that the job should be requeued. Defaults to
            SIGUSR1 on Unix.
    TN)auto_requeuerequeue_signalreturnc                    s<   t    || _|d u r"ts"tj}|| _|   |   d S )N)	super__init__r   r   signalSIGUSR1r	   _validate_srun_used_validate_srun_variables)selfr   r	   	__class__ t/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/lightning_fabric/plugins/environments/slurm.pyr   )   s    
zSLURMEnvironment.__init__r
   c                 C   s   dS )NTr   r   r   r   r   creates_processes_externally2   s    z-SLURMEnvironment.creates_processes_externallyc                 C   s<   t jdd}| |}|t jd< tdt jd   |S )NZSLURM_NODELISTz	127.0.0.1ZMASTER_ADDRzMASTER_ADDR: )osenvirongetresolve_root_node_addresslogdebug)r   ZnodelistZ	root_noder   r   r   main_address6   s
    

zSLURMEnvironment.main_addressc                 C   st   t jd}|d ur.|dd  }t|d }nd}dt jv rLtt jd }nt|t jd< tdt jd   |S )NSLURM_JOB_IDi:  in2  ZMASTER_PORTzMASTER_PORT: )r   r   r   intstrr   r   )r   job_iddefault_portr   r   r   	main_port>   s    
zSLURMEnvironment.main_portc                   C   s   t   t S )a  Returns ``True`` if the current process was launched on a SLURM cluster.

        It is possible to use the SLURM scheduler to request resources and then launch processes manually using a
        different environment. For this, the user can set the job name in SLURM to 'bash' (``SLURM_JOB_NAME=bash``).
        This will then avoid the detection of ``SLURMEnvironment`` and another environment can be detected
        automatically.
        )r   r   _is_srun_usedr   r   r   r   detectY   s    	zSLURMEnvironment.detectc                   C   s   t jdS )NZSLURM_JOB_NAME)r   r   r   r   r   r   r   job_namee   s    zSLURMEnvironment.job_namec                  C   sP   t  dk} | rd S tjd}|d u r,d S z
t|W S  tyJ   Y d S 0 d S )Nbashr    )r   r)   r   r   r   r"   
ValueError)Zin_slurm_interactive_moder$   r   r   r   r$   i   s    
zSLURMEnvironment.job_idc                 C   s   t tjd S )NSLURM_NTASKSr"   r   r   r   r   r   r   
world_sizex   s    zSLURMEnvironment.world_size)sizer
   c                 C   s   t d d S )Nz[SLURMEnvironment.set_world_size was called, but setting world size is not allowed. Ignored.r   r   )r   r/   r   r   r   set_world_size{   s    zSLURMEnvironment.set_world_sizec                 C   s   t tjd S )NZSLURM_PROCIDr-   r   r   r   r   global_rank~   s    zSLURMEnvironment.global_rank)rankr
   c                 C   s   t d d S )Nz]SLURMEnvironment.set_global_rank was called, but setting global rank is not allowed. Ignored.r0   )r   r3   r   r   r   set_global_rank   s    z SLURMEnvironment.set_global_rankc                 C   s   t tjd S )NZSLURM_LOCALIDr-   r   r   r   r   
local_rank   s    zSLURMEnvironment.local_rankc                 C   s   t tjd S )NZSLURM_NODEIDr-   r   r   r   r   	node_rank   s    zSLURMEnvironment.node_rank)nodesr
   c                 C   s4   t dd| } t dd| } | dd dd S )a  The node selection format in SLURM supports several formats.

        This function selects the first host name from

        - a space-separated list of host names, e.g., 'host0 host1 host3' yields 'host0' as the root
        - a comma-separated list of host names, e.g., 'host0,host1,host3' yields 'host0' as the root
        - the range notation with brackets, e.g., 'host[5-9]' yields 'host5' as the root
        z\[(.*?)[,-].*\]z\1z	\[(.*?)\] r   ,)resubsplit)r7   r   r   r   r      s    
z*SLURMEnvironment.resolve_root_node_addressc                  C   s^   t rdS tddu} | rZt sZddtjtj	gtj
dd }td| dtd dS )aT  Checks if the `srun` command is available and used.

        Parallel jobs (multi-GPU, multi-node) in SLURM are launched by prepending `srun` in front of the Python command.
        Not doing so will result in processes hanging, which is a frequent user error. Lightning will emit a warning if
        `srun` is found but not used.
        NZsrunr8   @   zThe `srun` command is available on your system but is not used. HINT: If your intention is to run Lightning on SLURM, prepend your python command with `srun` like so: z ...)category)r   shutilwhichr'   joinr   pathbasenamesys
executableargvr   r   )Zsrun_existshintr   r   r   r      s    
&z$SLURMEnvironment._validate_srun_usedc                  C   s>   t tjdd} | dkr:dtjvr:td|  d|  ddS )	a1  Checks for conflicting or incorrectly set variables set through `srun` and raises a useful error
        message.

        Right now, we only check for the most common user errors. See `the srun docs
        <https://slurm.schedmd.com/srun.html>`_ for a complete list of supported srun variables.
        r,   1   ZSLURM_NTASKS_PER_NODEzYou set `--ntasks=z^` in your SLURM bash script, but this variable is not supported. HINT: Use `--ntasks-per-node=z
` instead.N)r"   r   r   r   RuntimeError)Zntasksr   r   r   r      s    z)SLURMEnvironment._validate_srun_variables)TN)__name__
__module____qualname____doc__boolr   r   Signalsr   propertyr   r#   r   r"   r&   staticmethodr(   r)   r$   r.   r1   r2   r4   r5   r6   r   r   r   __classcell__r   r   r   r   r      s4   		r   r   c                   C   s   dt jv ot dkS )Nr,   r*   )r   r   r   r)   r   r   r   r   r'      s    r'   )loggingr   r:   r?   r   rD   typingr   Z9lightning_fabric.plugins.environments.cluster_environmentr   Z"lightning_fabric.utilities.importsr   Z$lightning_fabric.utilities.rank_zeror   Z#lightning_fabric.utilities.warningsr   	getLoggerrK   r   r   rO   r'   r   r   r   r   <module>   s   
 