
    bi                     P   d dl Z d dlmZmZ d dlmZmZ d dlZd dlm	c m
Z ddlmZ ddlmZmZmZ ddlmZmZ  ee      Zd	Ze G d
 d             Z G d de      Z	 ddej                  j4                  dededee   ddf
dZdej<                  dedededej<                  f
dZ y)    N)asdict	dataclass)ListOptional   )
get_logger   )"_ALL_TRANSFORMER_BLOCK_IDENTIFIERS_ATTENTION_CLASSES_get_submodule_from_fqn)HookRegistry	ModelHooksmoothed_energy_guidance_hookc                   d    e Zd ZU dZee   ed<   dZeed<   dZ	ee   ed<   d Z
eded	d fd
       Zy)SmoothedEnergyGuidanceConfiga}  
    Configuration for skipping internal transformer blocks when executing a transformer model.

    Args:
        indices (`List[int]`):
            The indices of the layer to skip. This is typically the first layer in the transformer block.
        fqn (`str`, defaults to `"auto"`):
            The fully qualified name identifying the stack of transformer blocks. Typically, this is
            `transformer_blocks`, `single_transformer_blocks`, `blocks`, `layers`, or `temporal_transformer_blocks`.
            For automatic detection, set this to `"auto"`. "auto" only works on DiT models. For UNet models, you must
            provide the correct fqn.
        _query_proj_identifiers (`List[str]`, defaults to `None`):
            The identifiers for the query projection layers. Typically, these are `to_q`, `query`, or `q_proj`. If
            `None`, `to_q` is used by default.
    indicesautofqnN_query_proj_identifiersc                     t        |       S N)r   )selfs    i/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/diffusers/hooks/smoothed_energy_guidance_utils.pyto_dictz$SmoothedEnergyGuidanceConfig.to_dict6   s    d|    datareturnc                     t        di | S )N )r   )r   s    r   	from_dictz&SmoothedEnergyGuidanceConfig.from_dict9   s    +3d33r   )__name__
__module____qualname____doc__r   int__annotations__r   strr   r   staticmethoddictr    r   r   r   r   r       sT      #YC)-T#Y- 4 4!? 4 4r   r   c                        e Zd Zd	dededdf fdZdej                  j                  dej                  dej                  fdZ	 xZ
S )
SmoothedEnergyGuidanceHook
blur_sigmablur_threshold_infr   Nc                 >    t         |           || _        || _        y r   )super__init__r,   r-   )r   r,   r-   	__class__s      r   r0   z#SmoothedEnergyGuidanceHook.__init__?   s    $"4r   moduleoutputc                     t        j                  d| j                  z        dz   t        j                  d| j                  z        dz  z
  }t        ||| j                  | j                        }|S )N   r	   r   )mathceilr,   _gaussian_blur_2dr-   )r   r2   r3   kernel_sizesmoothed_outputs        r   post_forwardz'SmoothedEnergyGuidanceHook.post_forwardD   s\    iiDOO 34q8499QEX;Y\];]]+FKRVRiRijr   )g      ?g3333@)r!   r"   r#   floatr0   torchnnModuleTensorr;   __classcell__)r1   s   @r   r+   r+   >   sH    55 5E 5W[ 5
588?? ELL U\\ r   r+   r2   configr,   namer   c                 *   |xs t         }|j                  dk(  r+t        D ]  }t        | |      s||_         n t	        d      |j
                  dg|_        t        | |j                        }d}t        |      D ]  \  }}||j                  vrd}|j                         D ]  \  }	}
t        |
t              r|
j                  r#|j
                  D ]  }t        |
|d       }|$t        |t        j                  j                         s7t"        j%                  d|j                   d| d|	 d|        t'        j(                  |      }t+        |      }|j-                  ||          |s&t	        d|j                   d	|j                   d
      y )Nr   zCould not find a suitable identifier for the transformer blocks automatically. Please provide a valid `fqn` (fully qualified name) that identifies a stack of transformer blocks.to_qFTz-Registering smoothed energy guidance hook on .zDCould not find any transformer blocks matching the provided indices z and fully qualified name 'z4'. Please check the indices and fqn for correctness.)_SMOOTHED_ENERGY_GUIDANCE_HOOKr   r
   hasattr
ValueErrorr   r   	enumerater   named_modules
isinstancer   is_cross_attentiongetattrr=   r>   Linearloggerdebugr   check_if_exists_or_initializer+   register_hook)r2   rB   r,   rC   
identifiertransformer_blocksblocks_foundiblocksubmodule_name	submodule
query_projregistryhooks                 r   $_apply_smoothed_energy_guidance_hookr^   K   s    11DzzV< 	Jvz*'
	
 ^ 
 %%-*0&0DL01 35FNN").)<)<)> 	3%NIi);<	@\@\$<< 	3
$Y
DA
%Z
EHHOO-TCFJJ<qQRPSSTUcTddefpeqr (EEjQ1*=&&tT2	3	33( RSYSaSaRb c%%+ZZL0df
 	
 r   queryr9   sigmasigma_threshold_infc                    | j                   dk(  sJ ||kD  }| j                  \  }}}t        t        j                  |            }||z  }	| ddd|	ddf   }
|
j                  ddd      }
|
j                  ||||      }
|rt        |||dz  dz
  z
        }|dz
  dz  }t        j                  | ||      }t        j                  d||z  j                  d      z        }||j                         z  }|j                  |       }t        j                  |dddf   |dddf         }|j                  |d|j                  d   |j                  d         }|dz  |dz  |dz  |dz  g}t!        j"                  |
|d	      }
t!        j$                  |
||
      }
n|
j'                  dd      |
dd |
j                  |||	      }
|
j                  ddd      }
|
j)                         | ddd|	ddf<   | S )a  
    This implementation assumes that the input query is for visual (image/videos) tokens to apply the 2D gaussian blur.
    However, some models use joint text-visual token attention for which this may not be suitable. Additionally, this
    implementation also assumes that the visual tokens come from a square image/video. In practice, despite these
    assumptions, applying the 2D square gaussian blur on the query projections generates reasonable results for
    Smoothed Energy Guidance.

    SEG is only supported as an experimental prototype feature for now, so the implementation may be modified in the
    future without warning or guarantee of reproducibility.
       Nr   r   r	   )stepsg      reflect)mode)groups)T)dimkeepdim)ndimshaper%   r6   sqrtpermutereshapeminr=   linspaceexppowsumtomatmulexpandFpadconv2dmeanclone)r_   r9   r`   ra   is_inf
batch_sizeseq_len	embed_dimseq_len_sqrtnum_square_tokensquery_slicekernel_size_halfxpdfkernel1dkernel2dpaddings                    r   r8   r8   |   s    ::??((F%*[["Jtyy)*L$|3---q01K%%aA.K%%j)\<XK+||a7G!7K'LM'!Oq0NN,,.>kRiiE	q112?;;u%<<D 18D!G3DE??9a1BHNNSTDUV!#[A%5{a7GXYIYZeeKyAhh{HYG$))h)EA%%j)=NOK%%aA.K&1&7&7&9E!
"#Lr   r   )!r6   dataclassesr   r   typingr   r   r=   torch.nn.functionalr>   
functionalry   utilsr   _commonr
   r   r   hooksr   r   r!   rP   rG   r   r+   r?   r<   r'   r^   r@   r%   r8   r   r   r   <module>r      s     ) !     d d * 
H	!@  4 4 4:
 
 mq-
HHOO-
%A-
OT-
\deh\i-
	-
b+U\\ + +E +`e +jojvjv +r   