






import inspect
import unittest

from transformers import is_torch_available, is_vision_available
from transformers.models.auto import get_values
from transformers.testing_utils import require_torch, slow, torch_device

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, floats_tensor, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
			import torch

			from transformers import MODEL_MAPPING, PoolFormerConfig, PoolFormerForImageClassification, PoolFormerModel
			from transformers.models.poolformer.modeling_poolformer import POOLFORMER_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
			from PIL import Image

			from transformers import PoolFormerImageProcessor


class 			__lowerCAmelCase				(					_SCREAMING_SNAKE_CASE			):


	'''simple docstring'''





	def       snake_case__(	self:	Tuple ):
			lowercase__				:			Optional[int]            =		self.config_class(**self.inputs_dict )
			self.parent.assertTrue(hasattr(__A,				'hidden_sizes' ) )
			self.parent.assertTrue(hasattr(__A,				'num_encoder_blocks' ) )


class 			__lowerCAmelCase				:


	'''simple docstring'''





	def __init__(	self:	str,				lowerCamelCase_:	Union[str, Any],				lowerCamelCase_:	List[str]=13,				lowerCamelCase_:	Dict=64,				lowerCamelCase_:	Optional[Any]=3,				lowerCamelCase_:	Dict=4,				lowerCamelCase_:	Union[str, Any]=[2, 2, 2, 2],				lowerCamelCase_:	Optional[Any]=[8, 4, 2, 1],				lowerCamelCase_:	str=[16, 32, 64, 128],				lowerCamelCase_:	str=[1, 4, 8, 16],				lowerCamelCase_:	Any=False,				lowerCamelCase_:	Union[str, Any]=True,				lowerCamelCase_:	Dict="gelu",				lowerCamelCase_:	Optional[int]=0.1,				lowerCamelCase_:	Union[str, Any]=0.0_2,				lowerCamelCase_:	Optional[int]=3,				lowerCamelCase_:	Any=None,				):
			lowercase__				:			Optional[Any]            =		parent
			lowercase__				:			Union[str, Any]            =		batch_size
			lowercase__				:			Any            =		image_size
			lowercase__				:			Tuple            =		num_channels
			lowercase__				:			Tuple            =		num_encoder_blocks
			lowercase__				:			Optional[int]            =		sr_ratios
			lowercase__				:			Tuple            =		depths
			lowercase__				:			str            =		hidden_sizes
			lowercase__				:			Dict            =		downsampling_rates
			lowercase__				:			Tuple            =		is_training
			lowercase__				:			str            =		use_labels
			lowercase__				:			Union[str, Any]            =		hidden_act
			lowercase__				:			Dict            =		hidden_dropout_prob
			lowercase__				:			Any            =		initializer_range
			lowercase__				:			Tuple            =		num_labels
			lowercase__				:			Optional[int]            =		scope

	def       snake_case__(	self:	Tuple ):
			lowercase__				:			List[Any]            =		floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size] )

			lowercase__				:			Any            =		None
			if self.use_labels:
					lowercase__				:			List[str]            =		ids_tensor([self.batch_size, self.image_size, self.image_size],				self.num_labels )

			lowercase__				:			Optional[int]            =		PoolFormerConfig(
			    image_size=self.image_size,				num_channels=self.num_channels,				num_encoder_blocks=self.num_encoder_blocks,				depths=self.depths,				hidden_sizes=self.hidden_sizes,				hidden_act=self.hidden_act,				hidden_dropout_prob=self.hidden_dropout_prob,				initializer_range=self.initializer_range,				)

			return config, pixel_values, labels

	def       snake_case__(	self:	Optional[Any],				lowerCamelCase_:	Any,				lowerCamelCase_:	Any,				lowerCamelCase_:	Optional[Any] ):
			lowercase__				:			int            =		PoolFormerModel(config=__A )
			model.to(__A )
			model.eval()
			lowercase__				:			int            =		model(__A )
			lowercase__				:			Union[str, Any]            =		self.image_size // 3_2.0
			self.parent.assertEqual(
			    result.last_hidden_state.shape,				(self.batch_size, self.hidden_sizes[-1], expected_height, expected_width) )





	def       snake_case__(	self:	List[Any] ):
			lowercase__				:			Optional[Any]            =		self.prepare_config_and_inputs()
			lowercase__      ,							lowercase__      ,							lowercase__				:			List[str]            =		config_and_inputs
			lowercase__				:			List[str]            =		{'pixel_values': pixel_values}
			return config, inputs_dict


