
    3jTL                       S SK Jr  S SKJrJr  S SKJr  S SKJrJ	r	J
r
JrJrJrJrJrJrJr  S SKrS SKJr  S SKJrJr  SS	KJrJr  \" S
\R4                  R6                  SS9r\
\\4   r \" S\5      r  " S S\\\   5      r \S   r!  " S S\5      r" " S S\#5      r$ " S S\\\   5      r% " S S\%\   \\   5      r& " S S\%\   \\   5      r'\\&\R4                  R6                     \'\R4                  R6                     4   r(g)    )annotations)ABCabstractmethod)Enum)
AnyCallableDictFinalGenericLiteralNewTypeTypeVarUnionoverloadN)Tensor)Selfoverride   )SizeRequirements
pad_tensorTT)bound	covariantArchIdc                     ^  \ rS rSrSrSS.       SU 4S jjjr\SS j5       r\SS j5       rSS jr	\
    SS	 j5       rS
rU =r$ )Architecture'   z0
The abstract base class for all architectures.
N)namec               n   > [         TU ]  5         [        U5      U l        U=(       d    UU l        X l        g N)super__init__r   _id_name_detect)selfiddetectr   	__class__s       ]/home/wildlama/miniconda3/lib/python3.13/site-packages/spandrel/__helpers/model_descriptor.pyr"   Architecture.__init__,   s+     	"(*!%
    c                    U R                   $ )z
The unique ID of the architecture.

For built-in architectures, this is the same as the module name. E.g. `spandrel.architectures.RestoreFormer` has the ID `RestoreFormer`.
)r#   r&   s    r*   r'   Architecture.id9   s     xxr,   c                    U R                   $ )z@
The name of the architecture.

This is often the same as `id`.
)r$   r.   s    r*   r   Architecture.nameB   s     zzr,   c                $    U R                  U5      $ )a|  
Inspects the given state dict and returns ``True`` if it is a state dict of this architecture.

This guarantees that there are no false negatives, but there might be false positives.
This is important to remember when ordering architectures in a registry.

(Note: while false positives are allowed, they are supposed to be rare. So we do accept bug reports for false positives.)
)r%   r&   
state_dicts     r*   r(   Architecture.detectK   s     ||J''r,   c                    g)aa  
Loads the given state dict into a model. The hyperparameters will automatically be deduced.

The state dict is assumed to be a state dict of this architecture, meaning that `detect` returned `True` for the state dict.
If this is not the case, then the behavior of this function is unspecified (the model may be loaded incorrect or an error is thrown).
N r3   s     r*   loadArchitecture.loadV   s    r,   )r%   r#   r$   )r'   zArchId | strr(   zCallable[[StateDict], bool]r   z
str | NonereturnNone)r:   r   )r:   str)r4   	StateDictr:   bool)r4   r=   r:   z7ImageModelDescriptor[T] | MaskedImageModelDescriptor[T])__name__
__module____qualname____firstlineno____doc__r"   propertyr'   r   r(   r   r8   __static_attributes____classcell__r)   s   @r*   r   r   '   s        ,	
  
     	( #	@ r,   r   )SRFaceSR
InpaintingRestorationc                  (    \ rS rSrSrSr Sr SrSrg)ModelTilingm   z4
Describes whether and how a model supports tiling.
r         r7   N)	r?   r@   rA   rB   rC   	SUPPORTEDDISCOURAGEDINTERNALrE   r7   r,   r*   rM   rM   m   s+     I K Hr,   rM   c                      \ rS rSrSrSrg)UnsupportedDtypeError   z
An error that will be thrown by `.to` if the model does not support the given dtype.

See `ModelBase.to` for more information.
r7   N)r?   r@   rA   rB   rC   rE   r7   r,   r*   rU   rU      s    r,   rU   c                  h   \ rS rSrSrS\R                  4                     SS jjr\SS j5       r	\SS j5       r
\\SS j5       5       r\SS j5       r\SS	 j5       r\  S     SS
 jj5       r\SS j5       rSS jrSS jrSS jrSS jrSS jrS S!S jjrSS jrS"S#S jjrSrg)$	ModelBase   z
The base class of all model descriptors.

This is mostly intended for `instanceof` checks in user code. Use `ModelDescriptor` for type hints instead.
Nc                    Xl         X0l        X@l         XPl         X`l         Xpl         Xl         Xl         U
=(       d
    [        5       U l	         Xl
         U R                  R                  U5        g r    )_model_architecturetagssupports_halfsupports_bfloat16scaleinput_channelsoutput_channelsr   size_requirementstilingmodelload_state_dict)r&   re   r4   architecturer]   r^   r_   r`   ra   rb   rc   rd   s               r*   r"   ModelBase.__init__   s     .:#		 $1	 (9	  
	 $2	 %4	
 3!1!3 		 $*	 	

