a
    d                     @   s   d dl Z d dlZd dlZd dlmZmZmZmZmZ d dl	m
Z
 d dlmZ d dlmZ e
dZG dd deZee d	d
dZeeee ef dddZdS )    N)AnyCallableOptionalSequenceTuple)RequirementCache)ClusterEnvironment)	_Launcherz
hydra-corec                       sn   e Zd ZdZdeedd fddZeeddd	Ze	e
e
e
d
ddZddddZddddZ  ZS )_SubprocessScriptLaunchera  A process laucher that invokes the current script as many times as desired in a single node.

    This launcher needs to be invoked on each node.
    In its default behavior, the main process in each node then spawns N-1 child processes via :func:`subprocess.Popen`,
    where N is the number of devices (e.g. GPU) per node. It is very similar to how :mod:`torch.distributed.run`
    launches processes.

    For example, if the script gets invoked with the command

    .. code-block:: bash

        python train.py --devices 4

    The launcher will create three additional subprocesses that get called like so:

    .. code-block:: bash

        LOCAL_RANK=1 python train.py --devices 4
        LOCAL_RANK=2 python train.py --devices 4
        LOCAL_RANK=3 python train.py --devices 4

    It is implied that the main process which launched the others has ``LOCAL_RANK=0``.
    Beside the local rank, the following other environment variables also get set, but unlike the local rank, these
    get determined by the cluster environment:

    1. `MASTER_ADDR`: The IP address of the main node.
    2. `MASTER_PORT`: The port number of the main node through which all processes communicate.
    3. `NODE_RANK`: The index of the node the current process is running on. Ranges from 0 to ``num_nodes - 1``.
    4. `WORLD_SIZE`: The total number of processes across all nodes, i.e., ``num_processes * num_nodes``.

    Arguments:
        cluster_environment: A cluster environment that provides access to world size, node rank, etc.
        num_processes: The number of processes to launch in the current node.
        num_nodes: The total number of nodes that participate in this process group.
    r   N)cluster_environmentnum_processes	num_nodesreturnc                    s    t    || _|| _|| _d S )N)super__init__r   r   r   )selfr   r   r   	__class__ /var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/lightning_fabric/strategies/launchers/subprocess_script.pyr   @   s    
z"_SubprocessScriptLauncher.__init__r   c                 C   s   dS )NFr   r   r   r   r   is_interactive_compatibleK   s    z3_SubprocessScriptLauncher.is_interactive_compatible)functionargskwargsr   c                 O   s   | j js|   ||i |S )a  Creates new processes, then calls the given function.

        Arguments:
            function: A callback function to execute after all processes have been created.
                It is up to the implementation of this function to synchronize the processes, e.g., with barriers.
            *args: Optional positional arguments to be passed to the given function.
            **kwargs: Optional keyword arguments to be passed to the given function.
        )r   Zcreates_processes_externally_call_children_scripts)r   r   r   r   r   r   r   launchO   s    	z _SubprocessScriptLauncher.launchc                 C   s   |    | jjtjd< t| jjtjd< t| j tjd< t| j tjd< | j	| j
  tjd< td| j	D ]}tj }| |d< tjdd u rd|v r|d= d}d }trd	d
lm} | }|rt|d\}}nt }tj|||d qpd S )NZMASTER_ADDRZMASTER_PORTZ	NODE_RANKZ
LOCAL_RANKZ
WORLD_SIZE   ZPL_GLOBAL_SEEDFr   )HydraConfig)
local_rank)envcwd)_check_can_spawn_childrenr   Zmain_addressosenvironstrZ	main_portZ	node_rankr    r   r   rangecopyget_HYDRA_AVAILABLEZhydra.core.hydra_configr   Zinitialized_hydra_subprocess_cmd_basic_subprocess_cmd
subprocessPopen)r   r    Zenv_copyZhydra_in_user"   r   commandr   r   r   r   \   s(    

z0_SubprocessScriptLauncher._call_children_scriptsc                 C   s   | j  dkrtdd S )Nr   a  Lightning attempted to launch new distributed processes with `local_rank > 0`. This should not happen. Possible reasons: 1) LOCAL_RANK environment variable was incorrectly modified by the user, 2) `ClusterEnvironment.creates_processes_externally` incorrectly implemented.)r   r    RuntimeErrorr   r   r   r   r#      s    z3_SubprocessScriptLauncher._check_can_spawn_children)__name__
__module____qualname____doc__intr   propertyboolr   r   r   r   r   r#   __classcell__r   r   r   r   r
      s   &#r
   r   c                  C   sZ   dd l } | jd u r8tjtjtjd gtjdd   S tjd| jjgtjdd   S d S )Nr   r   -m)	__main____spec__sys
executabler$   pathabspathargvname)r:   r   r   r   r,      s    
&r,   )r    r   c                 C   s   dd l }ddlm}m} |jd u r8tj|tjd g}ntjd|jjg}|tjdd  7 }| }dt	
  d}|d| d|  g7 }||fS )Nr   )get_original_cwdto_absolute_pathr9   r   "zhydra.run.dir=z!hydra.job.name=train_ddp_process_)r:   Zhydra.utilsrB   rC   r;   r<   r=   r@   rA   r$   getcwd)r    r:   rB   rC   r/   r"   Zos_cwdr   r   r   r+      s    
r+   )r$   r-   r<   typingr   r   r   r   r   Z lightning_utilities.core.importsr   Z9lightning_fabric.plugins.environments.cluster_environmentr   Z*lightning_fabric.strategies.launchers.baser	   r*   r
   r&   r,   r5   r+   r   r   r   r   <module>   s   m	