o
    i;                  
   @   s   d Z ddlZddlZddlmZ ddlmZ eeZ	G dd dej
ZG dd	 d	ZG d
d dZ				ddedB dedB dedB dedB fddZdd ZdS )zACollection of utils to be used by backbones and their components.    N)repo_exists   )loggingc                   @   s   e Zd ZdZdZdS )BackboneTypetimmtransformersN)__name__
__module____qualname__TIMMTRANSFORMERS r   r   ]/sda-disk/www/egybert/egybert_env/lib/python3.10/site-packages/transformers/backbone_utils.pyr      s    r   c                       s   e Zd ZdZdedB dedB fddZ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df ee B 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.
    out_featuresNout_indicesc                    s   | _ t|trt|n| _    j  j}}|du r1|du r1t jd g} jd g}n#|du rC|durC fdd|D }n|du rT|durT fdd|D }|| _  _   dS )ap  
        Sets output indices and features to new values and aligns them with the given `stage_names`.
        If one of the inputs is not given, find the corresponding `out_features` or `out_indices`
        for the given `stage_names`.

        Args:
            out_features (`list[str]`, *optional*):
                The names of the features for the backbone to output. Defaults to `config._out_features` if not provided.
            out_indices (`list[int]` or `tuple[int]`, *optional*):
                The indices of the features for the backbone to output. Defaults to `config._out_indices` if not provided.
        Nr   c                    s   g | ]} j |qS r   )stage_namesindex).0layerselfr   r   
<listcomp>B   s    zJBackboneConfigMixin.set_output_features_output_indices.<locals>.<listcomp>c                       g | ]} j | qS r   r   r   idxr   r   r   r   D       )_out_features
isinstancetuplelist_out_indicesverify_out_features_out_indiceslenr   )r   r   r   r   r   r   "set_output_features_output_indices&   s   z6BackboneConfigMixin.set_output_features_output_indicesc                    s,   j du r	td jduret jtfstdt j t fdd jD r7td j  d j t jtt jkrKtd j  j fd	d
 j D  }kretd| d j  j	durt j	tsztdt j	 t
 fdd j	D }t fdd|D rtd j  d j	 t|tt|krd j	 }|| j	krd| dnd7 }t||t
t|krdd
 tt| j	dd dD }td| d j	  jdur j	durt jt j	krtd j fdd
 j	D krtddS dS dS )z_
        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    | ]}| j vV  qd S Nr   r   featr   r   r   	<genexpr>T   s    zFBackboneConfigMixin.verify_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 | ]	}| j v r|qS r   r   r(   r   r   r   r   [   s    zGBackboneConfigMixin.verify_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  j n|V  qdS )r   N)r%   r   r   r   r   r   r*   e   s   ( c                 3   s&    | ]}|t t jvr|V  qd S r'   )ranger%   r   r   r   r   r   r*   f   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   o   s    c                 S   s   | d S )Nr   r   )xr   r   r   <lambda>p   s    zEBackboneConfigMixin.verify_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                    r   r   r   r   r   r   r   r   y   r   zQout_features and out_indices should correspond to the same stages if both are set)r   
ValueErrorr   r    r"   typeanyr%   setr#   r!   sortedzip)r   sorted_featspositive_indicesmsgsorted_negativer   r   r   r$   J   sV   


z3BackboneConfigMixin.verify_out_features_out_indicesc                 C      | j S r'   r+   r   r   r   r   r   |      z BackboneConfigMixin.out_featuresc                 C   s   | j |dd dS )
        Set the out_features attribute. This will also update the out_indices attribute to match the new out_features.
        Nr   r   )r&   r   r   r   r   r   r      s   c                 C   r<   r'   )r#   r   r   r   r   r      r=   zBackboneConfigMixin.out_indices.c                 C   s&   |durt |n|}| jd|d dS )
        Set the out_indices attribute. This will also update the out_features attribute to match the new out_indices.
        Nr?   )r"   r&   r   r   r   r   r   r      s   c                    s.   t   }|dd|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   Nr   r#   r   )superto_dictpop)r   output	__class__r   r   rD      s   
zBackboneConfigMixin.to_dict)r   r	   r
   __doc__r"   r&   r$   propertyr   setterstrr   r!   intrD   __classcell__r   r   rG   r   r   !   s"    
$2

 r   c                       s   e Zd ZU dZedB ed< dZeed< d f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 B fddZedd Zedd Zdd Z			d dedB dedB dedB fddZ  ZS )!BackboneMixinNbackbone_typeThas_attentionsreturnc                    s~   t  j|i | |dd}|durtj| _ntj| _| jtjkr*| j|d dS | jtjkr6|   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.
        timm_backboneN)backbonezbackbone_type z not supported.)
