
import inspect
import unittest
import warnings
from typing import List

from transformers import EfficientFormerConfig
from transformers.models.auto import get_values
from transformers.testing_utils import require_torch, require_vision, slow, torch_device
from transformers.utils import cached_property, is_torch_available, is_vision_available

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_FOR_IMAGE_CLASSIFICATION_MAPPING,
			    MODEL_MAPPING,
			    EfficientFormerForImageClassification,
			    EfficientFormerForImageClassificationWithTeacher,
			    EfficientFormerModel,
			)
			from transformers.models.efficientformer.modeling_efficientformer import (
			    EFFICIENTFORMER_PRETRAINED_MODEL_ARCHIVE_LIST,
			)


if is_vision_available():
			from PIL import Image

			from transformers import EfficientFormerImageProcessor





class      _lowerCAmelCase :




				def __init__( self    ,    _UpperCamelCase    ,    _UpperCamelCase = 13    ,    _UpperCamelCase = 64    ,    _UpperCamelCase = 2    ,    _UpperCamelCase = 3    ,    _UpperCamelCase = 3    ,    _UpperCamelCase = True    ,    _UpperCamelCase = True    ,    _UpperCamelCase = 128    ,    _UpperCamelCase=[16, 32, 64, 128]    ,    _UpperCamelCase = 7    ,    _UpperCamelCase = 4    ,    _UpperCamelCase = 37    ,    _UpperCamelCase = "gelu"    ,    _UpperCamelCase = 0.1    ,    _UpperCamelCase = 0.1    ,    _UpperCamelCase = 10    ,    _UpperCamelCase = 0.02    ,    _UpperCamelCase = 2    ,    _UpperCamelCase = 1    ,    _UpperCamelCase = 128    ,    _UpperCamelCase = [2, 2, 2, 2]    ,    _UpperCamelCase = 2    ,    _UpperCamelCase = 2    ,    )    ->				str:
							lowerCAmelCase_      =     parent
							lowerCAmelCase_      =     batch_size
							lowerCAmelCase_      =     image_size
							lowerCAmelCase_      =     patch_size
							lowerCAmelCase_      =     num_channels
							lowerCAmelCase_      =     is_training
							lowerCAmelCase_      =     use_labels
							lowerCAmelCase_      =     hidden_size
							lowerCAmelCase_      =     num_hidden_layers
							lowerCAmelCase_      =     num_attention_heads
							lowerCAmelCase_      =     intermediate_size
							lowerCAmelCase_      =     hidden_act
							lowerCAmelCase_      =     hidden_dropout_prob
							lowerCAmelCase_      =     attention_probs_dropout_prob
							lowerCAmelCase_      =     type_sequence_label_size
							lowerCAmelCase_      =     initializer_range
							lowerCAmelCase_      =     encoder_stride
							lowerCAmelCase_      =     num_attention_outputs
							lowerCAmelCase_      =     embed_dim
							lowerCAmelCase_      =     embed_dim + 1
							lowerCAmelCase_      =     resolution
							lowerCAmelCase_      =     depths
							lowerCAmelCase_      =     hidden_sizes
							lowerCAmelCase_      =     dim
							lowerCAmelCase_      =     mlp_expansion_ratio




				def 					__a						( self					)    ->				int:
							lowerCAmelCase_      =     floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]					)

							lowerCAmelCase_      =     None
							if self.use_labels:
										lowerCAmelCase_      =     ids_tensor([self.batch_size]    ,    self.type_sequence_label_size					)

							lowerCAmelCase_      =     self.get_config()
							return config, pixel_values, labels




				def 					__a						( self					)    ->				Tuple:
							return EfficientFormerConfig(
							    image_size=self.image_size    ,    patch_size=self.patch_size    ,    num_channels=self.num_channels    ,    hidden_size=self.hidden_size    ,    num_hidden_layers=self.num_hidden_layers    ,    num_attention_heads=self.num_attention_heads    ,    intermediate_size=self.intermediate_size    ,    hidden_act=self.hidden_act    ,    hidden_dropout_prob=self.hidden_dropout_prob    ,    attention_probs_dropout_prob=self.attention_probs_dropout_prob    ,    is_decoder=_UpperCamelCase    ,    initializer_range=self.initializer_range    ,    encoder_stride=self.encoder_stride    ,    resolution=self.resolution    ,    depths=self.depths    ,    hidden_sizes=self.hidden_sizes    ,    dim=self.dim    ,    mlp_expansion_ratio=self.mlp_expansion_ratio    ,    )




				def 					__a						( self    ,    _UpperCamelCase    ,    _UpperCamelCase    ,    _UpperCamelCase					)    ->				int:
							lowerCAmelCase_      =     EfficientFormerModel(config=_UpperCamelCase					)
							model.to(_UpperCamelCase					)
							model.eval()
							lowerCAmelCase_      =     model(_UpperCamelCase					)
							self.parent.assertEqual(result.last_hidden_state.shape    ,    (self.batch_size, self.seq_length, self.hidden_size)					)




				def 					__a						( self    ,    _UpperCamelCase    ,    _UpperCamelCase    ,    _UpperCamelCase					)    ->				int:
							lowerCAmelCase_      =     self.type_sequence_label_size
							lowerCAmelCase_      =     EfficientFormerForImageClassification(_UpperCamelCase					)
							model.to(_UpperCamelCase					)
							model.eval()
							lowerCAmelCase_      =     model(_UpperCamelCase    ,    labels=_UpperCamelCase					)
							self.parent.assertEqual(result.logits.shape    ,    (self.batch_size, self.type_sequence_label_size)					)

							# test greyscale images
							lowerCAmelCase_      =     1
							lowerCAmelCase_      =     EfficientFormerForImageClassification(_UpperCamelCase					)
							model.to(_UpperCamelCase					)
							model.eval()

							lowerCAmelCase_      =     floats_tensor([self.batch_size, 1, self.image_size, self.image_size]					)
							lowerCAmelCase_      =     model(_UpperCamelCase					)
							self.parent.assertEqual(result.logits.shape    ,    (self.batch_size, self.type_sequence_label_size)					)




				def 					__a						( self					)    ->				Any:
							lowerCAmelCase_      =     self.prepare_config_and_inputs()
							(
							    (
							    lowerCAmelCase_
							)     ,  (
							    lowerCAmelCase_
							)     ,  (
							    lowerCAmelCase_
							)     ,  
							)      =     config_and_inputs
							lowerCAmelCase_      =     {"pixel_values": pixel_values}
							return config, inputs_dict





