
    3j@                        S r SSKJr  SSKrSSKrSSKrSSKJrJrJ	r	J
r
Jr   " S S5      rSS jrSS jrSS	 jr  S       SS
 jjr0 S.SS jjr/ SQrg)zM
A module containing commonly-used functionality to implement architectures.
    )annotationsN)AnyLiteralMappingProtocolTypeVarc                  \    \ rS rSrSr    S	S jr\S
S j5       r\S
S j5       rSS jr	Sr
g)KeyCondition   z=
A condition that checks if a state dict has the given keys.
c                    X l         Xl        g N_keys_kind)selfkindkeyss      P/home/wildlama/miniconda3/lib/python3.13/site-packages/spandrel/util/__init__.py__init__KeyCondition.__init__   s     
,0
    c                     [        SU 5      $ )Nallr
   r   s    r   has_allKeyCondition.has_all       E4((r   c                     [        SU 5      $ )Nanyr   r   s    r   has_anyKeyCondition.has_any   r   r   c                   ^^ SU4S jjmU R                   S:X  a  [        U4S jU R                   5       5      $ [        U4S jU R                   5       5      $ )Nc                H   > [        U [        5      (       a  U " T5      $ U T;   $ r   )
isinstancer
   )key
state_dicts    r   _detect&KeyCondition.__call__.<locals>._detect!   s%    #|,,:&*$$r   r   c              3  4   >#    U  H  nT" U5      v   M     g 7fr    .0r&   r(   s     r   	<genexpr>(KeyCondition.__call__.<locals>.<genexpr>'        :zws||z   c              3  4   >#    U  H  nT" U5      v   M     g 7fr   r+   r,   s     r   r.   r/   )   r0   r1   )r&   str | KeyConditionreturnbool)r   r   r   r    )r   r'   r(   s    `@r   __call__KeyCondition.__call__    s@    	%
 :::tzz::::tzz:::r   r   N)r   zLiteral['all', 'any']r   ztuple[str | KeyCondition, ...])r   r3   r4   r
   )r'   Mapping[str, object]r4   r5   )__name__
__module____qualname____firstlineno____doc__r   staticmethodr   r!   r6   __static_attributes__r+   r   r   r
   r
      sI    1)11O1 ) ) ) )	;r   r
   c                l    [        S5       H%  nUR                  [        U5      5      U ;   d  M#  Us  $    g)a   
Returns the maximum index `i` such that `key_pattern.format(str(i))` is in `state`.

If no such key is in state, then `-1` is returned.

Example:
    get_first_seq_index(state, "body.{}.weight") -> -1
    get_first_seq_index(state, "body.{}.weight") -> 3
d   )rangeformatstr)r'   key_patternis      r   get_first_seq_indexrH   ,   s3     3Zc!f%3H  r   c                ,   US-   n[        5       nU R                  5        HT  nUR                  U5      (       d  M  U[        U5      S R	                  SSS9S   nUR                  [        U5      5        MV     [        U5      S:X  a  g[        U5      S-   $ )z
Returns the length of a sequence in the state dict.

The length is detected by finding the maximum index `i` such that
`{seq_key}.{i}.{suffix}` is in `state` for some suffix.

Example:
    get_seq_len(state, "body") -> 5
.N   )maxsplitr   )setr   
startswithlensplitaddintmax)r'   seq_keyprefixr   kindexs         r   get_seq_lenrX   <   s     s]FUD__<<c&km$**3*;A>EHHSZ  
 4yA~t9q=r   c                    SS jnUSSS/nU HA  nX-  S:X  d  M  U" X-  5      (       d  M  [        [        R                  " X-  5      5      U4s  $    [        SU  S35      e)	z
Returns a scale and number of output channels such that `scale**2 * out_nc = x`.

