o
    ZhD                     @   s^  d Z ddlZddlZddlmZ ddlmZmZmZ er"ddl	m
Z
 G dd dejZd	eee  d
eee  deee  fddZd	eee  d
eeee ee f  dee fddZd	eee  d
eeee ee f  dee deee ee f fddZG dd dZG dd dZdd Zdededee deeedf  dee f
dd ZdS )!zACollection of utils to be used by backbones and their components.    N)Iterable)TYPE_CHECKINGOptionalUnion   )PretrainedConfigc                   @   s   e Zd ZdZdZdS )BackboneTypeZtimmtransformersN)__name__
__module____qualname__TIMMTRANSFORMERS r   r   P/var/www/auris/lib/python3.10/site-packages/transformers/utils/backbone_utils.pyr      s    r   out_featuresout_indicesstage_namesc                    s  du rt d durXt tfst dt  tfdd D r0t d d  t tt krAt d    fd	d
D  }krXt d| d  |durt|tsjt dt| tfdd|D }tfdd|D rt d d| t|tt|krd| }|||krd| dnd7 }t ||tt|krdd
 tt	||dd dD }t d| d|  dur|durt t|krt d fdd
|D krt ddS dS dS )zW
    Verify that out_indices and out_features are valid for the given stage_names.
    Nz2Stage_names must be set for transformers backbonesz out_features must be a list got c                 3   s    | ]}| vV  qd S Nr   .0Zfeatr   r   r   	<genexpr>,   s    z2verify_out_features_out_indices.<locals>.<genexpr>z.out_features must be a subset of stage_names: z got z2out_features must not contain any duplicates, got c                    s   g | ]}| v r|qS r   r   r   r   r   r   
<listcomp>0   s    z3verify_out_features_out_indices.<locals>.<listcomp>z@out_features must be in the same order as stage_names, expected z out_indices must be a list, got c                 3   s(    | ]}|d k r|t   n|V  qdS )r   Nlenr   idxr   r   r   r   9   s   & c                 3   s$    | ]}|t t vr|V  qd S r   )ranger   r   r   r   r   r   :   s   " z2out_indices must be valid indices for stage_names z, got z1out_indices must not contain any duplicates, got z(equivalent to z)) c                 S   s   g | ]\}}|qS r   r   )r   _r   r   r   r   r   A       c                 S   s   | d S )Nr   r   )xr   r   r   <lambda>A   s    z1verify_out_features_out_indices.<locals>.<lambda>)keyz?out_indices must be in the same order as stage_names, expected zHout_features and out_indices should have the same length if both are setc                       g | ]} | qS r   r   r   r   r   r   r   I   r"   zQout_features and out_indices should correspond to the same stages if both are set)

ValueError
isinstancelisttypeanyr   settuplesortedzip)r   r   r   Zsorted_featsZpositive_indicesmsgZsorted_negativer   )r   r   r   verify_out_features_out_indices    sF   

 r1   c                    s   |du r| du rt  d g} d g} | |fS |du r-| dur- fdd| D }| |fS | du r>|dur> fdd|D } | |fS )a  
    Finds the corresponding `out_features` and `out_indices` for the given `stage_names`.

    The logic is as follows:
        - `out_features` not set, `out_indices` set: `out_features` is set to the `out_features` corresponding to the
        `out_indices`.
        - `out_indices` not set, `out_features` set: `out_indices` is set to the `out_indices` corresponding to the
        `out_features`.
        - `out_indices` and `out_features` not set: `out_indices` and `out_features` are set to the last stage.
        - `out_indices` and `out_features` set: input `out_indices` and `out_features` are returned.

    Args:
        out_features (`List[str]`): The names of the features for the backbone to output.
        out_indices (`List[int]` or `Tuple[int]`): The indices of the features for the backbone to output.
        stage_names (`List[str]`): The names of the stages of the backbone.
    N   c                    s   g | ]}  |qS r   )index)r   layerr   r   r   r   f       z9_align_output_features_output_indices.<locals>.<listcomp>c                    r&   r   r   r   r   r   r   r   h   r"   r   r   r   r   r   r   r   %_align_output_features_output_indicesM   s   
