o
    iU                     @   s   d dl Z d dlmZmZmZ d dlmZ d dlmZm	Z	 d dl
Z
dde jdefddZd	d
 Z	dde jdededededededeeef f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)TupleCallableOptional)override)ComfyExtensionioxmodec                 C      | S N )r   r	   r   r   7/mnt/c/Users/fbmor/ComfyUI/comfy_extras/nodes_tomesd.py
do_nothing	   s   r   c                 C   sL   | j d dkrt| d|dk r|d n||ddS t| ||S )N   r   )shapetorchgather	unsqueezesqueeze)inputdimindexr   r   r   mps_gather_workaround   s   r   Fmetricwhsxsyrno_randreturnc                    s  | j \ }dks|dks|dkrttfS | jjdkrtntjt  || || }}	|r?tj||	d| jtj	d}
ntj
|| ||	df| jd}
tj||	|| | jtj	d}|jd|
tj|
|
jd d |||	||dd|| |	| }|| |k s|	| |k rtj||| jtj	d}||d	|| d	|	| f< n|}|dd
djdd}
~~||	 |
d	d	d	d	d	f |
d	d	d	d	d	f  fdd| | jd
dd } | \}}||d
d }t|j d |jd
d\}}|jd
ddd }|dd	d	d	f 
|dd	d	d	f 	|d d	dW d	   n	1 s6w   Y  ddtjdtjf	
fdd}dtjdtjf 	
f
dd}||fS )a  
    Partitions the tokens into src and dst and merges r tokens from src to dst.
    Dst tokens are partitioned by choosing one randomy in each (sx, sy) region.
    Args:
     - metric [B, N, C]: metric to use for similarity
     - w: image width in tokens
     - h: image height in tokens
     - sx: stride in the x dimension for dst, must divide w
     - sy: stride in the y dimension for dst, must divide h
     - r: number of tokens to remove (by merging)
     - no_rand: if true, disable randomness (use top left corner only)
    r   r   mpsdevicedtype)sizer$      )r%   r   r   srcNr   r   c                    sF   | j d }| d  |d}| d |d}||fS )Nr   r   r   r   )r   expand)r   Cr)   dst)BNa_idxb_idxr   num_dstr   r   splitN   s   
z/bipartite_soft_matching_random2d.<locals>.splitT)r   keepdim)r   
descending).N.r+   meanr   r!   c                    sz   | \}}|j \}}}|d|| |d}|d||d}|jd ||||d}tj||gddS )Nr6   r+   )reducer   r*   )r   r,   scatter_reducer   cat)r   r	   r)   r.   nt1cunm)dst_idxr   r   r4   src_idxunm_idxr   r   merged   s   z/bipartite_soft_matching_random2d.<locals>.mergec                    s   	j d }| dd |d d f | d|d d d f }}|j \}}}|d |d}tj || j| jd}|jd ||d |jd j d dd	d |||d |jd j d ddd ||d |S )Nr   .r6   r+   r#   r(   )r   r,   r   zerosr$   r%   scatter_)r   unm_lenr?   r.   _r>   r)   out)
r/   r0   r1   r2   r@   r   r3   r   rA   rB   r   r   unmergen   s   
.44z1bipartite_soft_matching_random2d.<locals>.unmerge)r8   )r   r   r$   typer   r   r   no_gradrD   int64randintrE   	ones_liker%   view	transposereshapeargsortnormminmaxTensor)r   r   r   r   r   r   r    rG   hsywsxrand_idxidx_buffer_view
idx_bufferabscoresnode_maxnode_idxedge_idxrC   rI   r   )r/   r0   r1   r2   r@   r   r3   r   r4   rA   rB   r    bipartite_soft_matching_random2d   sF   (&6,
rb   c                 C   s   |\}}}}|| }t tt|| jd  }d}	d}
d}||krPt t|| }t t|| }t | jd | }d}t| |||	|
||\}}||fS dd }||fS )Nr   r'   Fc                 S   r
   r   r   )yr   r   r   <lambda>   s    zget_functions.<locals>.<lambda>)intmathceilsqrtr   rb   )r   ratiooriginal_shaper]   r>   
original_h
original_woriginal_tokens
downsamplestride_xstride_ymax_downsampler   r   r   r    munothingr   r   r   get_functions   s   ru   c                   @   s,   e Zd Zedd ZedejfddZdS )TomePatchModelc                 C   s8   t jddt jdt jjdddddd	gt j gd
S )Nrv   zmodel_patches/unetmodelri   g333333?g        g      ?g{Gz?)defaultrT   rU   step)node_idcategoryinputsoutputs)r   SchemaModelInputFloatOutput)clsr   r   r   define_schema   s   

zTomePatchModel.define_schemar!   c                    sD   d  fdd}fdd}|  }|| || t|S )Nc                    s"   t |  |d \}|| ||fS )Nrj   )ru   )qkvextra_optionsrr   ri   rs   r   r   tomesd_m   s   z(TomePatchModel.execute.<locals>.tomesd_mc                    s    | S r   r   )r<   r   )rs   r   r   tomesd_u   s   z(TomePatchModel.execute.<locals>.tomesd_u)cloneset_model_attn1_patchset_model_attn1_output_patchr   
NodeOutput)r   rw   ri   r   r   rr   r   r   r   execute   s   


zTomePatchModel.executeN)__name__
__module____qualname__classmethodr   r   r   r   r   r   r   r   rv      s
    
rv   c                   @   s(   e Zd Zedeeej  fddZdS )TomePatchModelExtensionr!   c                    s   t gS r   )rv   )selfr   r   r   get_node_list   s   z%TomePatchModelExtension.get_node_listN)	r   r   r   r   listrJ   r   	ComfyNoder   r   r   r   r   r      s    r   c                      s   t  S r   )r   r   r   r   r   comfy_entrypoint   s   r   r   )F)r   typingr   r   r   typing_extensionsr   comfy_api.latestr   r   rf   rV   strr   r   re   boolrb   ru   r   rv   r   r   r   r   r   r   <module>   s6   


h 