o
    h.                     @   s  d Z ddlZddlZddlmZmZmZmZ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S )zB Collection of utils to be used by backbones and their components.    N)IterableListOptionalTupleUnionc                   @   s   e Zd ZdZdZdS )BackboneTypetimmtransformersN)__name__
__module____qualname__TIMMTRANSFORMERS r   r   W/var/www/html/ai/venv/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r0t| tfst dt|  t fdd| D r0t d  d|  |durYt|ttfsDt dt| t fd	d|D rYt d
  d| | dur||dur~t| t|krmt 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 c                 3   s    | ]}| vV  qd S Nr   ).0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 z)out_indices must be a list or tuple, got c                 3   s    | ]	}|t  kV  qd S r   lenr   idxr   r   r   r   .   s    z2out_indices must be valid indices for stage_names z, got zHout_features and out_indices should have the same length if both are setc                       g | ]} | qS r   r   r   r   r   r   
<listcomp>4       z3verify_out_features_out_indices.<locals>.<listcomp>zQout_features and out_indices should correspond to the same stages if both are set)
ValueError
isinstancelisttypeanytupler   r   r   r   r   r   r   verify_out_features_out_indices   s&   r'   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   Q       z9_align_output_features_output_indices.<locals>.<listcomp>c                    r   r   r   r   r   r   r   r   S   r   r   r&   r   r   r   %_align_output_features_output_indices8   s   
r-   returnc                 C   s6   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.
    r&   )r'   r-   )r   r   r   output_featuresoutput_indicesr   r   r   *get_aligned_output_features_output_indicesW   s   
r1   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_typer.   c                 C   s|   t | dddu rtddd | jjjD | _dd | jjjD | _| 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   r5   )num_chsr   r7   r   r   r   r      r   r&   )getattrr    r4   feature_infoinfor   num_featuresr   module_namer'   _out_features_out_indices)selfconfigr   r   r   r   r   _init_timm_backboney   s   
z!BackboneMixin._init_timm_backbonec                 C   sH   t |d}t |dd }t |dd }|| _t|||d\| _| _d | _d S )Nr   r   r   r&   )r:   r   r1   r?   r@   r=   )rA   rB   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)
rB   r:   rE   r   r   r   r3   rC   rD   r    )rA   rB   r   r   r   _init_backbone   s   zBackboneMixin._init_backbonec                 C      | j S r   r?   rA   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.
        Nr&   r1   r   r?   r@   rA   r   r   r   r   r         c                 C   rG   r   r@   rI   r   r   r   r      rJ   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.
        Nr&   rM   rA   r   r   r   r   r      rO   c                    s    fddt  jD S )Nc                    s   i | ]
\}}| j | qS r   )r=   )r   ir8   rI   r   r   
<dictcomp>   s    z6BackboneMixin.out_feature_channels.<locals>.<dictcomp>)	enumerater   rI   r   rI   r   out_feature_channels   s   z"BackboneMixin.out_feature_channelsc                    s    fdd j D S )Nc                    s   g | ]} j | qS r   )rW   )r   namerI   r   r   r      r,   z*BackboneMixin.channels.<locals>.<listcomp>)r   rI   r   rI   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   rU      s    z>BackboneMixin.forward_with_filtered_kwargs.<locals>.<dictcomp>)dictinspectr]   forward
parametersitems)rA   argskwargsfiltered_kwargsr   r\   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)rA   pixel_valuesrg   rh   ri   r   r   r   r`      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.
        r?   r   r@   r   superto_dictpoprA   output	__class__r   r   rp         
zBackboneMixin.to_dict)r.   N)NNN)r
   r   r   r3   r   r   __annotations__rC   rD   rF   propertyr   setterr   strr   r   r   intrW   rY   rf   boolr`   rp   __classcell__r   r   rt   r   r2   v   s:   
 




 


	r2   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   rG   r   rH   rI   r   r   r   r      rJ   z BackboneConfigMixin.out_featuresr   c                 C   rK   rL   rM   rN   r   r   r   r      rO   c                 C   rG   r   rP   rI   r   r   r   r      rJ   zBackboneConfigMixin.out_indicesr   c                 C   rQ   rR   rM   rS   r   r   r   r      rO   c                    rl   rm   rn   rr   rt   r   r   rp     rv   zBackboneConfigMixin.to_dict)r
   r   r   __doc__rx   r   ry   r   rz   r   r   r   r{   rp   r}   r   r   rt   r   r~      s    

 r~   )r   enumr_   typingr   r   r   r   r   Enumr   rz   r{   r'   r-   r1   r2   r~   r   r   r   r   <module>   s<   







r