




import enum
import inspect
from typing import Iterable, List, Optional, Tuple, Union


class 				__UpperCamelCase      (			enum.Enum	):





				'''simple docstring'''



				__a				:			List[str]					    ="""timm"""
				__a				:			str					    ="""transformers"""




def    UpperCAmelCase							(  _snake_case    ,			_snake_case    ,			_snake_case				):
							if stage_names is None:
														raise ValueError('''Stage_names must be set for transformers backbones'''				)

							if out_features is not None:
														if not isinstance(__lowerCamelCase    ,			(list,)				):
																					raise ValueError(F"""out_features must be a list {type(__lowerCamelCase				)}"""				)
														if any(feat not in stage_names for feat in out_features				):
																					raise ValueError(F"""out_features must be a subset of stage_names: {stage_names} got {out_features}"""				)

							if out_indices is not None:
														if not isinstance(__lowerCamelCase    ,			(list, tuple)				):
																					raise ValueError(F"""out_indices must be a list or tuple, got {type(__lowerCamelCase				)}"""				)
														if any(idx >= len(__lowerCamelCase				) for idx in out_indices				):
																					raise ValueError('''out_indices must be valid indices for stage_names {stage_names}, got {out_indices}'''				)

							if out_features is not None and out_indices is not None:
														if len(__lowerCamelCase				) != len(__lowerCamelCase				):
																					raise ValueError('''out_features and out_indices should have the same length if both are set'''				)
														if out_features != [stage_names[idx] for idx in out_indices]:
																					raise ValueError('''out_features and out_indices should correspond to the same stages if both are set'''				)



def    UpperCAmelCase							(  _snake_case    ,			_snake_case    ,			_snake_case    ,			):
							if out_indices is None and out_features is None:
														lowerCAmelCase =		[len(__lowerCamelCase				) - 1]
														lowerCAmelCase =		[stage_names[-1]]
							elif out_indices is None and out_features is not None:
														lowerCAmelCase =		[stage_names.index(__lowerCamelCase				) for layer in out_features]
							elif out_features is None and out_indices is not None:
														lowerCAmelCase =		[stage_names[idx] for idx in out_indices]
							return out_features, out_indices



def    UpperCAmelCase							(  _snake_case    ,			_snake_case    ,			_snake_case    ,			):
							verify_out_features_out_indices(out_features=__lowerCamelCase    ,			out_indices=__lowerCamelCase    ,			stage_names=__lowerCamelCase				)
							lowerCAmelCase =		_align_output_features_output_indices(
							    out_features=__lowerCamelCase    ,			out_indices=__lowerCamelCase    ,			stage_names=__lowerCamelCase				)
							# Verify that the aligned out_features and out_indices are valid
							verify_out_features_out_indices(out_features=__lowerCamelCase    ,			out_indices=__lowerCamelCase    ,			stage_names=__lowerCamelCase				)
							return output_features, output_indices


