a
    d                     @   s   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	m
Z
 ee
d eddd	Zdeeee
d edddZeeeee dddZdeee ee dddZdS )    )AnyListOptionalN)Tensor)
functional)Literal)elementwise_meansumnoneN)x	reductionreturnc                 C   sD   |dkrt | S |dks"|du r&| S |dkr8t | S tddS )aB  Reduces a given tensor by a given reduction method.

    Args:
        x: the tensor, which shall be reduced
        reduction:  a string specifying the reduction method ('elementwise_mean', 'none', 'sum')

    Return:
        reduced Tensor

    Raise:
        ValueError if an invalid reduction parameter was given

    r   r
   Nr	   zReduction parameter unknown.)torchmeanr	   
ValueError)r   r    r   k/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/utilities/distributed.pyreduce   s    

r   r
   micromacroweightedr
   N)numdenomweightsclass_reductionr   c                 C   s   d}|dkr t | t | n| | }d|||k< |dkr@|S |dkrRt |S |dkrvt || t |  S |dks|du r|S td| d	| dS )
a  Reduce classification metrics of the form ``num / denom * weights``.

    For example for calculating standard accuracy the num would be number of true positives per class, denom would be
    the support per class, and weights would be a tensor of 1s.

    Args:
        num: numerator tensor
        denom: denominator tensor
        weights: weights for each class
        class_reduction: reduction method for multiclass problems:

            - ``'micro'``: calculate metrics globally (default)
            - ``'macro'``: calculate metrics for each label, and find their unweighted mean.
            - ``'weighted'``: calculate metrics for each label, and find their weighted mean.
            - ``'none'`` or ``None``: returns calculated metric per class

    Raises:
        ValueError:
            If ``class_reduction`` is none of ``"micro"``, ``"macro"``, ``"weighted"``, ``"none"`` or ``None``.

    r   r   r   r   r   r
   NzReduction parameter z' unknown. Choose between one of these: )r   r	   r   floatr   )r   r   r   r   Zvalid_reductionfractionr   r   r   class_reduce-   s    $
r   )resultgroup
world_sizer   c                    s*    fddt |D }tj| | |S )Nc                    s   g | ]}t  qS r   r   Z
zeros_like.0_r   r   r   
<listcomp>\       z._simple_gather_all_tensors.<locals>.<listcomp>)ranger   distributed
all_gather)r   r    r!   gathered_resultr   r&   r   _simple_gather_all_tensors[   s    r-   )r   r    r   c                    s`  |du rt jjj}|  } t j|}t jj|d | jdkrJt| ||S t j	| j
| jd  fddt|D }t jj| |d t |jddjtfdd	|D }|rt| ||S g }    }t|D ]}|d ||  qt| |fd
dt|D }t j|| t|D ](\}	}
dd |
D }||	 | ||	< q2|S )ae  Gather all tensors from several ddp processes onto a list that is broadcasted to all processes.

    Works on tensors that have the same number of dimensions, but where each dimension may differ. In this case
    tensors are padded, gathered and then trimmed to secure equal workload for all processes.

    Args:
        result: the value to sync
        group: the process group to gather results from. Defaults to all processes (world)

    Return:
        gathered_result: list with size equal to the process group where
            ``gathered_result[i]`` corresponds to result tensor from process ``i``

    N)r    r   )devicec                    s   g | ]}t  qS r   r"   r#   )
local_sizer   r   r'      r(   z&gather_all_tensors.<locals>.<listcomp>)Zdimc                 3   s   | ]}t | kV  qd S )N)all)r$   Zls)max_sizer   r   	<genexpr>   r(   z%gather_all_tensors.<locals>.<genexpr>c                    s   g | ]}t  qS r   r"   r#   )result_paddedr   r   r'      r(   c                 S   s   g | ]}t |qS r   )slice)r$   Zdim_sizer   r   r   r'      r(   )r   r*   r    ZWORLD
contiguousZget_world_sizeZbarrierndimr-   Ztensorshaper.   r)   r+   stackmaxvaluesr0   detachcpureversedappenditemFpad	enumerate)r   r    r!   Zlocal_sizesZall_sizes_equalZpad_dimsZpad_byvalr,   idxZ	item_sizeZslice_paramr   )r/   r1   r3   r   gather_all_tensorsa   s4    


rE   )r
   )N)typingr   r   r   r   r   Ztorch.nnr   r@   Ztyping_extensionsr   r   r   intr-   rE   r   r   r   r   <module>   s    .