





import inspect
import unittest

from transformers import ConvNextConfig
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_backbone_common import BackboneTesterMixin
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 ConvNextBackbone, ConvNextForImageClassification, ConvNextModel
 from transformers.models.convnext.modeling_convnext import CONVNEXT_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
 from PIL import Image

 from transformers import AutoImageProcessor


class        __magic_name__	:





     """simple docstring"""



     def __init__(				self							:str      ,   snake_case							:Union[str, Any]      ,   snake_case							:int=13      ,   snake_case							:Union[str, Any]=32      ,   snake_case							:int=3      ,   snake_case							:Dict=4      ,   snake_case							:List[Any]=[10, 20, 30, 40]      ,   snake_case							:int=[2, 2, 3, 2]      ,   snake_case							:Optional[Any]=True      ,   snake_case							:Optional[int]=True      ,   snake_case							:Union[str, Any]=37      ,   snake_case							:Optional[int]="gelu"      ,   snake_case							:Any=10      ,   snake_case							:Union[str, Any]=0.02      ,   snake_case							:int=["stage2", "stage3", "stage4"]      ,   snake_case							:Optional[int]=[2, 3, 4]      ,   snake_case							:List[str]=None      ,   ):





        '''simple docstring'''




        A_       :					Dict        =      parent
        A_       :					Any        =      batch_size
        A_       :					Union[str, Any]        =      image_size
        A_       :					Union[str, Any]        =      num_channels
        A_       :					Union[str, Any]        =      num_stages
        A_       :					str        =      hidden_sizes
        A_       :					Union[str, Any]        =      depths
        A_       :					Union[str, Any]        =      is_training
        A_       :					List[str]        =      use_labels
        A_       :					Optional[Any]        =      intermediate_size
        A_       :					Union[str, Any]        =      hidden_act
        A_       :					Dict        =      num_labels
        A_       :					Optional[Any]        =      initializer_range
        A_       :					Tuple        =      out_features
        A_       :					Any        =      out_indices
        A_       :					List[Any]        =      scope



     def     SCREAMING_SNAKE_CASE		(				self							:Any	):





        '''simple docstring'''




        A_       :					Optional[Any]        =      floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]	)

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

        A_       :					Optional[int]        =      self.get_config()
        return config, pixel_values, labels



     def     SCREAMING_SNAKE_CASE		(				self							:int	):





        '''simple docstring'''




        return ConvNextConfig(
            num_channels=self.num_channels      ,   hidden_sizes=self.hidden_sizes      ,   depths=self.depths      ,   num_stages=self.num_stages      ,   hidden_act=self.hidden_act      ,   is_decoder=snake_case      ,   initializer_range=self.initializer_range      ,   out_features=self.out_features      ,   out_indices=self.out_indices      ,   num_labels=self.num_labels      ,   )



     def     SCREAMING_SNAKE_CASE		(				self							:List[Any]      ,   snake_case							:List[str]      ,   snake_case							:Optional[int]      ,   snake_case							:Dict	):





        '''simple docstring'''




        A_       :					Optional[Any]        =      ConvNextModel(config=snake_case	)
        model.to(snake_case	)
        model.eval()
        A_       :					Dict        =      model(snake_case	)
        # expected last hidden states: B, C, H // 32, W // 32
        self.parent.assertEqual(
            result.last_hidden_state.shape      ,   (self.batch_size, self.hidden_sizes[-1], self.image_size // 32, self.image_size // 32)      ,   )



     def     SCREAMING_SNAKE_CASE		(				self							:Optional[int]      ,   snake_case							:Any      ,   snake_case							:str      ,   snake_case							:List[Any]	):





        '''simple docstring'''




        A_       :					Optional[int]        =      ConvNextForImageClassification(snake_case	)
        model.to(snake_case	)
        model.eval()
        A_       :					int        =      model(snake_case      ,   labels=snake_case	)
        self.parent.assertEqual(result.logits.shape      ,   (self.batch_size, self.num_labels)	)



     def     SCREAMING_SNAKE_CASE		(				self							:Optional[int]      ,   snake_case							:List[str]      ,   snake_case							:Union[str, Any]      ,   snake_case							:Any	):





        '''simple docstring'''




        A_       :					str        =      ConvNextBackbone(config=snake_case	)
        model.to(snake_case	)
        model.eval()
        A_       :					str        =      model(snake_case	)

        # verify hidden states
        self.parent.assertEqual(len(result.feature_maps	)      ,   len(config.out_features	)	)
        self.parent.assertListEqual(list(result.feature_maps[0].shape	)      ,   [self.batch_size, self.hidden_sizes[1], 4, 4]	)

        # verify channels
        self.parent.assertEqual(len(model.channels	)      ,   len(config.out_features	)	)
        self.parent.assertListEqual(model.channels      ,   config.hidden_sizes[1:]	)

        # verify backbone works with out_features=None
        A_       :					int        =      None
        A_       :					List[Any]        =      ConvNextBackbone(config=snake_case	)
        model.to(snake_case	)
        model.eval()
        A_       :					str        =      model(snake_case	)

        # verify feature maps
        self.parent.assertEqual(len(result.feature_maps	)      ,   1	)
        self.parent.assertListEqual(list(result.feature_maps[0].shape	)      ,   [self.batch_size, self.hidden_sizes[-1], 1, 1]	)

        # verify channels
        self.parent.assertEqual(len(model.channels	)      ,   1	)
        self.parent.assertListEqual(model.channels      ,   [config.hidden_sizes[-1]]	)





     def     SCREAMING_SNAKE_CASE		(				self							:List[Any]	):





        '''simple docstring'''




        A_       :					Union[str, Any]        =      self.prepare_config_and_inputs()
        A_   ,    A_   ,    A_       :					Union[str, Any]        =      config_and_inputs
        A_       :					Any        =      {"pixel_values": pixel_values}
        return config, inputs_dict




@require_torch
class        __magic_name__	(				lowerCamelCase__     ,					lowerCamelCase__     ,					unittest.TestCase				):





     """simple docstring"""



     __UpperCamelCase            =  (
         (
             ConvNextModel,
             ConvNextForImageClassification,
             ConvNextBackbone,
         )
         if is_torch_available()
         else ()
     )
     __UpperCamelCase            =  (
         {'''feature-extraction''': ConvNextModel, '''image-classification''': ConvNextForImageClassification}
         if is_torch_available()
         else {}
     )

     __UpperCamelCase            =  True
     __UpperCamelCase            =  False
     __UpperCamelCase            =  False
     __UpperCamelCase            =  False
     __UpperCamelCase            =  False



     def     SCREAMING_SNAKE_CASE		(				self							:Any	):





        '''simple docstring'''




        A_       :					Optional[int]        =      ConvNextModelTester(self	)
        A_       :					List[Any]        =      ConfigTester(self      ,   config_class=snake_case      ,   has_text_modality=snake_case      ,   hidden_size=37	)



     def     SCREAMING_SNAKE_CASE		(				self							:Optional[int]	):





        '''simple docstring'''




        self.create_and_test_config_common_properties()
        self.config_tester.create_and_test_config_to_json_string()
        self.config_tester.create_and_test_config_to_json_file()
        self.config_tester.create_and_test_config_from_and_save_pretrained()
        self.config_tester.create_and_test_config_with_num_labels()
        self.config_tester.check_config_can_be_init_without_params()
        self.config_tester.check_config_arguments_init()



     def     SCREAMING_SNAKE_CASE		(				self							:List[str]	):





        '''simple docstring'''




        return



     @unittest.skip(reason="ConvNext does not use inputs_embeds"	)
     def     SCREAMING_SNAKE_CASE		(				self							:List[str]	):





        '''simple docstring'''




        pass



     @unittest.skip(reason="ConvNext does not support input and output embeddings"	)
     def     SCREAMING_SNAKE_CASE		(				self							:List[Any]	):





        '''simple docstring'''




        pass



     @unittest.skip(reason="ConvNext does not use feedforward chunking"	)
     def     SCREAMING_SNAKE_CASE		(				self							:List[Any]	):





        '''simple docstring'''




        pass



     def     SCREAMING_SNAKE_CASE		(				self							:int	):





        '''simple docstring'''




        A_   ,    A_       :					List[str]        =      self.model_tester.prepare_config_and_inputs_for_common()

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

           A_       :					Dict        =      ["pixel_values"]
           self.assertListEqual(arg_names[:1]      ,   snake_case	)



     def     SCREAMING_SNAKE_CASE		(				self							:Tuple	):





        '''simple docstring'''




        A_       :					Union[str, Any]        =      self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_model(*snake_case	)



     def     SCREAMING_SNAKE_CASE		(				self							:Optional[Any]	):





        '''simple docstring'''




        A_       :					Optional[int]        =      self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_backbone(*snake_case	)



     def     SCREAMING_SNAKE_CASE		(				self							:str	):





        '''simple docstring'''




        def check_hidden_states_output(snake_case							:Tuple      ,   snake_case							:str      ,   snake_case							:int	):
           A_       :					Tuple        =      model_class(snake_case	)
           model.to(snake_case	)
           model.eval()

           with torch.no_grad():
              A_       :					Optional[Any]        =      model(**self._prepare_for_class(snake_case      ,   snake_case	)	)

           A_       :					Any        =      outputs.encoder_hidden_states if config.is_encoder_decoder else outputs.hidden_states

           A_       :					Dict        =      self.model_tester.num_stages
           self.assertEqual(len(snake_case	)      ,   expected_num_stages + 1	)

           # ConvNext's feature maps are of shape (batch_size, num_channels, height, width)
           self.assertListEqual(
               list(hidden_states[0].shape[-2:]	)      ,   [self.model_tester.image_size // 4, self.model_tester.image_size // 4]      ,   )

        A_   ,    A_       :					int        =      self.model_tester.prepare_config_and_inputs_for_common()

        for model_class in self.all_model_classes:
           A_       :					int        =      True
           check_hidden_states_output(snake_case      ,   snake_case      ,   snake_case	)

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

           check_hidden_states_output(snake_case      ,   snake_case      ,   snake_case	)



     def     SCREAMING_SNAKE_CASE		(				self							:Any	):





        '''simple docstring'''




        A_       :					int        =      self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_for_image_classification(*snake_case	)





     @slow
     def     SCREAMING_SNAKE_CASE		(				self							:List[Any]	):





        '''simple docstring'''




        for model_name in CONVNEXT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
           A_       :					Any        =      ConvNextModel.from_pretrained(snake_case	)
           self.assertIsNotNone(snake_case	)




def   __snake_case    (       )			->    Union[str, Any]:
   A_       :					Dict        =      Image.open("./tests/fixtures/tests_samples/COCO/000000039769.png"						)
   return image


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





     """simple docstring"""



     @cached_property
     def     SCREAMING_SNAKE_CASE		(				self							:str	):





        '''simple docstring'''




        return AutoImageProcessor.from_pretrained("facebook/convnext-tiny-224"	) if is_vision_available() else None





     @slow
     def     SCREAMING_SNAKE_CASE		(				self							:Dict	):





        '''simple docstring'''




        A_       :					Union[str, Any]        =      ConvNextForImageClassification.from_pretrained("facebook/convnext-tiny-224"	).to(snake_case	)

        A_       :					Optional[Any]        =      self.default_image_processor
        A_       :					List[str]        =      prepare_img()
        A_       :					Optional[Any]        =      image_processor(images=snake_case      ,   return_tensors="pt"	).to(snake_case	)

        # forward pass
        with torch.no_grad():
           A_       :					str        =      model(**snake_case	)

        # verify the logits
        A_       :					List[Any]        =      torch.Size((1, 1_000)	)
        self.assertEqual(outputs.logits.shape      ,   snake_case	)

        A_       :					List[str]        =      torch.tensor([-0.0260, -0.4739, 0.1911]	).to(snake_case	)

        self.assertTrue(torch.allclose(outputs.logits[0, :3]      ,   snake_case      ,   atol=1e-4	)	)




@require_torch
class        __magic_name__	(				unittest.TestCase     ,					lowerCamelCase__				):





     """simple docstring"""



     __UpperCamelCase            =  (ConvNextBackbone,) if is_torch_available() else ()
     __UpperCamelCase            =  ConvNextConfig

     __UpperCamelCase            =  False



     def     SCREAMING_SNAKE_CASE		(				self							:Tuple	):





        '''simple docstring'''




        A_       :					Union[str, Any]        =      ConvNextModelTester(self	)







from timeit import timeit

_lowerCAmelCase				:   Tuple						       =						{
    '''MALAYALAM''': True,
    '''String''': False,
    '''rotor''': True,
    '''level''': True,
    '''A''': True,
    '''BB''': True,
    '''ABC''': False,
    '''amanaplanacanalpanama''': True,  # "a man a plan a canal panama"
}
# Ensure our test data is valid
assert all((key == key[::-1]) is value for key, value in test_data.items())

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   A_       :					List[str]        =      0
   A_       :					str        =      len(_lowerCAmelCase						) - 1
   while start_i < end_i:
      if s[start_i] == s[end_i]:
         start_i += 1
         end_i -= 1
      else:
         return False
   return True

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   A_       :					int        =      len(_lowerCAmelCase						) // 2
   A_       :					Union[str, Any]        =      len(_lowerCAmelCase						)

   # We need to traverse till half of the length of string
   # as we can get access of the i'th last element from
   # i'th index.
   # eg: [0,1,2,3,4,5] => 4th index can be accessed
   # with the help of 1st index (i==n-i-1)
   # where n is length of string
   return all(s[i] == s[n - i - 1] for i in range(_lowerCAmelCase						)						)

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   if len(_lowerCAmelCase						) <= 2:
      return True
   if s[0] == s[len(_lowerCAmelCase						) - 1]:
      return is_palindrome_recursive(s[1:-1]						)
   else:
      return False

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    bool:
   return s == s[::-1]

def   __snake_case    (       _lowerCAmelCase			:			str						)			->    None:
   A_       :					int        =      f"all({name}(key) is value for key, value in test_data.items())"
   A_       :					List[str]        =      f"from __main__ import test_data, {name}"
   A_       :					str        =      500000
   A_       :					List[str]        =      timeit(stmt=_lowerCAmelCase					,					setup=_lowerCAmelCase					,					number=_lowerCAmelCase						)
   print(f"{name:<35} finished {number:,} runs in {result:.5f} seconds"						)


if __name__ == "__main__":
 for key, value in test_data.items():
  assert is_palindrome(key) is is_palindrome_recursive(key)
  assert is_palindrome(key) is is_palindrome_slice(key)
  print(F'''{key:21} {value}''')
 print('''a man a plan a canal panama''')

 # finished 500,000 runs in 0.46793 seconds
 benchmark_function('''is_palindrome_slice''')
 # finished 500,000 runs in 0.85234 seconds
 benchmark_function('''is_palindrome''')
 # finished 500,000 runs in 1.32028 seconds
 benchmark_function('''is_palindrome_recursive''')
 # finished 500,000 runs in 2.08679 seconds
 benchmark_function('''is_palindrome_traversal''')
