

import copy
import inspect
import unittest

import numpy as np
from huggingface_hub import hf_hub_download

from transformers import TimesformerConfig
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 torch import nn

	from transformers import (
	    MODEL_FOR_VIDEO_CLASSIFICATION_MAPPING,
	    TimesformerForVideoClassification,
	    TimesformerModel,
	)
	from transformers.models.timesformer.modeling_timesformer import TIMESFORMER_PRETRAINED_MODEL_ARCHIVE_LIST


if is_vision_available():
	from transformers import VideoMAEImageProcessor


class 			lowerCamelCase_    :


							def __init__( self      ,				lowerCamelCase_      ,				lowerCamelCase_=13      ,				lowerCamelCase_=10      ,				lowerCamelCase_=3      ,				lowerCamelCase_=2      ,				lowerCamelCase_=2      ,				lowerCamelCase_=True      ,				lowerCamelCase_=True      ,				lowerCamelCase_=32      ,				lowerCamelCase_=5      ,				lowerCamelCase_=4      ,				lowerCamelCase_=37      ,				lowerCamelCase_="gelu"      ,				lowerCamelCase_=0.1      ,				lowerCamelCase_=0.1      ,				lowerCamelCase_=10      ,				lowerCamelCase_=0.02      ,				lowerCamelCase_="divided_space_time"      ,				lowerCamelCase_=None      ,				)							->   str:



								"""simple docstring"""

								_UpperCamelCase			=   parent
								_UpperCamelCase			=   batch_size
								_UpperCamelCase			=   image_size
								_UpperCamelCase			=   num_channels
								_UpperCamelCase			=   patch_size
								_UpperCamelCase			=   num_frames
								_UpperCamelCase			=   is_training
								_UpperCamelCase			=   use_labels
								_UpperCamelCase			=   hidden_size
								_UpperCamelCase			=   num_hidden_layers
								_UpperCamelCase			=   num_attention_heads
								_UpperCamelCase			=   intermediate_size
								_UpperCamelCase			=   hidden_act
								_UpperCamelCase			=   hidden_dropout_prob
								_UpperCamelCase			=   attention_probs_dropout_prob
								_UpperCamelCase			=   attention_type
								_UpperCamelCase			=   initializer_range
								_UpperCamelCase			=   scope
								_UpperCamelCase			=   num_labels

								# in TimeSformer, the number of spatial tokens equals num_frames * num_patches per frame + 1 CLS token
								_UpperCamelCase			=   (image_size // patch_size) ** 2
								_UpperCamelCase			=   (num_frames) * self.num_patches_per_frame + 1


							def  lowercase   ( self						)							->   int:



								"""simple docstring"""

								_UpperCamelCase			=   floats_tensor(
								    [self.batch_size, self.num_frames, self.num_channels, self.image_size, self.image_size]						)

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

								_UpperCamelCase			=   self.get_config()

								return config, pixel_values, labels


							def  lowercase   ( self						)							->   int:



								"""simple docstring"""

								_UpperCamelCase			=   TimesformerConfig(
								    image_size=self.image_size      ,				patch_size=self.patch_size      ,				num_channels=self.num_channels      ,				num_frames=self.num_frames      ,				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      ,				attention_type=self.attention_type      ,				)
								_UpperCamelCase			=   self.num_labels
								return config


							def  lowercase   ( self      ,				lowerCamelCase_      ,				lowerCamelCase_      ,				lowerCamelCase_						)							->   int:



								"""simple docstring"""

								_UpperCamelCase			=   TimesformerModel(config=snake_case_						)
								model.to(snake_case_						)
								model.eval()
								_UpperCamelCase			=   model(snake_case_						)
								self.parent.assertEqual(result.last_hidden_state.shape      ,				(self.batch_size, self.seq_length, self.hidden_size)						)


							def  lowercase   ( self      ,				lowerCamelCase_      ,				lowerCamelCase_      ,				lowerCamelCase_						)							->   str:



								"""simple docstring"""

								_UpperCamelCase			=   TimesformerForVideoClassification(snake_case_						)
								model.to(snake_case_						)
								model.eval()

								_UpperCamelCase			=   model(snake_case_						)

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







							def  lowercase   ( self						)							->   Optional[Any]:



								"""simple docstring"""

								_UpperCamelCase			=   self.prepare_config_and_inputs()
								_UpperCamelCase	,				_UpperCamelCase	,				_UpperCamelCase			=   config_and_inputs
								_UpperCamelCase			=   {"pixel_values": pixel_values}
								return config, inputs_dict






@require_torch
class 			lowerCamelCase_    (  lowerCAmelCase__	,     lowerCAmelCase__	,     unittest.TestCase		):
							__lowercase				:	int        =				(TimesformerModel, TimesformerForVideoClassification) if is_torch_available() else ()
							__lowercase				:	Dict        =				(
							    {"feature-extraction": TimesformerModel, "video-classification": TimesformerForVideoClassification}
							    if is_torch_available()
							    else {}
							)

							__lowercase				:	Optional[Any]        =				False
							__lowercase				:	int        =				False
							__lowercase				:	Optional[int]        =				False
							__lowercase				:	Optional[Any]        =				False


							def  lowercase   ( self						)							->   str:



								"""simple docstring"""

								_UpperCamelCase			=   TimesformerModelTester(self						)
								_UpperCamelCase			=   ConfigTester(
								    self      ,				config_class=snake_case_      ,				has_text_modality=snake_case_      ,				hidden_size=37						)


							def  lowercase   ( self      ,				lowerCamelCase_      ,				lowerCamelCase_      ,				lowerCamelCase_=False						)							->   List[Any]:



								"""simple docstring"""

								_UpperCamelCase			=   copy.deepcopy(snake_case_						)

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

								return inputs_dict


							def  lowercase   ( self						)							->   List[Any]:



								"""simple docstring"""

								self.config_tester.run_common_tests()


							@unittest.skip(reason="TimeSformer does not use inputs_embeds"						)
							def  lowercase   ( self						)							->   Any:



								"""simple docstring"""

								pass


							def  lowercase   ( self						)							->   int:



								"""simple docstring"""

								_UpperCamelCase	,				_UpperCamelCase			=   self.model_tester.prepare_config_and_inputs_for_common()

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


							def  lowercase   ( self						)							->   Any:



								"""simple docstring"""

								_UpperCamelCase	,				_UpperCamelCase			=   self.model_tester.prepare_config_and_inputs_for_common()

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

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


							def  lowercase   ( self						)							->   Tuple:



								"""simple docstring"""

								_UpperCamelCase			=   self.model_tester.prepare_config_and_inputs()
								self.model_tester.create_and_check_model(*snake_case_						)


							def  lowercase   ( self						)							->   List[str]:



								"""simple docstring"""

								_UpperCamelCase			=   self.model_tester.prepare_config_and_inputs()
								self.model_tester.create_and_check_for_video_classification(*snake_case_						)


							@slow
							def  lowercase   ( self						)							->   Any:



								"""simple docstring"""

								for model_name in TIMESFORMER_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
									_UpperCamelCase			=   TimesformerModel.from_pretrained(snake_case_						)
									self.assertIsNotNone(snake_case_						)


							def  lowercase   ( self						)							->   List[str]:



								"""simple docstring"""

								if not self.has_attentions:
									pass

								else:
									_UpperCamelCase	,				_UpperCamelCase			=   self.model_tester.prepare_config_and_inputs_for_common()
									_UpperCamelCase			=   True

									for model_class in self.all_model_classes:
										_UpperCamelCase			=   self.model_tester.seq_length
										_UpperCamelCase			=   self.model_tester.num_frames

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

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

										# attentions has shape (batch_size x num_frames) x num_heads x (num_patches per frame + 1) x (num_patches per frame + 1)
										self.assertListEqual(
										    list(attentions[0].shape[-3:]						)      ,				[self.model_tester.num_attention_heads, seq_len // num_frames + 1, seq_len // num_frames + 1]      ,				)
										_UpperCamelCase			=   len(snake_case_						)

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

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

										_UpperCamelCase			=   outputs.attentions

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

										# attentions has shape (batch_size x num_frames) x num_heads x (num_patches per frame + 1) x (num_patches per frame + 1)
										self.assertListEqual(
										    list(self_attentions[0].shape[-3:]						)      ,				[self.model_tester.num_attention_heads, seq_len // num_frames + 1, seq_len // num_frames + 1]      ,				)







							def  lowercase   ( self						)							->   Optional[Any]:



								"""simple docstring"""

								def check_hidden_states_output(lowerCamelCase_      ,				lowerCamelCase_      ,				lowerCamelCase_						):
									_UpperCamelCase			=   model_class(snake_case_						)
									model.to(snake_case_						)
									model.eval()

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

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

									_UpperCamelCase			=   self.model_tester.seq_length

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

								_UpperCamelCase	,				_UpperCamelCase			=   self.model_tester.prepare_config_and_inputs_for_common()

								for model_class in self.all_model_classes:
									_UpperCamelCase			=   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"]
									_UpperCamelCase			=   True

									check_hidden_states_output(snake_case_      ,				snake_case_      ,				snake_case_						)






def    _lowercase			(	)							->					List[str]:





	"""simple docstring"""


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




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


							@cached_property
							def  lowercase   ( self						)							->   Any:



								"""simple docstring"""

								return (
								    VideoMAEImageProcessor(image_mean=[0.5, 0.5, 0.5]      ,				image_std=[0.5, 0.5, 0.5]						)
								    if is_vision_available()
								    else None
								)







							@slow
							def  lowercase   ( self						)							->   Dict:



								"""simple docstring"""

								_UpperCamelCase			=   TimesformerForVideoClassification.from_pretrained("facebook/timesformer-base-finetuned-k400"						).to(
								    snake_case_						)

								_UpperCamelCase			=   self.default_image_processor
								_UpperCamelCase			=   prepare_video()
								_UpperCamelCase			=   image_processor(video[:8]      ,				return_tensors="pt"						).to(snake_case_						)

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

								# verify the logits
								_UpperCamelCase			=   torch.Size((1, 4_00)						)
								self.assertEqual(outputs.logits.shape      ,				snake_case_						)

								_UpperCamelCase			=   torch.tensor([-0.30_16, -0.77_13, -0.42_05]						).to(snake_case_						)

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








import copy
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, Optional, Union
@dataclass
class 						lowerCamelCase_							:



					'''simple docstring'''







					__UpperCAmelCase							  =					None
					__UpperCAmelCase							  =					False
					__UpperCAmelCase							  =					False
					__UpperCAmelCase							  =					False
					__UpperCAmelCase							  =					None
					__UpperCAmelCase							  =					None
					__UpperCAmelCase							  =					False
					__UpperCAmelCase							  =					False
					__UpperCAmelCase							  =					False
					__UpperCAmelCase							  =					True
					__UpperCAmelCase							  =					None
					__UpperCAmelCase							  =					1
					__UpperCAmelCase							  =					None
					__UpperCAmelCase							  =					False
					__UpperCAmelCase							  =					None
					__UpperCAmelCase							  =					None






					def A   (					self    ) ->      "DownloadConfig":







								'''simple docstring'''

								return self.__class__(**{k: copy.deepcopy(snake_case_    ) for k, v in self.__dict__.items()}    )


