

import copy
import inspect
import unittest

import numpy as np
from huggingface_hub import hf_hub_download

from transformers import VivitConfig
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


if is_torch_available():
    import torch
    from torch import nn

    from transformers import MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING, VivitForVideoClassification, VivitModel
    from transformers.models.vivit.modeling_vivit import VIVIT_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
    from transformers import VivitImageProcessor







class 					__lowerCamelCase							:







      def __init__(	self				,    lowerCamelCase				,    lowerCamelCase=2				,    lowerCamelCase=True				,    lowerCamelCase=True				,    lowerCamelCase=10				,    lowerCamelCase=10				,    lowerCamelCase=8				,    lowerCamelCase=[2, 4, 4]				,    lowerCamelCase=3				,    lowerCamelCase=768				,    lowerCamelCase=5				,    lowerCamelCase=4				,    lowerCamelCase=37				,    lowerCamelCase="gelu_fast"				,    lowerCamelCase=0.0				,    lowerCamelCase=0.0				,    lowerCamelCase=0.02				,    lowerCamelCase=1e-06				,    lowerCamelCase=True				,    lowerCamelCase=None				,    )		->			List[Any]:
        snake_case_					= parent
        snake_case_					= batch_size
        snake_case_					= is_training
        snake_case_					= use_labels
        snake_case_					= num_labels
        snake_case_					= image_size
        snake_case_					= num_frames
        snake_case_					= tubelet_size
        snake_case_					= num_channels
        snake_case_					= hidden_size
        snake_case_					= num_hidden_layers
        snake_case_					= num_attention_heads
        snake_case_					= intermediate_size
        snake_case_					= hidden_act
        snake_case_					= hidden_dropout_prob
        snake_case_					= attention_probs_dropout_prob
        snake_case_					= initializer_range
        snake_case_					= layer_norm_eps
        snake_case_					= qkv_bias
        snake_case_					= scope

        snake_case_					= (
            (self.image_size // self.tubelet_size[2])
            * (self.image_size // self.tubelet_size[1])
            * (self.num_frames // self.tubelet_size[0])
        ) + 1  # CLS token







      def       lowerCAmelCase_       (	self  )		->			List[str]:
        snake_case_					= floats_tensor(
            [self.batch_size, self.num_frames, self.num_channels, self.image_size, self.image_size]  )

        snake_case_					= None
        if self.use_labels:
          snake_case_					= ids_tensor([self.batch_size]				,    self.num_labels  )

        snake_case_					= self.get_config()

        return config, pixel_values, labels







      def       lowerCAmelCase_       (	self  )		->			Any:
        snake_case_					= VivitConfig(
            num_frames=self.num_frames				,    image_size=self.image_size				,    tubelet_size=self.tubelet_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				,    initializer_range=self.initializer_range				,    layer_norm_eps=self.layer_norm_eps				,    qkv_bias=self.qkv_bias				,    )
        snake_case_					= self.num_labels
        return config







      def       lowerCAmelCase_       (	self				,    lowerCamelCase				,    lowerCamelCase				,    lowerCamelCase  )		->			List[str]:
        snake_case_					= VivitModel(config=lowerCamelCase  )
        model.to(lowerCamelCase  )
        model.eval()
        snake_case_					= 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  )		->			Optional[Any]:
        snake_case_					= VivitForVideoClassification(lowerCamelCase  )
        model.to(lowerCamelCase  )
        model.eval()

        snake_case_					= model(lowerCamelCase  )

        # verify the logits shape
        snake_case_					= torch.Size((self.batch_size, self.num_labels)  )
        self.parent.assertEqual(result.logits.shape				,    lowerCamelCase  )







      def       lowerCAmelCase_       (	self  )		->			Union[str, Any]:
        snake_case_					= self.prepare_config_and_inputs()
        snake_case_		,							snake_case_		,							snake_case_					= config_and_inputs
        snake_case_					= {"""pixel_values""": pixel_values}
        return config, inputs_dict







@require_torch
class 					__lowerCamelCase							(      __snake_case    ,				unittest.TestCase      ):
      lowerCamelCase_      : int  			=   (VivitModel, VivitForVideoClassification) if is_torch_available() else ()

      lowerCamelCase_      : Optional[int]  			=   False
      lowerCamelCase_      : Any  			=   False
      lowerCamelCase_      : Optional[Any]  			=   False
      lowerCamelCase_      : List[Any]  			=   False







      def       lowerCAmelCase_       (	self  )		->			Optional[int]:
        snake_case_					= VivitModelTester(self  )
        snake_case_					= ConfigTester(self				,    config_class=lowerCamelCase				,    has_text_modality=lowerCamelCase				,    hidden_size=37  )







      def       lowerCAmelCase_       (	self				,    lowerCamelCase				,    lowerCamelCase				,    lowerCamelCase=False  )		->			Any:
        snake_case_					= copy.deepcopy(lowerCamelCase  )

        if return_labels:
          if model_class in get_values(lowerCamelCase  ):
            snake_case_					= torch.zeros(
                self.model_tester.batch_size				,    dtype=torch.long				,    device=lowerCamelCase  )

        return inputs_dict







      def       lowerCAmelCase_       (	self  )		->			Any:
        self.config_tester.run_common_tests()







      @unittest.skip(reason="""Vivit does not use inputs_embeds"""  )
      def       lowerCAmelCase_       (	self  )		->			List[Any]:
        pass







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

        for model_class in self.all_model_classes:
          snake_case_					= model_class(lowerCamelCase  )
          self.assertIsInstance(model.get_input_embeddings()				,    (nn.Module)  )
          snake_case_					= model.get_output_embeddings()
          self.assertTrue(x is None or isinstance(lowerCamelCase				,    nn.Linear  )  )







      def       lowerCAmelCase_       (	self  )		->			Optional[Any]:
        snake_case_		,							snake_case_					= self.model_tester.prepare_config_and_inputs_for_common()

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

          snake_case_					= ["""pixel_values""", """head_mask"""]
          self.assertListEqual(arg_names[:2]				,    lowerCamelCase  )







      def       lowerCAmelCase_       (	self  )		->			int:
        snake_case_					= self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_model(*lowerCamelCase  )







      def       lowerCAmelCase_       (	self  )		->			Optional[Any]:
        snake_case_					= self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_for_video_classification(*lowerCamelCase  )







      @slow
      def       lowerCAmelCase_       (	self  )		->			Optional[Any]:
        for model_name in VIVIT_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
          snake_case_					= VivitModel.from_pretrained(lowerCamelCase  )
          self.assertIsNotNone(lowerCamelCase  )







      def       lowerCAmelCase_       (	self  )		->			Tuple:
        snake_case_		,							snake_case_					= self.model_tester.prepare_config_and_inputs_for_common()
        snake_case_					= True

        for model_class in self.all_model_classes:
          snake_case_					= self.model_tester.seq_length

          snake_case_					= True
          snake_case_					= False
          snake_case_					= True
          snake_case_					= model_class(lowerCamelCase  )
          model.to(lowerCamelCase  )
          model.eval()
          with torch.no_grad():
            snake_case_					= model(**self._prepare_for_class(lowerCamelCase				,    lowerCamelCase  )  )
          snake_case_					= outputs.attentions
          self.assertEqual(len(lowerCamelCase  )				,    self.model_tester.num_hidden_layers  )

          # check that output_attentions also work using config
          del inputs_dict["output_attentions"]
          snake_case_					= True
          snake_case_					= model_class(lowerCamelCase  )
          model.to(lowerCamelCase  )
          model.eval()
          with torch.no_grad():
            snake_case_					= model(**self._prepare_for_class(lowerCamelCase				,    lowerCamelCase  )  )
          snake_case_					= outputs.attentions
          self.assertEqual(len(lowerCamelCase  )				,    self.model_tester.num_hidden_layers  )

          self.assertListEqual(
              list(attentions[0].shape[-3:]  )				,    [self.model_tester.num_attention_heads, seq_len, seq_len]				,    )
          snake_case_					= len(lowerCamelCase  )

          # Check attention is always last and order is fine
          snake_case_					= True
          snake_case_					= True
          snake_case_					= model_class(lowerCamelCase  )
          model.to(lowerCamelCase  )
          model.eval()
          with torch.no_grad():
            snake_case_					= model(**self._prepare_for_class(lowerCamelCase				,    lowerCamelCase  )  )

          self.assertEqual(out_len + 1				,    len(lowerCamelCase  )  )

          snake_case_					= outputs.attentions

          self.assertEqual(len(lowerCamelCase  )				,    self.model_tester.num_hidden_layers  )

          self.assertListEqual(
              list(self_attentions[0].shape[-3:]  )				,    [self.model_tester.num_attention_heads, seq_len, seq_len]				,    )







      def       lowerCAmelCase_       (	self  )		->			Dict:
        def check_hidden_states_output(lowerCamelCase				,    lowerCamelCase				,    lowerCamelCase  ):
          snake_case_					= model_class(lowerCamelCase  )
          model.to(lowerCamelCase  )
          model.eval()

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

          snake_case_					= outputs.hidden_states
          snake_case_					= self.model_tester.num_hidden_layers + 1
          self.assertEqual(len(lowerCamelCase  )				,    lowerCamelCase  )

          snake_case_					= self.model_tester.seq_length

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

        snake_case_		,							snake_case_					= self.model_tester.prepare_config_and_inputs_for_common()

        for model_class in self.all_model_classes:
          snake_case_					= True
          check_hidden_states_output(lowerCamelCase				,    lowerCamelCase				,    lowerCamelCase  )

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

          check_hidden_states_output(lowerCamelCase				,    lowerCamelCase				,    lowerCamelCase  )







      @unittest.skip("""Will be fixed soon by reducing the size of the model used for common tests."""  )
      def       lowerCAmelCase_       (	self  )		->			Dict:
        pass



def   UpperCamelCase(   )      ->							Tuple:





  '''simple docstring'''





  snake_case_					= hf_hub_download(
      repo_id="""hf-internal-testing/spaghetti-video"""     ,   filename="""eating_spaghetti_32_frames.npy"""     ,   repo_type="""dataset"""				)
  snake_case_					= np.load(lowercase_				)
  return list(lowercase_				)







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







      @cached_property
      def       lowerCAmelCase_       (	self  )		->			Tuple:
        return VivitImageProcessor() if is_vision_available() else None







      @slow
      def       lowerCAmelCase_       (	self  )		->			Optional[int]:
        snake_case_					= VivitForVideoClassification.from_pretrained("""google/vivit-b-16x2-kinetics400"""  ).to(lowerCamelCase  )

        snake_case_					= self.default_image_processor
        snake_case_					= prepare_video()
        snake_case_					= image_processor(lowerCamelCase				,    return_tensors="""pt"""  ).to(lowerCamelCase  )

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

        # verify the logits
        snake_case_					= torch.Size((1, 400)  )
        self.assertEqual(outputs.logits.shape				,    lowerCamelCase  )

        # taken from original model
        snake_case_					= torch.tensor([-1.0543, 2.0764, -0.2104, 0.4439, -0.9658]  ).to(lowerCamelCase  )

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


from math import pi



def   UpperCamelCase(   lowercase_				)      ->							float:





  '''simple docstring'''





  return degree / (180 / pi)


if __name__ == "__main__":
    from doctest import testmod

    testmod()