rC   __init__rE   r   r   rP   r   _init_timm_backbone_init_transformers_backboner2   )r   argskwargsrS   rG   r   r   rU      s   
zBackboneMixin.__init__c                 C   s   t | jdd}t | jdd}dd |jjD | _dd |jjD | _t|jj}|j }|dur=||kr=t	d| d|durN|| jkrNt	d	| d
| j| j_| j
|| dS )zj
        Initialize the backbone model from timm. The backbone must already be loaded to backbone
        r   Nr   c                 S      g | ]}|d  qS )moduler   r   stager   r   r   r          z5BackboneMixin._init_timm_backbone.<locals>.<listcomp>c                 S   rZ   )num_chsr   r\   r   r   r   r      r^   z!Config has `out_features` set to z which doesn't match `out_features` from backbone's feature_info. Please check if your checkpoint has correct out features/indices saved.z Config has `stage_names` set to z which doesn't match `stage_names` from backbone's feature_info. Please check if your checkpoint has correct `stage_names` saved.)getattrconfigfeature_infoinfor   num_featuresr"   r   module_namer2   r&   )r   rT   out_features_from_configstage_names_from_configr   r   r   r   r   rV      s    



z!BackboneMixin._init_timm_backbonec                 C   s   | j j| _| j   d | _d S r'   )ra   r   r$   rd   r   r   r   r   rW      s   


z)BackboneMixin._init_transformers_backbonec                 C      | j jS r'   )ra   r   r   r   r   r   r         zBackboneMixin.out_featuresr   c                 C      || j _dS )r>   N)ra   r   r@   r   r   r   r         c                 C   rh   r'   )ra   r#   r   r   r   r   r      ri   zBackboneMixin.out_indicesr   c                 C   rj   )rA   N)ra   r   rB   r   r   r   r      rk   c                    s    fddt  jD S )Nc                    s   i | ]
\}}| j | qS r   )rd   )r   ir]   r   r   r   
<dictcomp>   s    z6BackboneMixin.out_feature_channels.<locals>.<dictcomp>)	enumerater   r   r   r   r   out_feature_channels   s   z"BackboneMixin.out_feature_channelsc                    s    fdd j D S )Nc                    r   r   )ro   )r   namer   r   r   r      r   z*BackboneMixin.channels.<locals>.<listcomp>)r   r   r   r   r   channels   s   zBackboneMixin.channelsc                    sT   | j s	|dd  | jtjkr#tt| jj	  fdd|
 D }| |i |S )Noutput_attentionsc                    s   i | ]\}}| v r||qS r   r   )r   kv	signaturer   r   rm     s    z>BackboneMixin.forward_with_filtered_kwargs.<locals>.<dictcomp>)rQ   rE   rP   r   r   dictinspectrv   forward
parametersitems)r   rX   rY   r   ru   r   forward_with_filtered_kwargs   s   z*BackboneMixin.forward_with_filtered_kwargsoutput_hidden_statesrr   return_dictc                 C   s   t d)Nz7This method should be implemented by the derived class.)NotImplementedError)r   pixel_valuesr}   rr   r~   r   r   r   ry     s   zBackboneMixin.forward)rR   N)NNN)r   r	   r
   rP   r   __annotations__rQ   boolrU   rV   rW   rJ   r   rK   r"   rL   r   r!   rM   ro   rq   r|   ry   rN   r   r   rG   r   rO      s:   
 

!



rO   default_backbonedefault_config_typedefault_config_kwargstimm_default_kwargsc                 K   sx  ddl m} ddlm} |dd}|di }	|dd ur$|dn|}
|dd  |d urK|rK|
d urK| d u rK|	sK|d	 dd|
i|} | |fS |
d ur| d u rt|
rt||
\}}||d
  }||	 |di |} | |fS |d	 dd|
i|	} | |fS | d u r|d urt	
d| d |pi }|| di |} | |fS t| tr| d
}|| }|| } | |fS )Nr   )PreTrainedConfig)CONFIG_MAPPINGuse_timm_backboneTbackbone_kwargsrT   use_pretrained_backbonerS   
model_typezG`backbone_config` is `None`. Initializing the config with the default `z` vision config.r   )configuration_utilsr   models.autor   rE   getr   get_config_dictupdateloggerrc   r    rw   	from_dict)backbone_configr   r   r   r   rY   r   r   r   r   rT   config_dictr.   config_classbackbone_model_typer   r   r   %consolidate_backbone_kwargs_to_config  sH   





r   c                 C   s@   ddl m} t| dd}|du r|j| d}|S |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   )AutoBackboner   N)ra   )r   r   r`   from_config)ra   r   r   rT   r   r   r   load_backboneC  s   
r   )NNNN)rI   enumrx   huggingface_hubr   utilsr   
get_loggerr   r   Enumr   r   rO   rL   rw   r   r   r   r   r   r   <module>   s.   
}u
2