This is commonly used for pixelshuffel layers.
c                n    [         R                  " U 5      [        [         R                  " U 5      5      :H  $ r   )mathsqrtrR   )ns    r   	is_square0get_scale_and_output_channels.<locals>.is_squarec   s"    yy|s499Q<000r         rK   r   zwExpected output channels to be either 1, 3, or 4. Could not find a pair (scale, out_nc) such that `scale**2 * out_nc = `)r]   rR   r4   r5   )rR   r[   r\   AssertionError)xinput_channelsr^   
candidatescs        r   get_scale_and_output_channelsrh   S   su     1 !!Q*J5A:)AF++tyy()1,,  QQRPSST	V r   c                    SnUn[        SSS5       HH  nU SU S3nX`;  a    X44$ X   nUR                  nUS   nU[        R                  " US   U-  5      -  nMJ     X44$ )aa  
This will detect the upscale factor and number of features of a pixelshuffle module in the state dict.

A pixelshuffle module is a sequence of alternating up convolutions and pixelshuffle.
The class of this module is commonyl called `Upsample`.
Examples of such modules can be found in most SISR architectures, such as SwinIR, HAT, RGT, and many more.
rK   r   
      rJ   z.weight)rC   shaper[   isqrt)	r'   upsample_key
default_nfupscalenum_featrG   r&   tensorrl   s	            r   get_pixelshuffle_paramsrs   r   s     GH1b!_as'*   !'84::eAh(233  r   )extra_parametersc                X   ^ ^ SS jm " S S[         5      n[        SUS9nSU U4S jjnU$ )	zI
Stores the hyperparameters of a class in a `hyperparameters` attribute.
c           	         0 nU R                   b  U R                   nU R                  bD  0 UE[        [        U R                  [        U R                  5      * S  U R                  5      5      EnU$ r   )kwonlydefaultsdefaultsdictzipargsrO   )specrx   s     r   get_arg_defaults/store_hyperparameters.<locals>.get_arg_defaults   sn    ***H==$s499c$--&8%8%:;T]]KLH
 r   c                       \ rS rSr% S\S'   Srg)2store_hyperparameters.<locals>.WithHyperparameters   dict[str, Any]hyperparametersr+   N)r9   r:   r;   r<   __annotations__r?   r+   r   r   WithHyperparametersr      s    ''r   r   C)boundc                j  >^^ U R                   m[        R                  " T5      nT" U5      mUR                  b  [	        S5      eUR
                  b  [	        S5      eUR                  S/:w  a  [	        SU R                  -   S-   5      e[        R                  " T5      SUUU4S jj5       nX l         U $ )NzPClass has *args, which is not allowed in combination with @store_hyperparameterszSClass has **kwargs, which is not allowed in combination with @store_hyperparametersr   z2@store_hyperparameters requires all arguments of `zW.__init__` after `self` to be keyword arguments. Use `def __init__(self, *, a, b, c):`.c           
        > TR                  5        H,  u  p#X!;   d  M  X   U:w  a  [        SU SU SX    35      eX	 M.     0 TETEUEU l        T" U 40 UD6  g )NzExpected hyperparameter z to be z
, but got )items
ValueErrorr   )r   kwargsrV   vrx   rt   old_inits       r   new_init6store_hyperparameters.<locals>.inner.<locals>.new_init   s|     )..0;yA~(6qc:fi[Y  	 1 $N&6#M(#Mf#MD T$V$r   )r   r   )
r   inspectgetfullargspecvarargsUserWarningvarkwr{   r9   	functoolswraps)clsr|   r   rx   r   rt   r}   s      @@r   inner$store_hyperparameters.<locals>.inner   s    <<%%h/#D)<<#b  ::!e  99 D,,kl  
	"	% 	% 
#	%  
r   )r|   zinspect.FullArgSpecr4   r   )r   type[C]r4   r   )r   r   )rt   r   r   r   r}   s   `   @r   store_hyperparametersr      s5    
(h ( 	./A$ $L Lr   )rH   rs   rh   rX   r
   r   )r'   r8   rF   rE   r4   rR   )r'   r8   rT   rE   r4   rR   )rd   rR   re   rR   r4   tuple[int, int])upsample@   )r'   r8   rn   rE   ro   rR   r4   r   )rt   r8   )r=   
__future__r   r   r   r[   typingr   r   r   r   r   r
   rH   rX   rh   rs   r   __all__r+   r   r   <module>r      s}    #    ; ;; ;> .B #$  	: GI =@r   