@require_torch
class      _lowerCAmelCase (     __a ,				__a ,				unittest.TestCase	):
				_lowercase      		=(
				    (
				        EfficientFormerModel,
				        EfficientFormerForImageClassificationWithTeacher,
				        EfficientFormerForImageClassification,
				    )
				    if is_torch_available()
				    else ()
				)
				_lowercase      		=(
				    {
				        '''feature-extraction''': EfficientFormerModel,
				        '''image-classification''': (
				            EfficientFormerForImageClassification,
				            EfficientFormerForImageClassificationWithTeacher,
				        ),
				    }
				    if is_torch_available()
				    else {}
				)
				_lowercase      		=False

				_lowercase      		=False
				_lowercase      		=False
				_lowercase      		=False




				def 					__a						( self					)    ->				List[Any]:
							lowerCAmelCase_      =     EfficientFormerModelTester(self					)
							lowerCAmelCase_      =     ConfigTester(
							    self    ,    config_class=_UpperCamelCase    ,    has_text_modality=_UpperCamelCase    ,    hidden_size=37					)




				def 					__a						( self					)    ->				List[str]:
							self.config_tester.run_common_tests()




				@unittest.skip(reason="EfficientFormer does not use inputs_embeds"					)
				def 					__a						( self					)    ->				Tuple:
							pass




				@unittest.skip(reason="EfficientFormer does not support input and output embeddings"					)
				def 					__a						( self					)    ->				Optional[int]:
							pass




				def 					__a						( self					)    ->				List[str]:
							lowerCAmelCase_     ,  lowerCAmelCase_      =     self.model_tester.prepare_config_and_inputs_for_common()

							for model_class in self.all_model_classes:
										lowerCAmelCase_      =     model_class(_UpperCamelCase					)
										lowerCAmelCase_      =     inspect.signature(model.forward					)
										# signature.parameters is an OrderedDict => so arg_names order is deterministic
										lowerCAmelCase_      =     [*signature.parameters.keys()]

										lowerCAmelCase_      =     ["pixel_values"]
										self.assertListEqual(arg_names[:1]    ,    _UpperCamelCase					)




				def 					__a						( self					)    ->				Union[str, Any]:
							def check_hidden_states_output(_UpperCamelCase    ,    _UpperCamelCase    ,    _UpperCamelCase					):
										lowerCAmelCase_      =     model_class(_UpperCamelCase					)
										model.to(_UpperCamelCase					)
										model.eval()

										with torch.no_grad():
													lowerCAmelCase_      =     model(**self._prepare_for_class(_UpperCamelCase    ,    _UpperCamelCase					)					)

										lowerCAmelCase_      =     outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states

										lowerCAmelCase_      =     getattr(
										    self.model_tester    ,    "expected_num_hidden_layers"    ,    self.model_tester.num_hidden_layers + 1					)
										self.assertEqual(len(_UpperCamelCase					)    ,    _UpperCamelCase					)

										if hasattr(self.model_tester    ,    "encoder_seq_length"					):
													lowerCAmelCase_      =     self.model_tester.encoder_seq_length
													if hasattr(self.model_tester    ,    "chunk_length"					) and self.model_tester.chunk_length > 1:
																lowerCAmelCase_      =     seq_length * self.model_tester.chunk_length
										else:
													lowerCAmelCase_      =     self.model_tester.seq_length

										self.assertListEqual(
										    list(hidden_states[-1].shape[-2:]					)    ,    [seq_length, self.model_tester.hidden_size]    ,    )

										if config.is_encoder_decoder:
													lowerCAmelCase_      =     outputs.decoder_hidden_states

													self.assertIsInstance(_UpperCamelCase    ,    (list, tuple)					)
													self.assertEqual(len(_UpperCamelCase					)    ,    _UpperCamelCase					)
													lowerCAmelCase_      =     getattr(self.model_tester    ,    "seq_length"    ,    _UpperCamelCase					)
													lowerCAmelCase_      =     getattr(self.model_tester    ,    "decoder_seq_length"    ,    _UpperCamelCase					)

													self.assertListEqual(
													    list(hidden_states[-1].shape[-2:]					)    ,    [decoder_seq_length, self.model_tester.hidden_size]    ,    )

							lowerCAmelCase_     ,  lowerCAmelCase_      =     self.model_tester.prepare_config_and_inputs_for_common()

							for model_class in self.all_model_classes:
										lowerCAmelCase_      =     True
										check_hidden_states_output(_UpperCamelCase    ,    _UpperCamelCase    ,    _UpperCamelCase					)

										# check that output_hidden_states also work using config
										del inputs_dict["output_hidden_states"]
										lowerCAmelCase_      =     True

										check_hidden_states_output(_UpperCamelCase    ,    _UpperCamelCase    ,    _UpperCamelCase					)




				def 					__a						( self    ,    _UpperCamelCase    ,    _UpperCamelCase    ,    _UpperCamelCase=False					)    ->				int:
							lowerCAmelCase_      =     super()._prepare_for_class(_UpperCamelCase    ,    _UpperCamelCase    ,    return_labels=_UpperCamelCase					)

							if return_labels:
										if model_class.__name__ == "EfficientFormerForImageClassificationWithTeacher":
													del inputs_dict["labels"]

							return inputs_dict




				def 					__a						( self					)    ->				Any:
							lowerCAmelCase_      =     self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_model(*_UpperCamelCase					)




				@unittest.skip(reason="EfficientFormer does not implement masked image modeling yet"					)
				def 					__a						( self					)    ->				Union[str, Any]:
							lowerCAmelCase_      =     self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_for_masked_image_modeling(*_UpperCamelCase					)




				def 					__a						( self					)    ->				Dict:
							lowerCAmelCase_      =     self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_for_image_classification(*_UpperCamelCase					)




				def 					__a						( self					)    ->				Tuple:
							if not self.model_tester.is_training:
										return

							lowerCAmelCase_     ,  lowerCAmelCase_      =     self.model_tester.prepare_config_and_inputs_for_common()
							lowerCAmelCase_      =     True

							for model_class in self.all_model_classes:
										# EfficientFormerForImageClassificationWithTeacher supports inference-only
										if (
										    model_class in get_values(_UpperCamelCase					)
										    or model_class.__name__ == "EfficientFormerForImageClassificationWithTeacher"
										):
													continue
										lowerCAmelCase_      =     model_class(_UpperCamelCase					)
										model.to(_UpperCamelCase					)
										model.train()
										lowerCAmelCase_      =     self._prepare_for_class(_UpperCamelCase    ,    _UpperCamelCase    ,    return_labels=_UpperCamelCase					)
										lowerCAmelCase_      =     model(**_UpperCamelCase					).loss
										loss.backward()




				def 					__a						( self					)    ->				Dict:
							lowerCAmelCase_     ,  lowerCAmelCase_      =     self.model_tester.prepare_config_and_inputs_for_common()

							lowerCAmelCase_      =     [
							    {"title": "multi_label_classification", "num_labels": 2, "dtype": torch.float},
							    {"title": "single_label_classification", "num_labels": 1, "dtype": torch.long},
							    {"title": "regression", "num_labels": 1, "dtype": torch.float},
							]

							for model_class in self.all_model_classes:
										if (
										    model_class
										    not in [
										        *get_values(_UpperCamelCase					),
										    ]
										    or model_class.__name__ == "EfficientFormerForImageClassificationWithTeacher"
										):
													continue

										for problem_type in problem_types:
													with self.subTest(msg=f"""Testing {model_class} with {problem_type['title']}"""					):
																lowerCAmelCase_      =     problem_type["title"]
																lowerCAmelCase_      =     problem_type["num_labels"]

																lowerCAmelCase_      =     model_class(_UpperCamelCase					)
																model.to(_UpperCamelCase					)
																model.train()

																lowerCAmelCase_      =     self._prepare_for_class(_UpperCamelCase    ,    _UpperCamelCase    ,    return_labels=_UpperCamelCase					)

																if problem_type["num_labels"] > 1:
																			lowerCAmelCase_      =     inputs["labels"].unsqueeze(1					).repeat(1    ,    problem_type["num_labels"]					)

																lowerCAmelCase_      =     inputs["labels"].to(problem_type["dtype"]					)

																# This tests that we do not trigger the warning form PyTorch "Using a target size that is different
																# to the input size. This will likely lead to incorrect results due to broadcasting. Please ensure
																# they have the same size." which is a symptom something in wrong for the regression problem.
																# See https://github.com/huggingface/transformers/issues/11780
																with warnings.catch_warnings(record=_UpperCamelCase					) as warning_list:
																			lowerCAmelCase_      =     model(**_UpperCamelCase					).loss
																for w in warning_list:
																			if "Using a target size that is different to the input size" in str(w.message					):
																						raise ValueError(
																						    f"""Something is going wrong in the regression problem: intercepted {w.message}"""					)

																loss.backward()




				@slow
				def 					__a						( self					)    ->				Tuple:
							for model_name in EFFICIENTFORMER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
										lowerCAmelCase_      =     EfficientFormerModel.from_pretrained(_UpperCamelCase					)
										self.assertIsNotNone(_UpperCamelCase					)




				def 					__a						( self					)    ->				str:
							lowerCAmelCase_     ,  lowerCAmelCase_      =     self.model_tester.prepare_config_and_inputs_for_common()
							lowerCAmelCase_      =     True

							lowerCAmelCase_      =     getattr(self.model_tester    ,    "seq_length"    ,    _UpperCamelCase					)
							lowerCAmelCase_      =     getattr(self.model_tester    ,    "encoder_seq_length"    ,    _UpperCamelCase					)
							lowerCAmelCase_      =     getattr(self.model_tester    ,    "key_length"    ,    _UpperCamelCase					)
							lowerCAmelCase_      =     getattr(self.model_tester    ,    "chunk_length"    ,    _UpperCamelCase					)

							if chunk_length is not None and hasattr(self.model_tester    ,    "num_hashes"					):
										lowerCAmelCase_      =     encoder_seq_length * self.model_tester.num_hashes

							for model_class in self.all_model_classes:
										lowerCAmelCase_      =     True
										lowerCAmelCase_      =     False
										lowerCAmelCase_      =     True
										lowerCAmelCase_      =     model_class(_UpperCamelCase					)
										model.to(_UpperCamelCase					)
										model.eval()
										with torch.no_grad():
													lowerCAmelCase_      =     model(**self._prepare_for_class(_UpperCamelCase    ,    _UpperCamelCase					)					)
										lowerCAmelCase_      =     outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions
										self.assertEqual(len(_UpperCamelCase					)    ,    self.model_tester.num_attention_outputs					)

										# check that output_attentions also work using config
										del inputs_dict["output_attentions"]
										lowerCAmelCase_      =     True
										lowerCAmelCase_      =     model_class(_UpperCamelCase					)
										model.to(_UpperCamelCase					)
										model.eval()
										with torch.no_grad():
													lowerCAmelCase_      =     model(**self._prepare_for_class(_UpperCamelCase    ,    _UpperCamelCase					)					)
										lowerCAmelCase_      =     outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions
										self.assertEqual(len(_UpperCamelCase					)    ,    self.model_tester.num_attention_outputs					)

										if chunk_length is not None:
													self.assertListEqual(
													    list(attentions[0].shape[-4:]					)    ,    [self.model_tester.num_attention_heads, encoder_seq_length, chunk_length, encoder_key_length]    ,    )
										else:
													self.assertListEqual(
													    list(attentions[0].shape[-3:]					)    ,    [self.model_tester.num_attention_heads, encoder_seq_length, encoder_key_length]    ,    )






