o
    i2                     @   s  d dl mZ d dlZd dlZd dlmZ d dlZd dlZd dlZd dl	m
Z
 d dlZd dlmZmZ d dlmZ d1dd	Zd
d Zdd Zd2ddZed3ddZdd Ze dd ZG dd dZG dd dejjZG dd dejjZdddejfd d!Zddded"dejfd#d$Z dejfd%d&Z!dded"dejfd'd(Z"dejfd)d*Z#G d+d, d,ej$Z%G d-d. d.Z&ed4d/d0Z'dS )5    )contextmanagerN)Path)Image)nnoptim)dataRGBc                    s     fdd| | D }||iS )z4Apply passed in transforms for HuggingFace Datasets.c                    s   g | ]	}|  qS  )convert).0imagemode	transformr	   5/mnt/c/Users/fbmor/ComfyUI/comfy/k_diffusion/utils.py
<listcomp>   s    z+hf_datasets_augs_helper.<locals>.<listcomp>r	   )examplesr   	image_keyr   imagesr	   r   r   hf_datasets_augs_helper   s   r   c                 C   sV   || j  }|dk rtd| j  d| d| dd|   }|jjdkr)|  S |S )zNAppends dimensions to the end of a tensor until it has target_dims dimensions.r   z
input has z dims but target_dims is z, which is less).Nmps)ndim
ValueErrordevicetypedetachclone)xtarget_dimsdims_to_appendexpandedr	   r	   r   append_dims   s
   
