



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 		UpperCAmelCase    :





   def __init__(						self							,  _lowerCAmelCase							,  _lowerCAmelCase = 13							,  _lowerCAmelCase = 64							,  _lowerCAmelCase = 2							,  _lowerCAmelCase = 3							,  _lowerCAmelCase = 3							,  _lowerCAmelCase = True							,  _lowerCAmelCase = True							,  _lowerCAmelCase = 128							,  _lowerCAmelCase=[16, 32, 64, 128]							,  _lowerCAmelCase = 7							,  _lowerCAmelCase = 4							,  _lowerCAmelCase = 37							,  _lowerCAmelCase = "gelu"							,  _lowerCAmelCase = 0.1							,  _lowerCAmelCase = 0.1							,  _lowerCAmelCase = 10							,  _lowerCAmelCase = 0.02							,  _lowerCAmelCase = 2							,  _lowerCAmelCase = 1							,  _lowerCAmelCase = 128							,  _lowerCAmelCase = [2, 2, 2, 2]							,  _lowerCAmelCase = 2							,  _lowerCAmelCase = 2							,  ):
         _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 						__lowerCAmelCase				(						self      ):
         _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 						__lowerCAmelCase				(						self      ):
         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=_lowerCAmelCase							,  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 						__lowerCAmelCase				(						self							,  _lowerCAmelCase							,  _lowerCAmelCase							,  _lowerCAmelCase      ):
         _lowerCAmelCase			      =	EfficientFormerModel(config=_lowerCAmelCase      )
         model.to(_lowerCAmelCase      )
         model.eval()
         _lowerCAmelCase			      =	model(_lowerCAmelCase      )
         self.parent.assertEqual(result.last_hidden_state.shape							,  (self.batch_size, self.seq_length, self.hidden_size)      )





   def 						__lowerCAmelCase				(						self							,  _lowerCAmelCase							,  _lowerCAmelCase							,  _lowerCAmelCase      ):
         _lowerCAmelCase			      =	self.type_sequence_label_size
         _lowerCAmelCase			      =	EfficientFormerForImageClassification(_lowerCAmelCase      )
         model.to(_lowerCAmelCase      )
         model.eval()
         _lowerCAmelCase			      =	model(_lowerCAmelCase							,  labels=_lowerCAmelCase      )
         self.parent.assertEqual(result.logits.shape							,  (self.batch_size, self.type_sequence_label_size)      )

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

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





   def 						__lowerCAmelCase				(						self      ):
         _lowerCAmelCase			      =	self.prepare_config_and_inputs()
         (
             (
             _lowerCAmelCase
         )      , (
             _lowerCAmelCase
         )      , (
             _lowerCAmelCase
         )      , 
         )			      =	config_and_inputs
         _lowerCAmelCase			      =	{'''pixel_values''': pixel_values}
         return config, inputs_dict






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

   SCREAMING_SNAKE_CASE__					      =  False
   SCREAMING_SNAKE_CASE__					      =  False
   SCREAMING_SNAKE_CASE__					      =  False





   def 						__lowerCAmelCase				(						self      ):
         _lowerCAmelCase			      =	EfficientFormerModelTester(self      )
         _lowerCAmelCase			      =	ConfigTester(
             self							,  config_class=_lowerCAmelCase							,  has_text_modality=_lowerCAmelCase							,  hidden_size=37      )





   def 						__lowerCAmelCase				(						self      ):
         self.config_tester.run_common_tests()





   @unittest.skip(reason='''EfficientFormer does not use inputs_embeds'''      )
   def 						__lowerCAmelCase				(						self      ):
         pass





   @unittest.skip(reason='''EfficientFormer does not support input and output embeddings'''      )
   def 						__lowerCAmelCase				(						self      ):
         pass





   def 						__lowerCAmelCase				(						self      ):
         _lowerCAmelCase      , _lowerCAmelCase			      =	self.model_tester.prepare_config_and_inputs_for_common()

         for model_class in self.all_model_classes:
               _lowerCAmelCase			      =	model_class(_lowerCAmelCase      )
               _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]							,  _lowerCAmelCase      )





   def 						__lowerCAmelCase				(						self      ):
         def check_hidden_states_output(_lowerCAmelCase							,  _lowerCAmelCase							,  _lowerCAmelCase      ):
               _lowerCAmelCase			      =	model_class(_lowerCAmelCase      )
               model.to(_lowerCAmelCase      )
               model.eval()

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

               _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(_lowerCAmelCase      )							,  _lowerCAmelCase      )

               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(_lowerCAmelCase							,  (list, tuple)      )
                     self.assertEqual(len(_lowerCAmelCase      )							,  _lowerCAmelCase      )
                     _lowerCAmelCase			      =	getattr(self.model_tester							,  '''seq_length'''							,  _lowerCAmelCase      )
                     _lowerCAmelCase			      =	getattr(self.model_tester							,  '''decoder_seq_length'''							,  _lowerCAmelCase      )

                     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(_lowerCAmelCase							,  _lowerCAmelCase							,  _lowerCAmelCase      )

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

               check_hidden_states_output(_lowerCAmelCase							,  _lowerCAmelCase							,  _lowerCAmelCase      )





   def 						__lowerCAmelCase				(						self							,  _lowerCAmelCase							,  _lowerCAmelCase							,  _lowerCAmelCase=False      ):
         _lowerCAmelCase			      =	super()._prepare_for_class(_lowerCAmelCase							,  _lowerCAmelCase							,  return_labels=_lowerCAmelCase      )

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

         return inputs_dict





   def 						__lowerCAmelCase				(						self      ):
         _lowerCAmelCase			      =	self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_model(*_lowerCAmelCase      )





   @unittest.skip(reason='''EfficientFormer does not implement masked image modeling yet'''      )
   def 						__lowerCAmelCase				(						self      ):
         _lowerCAmelCase			      =	self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_for_masked_image_modeling(*_lowerCAmelCase      )





   def 						__lowerCAmelCase				(						self      ):
         _lowerCAmelCase			      =	self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_for_image_classification(*_lowerCAmelCase      )





   def 						__lowerCAmelCase				(						self      ):
         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(_lowerCAmelCase      )
                   or model_class.__name__ == "EfficientFormerForImageClassificationWithTeacher"
               ):
                     continue
               _lowerCAmelCase			      =	model_class(_lowerCAmelCase      )
               model.to(_lowerCAmelCase      )
               model.train()
               _lowerCAmelCase			      =	self._prepare_for_class(_lowerCAmelCase							,  _lowerCAmelCase							,  return_labels=_lowerCAmelCase      )
               _lowerCAmelCase			      =	model(**_lowerCAmelCase      ).loss
               loss.backward()





   def 						__lowerCAmelCase				(						self      ):
         _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(_lowerCAmelCase      ),
                   ]
                   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(_lowerCAmelCase      )
                           model.to(_lowerCAmelCase      )
                           model.train()

                           _lowerCAmelCase			      =	self._prepare_for_class(_lowerCAmelCase							,  _lowerCAmelCase							,  return_labels=_lowerCAmelCase      )

                           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=_lowerCAmelCase      ) as warning_list:
                                 _lowerCAmelCase			      =	model(**_lowerCAmelCase      ).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 						__lowerCAmelCase				(						self      ):
         for model_name in EFFICIENTFORMER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
               _lowerCAmelCase			      =	EfficientFormerModel.from_pretrained(_lowerCAmelCase      )
               self.assertIsNotNone(_lowerCAmelCase      )





   def 						__lowerCAmelCase				(						self      ):
         _lowerCAmelCase      , _lowerCAmelCase			      =	self.model_tester.prepare_config_and_inputs_for_common()
         _lowerCAmelCase			      =	True

         _lowerCAmelCase			      =	getattr(self.model_tester							,  '''seq_length'''							,  _lowerCAmelCase      )
         _lowerCAmelCase			      =	getattr(self.model_tester							,  '''encoder_seq_length'''							,  _lowerCAmelCase      )
         _lowerCAmelCase			      =	getattr(self.model_tester							,  '''key_length'''							,  _lowerCAmelCase      )
         _lowerCAmelCase			      =	getattr(self.model_tester							,  '''chunk_length'''							,  _lowerCAmelCase      )

         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(_lowerCAmelCase      )
               model.to(_lowerCAmelCase      )
               model.eval()
               with torch.no_grad():
                     _lowerCAmelCase			      =	model(**self._prepare_for_class(_lowerCAmelCase							,  _lowerCAmelCase      )      )
               _lowerCAmelCase			      =	outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions
               self.assertEqual(len(_lowerCAmelCase      )							,  self.model_tester.num_attention_outputs      )

               # check that output_attentions also work using config
               del inputs_dict["output_attentions"]
               _lowerCAmelCase			      =	True
               _lowerCAmelCase			      =	model_class(_lowerCAmelCase      )
               model.to(_lowerCAmelCase      )
               model.eval()
               with torch.no_grad():
                     _lowerCAmelCase			      =	model(**self._prepare_for_class(_lowerCAmelCase							,  _lowerCAmelCase      )      )
               _lowerCAmelCase			      =	outputs.encoder_attentions if config.is_encoder_decoder else outputs.attentions
               self.assertEqual(len(_lowerCAmelCase      )							,  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 				UpperCAmelCase__		(					)->Optional[Any]:
      _lowerCAmelCase			      =	Image.open('''./tests/fixtures/tests_samples/COCO/000000039769.png'''					)
      return image





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





   @cached_property
   def 						__lowerCAmelCase				(						self      ):
         return (
             EfficientFormerImageProcessor.from_pretrained('''snap-research/efficientformer-l1-300'''      )
             if is_vision_available()
             else None
         )





   @slow
   def 						__lowerCAmelCase				(						self      ):
         _lowerCAmelCase			      =	EfficientFormerForImageClassification.from_pretrained('''snap-research/efficientformer-l1-300'''      ).to(
             _lowerCAmelCase      )

         _lowerCAmelCase			      =	self.default_image_processor
         _lowerCAmelCase			      =	prepare_img()
         _lowerCAmelCase			      =	image_processor(images=_lowerCAmelCase							,  return_tensors='''pt'''      ).to(_lowerCAmelCase      )

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

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

         _lowerCAmelCase			      =	torch.tensor([-0.0_555, 0.4_825, -0.0_852]      ).to(_lowerCAmelCase      )
         self.assertTrue(torch.allclose(outputs.logits[0][:3]							,  _lowerCAmelCase							,  atol=1E-4      )      )





   @slow
   def 						__lowerCAmelCase				(						self      ):
         _lowerCAmelCase			      =	EfficientFormerForImageClassificationWithTeacher.from_pretrained(
             '''snap-research/efficientformer-l1-300'''      ).to(_lowerCAmelCase      )

         _lowerCAmelCase			      =	self.default_image_processor
         _lowerCAmelCase			      =	prepare_img()
         _lowerCAmelCase			      =	image_processor(images=_lowerCAmelCase							,  return_tensors='''pt'''      ).to(_lowerCAmelCase      )

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

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

         _lowerCAmelCase			      =	torch.tensor([-0.1_312, 0.4_353, -1.0_499]      ).to(_lowerCAmelCase      )
         self.assertTrue(torch.allclose(outputs.logits[0][:3]							,  _lowerCAmelCase							,  atol=1E-4      )      )




def 				UpperCAmelCase__		(					_SCREAMING_SNAKE_CASE :						str					)->str:
      return " ".join(sorted(set(sentence.split()					)					)					)


if __name__ == "__main__":
    import doctest

    doctest.testmod()