U
    9%e.                     @   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
eee  eee  eee  dddZeee  eeee ee f  ee dd	d
Zeee  eeee ee f  ee eee ee f d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 )BackboneTypeZtimmZtransformersN)__name__
__module____qualname__TIMMTRANSFORMERS r   r   `/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/transformers/utils/backbone_utils.pyr      s   r   out_featuresout_indicesstage_namesc                    s    dkrt d| dk	r`t| tfs6t dt|  t fdd| D r`t d  d|  |dk	rt|ttfst dt| t fd	d|D rt d
| dk	r|dk	rt| t|krt d|  fdd|D krt d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   | ]}| k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 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     zRout_indices must be valid indices for stage_names {stage_names}, got {out_indices}zHout_features and out_indices should have the same length if both are setc                    s   g | ]} | qS r   r   r   r   r   r   
<listcomp>4   s     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   verify_out_features_out_indices   s"    r"   c                    sx   |dkr*| dkr*t  d g} d g} nF|dkrN| dk	rN fdd| D }n"| dkrp|dk	rp 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   s     z9_align_output_features_output_indices.<locals>.<listcomp>c                    s   g | ]} | qS r   r   r   r   r   r   r   S   s     r   r   r   r   r   %_align_output_features_output_indices8   s    r'   )r   r   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   Zoutput_featuresZoutput_indicesr   r   r   *get_aligned_output_features_output_indicesW   s      
r)   c                       s   e Zd ZU dZee ed< ddddZddddZdddd	Z	e
d
d Zejee dddZe
dd Zejeee ee f dddZe
dd Ze
dd Zdd Zdee ee ee dddZ fddZ  ZS )BackboneMixinNbackbone_type)r(   c                 C   s|   t | dddk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   s   g | ]}|d  qS )moduler   r   stager   r   r   r      s     z5BackboneMixin._init_timm_backbone.<locals>.<listcomp>c                 S   s   g | ]}|d  qS )Znum_chsr   r.   r   r   r   r      s     r   )getattrr   r,   Z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   )r0   r   r)   r4   r5   r2   )r6   r7   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@| | n*| jtjkrX| | nt	d| j ddS )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)
r7   r0   r:   r   r   r   r+   r8   r9   r   )r6   r7   r   r   r   _init_backbone   s    zBackboneMixin._init_backbonec                 C   s   | j S r   r4   r6   r   r   r   r      s    zBackboneMixin.out_featuresr   c                 C   s   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   r)   r   r4   r5   r6   r   r   r   r   r      s
      c                 C   s   | j S r   r5   r=   r   r   r   r      s    zBackboneMixin.out_indicesr   c                 C   s   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   r@   r6   r   r   r   r   r      s
      c                    s    fddt  jD S )Nc                    s   i | ]\}}| j | qS r   )r2   )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                    s   g | ]} j | qS r   )rI   )r   namer=   r   r   r      s     z*BackboneMixin.channels.<locals>.<listcomp>r>   r=   r   r=   r   channels   s    zBackboneMixin.channelsc                    s2   t t| jj  fdd| D }| ||S )Nc                    s   i | ]\}}| kr||qS r   r   )r   kv	signaturer   r   rG      s       z>BackboneMixin.forward_with_filtered_kwargs.<locals>.<dictcomp>)dictinspectrO   forward
parametersitems)r6   argskwargsZfiltered_kwargsr   rN   r   forward_with_filtered_kwargs   s    z*BackboneMixin.forward_with_filtered_kwargs)output_hidden_statesoutput_attentionsreturn_dictc                 C   s   t dd S )Nz7This method should be implemented by the derived class.)NotImplementedError)r6   Zpixel_valuesrX   rY   rZ   r   r   r   rR      s    zBackboneMixin.forwardc                    s*   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.
        r4   r   r5   r   superto_dictpopr6   output	__class__r   r   r_      s    
zBackboneMixin.to_dict)NNN)r   r	   r
   r+   r   r   __annotations__r8   r9   r;   propertyr   setterr   strr   r   r   intrI   rK   rW   boolrR   r_   __classcell__r   r   rc   r   r*   v   s4   


 

   	r*   c                       st   e Zd ZdZedd Zejee dddZedd Z	e	je
ee ee f d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   s   | j S r   r<   r=   r   r   r   r      s    z BackboneConfigMixin.out_featuresr>   c                 C   s   t |d| jd\| _| _dS r?   r@   rA   r   r   r   r      s
      c                 C   s   | j S r   rB   r=   r   r   r   r      s    zBackboneConfigMixin.out_indicesrC   c                 C   s   t d|| jd\| _| _dS rD   r@   rE   r   r   r   r      s
      c                    s*   t   }|d|d< |d|d< |S r\   r]   ra   rc   r   r   r_     s    
zBackboneConfigMixin.to_dict)r   r	   r
   __doc__rf   r   rg   r   rh   r   r   r   ri   r_   rk   r   r   rc   r   rl      s   

 rl   )rm   enumrQ   typingr   r   r   r   r   Enumr   rh   ri   r"   r'   r)   r*   rl   r   r   r   r   <module>   s&   
 
 

 
r