r"   c                 C   s   t dd |  D S )z7Returns the number of trainable parameters in a module.c                 s   s    | ]}|  V  qd S r   )numel)r   pr	   r	   r   	<genexpr>"   s    zn_params.<locals>.<genexpr>)sum
parameters)moduler	   r	   r   n_params    s   r)   c              	   C   s   t | } | jjddd |  sAtj|#}t| d}t	|| W d   n1 s-w   Y  W d   n1 s<w   Y  |dur`t
t| d  }||kr`td|  d| d| S )	zLDownloads a file if it does not exist, optionally checking its SHA-256 hash.T)parentsexist_okwbNrbzhash of z (url: z) failed to validate)r   parentmkdirexistsurllibrequesturlopenopenshutilcopyfileobjhashlibsha256read	hexdigestOSError)pathurldigestresponseffile_digestr	   r	   r   download_file%   s    rB   Tc              	   c   sj    dd |   D }z| |V  W t|   D ]	\}}|| |_qdS t|   D ]	\}}|| |_q*w )zdA context manager that places a model into training mode and restores
    the previous mode on exit.c                 S   s   g | ]}|j qS r	   )training)r   r(   r	   r	   r   r   7   s    ztrain_mode.<locals>.<listcomp>N)modulestrain	enumeraterC   )modelr   modesir(   r	   r	   r   
train_mode3   s   rJ   c                 C   s
   t | dS )zfA context manager that places a model into evaluation mode and restores
    the previous mode on exit.F)rJ   )rG   r	   r	   r   	eval_mode?   s   
rK   c           
      C   s   t |  }t | }| | ksJ | D ]\}}|| |j|d| d qt |  }t | }| | ksCJ | D ]\}}	|| |	 qGdS )zIncorporates updated model parameters into an exponential moving averaged
    version of a model. It should be called after each optimizer step.   )alphaN)dictnamed_parameterskeysitemsmul_add_named_bufferscopy_)
rG   averaged_modeldecaymodel_paramsaveraged_paramsnameparammodel_buffersaveraged_buffersbufr	   r	   r   
ema_updateE   s   r_   c                   @   s>   e Zd ZdZ		dddZdd Zd	d
 Zdd Zdd ZdS )	EMAWarmupaY  Implements an EMA warmup using an inverse decay schedule.
    If inv_gamma=1 and power=1, implements a simple average. inv_gamma=1, power=2/3 are
    good values for models you plan to train for a million or more steps (reaches decay
    factor 0.999 at 31.6K steps, 0.9999 at 1M steps), inv_gamma=1, power=3/4 for models
    you plan to train for less (reaches decay factor 0.999 at 10K steps, 0.9999 at
    215.4k steps).
    Args:
        inv_gamma (float): Inverse multiplicative factor of EMA warmup. Default: 1.
        power (float): Exponential factor of EMA warmup. Default: 1.
        min_value (float): The minimum EMA decay rate. Default: 0.
        max_value (float): The maximum EMA decay rate. Default: 1.
        start_at (int): The epoch to start averaging at. Default: 0.
        last_epoch (int): The index of last epoch. Default: 0.
          ?        r   c                 C   s(   || _ || _|| _|| _|| _|| _d S r   )	inv_gammapower	min_value	max_valuestart_at
last_epoch)selfrc   rd   re   rf   rg   rh   r	   r	   r   __init__h   s   
zEMAWarmup.__init__c                 C   s   t | j S )z2Returns the state of the class as a :class:`dict`.)rN   __dict__rQ   ri   r	   r	   r   
state_dictq   s   zEMAWarmup.state_dictc                 C   s   | j | dS )zLoads the class's state.
        Args:
            state_dict (dict): scaler state. Should be an object returned
                from a call to :meth:`state_dict`.
        N)rk   update)ri   rm   r	   r	   r   load_state_dictu   s   zEMAWarmup.load_state_dictc                 C   sL   t d| j| j }dd|| j  | j   }|dk rdS t| jt | j|S )z Gets the current EMA decay rate.r   rL   rb   )maxrh   rg   rc   rd   minrf   re   )ri   epochvaluer	   r	   r   	get_value}   s    zEMAWarmup.get_valuec                 C   s   |  j d7  _ dS )zUpdates the step count.rL   N)rh   rl   r	   r	   r   step   s   zEMAWarmup.stepN)ra   ra   rb   ra   r   r   )	__name__
__module____qualname____doc__rj   rm   ro   rt   ru   r	   r	   r	   r   r`   X   s    
	r`   c                       6   e Zd ZdZ		d fdd	Zdd	 Zd
d Z  ZS )	InverseLRaM  Implements an inverse decay learning rate schedule with an optional exponential
    warmup. When last_epoch=-1, sets initial lr as lr.
    inv_gamma is the number of steps/epochs required for the learning rate to decay to
    (1 / 2)**power of its original value.
    Args:
        optimizer (Optimizer): Wrapped optimizer.
        inv_gamma (float): Inverse multiplicative factor of learning rate decay. Default: 1.
        power (float): Exponential factor of learning rate decay. Default: 1.
        warmup (float): Exponential warmup factor (0 <= warmup < 1, 0 to disable)
            Default: 0.
        min_lr (float): The minimum learning rate. Default: 0.
        last_epoch (int): The index of last epoch. Default: -1.
        verbose (bool): If ``True``, prints a message to stdout for
            each update. Default: ``False``.
    ra   rb   Fc                    P   || _ || _d|  krdk std td|| _|| _t ||| d S Nrb   rL   zInvalid value for warmup)rc   rd   r   warmupmin_lrsuperrj   )ri   	optimizerrc   rd   r   r   rh   verbose	__class__r	   r   rj         zInverseLR.__init__c                 C      | j std |  S NzTTo get the last learning rate computed by the scheduler, please use `get_last_lr()`._get_lr_called_within_stepwarningswarn_get_closed_form_lrrl   r	   r	   r   get_lr      
zInverseLR.get_lrc                    sD   dj jd   djj  j    fddjD S )NrL   c                        g | ]}t j|   qS r	   rp   r   r   base_lrlr_multri   r   r	   r   r          z1InverseLR._get_closed_form_lr.<locals>.<listcomp>)r   rh   rc   rd   base_lrsrl   r	   r   r   r      s
   zInverseLR._get_closed_form_lr)ra   ra   rb   rb   r|   Frv   rw   rx   ry   rj   r   r   __classcell__r	   r	   r   r   r{          
r{   c                       rz   )ExponentialLRaE  Implements an exponential learning rate schedule with an optional exponential
    warmup. When last_epoch=-1, sets initial lr as lr. Decays the learning rate
    continuously by decay (default 0.5) every num_steps steps.
    Args:
        optimizer (Optimizer): Wrapped optimizer.
        num_steps (float): The number of steps to decay the learning rate by decay in.
        decay (float): The factor by which to decay the learning rate every num_steps
            steps. Default: 0.5.
        warmup (float): Exponential warmup factor (0 <= warmup < 1, 0 to disable)
            Default: 0.
        min_lr (float): The minimum learning rate. Default: 0.
        last_epoch (int): The index of last epoch. Default: -1.
        verbose (bool): If ``True``, prints a message to stdout for
            each update. Default: ``False``.
          ?rb   r|   Fc                    r}   r~   )	num_stepsrW   r   r   r   r   rj   )ri   r   r   rW   r   r   rh   r   r   r	   r   rj      r   zExponentialLR.__init__c                 C   r   r   r   rl   r	   r	   r   r      r   zExponentialLR.get_lrc                    sB   dj jd   jdj  j   fddjD S )NrL   c                    r   r	   r   r   r   r	   r   r      r   z5ExponentialLR._get_closed_form_lr.<locals>.<listcomp>)r   rh   rW   r   r   rl   r	   r   r   r      s
   z!ExponentialLR._get_closed_form_lr)r   rb   rb   r|   Fr   r	   r	   r   r   r      r   r   rb   ra   cpuc                 C   s   t j| ||d| |  S )z-Draws samples from an lognormal distribution.r   dtype)torchrandnexp)shapelocscaler   r   r	   r	   r   rand_log_normal   s   r   infc           
      C   s   t j||t jd}t j||t jd}| || }| || }t j| |t jd||  | }	|	 	|
| |S )zEDraws samples from an optionally truncated log-logistic distribution.r   )r   	as_tensorfloat64logsubdivsigmoidrandlogitmuladdr   to)
r   r   r   re   rf   r   r   min_cdfmax_cdfur	   r	   r   rand_log_logistic   s   r   c                 C   s4   t |}t |}tj| ||d||  |  S )z/Draws samples from an log-uniform distribution.r   )mathr   r   r   r   )r   re   rf   r   r   r	   r	   r   rand_log_uniform   s   

 r   c           	      C   sd   t || d t j }t || d t j }tj| ||d||  | }t|t j d | S )zJDraws samples from a truncated v-diffusion training timestep distribution.   r   )r   atanpir   r   tan)	r   
sigma_datare   rf   r   r   r   r   r   r	   r	   r   rand_v_diffusion   s   r   c                 C   s`   t j| ||d }t j| ||d}||  | }|| | }	|||  }
t ||
k ||	 S )z2Draws samples from a split lognormal distribution.r   )r   r   absr   wherer   )r   r   scale_1scale_2r   r   nr   n_leftn_rightratior	   r	   r   rand_split_log_normal   s   r   c                       sB   e Zd ZdZh dZd fdd	Zdd Zdd	 Zd
d Z  Z	S )FolderOfImageszURecursively finds all images in a directory. It does not support
    classes/targets.>	   .bmp.jpg.pgm.png.ppm.tif.jpeg.tiff.webpNc                    sN   t    t| _|d u rt n| _t fdd jdD  _	d S )Nc                 3   s$    | ]}|j   jv r|V  qd S r   )suffixlowerIMG_EXTENSIONS)r   r<   rl   r	   r   r%     s   " z*FolderOfImages.__init__.<locals>.<genexpr>*)