r8   returnc                 C   sJ   |durt |nd}t| ||d t| ||d\}}t|||d ||fS )a`  
    Get the `out_features` and `out_indices` so that they are aligned.

    The logic is as follows:
        - `out_features` not set, `out_indices` set: `out_features` is set to the `out_features` corresponding to the
        `out_indices`.
        - `out_indices` not set, `out_features` set: `out_indices` is set to the `out_indices` corresponding to the
        `out_features`.
        - `out_indices` and `out_features` not set: `out_indices` and `out_features` are set to the last stage.
        - `out_indices` and `out_features` set: they are verified to be aligned.

    Args:
        out_features (`List[str]`): The names of the features for the backbone to output.
        out_indices (`List[int]` or `Tuple[int]`): The indices of the features for the backbone to output.
        stage_names (`List[str]`): The names of the stages of the backbone.
    Nr7   )r)   r1   r8   )r   r   r   Zoutput_featuresZoutput_indicesr   r   r   *get_aligned_output_features_output_indicesl   s   
r:   c                       s   e Zd ZU dZee ed< dddZdddZddd	Z	e
d
d Zejdee fddZe
dd Zejdeee ee f fddZe
dd Ze
dd Zdd Z			d dee dee dee fddZ fddZ  ZS )!BackboneMixinNbackbone_typer9   c                 C   s   t | dddu rtddd | jjjD | _dd | jjjD | _t| jjj}| jj	 }t
||| jd ||| _| _dS )zo
        Initialize the backbone model from timm The backbone must already be loaded to self._backbone
        	_backboneNz=self._backbone must be set before calling _init_timm_backbonec                 S      g | ]}|d  qS )moduler   r   stager   r   r   r      r"   z5BackboneMixin._init_timm_backbone.<locals>.<listcomp>c                 S   r>   )Znum_chsr   r@   r   r   r   r      r"   r7   )getattrr'   r=   Zfeature_infoinfor   num_featuresr)   r   module_namer1   _out_features_out_indices)selfconfigr   r   r   r   r   _init_timm_backbone   s   z!BackboneMixin._init_timm_backbonec                 C   sH   t |d}t |dd }t |dd }|| _t|||d\| _| _d | _d S )Nr   r   r   r7   )rB   r   r:   rF   rG   rD   )rH   rI   r   r   r   r   r   r   _init_transformers_backbone   s   

z)BackboneMixin._init_transformers_backbonec                 C   sn   || _ t|dd| _| jrtjntj| _| jtjkr!| | dS | jtjkr.| | dS t	d| j d)z
        Method to initialize the backbone. This method is called by the constructor of the base class after the
        pretrained model weights have been loaded.
        use_timm_backboneFzbackbone_type z not supported.N)
rI   rB   rL   r   r   r   r<   rJ   rK   r'   )rH   rI   r   r   r   _init_backbone   s   zBackboneMixin._init_backbonec                 C      | j S r   rF   rH   r   r   r   r         zBackboneMixin.out_featuresr   c                 C      t |d| jd\| _| _dS z
        Set the out_features attribute. This will also update the out_indices attribute to match the new out_features.
        Nr7   r:   r   rF   rG   rH   r   r   r   r   r         c                 C   rN   r   rG   rP   r   r   r   r      rQ   zBackboneMixin.out_indicesr   c                 C      t d|| jd\| _| _dS z
        Set the out_indices attribute. This will also update the out_features attribute to match the new out_indices.
        Nr7   rT   rH   r   r   r   r   r      rV   c                    s    fddt  jD S )Nc                    s   i | ]
\}}| j | qS r   )rD   )r   irA   rP   r   r   
<dictcomp>   s    z6BackboneMixin.out_feature_channels.<locals>.<dictcomp>)	enumerater   rP   r   rP   r   out_feature_channels   s   z"BackboneMixin.out_feature_channelsc                    s    fdd j D S )Nc                    s   g | ]} j | qS r   )r^   )r   namerP   r   r   r      r6   z*BackboneMixin.channels.<locals>.<listcomp>r   rP   r   rP   r   channels   s   zBackboneMixin.channelsc                    s6   t t| jj  fdd| D }| |i |S )Nc                    s   i | ]\}}| v r||qS r   r   )r   kv	signaturer   r   r\      s    z>BackboneMixin.forward_with_filtered_kwargs.<locals>.<dictcomp>)dictinspectrd   forward
parametersitems)rH   argskwargsZfiltered_kwargsr   rc   r   forward_with_filtered_kwargs   s   z*BackboneMixin.forward_with_filtered_kwargsoutput_hidden_statesoutput_attentionsreturn_dictc                 C   s   t d)Nz7This method should be implemented by the derived class.)NotImplementedError)rH   Zpixel_valuesrm   rn   ro   r   r   r   rg      s   zBackboneMixin.forwardc                    *   t   }|d|d< |d|d< |S z
        Serializes this instance to a Python dictionary. Override the default `to_dict()` from `PretrainedConfig` to
        include the `out_features` and `out_indices` attributes.
        rF   r   rG   r   superto_dictpoprH   output	__class__r   r   ru         
zBackboneMixin.to_dict)r9   N)NNN)r
   r   r   r<   r   r   __annotations__rJ   rK   rM   propertyr   setterr)   strr   r   r-   intr^   r`   rl   boolrg   ru   __classcell__r   r   ry   r   r;      s:   
 




 


	r;   c                       st   e Zd ZdZedd Zejdee fddZedd Z	e	jde
