
"""simple docstring"""




from typing import Tuple, Union

from ...modeling_outputs import BackboneOutput
from ...modeling_utils import PreTrainedModel
from ...utils import is_timm_available, is_torch_available, requires_backends
from ...utils.backbone_utils import BackboneMixin
from .configuration_timm_backbone import TimmBackboneConfig


if is_timm_available():
   import timm


if is_torch_available():
   from torch import Tensor







class 					lowerCamelCase		(  A_							,			A_  ):
     UpperCAmelCase__    :							str									=		"pixel_values"
     UpperCAmelCase__    :							Optional[Any]									=		False
     UpperCAmelCase__    :							str									=		TimmBackboneConfig





     def __init__(self				:   Any    ,   _A				:   List[Any]    ,   **_A				:   int       )						->						Optional[Any]:
         requires_backends(self    ,   "timm"       )
         super().__init__(__A       )
         snake_case								= config

         if config.backbone is None:
             raise ValueError("backbone is not set in the config. Please set it to a timm model name."       )

         if config.backbone not in timm.list_models():
             raise ValueError(f'backbone {config.backbone} is not supported by timm.'       )

         if hasattr(__A    ,   "out_features"       ) and config.out_features is not None:
             raise ValueError("out_features is not supported by TimmBackbone. Please use out_indices instead."       )

         snake_case								= getattr(__A    ,   "use_pretrained_backbone"    ,   __A       )
         if pretrained is None:
             raise ValueError("use_pretrained_backbone is not set in the config. Please set it to True or False."       )

         # We just take the final layer by default. This matches the default for the transformers models.
         snake_case								= config.out_indices if getattr(__A    ,   "out_indices"    ,   __A       ) is not None else (-1,)

         snake_case								= timm.create_model(
             config.backbone    ,   pretrained=__A    ,   features_only=config.features_only    ,   in_chans=config.num_channels    ,   out_indices=__A    ,   **__A    ,   )
         # These are used to control the output of the model when called. If output_hidden_states is True, then
         # return_layers is modified to include all layers.
         snake_case								= self._backbone.return_layers
         snake_case								= {layer["module"]: str(__A       ) for i, layer in enumerate(self._backbone.feature_info.info       )}
         super()._init_backbone(__A       )





     @classmethod
     def 		UpperCAmelCase(cls				:   Dict    ,   _A				:   int    ,   *_A				:   str    ,   **_A				:   Union[str, Any]       )						->						Union[str, Any]:
         requires_backends(cls    ,   ["vision", "timm"]       )
         from ...models.timm_backbone import TimmBackboneConfig

         snake_case								= kwargs.pop("config"    ,   TimmBackboneConfig()       )

         snake_case								= kwargs.pop("use_timm_backbone"    ,   __A       )
         if not use_timm:
             raise ValueError("use_timm_backbone must be True for timm backbones"       )

         snake_case								= kwargs.pop("num_channels"    ,   config.num_channels       )
         snake_case								= kwargs.pop("features_only"    ,   config.features_only       )
         snake_case								= kwargs.pop("use_pretrained_backbone"    ,   config.use_pretrained_backbone       )
         snake_case								= kwargs.pop("out_indices"    ,   config.out_indices       )
         snake_case								= TimmBackboneConfig(
             backbone=__A    ,   num_channels=__A    ,   features_only=__A    ,   use_pretrained_backbone=__A    ,   out_indices=__A    ,   )
         return super()._from_config(__A    ,   **__A       )





     def 		UpperCAmelCase(self				:   Tuple    ,   _A				:   Any       )						->						Optional[int]:
         pass





     def 		UpperCAmelCase(self				:   List[Any]    ,   _A				:   Union[str, Any]    ,   _A				:   Optional[int]=None    ,   _A				:   List[str]=None    ,   _A				:   Tuple=None    ,   **_A				:   Optional[Any]       )						->						Union[BackboneOutput, Tuple[Tensor, ...]]:
         snake_case								= return_dict if return_dict is not None else self.config.use_return_dict
         snake_case								= (
             output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
         )
         snake_case								= output_attentions if output_attentions is not None else self.config.output_attentions

         if output_attentions:
             raise ValueError("Cannot output attentions for timm backbones at the moment"       )

         if output_hidden_states:
             # We modify the return layers to include all the stages of the backbone
             snake_case								= self._all_layers
             snake_case								= self._backbone(__A    ,   **__A       )
             snake_case								= self._return_layers
             snake_case								= tuple(hidden_states[i] for i in self.out_indices       )
         else:
             snake_case								= self._backbone(__A    ,   **__A       )
             snake_case								= None

         snake_case								= tuple(__A       )
         snake_case								= tuple(__A       ) if hidden_states is not None else None

         if not return_dict:
             snake_case								= (feature_maps,)
             if output_hidden_states:
                 snake_case								= output + (hidden_states,)
             return output

         return BackboneOutput(feature_maps=__A    ,   hidden_states=__A    ,   attentions=__A       )



from ....utils import logging


_A   =			logging.get_logger(__name__)







class 					lowerCamelCase		(  A_  ):





     def __init__(self				:   Tuple    ,   _A				:   Optional[int]    ,   _A				:   Tuple=None    ,   _A				:   Union[str, Any]=2_0_4_8       )						->						List[Any]:
         snake_case								= config.__dict__
         snake_case								= modal_hidden_size
         if num_labels:
             snake_case								= num_labels