"":.r,   c                    U R                   $ )z
The model itself: a `torch.nn.Module` with weights loaded in.

The specific subclass of `torch.nn.Module` depends on the model architecture.
)r[   r.   s    r*   re   ModelBase.model   s     {{r,   c                    U R                   $ )z 
The architecture of the model.
)r\   r.   s    r*   rg   ModelBase.architecture   s    
 !!!r,   c                    g)z
The purpose of this model.
Nr7   r.   s    r*   purposeModelBase.purpose   s     	r,   c                \    [        U R                  R                  5       5      R                  $ )zY
The device of the underlying module.

Use `to` to move the model to a different device.
)nextre   
parametersdevicer.   s    r*   rs   ModelBase.device   s"     DJJ))+,333r,   c                \    [        U R                  R                  5       5      R                  $ )z_
The data type of the underlying module.

Use `to` to cast the model to a different data type.
)rq   re   rr   dtyper.   s    r*   rv   ModelBase.dtype  s"     DJJ))+,222r,   c                    g r    r7   )r&   rs   rv   s      r*   toModelBase.to  s    
 r,   c                    g r    r7   )r&   rv   s     r*   ry   rz     s    .1r,   c                  ^ SU4S jjn[        U5      S:X  aw  US   n[        U[        R                  5      (       a
  U" SU5        O[        U[        R                  [
        45      (       d  Uc
  U" SU5        Oe[        S[        U5       35      e[        U5      S:X  a  U" SUS   5        U" SUS   5        O&[        U5      S:  a  [        S	[        U5       35      eTR                  SS5      nTR                  SS5      n[        T5      S:  a  [        S
[        T5       35      eUbz  U[        R                  :X  a)  U R                  (       d  [        U R                   S35      eU[        R                  :X  a)  U R                  (       d  [        U R                   S35      e[        U[
        5      (       a  [        R                  " U5      nU R                   R#                  XVS9  U $ )a  
Moves and casts the parameters and buffers of the underlying module to the given device and data type.

For more information, see https://pytorch.org/docs/stable/generated/torch.nn.Module.html#torch.nn.Module.to.

Use `device` to get the current device and `dtype` to get the current data type of the model.

Throws `UnsupportedDtypeError` if the model does not support the given data type. If you want to force a dtype cast, use `.model.to(dtype)` instead.
c                8   > U T;   a  [        SU  35      eUTU '   g )Nz.to() got multiple values for keyword argument )	TypeError)r   valuekwargss     r*   set_kwModelBase.to.<locals>.set_kw!  s(    v~"PQUPV WXX F4Lr,   r   r   rv   Nrs   z5to() expected a torch.device or torch.dtype, but got rO   z2to() expected at most 2 positional arguments, got z&to() got unexpected keyword arguments z' does not support half precision (fp16)z$ does not support bfloat16 precision)rs   rv   )r   r<   r   object)len
isinstancetorchrv   rs   r<   r~   typepoplistfloat16r^   rU   rg   bfloat16r_   re   ry   )r&   argsr   r   argrs   rv   s     `    r*   ry   rz     s   	!
 t9>q'C#u{{++w$C%,,!455x%KDQTI;W  Y!^8T!W%7DG$Y]DSYKP  -3JJx,F$*JJw$=v;?DT&\NSTT%d.@.@+(())PQ  &t/E/E+(())MN  fc""\\&)F

V1r,   c                D    U R                  [        R                  5        U $ )zu
Moves the parameters and buffers of the underlying module to half precision (fp16).

Same as `self.to(torch.half)`.
)ry   r   halfr.   s    r*   r   ModelBase.halfN  s     	

r,   c                D    U R                  [        R                  5        U $ )zv
Moves the parameters and buffers of the underlying module to bfloat16 precision.

Same as `self.to(torch.bfloat16)`.
)ry   r   r   r.   s    r*   r   ModelBase.bfloat16W  s     	r,   c                D    U R                  [        R                  5        U $ )zx
Moves the parameters and buffers of the underlying module to single precision (fp32).

Same as `self.to(torch.float)`.
)ry   r   floatr.   s    r*   r   ModelBase.float`  s     	r,   c                :    U R                   R                  5         U $ )zp
Moves the parameters and buffers of the underlying module to the CPU.

Same as `self.to(torch.device("cpu"))`.
)re   cpur.   s    r*   r   ModelBase.cpui  s     	

r,   c                <    U R                   R                  U5        U $ )zq
Moves the parameters and buffers of the underlying module to the GPU.

Same as `self.to(torch.device("cuda"))`.
)re   cuda)r&   rs   s     r*   r   ModelBase.cudar  s     	

r,   c                :    U R                   R                  5         U $ )zN
Sets the underlying module in evaluation mode.

Same as `self.train(False)`.
)re   evalr.   s    r*   r   ModelBase.eval{  s     	

r,   c                <    U R                   R                  U5        U $ )zQ
Sets the underlying module in training mode.

Same as `self.model.train(mode)`.
)re   train)r&   modes     r*   r   ModelBase.train  s     	

r,   )
r\   r[   ra   rb   r`   rc   r_   r^   r]   rd   )re   r   r4   r=   rg   Architecture[T]r]   	list[str]r^   r>   r_   r>   r`   intra   r   rb   r   rc   SizeRequirements | Nonerd   rM   )r:   r   )r:   r   )r:   Purpose)r:   ztorch.device)r:   torch.dtype)NN)rs   ztorch.device | str | Nonerv   ztorch.dtype | Noner:   r   )rv   r   r:   r   )r   r   r:   r   )r:   r   r    )rs   z
int | Noner:   r   )T)r   r>   r:   r   )r?   r@   rA   rB   rC   rM   rQ   r"   rD   re   rg   r   rn   rs   rv   r   ry   r   r   r   r   r   r   r   rE   r7   r,   r*   rX   rX      su   " 6:)33C/C/ C/ &	C/
 C/ C/  C/ C/ C/ C/ 3C/ C/J   " "    4 4 3 3  -1$() " 
	  1 17r r,   rX   c                     ^  \ rS rSrSrS\R                  S4                         SU 4S jjjr\\	S	S j5       5       r
