a
    
d                     @   s6  d dl Z d dlZd dlZd dl mZ d dlmZ d dlZd dlZd dl	Z	d dl
mZmZmZ d dlmZ d8ddZd	d
 Zdd Zd9ddZdd Zd:ddZdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Z d;d)d*Z!d+d, Z"d<d-d.Z#d/d0 Z$d1d2 Z%d=d3d4Z&e'd5d6d7Z(dS )>    N)partial)
isfunction)Image	ImageDraw	ImageFont)	load_fileTc                 C   s   | S )zbOverwrite model.train with this function to make sure train/eval mode
    does not change anymore. )selfmoder   r   O/var/www/html/stable-diffusion-webui/repositories/generative-models/sgm/util.pydisabled_train   s    r   c                 C   sL   z:| d dkr8| d dkr8t | }t|tkr8|d W S W n   Y n0 | S )Nr   ())evaltypetuple)str   r   r   get_string_from_tuple   s    
r   c                 C   s   | dkrdS | | d @ dkS )a  
    chat.openai.com/chat
    Return True if n is a power of 2, otherwise return False.

    The function is_power_of_two takes an integer n as input and returns True if n is a power of 2, otherwise it returns False.
    The function works by first checking if n is less than or equal to 0. If n is less than or equal to 0, it can't be a power of 2, so the function returns False.
    If n is greater than 0, the function checks whether n is a power of 2 by using a bitwise AND operation between n and n-1. If n is a power of 2, then it will have only one bit set to 1 in its binary representation. When we subtract 1 from a power of 2, all the bits to the right of that bit become 1, and the bit itself becomes 0. So, when we perform a bitwise AND between n and n-1, we get 0 if n is a power of 2, and a non-zero value otherwise.
    Thus, if the result of the bitwise AND operation is 0, then n is a power of 2 and the function returns True. Otherwise, the function returns False.

    r   F   r   )nr   r   r   is_power_of_two$   s    r   c                    s    fdd}|S )Nc                     sN   t jjj t  t  d | i |W  d    S 1 s@0    Y  d S )N)enableddtypecache_enabled)torchcudaampautocastget_autocast_gpu_dtypeis_autocast_cache_enabled)argskwargsr   fr   r   do_autocast5   s    zautocast.<locals>.do_autocastr   )r%   r   r&   r   r$   r   r   4   s    r   c                 C   s"   t t| d fi | dt S )Ntargetparams)r   get_obj_from_strgetdictconfigr   r   r   load_partial_from_config@   s    r.   
   c           
   	      s  t |}t }t|D ]}tjd| dd}t|}tjd|d}t	d| d d   t
|| trr|| d n|| d	 fd
dtdt  D }	z|jd|	d|d W n ty   td Y n0 t|dddd d }|| qt|}t|}|S )NRGBwhite)colorzdata/DejaVuSans.ttf)size(   r      
c                 3   s   | ]}||   V  qd S Nr   ).0startncZtext_seqr   r   	<genexpr>R   s   z!log_txt_as_img.<locals>.<genexpr>)r   r   black)fillfontz)Cant encode string for logging. Skipping.   r   g     _@g      ?)lenlistranger   newr   Drawr   truetypeint
isinstancejointextUnicodeEncodeErrorprintnparray	transposeappendstackr   tensor)
whxcr3   bZtxtsbitxtdrawr?   linesr   r:   r   log_txt_as_imgD   s,    


