a
    d(                     @   sj  d dl mZ d dlmZmZmZmZmZmZm	Z	m
Z
 d dlZd dlmZ d dlmZmZ d dlmZ eeddd	Zeedd
dZe	eeeef f ejdddZe	eeeef f ejdddZeedddZeedddZeeddddZeeedddZd9e	eejf eedf ddddZeeeed d!d"Zd:e	eejf ej j!ed$d%d&Z"d;e	eejf ej j!ed$d'd(Z#d<e	eejf e	e$eef e	e$eef eed)d*d+Z%d=e	eejf e	e$eef e	e$eef eed,d-d.Z&ee	e'e(f edd/d0d1Z)eeef eeef d2d3d4Z*d>eeef eeeef  eeeeef d6d7d8Z+dS )?    )wraps)AnyCallableDictListOptionalTupleUnioncastN)Tensor)BetaUniform)_extract_device_dtype)freturnc                    s   t  td fdd}|S )zValidate the 2D input of the wrapped function.

    Args:
        f: a function that takes the first argument as tensor.

    Returns:
        the wrapped function after input is validated.
    inputc                    sX   t | stdt|  t| jdd t| t jt jt j	gd  | g|R i |S )N Input type is not a Tensor. Got ZBCHW)required_shapesaccepted_dtypes)
torch	is_tensor	TypeErrortype_validate_shapeshape_validate_input_dtypefloat16float32float64)r   argskwargsr    j/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/kornia/augmentation/utils/helpers.pywrapper   s
    
z _validate_input.<locals>.wrapperr   r   r   r'   r%   r$   r&   _validate_input   s    
	r*   c                    s   t  td fdd}|S )zValidate the 3D input of the wrapped function.

    Args:
        f: a function that takes the first argument as tensor.

    Returns:
        the wrapped function after input is validated.
    r   c                    sl   t | stdt|  t| j}|dkr>td| dt| t jt j	t j
gd  | g|R i |S )Nr      z"Expect input of 5 dimensions, got z insteadr   )r   r   r   r   lenr   AssertionErrorr   r   r    r!   )r   r"   r#   Zinput_shaper$   r%   r&   r'   ,   s    

z"_validate_input3d.<locals>.wrapperr(   r)   r%   r$   r&   _validate_input3d"   s    
r.   )r   r   c                 C   s&   t | trt| d }nt| }|jS zXInfer input shape.

    Input may be either (tensor,) or (tensor, transform_matrix)
    r   )
isinstancetuple_transform_inputr   r   Ztensorr%   r%   r&   _infer_batch_shape;   s    
r4   c                 C   s&   t | trt| d }nt| }|jS r/   )r0   r1   _transform_input3dr   r3   r%   r%   r&   _infer_batch_shape3dG   s    
r6   c                 C   sn   t | stdt|  t| jdvr:td| j t| jdkrR| d} t| jdkrj| d} | S )zReshape an input tensor to be (*, C, H, W). Accept either (H, W), (C, H, W) or (*, C, H, W).
    Args:
        input: Tensor

    Returns:
        Tensor
    r   )         zNInput size must have a shape of either (H, W), (C, H, W) or (*, C, H, W). Got r7   r   r8   r   r   r   r   r,   r   
ValueErrorZ	unsqueezer   r%   r%   r&   r2   S   s    


r2   c                 C   sn   t | stdt|  t| jdvr:td| j t| jdkrR| d} t| jdkrj| d} | S )zReshape an input tensor to be (*, C, D, H, W). Accept either (D, H, W), (C, D, H, W) or (*, C, D, H, W).
    Args:
        input: Tensor

    Returns:
        Tensor
    r   )r8   r9   r+   zWInput size must have a shape of either (D, H, W), (C, D, H, W) or (*, C, D, H, W). Got r8   r   r9   r:   r   r%   r%   r&   r5   j   s    



r5   )r   r   r   c                 C   s$   | j |vr td| d| j  dS )zCheck if the dtype of the input tensor is in the range of accepted_dtypes
    Args:
        input: Tensor
        accepted_dtypes: List. e.g. [torch.float32, torch.float64]
    zExpected input of . Got N)dtyper   )r   r   r%   r%   r&   r      s    
r   )outputr   r   c                 C   s\   t t| }tt|jt| D ]6}|jd dkrLtd| d|jd  |d}q |S )zCollapse the broadcasted batch dimensions an input tensor to be the specified shape.
    Args:
        input: Tensor
        shape: List/tuple of int

    Returns:
        Tensor
    r      z
Dimension z# of input is expected to be 1, got )r
   r   ranger,   r   r-   Zsqueeze)r>   r   Z
out_tensorZdimr%   r%   r&   _transform_output_shape   s    

