o
    i                     @   s   d dl Z d dl mZ d dlm  mZ d dlZd dlmZ d dl	m
Z
mZ d dlmZ d dlZd dlmZmZ dddZdddZdd ZG dd dejZG dd deZdefddZdS )    N)einsum)override)	rearrangerepeat)optimized_attention)ComfyExtensionioc                    s  | j \ } d }}t fdd| ||f\} }}|tjkr3td|  | | }	ntd| || }	~ ~|d ur\t|d}t|	jj	 }
t
|d|d}|	| |
 |	jdd	}	td
|	|j|}|d ddddd d }||	fS )N      c                    s4   |  d ddddd  d S )N   r         )	unsqueezereshapepermute
contiguous)tbdim_headheads 4/mnt/c/Users/fbmor/ComfyUI/comfy_extras/nodes_sag.py<lambda>   s
    z*attention_basic_with_sim.<locals>.<lambda>zb i d, b j d -> b i jzb ... -> b (...)zb j -> (b h) () j)hr   )dimzb i j, b j d -> b i dr   r   r   r
   )shapemaptorchfloat32r   floatr   finfodtypemaxr   masked_fill_softmaxtor   r   r   )qkvr   maskattn_precision_scaler   simmax_neg_valueoutr   r   r   attention_basic_with_sim   s2   



r1         @      ?c                 C   s$  |j \}}}| j \}}}}	||d||}|jdddjddd|k}
|
j d }tt||	 | }d }tdtt|d D ] }|| t	d|| fD ]}|| dkr[|} nqO|d urb nqB|}|| }|
|||
d|j}
t|
||	f}
t| d|d}||
 | d|
   }|S )	Nr   r   F)keepdimr   r   	   )kernel_sizesigma)r   r   meansumroundmathsqrtrangefloorr#   r   typer"   Finterpolategaussian_blur_2d)x0attnr7   	thresholdr,   hw1hw2r   lhlwr*   totalxxxijyblurredr   r   r   create_blur_map8   s4   
rQ   c           	      C   s   |d d }t j| ||d}t d|| d }||  }|j| j| jd}t |d d d f |d d d f }|	| j
d d|j
d |j
d }|d |d |d |d g}tj| |d	d
} tj| || j
d d} | S )Nr         ?)stepsr	   r   )devicer"   r   reflect)mode)groups)r   linspaceexppowr9   r&   rT   r"   mmexpandr   r@   padconv2d)	imgr6   r7   
ksize_halfrK   pdfx_kernelkernel2dpaddingr   r   r   rB   [   s   $"rB   c                   @   s$   e Zd Zedd Zedd ZdS )SelfAttentionGuidancec                 C   sR   t jdddt jdt jjddddd	d
t jjdddddddgt j gddS )Nrf   zSelf-Attention Guidance_for_testingmodelr-   rR   g       g      @g{Gz?)defaultminr#   step
blur_sigmag       @g        g      $@g?T)ri   rj   r#   rk   advanced)node_iddisplay_namecategoryinputsoutputsis_experimental)r   SchemaModelInputFloatOutput)clsr   r   r   define_schemao   s   
z#SelfAttentionGuidance.define_schemac                    sP   |  }d   fdd} fdd}|j|dd ||ddd t|S )	Nc                    s   |d }|d }| j d t| }d|v r9|d}t| ||||d d\}}	|| }
|	|
| |
|d    |S t| ||||d dS )Nn_headscond_or_uncondr   r   r+   )r   r+   )r   lenindexr1   r   )r'   r(   r)   extra_optionsr   r|   r   uncond_indexr0   r.   n_slices)attn_scoresr   r   attn_and_record   s   
z6SelfAttentionGuidance.execute.<locals>.attn_and_recordc                    s    }}}d}| d }| d }| d }| d }| d }	| d }
| d }t |jd	d  d
kr1|S t||||}|| | }tj||g||	|
\}||| |  S )Nr3   rh   uncond_denoisedunconddenoisedr7   model_optionsinputr      )rj   r   rQ   comfysamplerscalc_cond_batch)argsuncond_attn	sag_scale	sag_sigmasag_thresholdrh   uncond_predr   
cfg_resultr7   r   rK   degradeddegraded_noisedsagr   rl   r-   r   r   post_cfg_function   s"   z8SelfAttentionGuidance.execute.<locals>.post_cfg_functionT)disable_cfg1_optimizationmiddler   )clone#set_model_sampler_post_cfg_functionset_model_attn1_replacer   
NodeOutput)ry   rh   r-   rl   mr   r   r   r   r   execute   s   
zSelfAttentionGuidance.executeN)__name__
__module____qualname__classmethodrz   r   r   r   r   r   rf   n   s
    
rf   c                   @   s(   e Zd Zedeeej  fddZdS )SagExtensionreturnc                    s   t gS N)rf   )selfr   r   r   get_node_list   s   zSagExtension.get_node_listN)	r   r   r   r   listr?   r   	ComfyNoder   r   r   r   r   r      s    r   r   c                      s   t  S r   )r   r   r   r   r   comfy_entrypoint   s   r   )NN)r2   r3   )r   r   torch.nn.functionalnn
functionalr@   r;   typing_extensionsr   einopsr   r   comfy.ldm.modules.attentionr   comfy.samplersr   comfy_api.latestr   r   r1   rQ   rB   r   rf   r   r   r   r   r   r   <module>   s    

)#L