o
    oi                     @   s   d dl mZmZmZmZmZmZmZ d dlZd dl	m
Z
mZ d dlmZ d dlmZmZmZ edZG dd deZG d	d
 d
eedZG dd de
ZG dd deeZdS )    )AnyCallableDictOptionalTupleTypeTypeVarN)DistributionUniform)MultiprocessWrapper)DeviceModuleTensorTc                   @   s.   e Zd ZdZdee dededefddZdS )	_PostInitInjectionMetaClasszMTo inject the ``__post_init__`` function after the creation of each instance.clsargskwargsreturnc                 O   s$   t j| g|R i |}|  |S N)type__call____post_init__)r   r   r   obj r   ]/home/ubuntu/.local/lib/python3.10/site-packages/kornia/augmentation/random_generator/base.pyr       s   z$_PostInitInjectionMetaClass.__call__N)__name__
__module____qualname____doc__r   r   r   r   r   r   r   r   r      s    "r   c                	       s   e Zd ZU dZdZee ed< ej	ed< d fddZ
ddd	Zdejfdeej dej	ddfd
dZdededd fddZdejdej	ddfddZddeedf dedeeef fddZ  ZS )RandomGeneratorBasez9Base class for generating random augmentation parameters.Ndevicedtyper   c                    s   t    d S r   )super__init__self	__class__r   r   r$   ,   s   zRandomGeneratorBase.__init__c                 C   s   |    d S r   )set_rng_device_and_dtyper%   r   r   r   r   /   s   z!RandomGeneratorBase.__post_init__c                 C   sF   |du r	t d}| j|ks| j|kr!| || || _|| _dS dS )zChange the random generation device and dtype.

        Note:
            The generated random numbers are not reproducible across different devices and dtypes.

        Ncpu)torchr!   r"   make_samplersr&   r!   r"   r   r   r   r)   2   s   

z,RandomGeneratorBase.set_rng_device_and_dtyper   r   c                 O   s.   t jjj|i |\}}}}| j||d | S )N)r!   r"   )r+   _C_nn	_parse_tor)   )r&   r   r   r!   r"   _r   r   r   toE   s   zRandomGeneratorBase.toc                 C      t r   NotImplementedErrorr-   r   r   r   r,   J      z!RandomGeneratorBase.make_samplersFbatch_shape.same_on_batchc                 C   r3   r   r4   )r&   r7   r8   r   r   r   forwardM   r6   zRandomGeneratorBase.forward)r   N)F)r   r   r   r   r!   r   r   __annotations__r+   r"   r$   r   float32r)   r   r2   r,   r   intboolr   strr   r9   __classcell__r   r   r'   r   r    &   s$   
 


0r    )	metaclassc                   @   s   e Zd ZdZddedeeegef  ddfddZde	e
d	f defd
dZde	e
d	f defddZde
defddZdedefddZdS )DistributionWithMappera  Wraps a distribution with a value mapper function.

    This is used to restrict the output values of a given distribution by a value mapper function.
    The value mapper function can be functions like sigmoid, tanh, etc.

    Args:
        dist: the target distribution.
        map_fn: the callable function to adjust the output from distributions.

    Example:
        >>> from torch.distributions import Normal
        >>> import torch.nn as nn
        >>> # without mapper
        >>> dist = DistributionWithMapper(Normal(0., 1.,), map_fn=None)
        >>> _ = torch.manual_seed(0)
        >>> dist.rsample((8,))
        tensor([ 1.5410, -0.2934, -2.1788,  0.5684, -1.0845, -1.3986,  0.4033,  0.8380])
        >>> # with sigmoid mapper
        >>> dist = DistributionWithMapper(Normal(0., 1.,), map_fn=nn.Sigmoid())
        >>> _ = torch.manual_seed(0)
        >>> dist.rsample((8,))
        tensor([0.8236, 0.4272, 0.1017, 0.6384, 0.2527, 0.1980, 0.5995, 0.6980])

    Ndistmap_fnr   c                 C   s   || _ || _d S r   )rB   rC   )r&   rB   rC   r   r   r   r$   k   s   
zDistributionWithMapper.__init__sample_shape.c                 C   *   | j t|}| jd ur| |}|S r   )rB   rsampler+   SizerC   r&   rD   outr   r   r   rF   o      

zDistributionWithMapper.rsamplec                 C   rE   r   )rB   sampler+   rG   rC   rH   r   r   r   rK   u   rJ   zDistributionWithMapper.samplenc                 C   s$   | j |}| jd ur| |}|S r   )rB   sample_nrC   )r&   rL   rI   r   r   r   rM   {   s   

zDistributionWithMapper.sample_nattrc                 C   s,   zt | |W S  ty   t | j| Y S w r   )getattrAttributeErrorrB   )r&   rN   r   r   r   __getattr__   s
   z"DistributionWithMapper.__getattr__r   )r   r   r   r   r	   r   r   r   r$   r   r<   rF   rK   rM   r>   r   rQ   r   r   r   r   rA   Q   s    &rA   c                   @   s   e Zd ZdZdS )UniformDistributionzgWrapper around torch Uniform distribution which makes it work with the 'spawn' multiprocessing context.N)r   r   r   r   r   r   r   r   rR      s    rR   )typingr   r   r   r   r   r   r   r+   torch.distributionsr	   r
   !kornia.augmentation.utils.helpersr   kornia.corer   r   r   r   r   r   r    rA   rR   r   r   r   r   <module>   s   $	+7