rA   r   .)r   r   r   c                 C   sD   d}|D ]}t | t |krd} q&q|s@td| d|  ddS )zCheck if the dtype of the input tensor is in the range of accepted_dtypes
    Args:
        shape: tensor shape
        required_shapes: List. e.g. ["BCHW", "BCDHW"]
    FTzExpected input shape in r<   .N)r,   r   )r   r   ZpassedZrequired_shaper%   r%   r&   r      s    r   )r   channel_indexnumberr   c                 C   s   | j | |kS )aR  Validate if an input has the right shape.

    e.g. to check if an input is channel first.
    If channel first, the second channel of an RGB input shall be fixed to 3. To verify using:
        _validate_input_shape(input, 1, 3)
    Args:
        input: Tensor
        channel_index: int
        number: int
    Returns:
        bool
    )r   )r   rC   rD   r%   r%   r&   _validate_input_shape   s    rE   F)r   distr   c                 C   sH   |r>| dg| dd R j| d gdgt| d  R  S | | S )zThe uniform reparameterized sampling function that accepts 'same_on_batch'.

    If same_on_batch is True, all values generated will be exactly same given a batch_size (shape[0]). By default,
    same_on_batch is set to False.
    r?   Nr   )Zrsamplerepeatr,   r   rF   same_on_batchr%   r%   r&   _adapted_rsampling   s    :rJ   c                 C   sH   |r>| dg| dd R j| d gdgt| d  R  S | | S )zThe uniform sampling function that accepts 'same_on_batch'.

    If same_on_batch is True, all values generated will be exactly same given a batch_size (shape[0]). By default,
    same_on_batch is set to False.
    r?   Nr   )samplerG   r,   rH   r%   r%   r&   _adapted_sampling   s    :rL   )r   lowhighrI   r   c                 C   sf   t t|tr|ndt|tr |ndg\}}tj|||d}tj|||d}t||dd}t| ||S )ay  The uniform sampling function that accepts 'same_on_batch'.

    If same_on_batch is True, all values generated will be exactly same given a batch_size (shape[0]).
    By default, same_on_batch is set to False.

    By default, sampling happens on the default device and dtype. If low/high is a tensor, sampling will happen
    in the same device/dtype as low/high tensor.
    Ndevicer=   FZvalidate_args)r   r0   r   r   	as_tensorr   rJ   )r   rM   rN   rI   rP   r=   rF   r%   r%   r&   _adapted_uniform   s    "rS   )r   abrI   r   c                 C   sf   t t|tr|ndt|tr |ndg\}}tj|||d}tj|||d}t||dd}t| ||S )al  The beta sampling function that accepts 'same_on_batch'.

    If same_on_batch is True, all values generated will be exactly same given a batch_size (shape[0]).
    By default, same_on_batch is set to False.

    By default, sampling happens on the default device and dtype. If a/b is a tensor, sampling will happen
    in the same device/dtype as a/b tensor.
    NrO   FrQ   )r   r0   r   r   rR   r   rJ   )r   rT   rU   rI   rP   r=   rF   r%   r%   r&   _adapted_beta   s
    ,rV   )paramr   namer   c                 C   s0   | j t|kr,td| d| d| j  d S )NzInvalid shape for z. Expected r<   )r   r   Sizer-   )rW   r   rX   r%   r%   r&   _shape_validation  s    rZ   )paramsr   c                 C   sF   i }|   D ]4\}}t|tr2||| i q|||i q|S )zEPerform deep copy on any dict.

    Support tensor copying here.
    )itemsr0   r   updateclone)r[   outkvr%   r%   r&   deepcopy_dict  s    
rb   ignore)r[   params_overrideif_none_existin_placer   c                 C   s~   |du r| S |r| nt | }| D ]T\}}||v r>|||< q$|dkrHq$|dkrhtd| d| dq$td| dq$|S )	aT  Override params dict w.r.t params_override.

    Args:
        params: source parameters.
        params_override: key-values to override the source parameters.
        if_none_exist: behaviour if the key in `params_override` does not exist in `params`.
            'raise' | 'ignore'.
        in_place: if to override in-place or not.
    Nrc   raisezParam `z` not existed in `z`.`z` is not a valid option.)rb   r\   RuntimeErrorr;   )r[   rd   re   rf   r_   r`   ra   r%   r%   r&   override_parameters  s    
rj   )r   )F)F)F)F)Nrc   F),	functoolsr   typingr   r   r   r   r   r   r	   r
   r   r   Ztorch.distributionsr   r   Zkornia.utilsr   r*   r.   rY   r4   r6   r2   r5   r   rA   strr   intboolrE   distributionsDistributionrJ   rL   floatrS   rV   r1   listrZ   rb   rj   r%   r%   r%   r&   <module>   sj   (""
&        

