
    +h_                        S r SSKrSSKJrJrJrJr  SSKJr  SSK	J
r
JrJr  \
" 5       (       a  SSKrSSKJrJrJrJr  \R&                  " \5      r SSKJr      S&S
\\\4   S\\\S   S4      S\\\S4      S\S   S\S   4
S jjrS\4S jrS rSSS\ S\ SS4S jr!S\ SSSSS\S   4S  jr"S! r#\RH                  S" 5       r%S'S#\\   4S$ jjr&S'S#\\   4S% jjr'g! \\4 a    S	 r Nf = f)(z1
PyTorch utilities: Utilities related to PyTorch
    N)ListOptionalTupleUnion   )logging)is_torch_availableis_torch_npu_availableis_torch_version)fftnfftshiftifftn	ifftshift)allow_in_graphc                     U $ N )clss    U/home/james-whalen/.local/lib/python3.13/site-packages/diffusers/utils/torch_utils.pymaybe_allow_in_graphr   #   s    
    shape	generatorztorch.Generatordeviceztorch.devicedtypeztorch.dtypelayoutztorch.layoutc                    [        U[        5      (       a  [        R                  " U5      nUnU S   nU=(       d    [        R                  nU=(       d    [        R                  " S5      nUb  [        U[
        5      (       d  UR                  R                  OUS   R                  R                  nXrR                  :w  a.  US:X  a(  SnUS:w  a  [        R                  SU SU SU S35        O'XrR                  :w  a  US	:X  a  [        S
U SU S35      e[        U[
        5      (       a  [        U5      S:X  a  US   n[        U[
        5      (       a`  SU SS -   n [        U5       Vs/ s H  n[        R                  " XU   XSUS9PM     n	n[        R                  " U	SS9R                  U5      n	U	$ [        R                  " XXSUS9R                  U5      n	U	$ s  snf )zA helper function to create random tensors on the desired `device` with the desired `dtype`. When
passing a list of generators, you can seed each batch size individually. If CPU generators are passed, the tensor
is always created on the CPU.
r   cpuNmpszBThe passed generator was created on 'cpu' even though a tensor on zB was expected. Tensors will be created on 'cpu' and then moved to zl. Note that one can probably slightly speed up this function by passing a generator that was created on the z device.cudazCannot generate a z! tensor from a generator of type .r   )r   )r   r   r   r   dim)
isinstancestrtorchr   stridedlisttypeloggerinfo
ValueErrorlenrangerandncatto)
r   r   r   r   r   rand_device
batch_sizegen_device_typeilatentss
             r   randn_tensorr7   '   s    &#f%KqJ$u}}F*u||E*F7A)T7R7R)**//XabcXdXkXkXpXpkk)o.FKXY_X` aKKQ( Sggmfnnvx
 +60I1&9Z[jZkklmnn )T""s9~':aL	)T""uQRy  :&
& KK1k_ef& 	 
 ))G+..v6 N ++ebhillmstN
s   )#Greturnc                     [        SS5      (       d  [        [        S5      (       d  g[        U [        R                  R
                  R                  5      $ )z:Check whether the module was compiled with torch.compile()<z2.0.0_dynamoF)r   hasattrr&   r$   r;   
eval_frameOptimizedModulemodules    r   is_compiled_modulerA   Y   s;    W%%WUI-F-Ffemm66FFGGr   c                 >    [        U 5      (       a  U R                  $ U $ )z8Unwraps a module if it was compiled with torch.compile())rA   	_orig_modr?   s    r   unwrap_modulerD   `   s    1&996EvEr   x_intorch.Tensor	thresholdscalec                 8   U nUR                   u  pEpgXwS-
  -  S:w  d  XfS-
  -  S:w  a  UR                  [        R                  S9nO;UR                  [        R
                  :X  a  UR                  [        R                  S9n[        USS9n[        USS9nUR                   u  pEpg[        R                  " XEXg4UR                  S9n	US-  US-  pX)SX-
  X-   2X-
  X-   24'   X-  n[        USS9n[        USS9R                  nUR                  U R                  S9$ )	zFourier filter as introduced in FreeU (https://huggingface.co/papers/2309.11497).

This version of the method comes from here:
https://github.com/huggingface/diffusers/pull/5164#issuecomment-1732638706
r   r   )r   )r"   )r      .)r   r1   r&   float32r   bfloat16r   r   onesr   r   r   real)rE   rG   rH   xBCHWx_freqmaskcrowccol
x_filtereds                r   fourier_filterr[   e   s    	AJA! 	
Uaq5ka/DDu}}D%	
ENN	"DDu}}D% !"Ff(+FJA!::qQl1884Daa$Z_d!1143CdFV3V	VW]F v8,Fv8,11J==tzz=**r   resolution_idxhidden_statesres_hidden_states)rF   rF   c                    U S:X  a:  UR                   S   S-  nUSS2SU24   US   -  USS2SU24'   [        USUS   S9nU S:X  a:  UR                   S   S-  nUSS2SU24   US   -  USS2SU24'   [        USUS	   S9nX4$ )
a5  Applies the FreeU mechanism as introduced in https:
//arxiv.org/abs/2309.11497. Adapted from the official code repository: https://github.com/ChenyangSi/FreeU.

Args:
    resolution_idx (`int`): Integer denoting the UNet block where FreeU is being applied.
    hidden_states (`torch.Tensor`): Inputs to the underlying block.
    res_hidden_states (`torch.Tensor`): Features from the skip block corresponding to the underlying block.
    s1 (`float`): Scaling factor for stage 1 to attenuate the contributions of the skip features.
    s2 (`float`): Scaling factor for stage 2 to attenuate the contributions of the skip features.
    b1 (`float`): Scaling factor for stage 1 to amplify the contributions of backbone features.
    b2 (`float`): Scaling factor for stage 2 to amplify the contributions of backbone features.
r   r   rL   Nb1s1)rG   rH   b2s2)r   r[   )r\   r]   r^   freeu_kwargsnum_half_channelss        r   apply_freeurf      s     )//2a7/<Q@RAR@R=R/SVbcgVh/ha++++,*+<Q]^bQcd)//2a7/<Q@RAR@R=R/SVbcgVh/ha++++,*+<Q]^bQcd++r   c                      [         R                  R                  5       (       aM  [         R                  " S5      n [         R                  R	                  U 5      nUS    SUS    3n[        U5      $ g )Nr    r   r!   r   )r&   r    is_availabler   get_device_capabilityfloat)r   compute_capabilitys     r    get_torch_cuda_device_capabilityrl      se    zz  f%"ZZ==fE 21 56a8J18M7NO'((r   c                  :   [         R                  R                  5       (       a  g[        5       (       a  g[	        [         S5      (       a$  [         R
                  R                  5       (       a  g[         R                  R                  R                  5       (       a  gg)Nr    npuxpur   r   )r&   r    rh   r
   r<   ro   backendsr   r   r   r   
get_devicerq      se    zz  		!	!			599#9#9#;#;				(	(	*	*r   device_typec                     U c
  [        5       n U S;   a  g [        [        U [        R                  5      nUR	                  5         g )N)r   )rq   getattrr&   r    empty_cacherr   
device_mods     r   empty_device_cacherx      s8     lgUZZ8Jr   c                 |    U c
  [        5       n [        [        U [        R                  5      nUR	                  5         g r   )rq   rt   r&   r    synchronizerv   s     r   device_synchronizer{      s-     lUZZ8Jr   )NNNNr   )(__doc__	functoolstypingr   r   r   r    r   import_utilsr	   r
   r   r&   	torch.fftr   r   r   r   
get_logger__name__r*   torch._dynamor   r   ImportErrorModuleNotFoundErrorr%   r7   boolrA   rD   intr[   rf   rl   	lru_cacherq   rx   r{   r   r   r   <module>r      s    / /  V V ::			H	%D NR37%)'+//d#457HHIJ/ U3./0/ M"	/
 ^$/dH$ HF
+ +C + + +D,,(6,KY,
)*,6 
 
HSM HSM E 	() s   C   C.-C.