a
    do                     @   s   d dl Z d dlZd dlmZmZmZ d dlZd dlmZ d dlm	Z	 d dl
Zd dlmZmZ d dlmZ dddd	ZG d
d deZedfeeeejf edddZeedddZdS )    N)AnyOptionalUnion)apply_to_collection)Tensor)_LightningModuleWrapperBase$_LightningPrecisionModuleWrapperBase)rank_zero_warn)returnc                   C   s   t jddd d S )NignorezvWas asked to gather along dimension 0, but all input tensors were scalars; will instead unsqueeze and return a vector.)message)warningsfilterwarnings r   r   r/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/pytorch_lightning/overrides/data_parallel.py_ignore_scalar_return_in_dp   s    r   c                       sj   e Zd ZdZdeedef  eedef  dd fddZeeed fdd	Z	edd
ddZ
  ZS )LightningParallelModulea@  Wraps the user's LightningModule and redirects the forward call to the appropriate method, either
    ``training_step``, ``validation_step``, ``test_step``, or ``predict_step``.

    This class is used in combination with :class:`~torch.nn.parallel.DataParallel` as shown in the example.
    It also takes care of converting Python scalars to Tensors and un-squeezes 0-dimensional Tensors as it is required
    by :class:`~torch.nn.parallel.DataParallel`.

    Example:

        dp_model = torch.nn.DataParallel(
            module=LightningParallelModule(lightning_module),
            device_ids=[3, 4],
            ...
        )

    Args:
        pl_module: The module to wrap. See description for `forward_module`.

            .. deprecated:: v1.8.0
                The argument ``pl_module`` is deprecated in v1.8.0 and will be removed in v2.0.0. Please use
                ``forward_module`` instead.

        forward_module: The module to wrap. If it's not a ``LightningModule``, it must have an attribute ``.module``
            pointing to a ``LightningModule`` reference.
    Nzpl.LightningModule)forward_module	pl_moduler
   c                    s(   |  || t j|p|d t  d S )N)r   )Z_validate_init_argumentssuper__init__r   )selfr   r   	__class__r   r   r   A   s    z LightningParallelModule.__init__)inputskwargsr
   c                    sH     | t j|i |}ttd fdd}t|tjtf|d}|S )Ndatar
   c                    s    j j}t| |} t| } | S )N)Zlightning_moduledevicepython_scalar_to_tensorunsqueeze_scalar_tensorr   r   r   r   r   output_transformO   s    
z9LightningParallelModule.forward.<locals>.output_transformZdtypefunction) update_replica_device_attributesr   forwardr   r   numbersNumberr   )r   r   r   outputr#   r   r"   r   r'   J   s
    
zLightningParallelModule.forward)r   r
   c                    sJ   d t t d fdd}t|t |d  dur>| jj d ntd dS )a/  Updates the device information of LightningModule by reading the device from the inputs. In
        :class:`~torch.nn.data_parallel.DataParallel` changes to the state during the `forward` pass are lost when
        the replicas get discarded. The only way to know the current device is from the inputs passed into the
        model.

        Args:
            inputs: A collection of inputs (typically a tuple). If the inputs don't contain tensors,
                a warning is shown that accessing ``self.device`` will not return the correct device.
        N)tensorr
   c                    s"    d u r| j t dkr| j  | S )Ncpu)r   torch)r+   Zreplica_devicer   r   find_tensor_with_deviced   s    zYLightningParallelModule.update_replica_device_attributes.<locals>.find_tensor_with_devicer$   r   zCould not determine on which device the inputs are. When using DataParallel (strategy='dp'), be aware that in case you are using self.device in your code, it will reference only the root device.)r   r   Z_forward_moduletor	   )r   r   r/   r   r.   r   r&   X   s    
z8LightningParallelModule.update_replica_device_attributes)NN)__name__
__module____qualname____doc__r   r   r   r   r   r'   r&   __classcell__r   r   r   r   r   &   s     	r   r,   )r   r   r
   c                 C   s    t | tjrtj| g|d} | S )zTConverts a Python scalar number to a torch tensor and places it on the given device.r0   )
isinstancer(   r)   r-   r+   r!   r   r   r   r   w   s    r   r   c                 C   s$   t | tr |  dkr | d} | S )zUn-squeezes a 0-dim tensor.r   )r7   r   ZdimZ	unsqueeze)r   r   r   r   r    ~   s    
r    )r(   r   typingr   r   r   r-   Z#lightning_utilities.core.apply_funcr   r   Zpytorch_lightningplZ pytorch_lightning.overrides.baser   r   Z%pytorch_lightning.utilities.rank_zeror	   r   r   r   strr   r    r   r   r   r   <module>   s   Q&