r   rj   r   rootr   Identityr   sortedrglobpaths)ri   r   r   r   rl   r   rj     s   

$zFolderOfImages.__init__c                 C   s   d| j  dt|  dS )NzFolderOfImages(root="z", len: ))r   lenrl   r	   r	   r   __repr__     zFolderOfImages.__repr__c                 C   s
   t | jS r   )r   r   rl   r	   r	   r   __len__  s   
zFolderOfImages.__len__c                 C   sT   | j | }t|d}t|d}W d    n1 sw   Y  | |}|fS )Nr-   r   )r   r4   r   r
   r   )ri   keyr<   r@   r   r	   r	   r   __getitem__  s   

zFolderOfImages.__getitem__r   )
rv   rw   rx   ry   r   rj   r   r   r   r   r	   r	   r   r   r     s    r   c                   @   s   e Zd Zdd Zdd ZdS )	CSVLoggerc                 C   sJ   t || _|| _| j rt| jd| _d S t| jd| _| j| j  d S )Naw)r   filenamecolumnsr0   r4   filewrite)ri   r   r   r	   r	   r   rj     s   

zCSVLogger.__init__c                 G   s   t |d| jdd d S )N,T)sepr   flush)printr   )ri   argsr	   r	   r   r   &  r   zCSVLogger.writeN)rv   rw   rx   rj   r   r	   r	   r	   r   r     s    	r   c                 c   s    t jjj}t jjjj}z.| dur| t jj_|dur |t jjj_dV  W | dur-|t jj_|dur9|t jjj_dS dS | durD|t jj_|durN|t jjj_w )zGA context manager that sets whether TF32 is allowed on cuDNN or matmul.N)r   backendscudnn
allow_tf32cudamatmul)r   r   	cudnn_old
matmul_oldr	   r	   r   	tf32_mode*  s$   



r   )r   r   )T)NN)(
contextlibr   r7   r   pathlibr   r5   r1   r   PILr   r   r   r   torch.utilsr   r   r"   r)   rB   rJ   rK   no_gradr_   r`   lr_scheduler_LRSchedulerr{   r   float32r   floatr   r   r   r   Datasetr   r   r   r	   r	   r	   r   <module>   s@    


0))