class 				__UpperCamelCase      :





				'''simple docstring'''



				__a				:			Union[str, Any]					    =None



				def    __snake_case		(			self							,			UpperCAmelCase_    ):
											if getattr(self							,			'''_backbone'''							,			UpperCAmelCase_    ) is None:
																		raise ValueError('''self._backbone must be set before calling _init_timm_backbone'''    )

											# These will diagree with the defaults for the transformers models e.g. for resnet50
											# the transformer model has out_features = ['stem', 'stage1', 'stage2', 'stage3', 'stage4']
											# the timm model has out_features = ['act', 'layer1', 'layer2', 'layer3', 'layer4']
											lowerCAmelCase =		[stage['''module'''] for stage in self._backbone.feature_info.info]
											lowerCAmelCase =		[stage['''num_chs'''] for stage in self._backbone.feature_info.info]
											lowerCAmelCase =		self._backbone.feature_info.out_indices
											lowerCAmelCase =		self._backbone.feature_info.module_name()

											# We verify the out indices and out features are valid
											verify_out_features_out_indices(
											    out_features=UpperCAmelCase_							,			out_indices=UpperCAmelCase_							,			stage_names=self.stage_names    )
											lowerCAmelCase =		out_features, out_indices



				def    __snake_case		(			self							,			UpperCAmelCase_    ):
											lowerCAmelCase =		getattr(UpperCAmelCase_							,			'''stage_names'''    )
											lowerCAmelCase =		getattr(UpperCAmelCase_							,			'''out_features'''							,			UpperCAmelCase_    )
											lowerCAmelCase =		getattr(UpperCAmelCase_							,			'''out_indices'''							,			UpperCAmelCase_    )

											lowerCAmelCase =		stage_names
											lowerCAmelCase =		get_aligned_output_features_output_indices(
											    out_features=UpperCAmelCase_							,			out_indices=UpperCAmelCase_							,			stage_names=UpperCAmelCase_    )
											# Number of channels for each stage. This is set in the transformer backbone model init
											lowerCAmelCase =		None



				def    __snake_case		(			self							,			UpperCAmelCase_    ):
											lowerCAmelCase =		config

											lowerCAmelCase =		getattr(UpperCAmelCase_							,			'''use_timm_backbone'''							,			UpperCAmelCase_    )
											lowerCAmelCase =		BackboneType.TIMM if self.use_timm_backbone else BackboneType.TRANSFORMERS

											if self.backbone_type == BackboneType.TIMM:
																		self._init_timm_backbone(UpperCAmelCase_    )
											elif self.backbone_type == BackboneType.TRANSFORMERS:
																		self._init_transformers_backbone(UpperCAmelCase_    )
											else:
																		raise ValueError(F"""backbone_type {self.backbone_type} not supported."""    )



				@property
				def    __snake_case		(			self    ):
											return self._out_features



				@out_features.setter
				def    __snake_case		(			self							,			UpperCAmelCase_    ):
											lowerCAmelCase =		get_aligned_output_features_output_indices(
											    out_features=UpperCAmelCase_							,			out_indices=UpperCAmelCase_							,			stage_names=self.stage_names    )



				@property
				def    __snake_case		(			self    ):
											return self._out_indices



				@out_indices.setter
				def    __snake_case		(			self							,			UpperCAmelCase_    ):
											lowerCAmelCase =		get_aligned_output_features_output_indices(
											    out_features=UpperCAmelCase_							,			out_indices=UpperCAmelCase_							,			stage_names=self.stage_names    )



				@property
				def    __snake_case		(			self    ):
											# the current backbones will output the number of channels for each stage
											# even if that stage is not in the out_features list.
											return {stage: self.num_features[i] for i, stage in enumerate(self.stage_names    )}



				@property
				def    __snake_case		(			self    ):
											return [self.out_feature_channels[name] for name in self.out_features]



				def    __snake_case		(			self							,			*UpperCAmelCase_							,			**UpperCAmelCase_    ):
											lowerCAmelCase =		dict(inspect.signature(self.forward    ).parameters    )
											lowerCAmelCase =		{k: v for k, v in kwargs.items() if k in signature}
											return self(*UpperCAmelCase_							,			**UpperCAmelCase_    )



				def    __snake_case		(			self							,			UpperCAmelCase_							,			UpperCAmelCase_ = None							,			UpperCAmelCase_ = None							,			UpperCAmelCase_ = None							,			):
											raise NotImplementedError('''This method should be implemented by the derived class.'''    )






				def    __snake_case		(			self    ):
											lowerCAmelCase =		super().to_dict()
											lowerCAmelCase =		output.pop('''_out_features'''    )
											lowerCAmelCase =		output.pop('''_out_indices'''    )
											return output