def        lowerCamelCase__    (    ):




			"""simple docstring"""


			lowerCAmelCase_      =     Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png"    )
			return image





@require_torch
@require_vision
class      _lowerCAmelCase (     unittest.TestCase	):




				@cached_property
				def 					__a						( self					)    ->				Any:
							return (
							    EfficientFormerImageProcessor.from_pretrained("snap-research/efficientformer-l1-300"					)
							    if is_vision_available()
							    else None
							)




				@slow
				def 					__a						( self					)    ->				str:
							lowerCAmelCase_      =     EfficientFormerForImageClassification.from_pretrained("snap-research/efficientformer-l1-300"					).to(
							    _UpperCamelCase					)

							lowerCAmelCase_      =     self.default_image_processor
							lowerCAmelCase_      =     prepare_img()
							lowerCAmelCase_      =     image_processor(images=_UpperCamelCase    ,    return_tensors="pt"					).to(_UpperCamelCase					)

							# forward pass
							with torch.no_grad():
										lowerCAmelCase_      =     model(**_UpperCamelCase					)

							# verify the logits
							lowerCAmelCase_      =     (1, 1_000)
							self.assertEqual(outputs.logits.shape    ,    _UpperCamelCase					)

							lowerCAmelCase_      =     torch.tensor([-0.0555, 0.4825, -0.0852]					).to(_UpperCamelCase					)
							self.assertTrue(torch.allclose(outputs.logits[0][:3]    ,    _UpperCamelCase    ,    atol=1e-4					)					)




				@slow
				def 					__a						( self					)    ->				str:
							lowerCAmelCase_      =     EfficientFormerForImageClassificationWithTeacher.from_pretrained(
							    "snap-research/efficientformer-l1-300"					).to(_UpperCamelCase					)

							lowerCAmelCase_      =     self.default_image_processor
							lowerCAmelCase_      =     prepare_img()
							lowerCAmelCase_      =     image_processor(images=_UpperCamelCase    ,    return_tensors="pt"					).to(_UpperCamelCase					)

							# forward pass
							with torch.no_grad():
										lowerCAmelCase_      =     model(**_UpperCamelCase					)

							# verify the logits
							lowerCAmelCase_      =     (1, 1_000)
							self.assertEqual(outputs.logits.shape    ,    _UpperCamelCase					)

							lowerCAmelCase_      =     torch.tensor([-0.1312, 0.4353, -1.0499]					).to(_UpperCamelCase					)
							self.assertTrue(torch.allclose(outputs.logits[0][:3]    ,    _UpperCamelCase    ,    atol=1e-4					)					)