@require_torch
class 			__lowerCAmelCase				(					_SCREAMING_SNAKE_CASE      ,						_SCREAMING_SNAKE_CASE      ,						unittest.TestCase			):


	'''simple docstring'''





	_A       	=							(PoolFormerModel, PoolFormerForImageClassification) if is_torch_available() else ()
	_A       	=							(
	    {"feature-extraction": PoolFormerModel, "image-classification": PoolFormerForImageClassification}
	    if is_torch_available()
	    else {}
	)

	_A       	=							False
	_A       	=							False
	_A       	=							False
	_A       	=							False
	_A       	=							False

	def       snake_case__(	self:	Optional[int] ):
			lowercase__				:			Optional[Any]            =		PoolFormerModelTester(self )
			lowercase__				:			int            =		PoolFormerConfigTester(self,				config_class=__A )

	def       snake_case__(	self:	int ):
			self.config_tester.run_common_tests()

	def       snake_case__(	self:	Optional[int] ):
			lowercase__				:			Dict            =		self.model_tester.prepare_config_and_inputs()
			self.model_tester.create_and_check_model(*__A )

	@unittest.skip('PoolFormer does not use inputs_embeds' )
	def       snake_case__(	self:	Tuple ):
			pass

	@unittest.skip('PoolFormer does not have get_input_embeddings method and get_output_embeddings methods' )
	def       snake_case__(	self:	List[Any] ):
			pass

	def       snake_case__(	self:	int ):
			def check_hidden_states_output(lowerCamelCase_:	Tuple,				lowerCamelCase_:	List[str],				lowerCamelCase_:	Optional[int] ):
					lowercase__				:			List[str]            =		model_class(__A )
					model.to(__A )
					model.eval()

					with torch.no_grad():
							lowercase__				:			str            =		model(**self._prepare_for_class(__A,				__A ) )

					lowercase__				:			List[str]            =		outputs.hidden_states

					lowercase__				:			str            =		self.model_tester.num_encoder_blocks
					self.assertEqual(len(__A ),				__A )

					# verify the first hidden states (first block)
					self.assertListEqual(
					    list(hidden_states[0].shape[-3:] ),				[
					        self.model_tester.hidden_sizes[0],
					        self.model_tester.image_size // 4,
					        self.model_tester.image_size // 4,
					    ],				)

			lowercase__      ,							lowercase__				:			Dict            =		self.model_tester.prepare_config_and_inputs_for_common()

			for model_class in self.all_model_classes:
					lowercase__				:			Union[str, Any]            =		True
					check_hidden_states_output(__A,				__A,				__A )

					# check that output_hidden_states also work using config
					del inputs_dict["output_hidden_states"]
					lowercase__				:			List[Any]            =		True

					check_hidden_states_output(__A,				__A,				__A )

	def       snake_case__(	self:	Any ):
			if not self.model_tester.is_training:
					return

			lowercase__      ,							lowercase__				:			Dict            =		self.model_tester.prepare_config_and_inputs_for_common()
			lowercase__				:			List[Any]            =		True

			for model_class in self.all_model_classes:
					if model_class in get_values(__A ):
							continue
					lowercase__				:			Any            =		model_class(__A )
					model.to(__A )
					model.train()
					lowercase__				:			List[Any]            =		self._prepare_for_class(__A,				__A,				return_labels=__A )
					lowercase__				:			Optional[Any]            =		model(**__A ).loss
					loss.backward()

	def       snake_case__(	self:	Optional[int] ):
			lowercase__      ,							lowercase__				:			List[Any]            =		self.model_tester.prepare_config_and_inputs_for_common()

			for model_class in self.all_model_classes:
					lowercase__				:			Union[str, Any]            =		model_class(__A )
					lowercase__				:			Dict            =		inspect.signature(model.forward )
					# signature.parameters is an OrderedDict => so arg_names order is deterministic
					lowercase__				:			Tuple            =		[*signature.parameters.keys()]

					lowercase__				:			Tuple            =		['pixel_values']
					self.assertListEqual(arg_names[:1],				__A )





	@slow
	def       snake_case__(	self:	List[str] ):
			for model_name in POOLFORMER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
					lowercase__				:			str            =		PoolFormerModel.from_pretrained(__A )
					self.assertIsNotNone(__A )


def 			SCREAMING_SNAKE_CASE__     (					)      ->       str:




		'''simple docstring'''
		lowercase__				:			Optional[Any]            =		Image.open('./tests/fixtures/tests_samples/COCO/000000039769.png' )
		return image