ee ee f fd	dZ	 fd
dZ  ZS )BackboneConfigMixinzv
    A Mixin to support handling the `out_features` and `out_indices` attributes for the backbone configurations.
    c                 C   rN   r   rO   rP   r   r   r   r     rQ   z BackboneConfigMixin.out_featuresr   c                 C   rR   rS   rT   rU   r   r   r   r   
  rV   c                 C   rN   r   rW   rP   r   r   r   r     rQ   zBackboneConfigMixin.out_indicesr   c                 C   rX   rY   rT   rZ   r   r   r   r     rV   c                    rq   rr   rs   rw   ry   r   r   ru      r{   zBackboneConfigMixin.to_dict)r
   r   r   __doc__r}   r   r~   r)   r   r   r   r-   r   ru   r   r   r   ry   r   r     s    

 r   c           	      C   s`  ddl m}m} t| dd}t| dd}t| dd}t| dd}t| dd}|du r,i n|}|r8|dur8td	|durH|durH|durHtd
|du rb|du rb|du rb|du rb|jdd| i|S |rz|du rltd|j|f||d|}|S |r|du rtd|j|fi |}|S |du r|du rtd|du r|j|fi |}|j|d}|S )a>  
    Loads the backbone model from a config object.

    If the config is from the backbone model itself, then we return a backbone model with randomly initialized
    weights.

    If the config is from the parent model of the backbone model itself, then we load the pretrained backbone weights
    if specified.
    r   )AutoBackbone
AutoConfigbackbone_configNrL   use_pretrained_backbonebackbonebackbone_kwargs?You can't specify both `backbone_kwargs` and `backbone_config`.z>Cannot specify both config.backbone_config and config.backbonerI   z8config.backbone must be set if use_timm_backbone is True)rL   r   z>config.backbone must be set if use_pretrained_backbone is Truez<Either config.backbone_config or config.backbone must be set)rI   r   )r	   r   r   rB   r'   Zfrom_configZfrom_pretrained)	rI   r   r   r   rL   r   Zbackbone_checkpointr   r   r   r   r   load_backbone+  sN   
r   rL   r   r   r   r   r   c                 C   sT   |dur|durt d|dur| rt d|dur$|r&|dur(t ddS dS dS )zR
    Verify that the config arguments to be passed to load_backbone are valid
    Nz8You can't specify both `backbone` and `backbone_config`.zAYou can't specify both `backbone_config` and `use_timm_backbone`.r   )r'   )rL   r   r   r   r   r   r   r    verify_backbone_config_argumentsh  s   
r   )r   enumrf   collections.abcr   typingr   r   r   Zconfiguration_utilsr   Enumr   r   r   r1   r)   r-   r8   r:   r;   r   r   r   re   r   r   r   r   r   <module>   sZ   



-



 u*=