class 				__UpperCamelCase      :





				'''simple docstring'''



				@property
				def    __snake_case		(			self    ):
											return self._out_features



				@out_features.setter
				def    __snake_case		(			self							,			UpperCAmelCase_    ):
											lowerCAmelCase =		get_aligned_output_features_output_indices(
											    out_features=UpperCAmelCase_							,			out_indices=UpperCAmelCase_							,			stage_names=self.stage_names    )



				@property
				def    __snake_case		(			self    ):
											return self._out_indices



				@out_indices.setter
				def    __snake_case		(			self							,			UpperCAmelCase_    ):
											lowerCAmelCase =		get_aligned_output_features_output_indices(
											    out_features=UpperCAmelCase_							,			out_indices=UpperCAmelCase_							,			stage_names=self.stage_names    )






				def    __snake_case		(			self    ):
											lowerCAmelCase =		super().to_dict()
											lowerCAmelCase =		output.pop('''_out_features'''    )
											lowerCAmelCase =		output.pop('''_out_indices'''    )
											return output








"""simple docstring"""






from typing import TYPE_CHECKING

from ...utils import (
    OptionalDependencyNotAvailable,
    _LazyModule,
    is_tf_available,
    is_tokenizers_available,
    is_torch_available,
)


_lowercase					:					str 		=		{
    "configuration_openai": ["OPENAI_GPT_PRETRAINED_CONFIG_ARCHIVE_MAP", "OpenAIGPTConfig"],
    "tokenization_openai": ["OpenAIGPTTokenizer"],
}

try:
		if not is_tokenizers_available():
				raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
		pass
else:
		_lowercase					:					List[Any] 		=		["OpenAIGPTTokenizerFast"]

try:
		if not is_torch_available():
				raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
		pass
else:
		_lowercase					:					Union[str, Any] 		=		[
		    "OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST",
		    "OpenAIGPTDoubleHeadsModel",
		    "OpenAIGPTForSequenceClassification",
		    "OpenAIGPTLMHeadModel",
		    "OpenAIGPTModel",
		    "OpenAIGPTPreTrainedModel",
		    "load_tf_weights_in_openai_gpt",
		]

try:
		if not is_tf_available():
				raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
		pass
else:
		_lowercase					:					Optional[Any] 		=		[
		    "TF_OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST",
		    "TFOpenAIGPTDoubleHeadsModel",
		    "TFOpenAIGPTForSequenceClassification",
		    "TFOpenAIGPTLMHeadModel",
		    "TFOpenAIGPTMainLayer",
		    "TFOpenAIGPTModel",
		    "TFOpenAIGPTPreTrainedModel",
		]


if TYPE_CHECKING:
		from .configuration_openai import OPENAI_GPT_PRETRAINED_CONFIG_ARCHIVE_MAP, OpenAIGPTConfig
		from .tokenization_openai import OpenAIGPTTokenizer

		try:
				if not is_tokenizers_available():
						raise OptionalDependencyNotAvailable()
		except OptionalDependencyNotAvailable:
				pass
		else:
				from .tokenization_openai_fast import OpenAIGPTTokenizerFast

		try:
				if not is_torch_available():
						raise OptionalDependencyNotAvailable()
		except OptionalDependencyNotAvailable:
				pass
		else:
				from .modeling_openai import (
				    OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST,
				    OpenAIGPTDoubleHeadsModel,
				    OpenAIGPTForSequenceClassification,
				    OpenAIGPTLMHeadModel,
				    OpenAIGPTModel,
				    OpenAIGPTPreTrainedModel,
				    load_tf_weights_in_openai_gpt,
				)

		try:
				if not is_tf_available():
						raise OptionalDependencyNotAvailable()
		except OptionalDependencyNotAvailable:
				pass
		else:
				from .modeling_tf_openai import (
				    TF_OPENAI_GPT_PRETRAINED_MODEL_ARCHIVE_LIST,
				    TFOpenAIGPTDoubleHeadsModel,
				    TFOpenAIGPTForSequenceClassification,
				    TFOpenAIGPTLMHeadModel,
				    TFOpenAIGPTMainLayer,
				    TFOpenAIGPTModel,
				    TFOpenAIGPTPreTrainedModel,
				)

else:
		import sys

		_lowercase					:					Dict 		=		_LazyModule(__name__, globals()["__file__"], _import_structure, module_spec=__spec__)