@require_torch
class 			__lowerCAmelCase				(					unittest.TestCase			):


	'''simple docstring'''





	@slow
	def       snake_case__(	self:	Optional[int] ):
			lowercase__				:			Dict            =		PoolFormerImageProcessor()
			lowercase__				:			List[Any]            =		PoolFormerForImageClassification.from_pretrained('sail/poolformer_s12' ).to(__A )

			lowercase__				:			Optional[Any]            =		image_processor(images=prepare_img(),				return_tensors='pt' ).to(__A )

			# forward pass
			with torch.no_grad():
					lowercase__				:			str            =		model(**__A )

			# verify the logits
			lowercase__				:			Dict            =		torch.Size((1, 1000) )
			self.assertEqual(outputs.logits.shape,				__A )

			lowercase__				:			List[str]            =		torch.tensor([-0.6_1_1_3, 0.1_6_8_5, -0.0_4_9_2] ).to(__A )
			self.assertTrue(torch.allclose(outputs.logits[0, :3],				__A,				atol=1E-4 ) )









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


class 			__lowerCAmelCase				(					enum.Enum			):


	'''simple docstring'''





	_A       	=							"timm"
	_A       	=							"transformers"


def 			SCREAMING_SNAKE_CASE__     (					_lowercase    :   Optional[Iterable[str]]      ,						_lowercase    :   Optional[Iterable[int]]      ,						_lowercase    :   Optional[Iterable[str]] )      ->       Optional[int]:




		'''simple docstring'''
		if stage_names is None:
				raise ValueError('Stage_names must be set for transformers backbones' )

		if out_features is not None:
				if not isinstance(_lowercase      ,						(list,) ):
						raise ValueError(f"""out_features must be a list {type(_lowercase )}""" )
				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(_lowercase      ,						(list, tuple) ):
						raise ValueError(f"""out_indices must be a list or tuple, got {type(_lowercase )}""" )
				if any(idx >= len(_lowercase ) 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(_lowercase ) != len(_lowercase ):
						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 			SCREAMING_SNAKE_CASE__     (					_lowercase    :   Optional[List[str]]      ,						_lowercase    :   Optional[Union[List[int], Tuple[int]]]      ,						_lowercase    :   List[str]      ,						)      ->       Dict:




		'''simple docstring'''
		if out_indices is None and out_features is None:
				lowercase__				:			str            =		[len(_lowercase ) - 1]
				lowercase__				:			Union[str, Any]            =		[stage_names[-1]]
		elif out_indices is None and out_features is not None:
				lowercase__				:			Optional[int]            =		[stage_names.index(_lowercase ) for layer in out_features]
		elif out_features is None and out_indices is not None:
				lowercase__				:			str            =		[stage_names[idx] for idx in out_indices]
		return out_features, out_indices


def 			SCREAMING_SNAKE_CASE__     (					_lowercase    :   Optional[List[str]]      ,						_lowercase    :   Optional[Union[List[int], Tuple[int]]]      ,						_lowercase    :   List[str]      ,						)      ->       Tuple[List[str], List[int]]:




		'''simple docstring'''
		verify_out_features_out_indices(out_features=_lowercase      ,						out_indices=_lowercase      ,						stage_names=_lowercase )
		lowercase__      ,							lowercase__				:			List[str]            =		_align_output_features_output_indices(
		    out_features=_lowercase      ,						out_indices=_lowercase      ,						stage_names=_lowercase )
		# Verify that the aligned out_features and out_indices are valid
		verify_out_features_out_indices(out_features=_lowercase      ,						out_indices=_lowercase      ,						stage_names=_lowercase )
		return output_features, output_indices


class 			__lowerCAmelCase				:


	'''simple docstring'''





	_A       	=							None

	def       snake_case__(	self:	Dict,				lowerCamelCase_:	Optional[Any] ):
			if getattr(self,				'_backbone',				lowerCamelCase_ ) 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']
			lowercase__				:			Tuple            =		[stage['module'] for stage in self._backbone.feature_info.info]
			lowercase__				:			Union[str, Any]            =		[stage['num_chs'] for stage in self._backbone.feature_info.info]
			lowercase__				:			Dict            =		self._backbone.feature_info.out_indices
			lowercase__				:			Tuple            =		self._backbone.feature_info.module_name()

			# We verify the out indices and out features are valid
			verify_out_features_out_indices(
			    out_features=lowerCamelCase_,				out_indices=lowerCamelCase_,				stage_names=self.stage_names )
			lowercase__      ,							lowercase__				:			List[Any]            =		out_features, out_indices

	def       snake_case__(	self:	Any,				lowerCamelCase_:	List[str] ):
			lowercase__				:			Dict            =		getattr(lowerCamelCase_,				'stage_names' )
			lowercase__				:			List[str]            =		getattr(lowerCamelCase_,				'out_features',				lowerCamelCase_ )
			lowercase__				:			Optional[int]            =		getattr(lowerCamelCase_,				'out_indices',				lowerCamelCase_ )

			lowercase__				:			Optional[int]            =		stage_names
			lowercase__      ,							lowercase__				:			Union[str, Any]            =		get_aligned_output_features_output_indices(
			    out_features=lowerCamelCase_,				out_indices=lowerCamelCase_,				stage_names=lowerCamelCase_ )
			# Number of channels for each stage. This is set in the transformer backbone model init
			lowercase__				:			Dict            =		None

	def       snake_case__(	self:	List[Any],				lowerCamelCase_:	List[str] ):
			lowercase__				:			List[Any]            =		config

			lowercase__				:			Optional[int]            =		getattr(lowerCamelCase_,				'use_timm_backbone',				lowerCamelCase_ )
			lowercase__				:			List[Any]            =		BackboneType.TIMM if self.use_timm_backbone else BackboneType.TRANSFORMERS

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

	@property
	def       snake_case__(	self:	List[str] ):
			return self._out_features

	@out_features.setter
	def       snake_case__(	self:	Union[str, Any],				lowerCamelCase_:	List[str] ):
			lowercase__      ,							lowercase__				:			Optional[int]            =		get_aligned_output_features_output_indices(
			    out_features=lowerCamelCase_,				out_indices=lowerCamelCase_,				stage_names=self.stage_names )

	@property
	def       snake_case__(	self:	List[Any] ):
			return self._out_indices

	@out_indices.setter
	def       snake_case__(	self:	Tuple,				lowerCamelCase_:	Union[Tuple[int], List[int]] ):
			lowercase__      ,							lowercase__				:			List[str]            =		get_aligned_output_features_output_indices(
			    out_features=lowerCamelCase_,				out_indices=lowerCamelCase_,				stage_names=self.stage_names )

	@property
	def       snake_case__(	self:	str ):
			# 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:	Optional[int] ):
			return [self.out_feature_channels[name] for name in self.out_features]

	def       snake_case__(	self:	List[Any],				*lowerCamelCase_:	List[Any],				**lowerCamelCase_:	Optional[Any] ):
			lowercase__				:			Any            =		dict(inspect.signature(self.forward ).parameters )
			lowercase__				:			List[Any]            =		{k: v for k, v in kwargs.items() if k in signature}
			return self(*lowerCamelCase_,				**lowerCamelCase_ )

	def       snake_case__(	self:	int,				lowerCamelCase_:	str,				lowerCamelCase_:	Optional[bool] = None,				lowerCamelCase_:	Optional[bool] = None,				lowerCamelCase_:	Optional[bool] = None,				):
			raise NotImplementedError('This method should be implemented by the derived class.' )





	def       snake_case__(	self:	Dict ):
			lowercase__				:			List[Any]            =		super().to_dict()
			lowercase__				:			Union[str, Any]            =		output.pop('_out_features' )
			lowercase__				:			Any            =		output.pop('_out_indices' )
			return output


class 			__lowerCAmelCase				:


	'''simple docstring'''





	@property
	def       snake_case__(	self:	Optional[int] ):
			return self._out_features

	@out_features.setter
	def       snake_case__(	self:	List[Any],				lowerCamelCase_:	List[str] ):
			lowercase__      ,							lowercase__				:			List[Any]            =		get_aligned_output_features_output_indices(
			    out_features=lowerCamelCase_,				out_indices=lowerCamelCase_,				stage_names=self.stage_names )

	@property
	def       snake_case__(	self:	Dict ):
			return self._out_indices

	@out_indices.setter
	def       snake_case__(	self:	Optional[int],				lowerCamelCase_:	Union[Tuple[int], List[int]] ):
			lowercase__      ,							lowercase__				:			Any            =		get_aligned_output_features_output_indices(
			    out_features=lowerCamelCase_,				out_indices=lowerCamelCase_,				stage_names=self.stage_names )





	def       snake_case__(	self:	Union[str, Any] ):
			lowercase__				:			List[str]            =		super().to_dict()
			lowercase__				:			str            =		output.pop('_out_features' )
			lowercase__				:			str            =		output.pop('_out_indices' )
			return output