\R                  " 5       S
S j5       rSrU =r$ )ImageModelDescriptori  za
A model that takes an image as input and returns an image. See `__call__` for more information.
Nc                   > US:w  d  US:X  d   S5       e[         TU ]  UUUUUUUU	U
UUS9  X@l        U=(       d    S U l        g )NrK   r   z)Restoration models must have a scale of 1r^   r_   r`   ra   rb   rc   rd   c                    U " U5      $ r    r7   )re   images     r*   <lambda>/ImageModelDescriptor.__init__.<locals>.<lambda>  s    ur,   r!   r"   _purpose_call_fn)r&   re   r4   rg   rn   r]   r^   r_   r`   ra   rb   rc   rd   call_fnr)   s                 r*   r"   ImageModelDescriptor.__init__  sn    " }$
	76	72 	'/)+/ 	 	
 AHF$Er,   c                    U R                   $ r    r   r.   s    r*   rn   ImageModelDescriptor.purpose       }}r,   c                b   [        UR                  5      S:w  a  [        SUR                   35      eUR                  u    p#n[        XR                  5      u  pQU R
                  R                  (       a  U R
                  R                  5         U R                  U R
                  U5      n[        U[        5      (       d3   S[        U R
                  5      R                   S[        U5       35       eUR                  SS5      nU(       a$  USSX0R                  -  2SX@R                  -  24   nU$ )	ar  
Takes a single image tensor as input and returns a single image tensor as output.

The `image` tensor must be a 4D tensor with shape `(1, input_channels, H, W)`. The data type (float32, float16, bfloat16) and device of the `image` tensor must be the same as the model. The range of the `image` tensor must be ``[0, 1]``.

The output tensor will be a 4D tensor with shape `(1, output_channels, H*scale, W*scale)`. The data type and device of the output tensor will be the same as the `image` tensor. The range of the output tensor will be ``[0, 1]``.

If the width and height of the `image` tensor do not satisfy the `size_requirements` of the model, then the `image` tensor will be padded to satisfy the requirements. The additional padding will be removed from the output tensor before returning it. If the image already satisfies the requirements, then no padding will be added.
   4Expected image tensor to have 4 dimensions, but got 	Expected z# model to return a tensor, but got r   r   .N)r   shape
ValueErrorr   rc   re   trainingr   r   r   r   r   r?   clamp_r`   )r&   r   _hwdid_padoutputs          r*   __call__ImageModelDescriptor.__call__  s    u{{q Fu{{mT  [[
1 $E+A+AB ::JJOO tzz51F
 
 	dtDJJ'0011TUYZ`UaTbc	d 

 q!$ C!11zz>!13CQ^3CCDFr,   r   r   )re   r   r4   r=   rg   r   rn   &Literal['SR', 'FaceSR', 'Restoration']r]   r   r^   r>   r_   r>   r`   r   ra   r   rb   r   rc   r   rd   rM   r   z$Callable[[T, Tensor], Tensor] | None)r:   r   )r   r   r:   r   )r?   r@   rA   rB   rC   rM   rQ   r"   rD   r   rn   r   inference_moder   rE   rF   rG   s   @r*   r   r     s      6:)338<$G$G $G &	$G
 8$G $G $G  $G $G $G $G 3$G $G 6$G $GL    % %r,   r   c                     ^  \ rS rSrSrS\R                  S4                       SU 4S jjjr\\	S	S j5       5       r
S
S jrSrU =r$ )MaskedImageModelDescriptori  z{
A model that takes an image and a mask for that image as input and returns an image. See `__call__` for more information.
Nc                b   > [         TU ]  UUUUUUSUU	U
US9  X@l        U=(       d    S U l        g )Nr   r   c                    U " X5      $ r    r7   )re   r   masks      r*   r   5MaskedImageModelDescriptor.__init__.<locals>.<lambda>  s	    uU?Qr,   r   )r&   re   r4   rg   rn   r]   r^   r_   ra   rb   rc   rd   r   r)   s                r*   r"   #MaskedImageModelDescriptor.__init__  sL     	'/)+/ 	 	
 07R$Qr,   c                    U R                   $ r    r   r.   s    r*   rn   "MaskedImageModelDescriptor.purpose  r   r,   c                   [        UR                  5      S:w  a  [        SUR                   35      e[        UR                  5      S:w  a  [        SUR                   35      eUR                  u    p4n[        R                  " SSXE/5      nUR                  U:w  a  [        SU SUR                   35      e[        XR                  5      u  pq[        X R                  5      u  p2U R                  U R                  X5      n[        U[        5      (       d3   S[        U R                  5      R                   S[        U5       35       eUR                  S	S5      nU(       a$  US
SX@R                  -  2SXPR                  -  24   nU$ )aI  
Takes an image tensor and an image mask tensor as input and returns a single image tensor as output.

The data type (float32, float16, bfloat16) and device of the `image` and `mask` tensors must be the same as the model.

The `image` tensor must be a 4D tensor with shape `(1, input_channels, H, W)`. The range of the `image` tensor must be ``[0, 1]``.

The `mask` tensor must be a 4D tensor with shape `(1, 1, H, W)`. The width and height must be the same as `image` tensor. The values of the `mask` tensor must be either 0 (keep) or 1 (inpaint).

The output tensor will be a 4D tensor with shape `(1, output_channels, H, W)`. The data type and device of the output tensor will be the same as the `image` tensor. The range of the output tensor will be ``[0, 1]``.

If the width and height of the `image` tensor do not satisfy the `size_requirements` of the model, then the `image` tensor will be padded to satisfy the requirements. The additional padding will be removed from the output tensor before returning it. If the image already satisfies the requirements, then no padding will be added.
r   r   z3Expected mask tensor to have 4 dimensions, but got r   zExpected mask shape to be z
, but got r   z$ model to returns a tensor, but got r   .N)r   r   r   r   Sizer   rc   r   re   r   r   r   r?   r   r`   )	r&   r   r   r   r   r   
mask_shaper   r   s	            r*   r   #MaskedImageModelDescriptor.__call__  s~    u{{q Fu{{mT  tzz?aEdjj\R  [[
1 ZZAq-
::#,ZL
4::,O 
 $E+A+ABT#9#9: tzz57F
 
 	etDJJ'0011UVZ[aVbUcd	e 

 q!$ C!11zz>!13CQ^3CCDFr,   r   )re   r   r4   r=   rg   r   rn   Literal['Inpainting']r]   r   r^   r>   r_   r>   ra   r   rb   r   rc   r   rd   rM   r   z,Callable[[T, Tensor, Tensor], Tensor] | None)r:   r   )r   r   r   r   r:   r   )r?   r@   rA   rB   rC   rM   rQ   r"   rD   r   rn   r   rE   rF   rG   s   @r*   r   r     s     6:)33@DSS S &	S
 'S S S  S S S 3S S >S SB   1 1r,   r   ))
__future__r   abcr   r   enumr   typingr   r   r	   r
   r   r   r   r   r   r   r   r   typing_extensionsr   r   size_reqr   r   nnModuler   r<   r=   r   r   r   rM   	ExceptionrU   rX   r   r   ModelDescriptorr7   r,   r*   <module>r      s    " #      , 2Cuxx$7cN	 
3	
83
 8v =
>$ 4I |WQZ |~V9Q< Vr\1wqz \~ )uxx/1r,   