rZ   c                    s   G  fddd}|S )Nc                       s&   e Zd Zejjg R i ZdS )zpartialclass.<locals>.NewClsN)__name__
__module____qualname__	functoolspartialmethod__init__r   r"   clsr#   r   r   NewClsc   s   rc   r   )rb   r"   r#   rc   r   ra   r   partialclassb   s    rd   c                 C   s*   t j| \}}|jdkr&tj|S | S )Nfile)fsspeccore	url_to_fsprotocolospathabspath)rk   fspr   r   r   make_path_absolutei   s    
ro   c                 C   s,   t | tjsdS t| jdko*| jd dkS NF   r      rH   r   TensorrA   shapexr   r   r   ismapp   s    rx   c                 C   s:   t | tjsdS t| jdko8| jd dkp8| jd dkS rp   rs   rv   r   r   r   isimagev   s    ry   c                 C   s   t | tjsdS | jdkS )NFr@   )rH   r   rt   ndimrv   r   r   r   	isheatmap|   s    r{   c                 C   s6   t | tjsdS | jdko4| jd dkp4| jd dkS )NF   r@   rr   r   )rH   r   rt   rz   ru   rv   r   r   r   isneighbors   s    r}   c                 C   s   | d uS r7   r   rv   r   r   r   exists   s    r~   c                 C   s    |   |  kr| d} q | S )Nr   )dim	unsqueeze)rw   yr   r   r   expand_dims_like   s    r   c                 C   s   t | r| S t|r| S |S r7   )r~   r   )valdr   r   r   default   s    r   c                 C   s   | j ttdt| jdS )z
    https://github.com/openai/guided-diffusion/blob/27c20a8fab9cb472df5d6bdd6c8d11c8f430b924/guided_diffusion/nn.py#L86
    Take the mean over all non-batch dimensions.
    r   )r   )meanrB   rC   rA   ru   )rR   r   r   r   	mean_flat   s    r   Fc                 C   s<   t dd |  D }|r8t| jj d|d dd |S )Nc                 s   s   | ]}|  V  qd S r7   )numel)r8   rn   r   r   r   r<          zcount_params.<locals>.<genexpr>z has gư>z.2fz
 M params.)sum
parametersrL   	__class__r[   )modelverbosetotal_paramsr   r   r   count_params   s    r   c                 C   sH   d| vr(| dkrd S | dkr d S t dt| d f i | dt S )Nr'   Z__is_first_stage__Z__is_unconditional__z%Expected key `target` to instantiate.r(   )KeyErrorr)   r*   r+   r,   r   r   r   instantiate_from_config   s    r   c                 C   sH   |  dd\}}|rt  |r4t|}t| ttj|d d|S )N.r   )package)rsplit	importlibinvalidate_cachesimport_modulereloadgetattr)stringr   invalidate_cachemodulerb   Z
module_impr   r   r   r)      s    

r)   c                 C   s   t | | dggS )Nr   )r   cat	new_zerosrv   r   r   r   append_zero   s    r   c                 C   s:   || j  }|dk r*td| j  d| d| dd|   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).r7   )rz   
ValueError)rw   Ztarget_dimsZdims_to_appendr   r   r   append_dims   s    
r   c           
      C   s   t d|  |drJtj|dd}d|v r@t d|d   |d }n|dr^t|}ntt| j}|j|d	d
\}}t	|dkr|rt d t | t	|dkr|rt d t | |r|
 D ]
}	d	|	_q|  |S )NzLoading model from ckptcpu)map_locationglobal_stepzGlobal Step: 
state_dictsafetensorsF)strictr   zmissing keys:zunexpected keys:)rL   endswithr   loadload_safetensorsNotImplementedErrorr   r   load_state_dictrA   r   requires_gradr   )
r-   r   r   freezeZpl_sdsdr   muparamr   r   r   load_model_from_config   s,    




r   )returnc                  C   sf   t jt} t j| dt j| ddf}|D ]$}t j|}t j|r.|  S q.td| dS )z
    Get the `configs` directory.
    For a working copy, this is the one in the root of the repository,
    but for an installed copy, it's in the `sgm` package (see pyproject.toml).
    configsz..zCould not find SGM configs in N)rj   rk   dirname__file__rI   rl   isdirFileNotFoundError)this_dir
candidates	candidater   r   r   get_configs_path   s    
r   )T)T)r/   )F)FT)TT))r^   r   rj   r   inspectr   rf   numpyrM   r   PILr   r   r   safetensors.torchr   r   r   r   r   r   r.   rZ   rd   ro   rx   ry   r{   r}   r~   r   r   r   r   r   r)   r   r   r   strr   r   r   r   r   <module>   s@   