class      _lowerCAmelCase :




				def __init__( self					)    ->				None:
							# numbermap keys are the number and its values are lists of indexes sorted
							# in ascending order
							lowerCAmelCase_      =     {}
							# indexmap keys are an index and it's values are the number at that index
							lowerCAmelCase_      =     {}




				def 					__a						( self    ,    _UpperCamelCase    ,    _UpperCamelCase					)    ->				list[int]:
							if isinstance(_UpperCamelCase    ,    (range, str)					):
										lowerCAmelCase_      =     list(_UpperCamelCase					)
							elif not isinstance(_UpperCamelCase    ,    _UpperCamelCase					):
										raise TypeError(
										    "binary_search_delete() only accepts either a list, range or str"					)

							lowerCAmelCase_      =     0
							lowerCAmelCase_      =     len(_UpperCamelCase					) - 1

							while low <= high:
										lowerCAmelCase_      =     (low + high) // 2
										if array[mid] == item:
													array.pop(_UpperCamelCase					)
													return array
										elif array[mid] < item:
													lowerCAmelCase_      =     mid + 1
										else:
													lowerCAmelCase_      =     mid - 1
							raise ValueError(
							    "Either the item is not in the array or the array was unsorted"					)




				def 					__a						( self    ,    _UpperCamelCase    ,    _UpperCamelCase					)    ->				list[int]:
							if isinstance(_UpperCamelCase    ,    (range, str)					):
										lowerCAmelCase_      =     list(_UpperCamelCase					)
							elif not isinstance(_UpperCamelCase    ,    _UpperCamelCase					):
										raise TypeError(
										    "binary_search_insert() only accepts either a list, range or str"					)

							lowerCAmelCase_      =     0
							lowerCAmelCase_      =     len(_UpperCamelCase					) - 1

							while low <= high:
										lowerCAmelCase_      =     (low + high) // 2
										if array[mid] == index:
													# If the item already exists in the array,
													# insert it after the existing item
													array.insert(mid + 1    ,    _UpperCamelCase					)
													return array
										elif array[mid] < index:
													lowerCAmelCase_      =     mid + 1
										else:
													lowerCAmelCase_      =     mid - 1

        # If the item doesn't exist in the array, insert it at the appropriate position
							array.insert(_UpperCamelCase    ,    _UpperCamelCase					)
							return array




				def 					__a						( self    ,    _UpperCamelCase    ,    _UpperCamelCase					)    ->				None:
							# Remove previous index
							if index in self.indexmap:
										lowerCAmelCase_      =     self.indexmap[index]
										if len(self.numbermap[n]					) == 1:
													del self.numbermap[n]
										else:
													lowerCAmelCase_      =     self.binary_search_delete(self.numbermap[n]    ,    _UpperCamelCase					)

        # Set new index
							lowerCAmelCase_      =     number

							# Number not seen before or empty so insert number value
							if number not in self.numbermap:
										lowerCAmelCase_      =     [index]

							# Here we need to perform a binary search insertion in order to insert
							# The item in the correct place
							else:
										lowerCAmelCase_      =     self.binary_search_insert(
										    self.numbermap[number]    ,    _UpperCamelCase					)




				def 					__a						( self    ,    _UpperCamelCase					)    ->				int:
							return self.numbermap.get(_UpperCamelCase    ,    [-1]					)[0]


if __name__ == "__main__":
			import doctest

			doctest.testmod()



