

import copy
import unittest

from transformers.models.auto import get_values
from transformers.testing_utils import require_torch, 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, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
	import torch

	from transformers import (
	    MODEL_FOR_MULTIPLE_CHOICE_MAPPING,
	    MODEL_FOR_QUESTION_ANSWERING_MAPPING,
	    MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING,
	    MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING,
	    LayoutLMvaConfig,
	    LayoutLMvaForQuestionAnswering,
	    LayoutLMvaForSequenceClassification,
	    LayoutLMvaForTokenClassification,
	    LayoutLMvaModel,
	)
	from transformers.models.layoutlmva.modeling_layoutlmva import LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST

if is_vision_available():
	from PIL import Image

	from transformers import LayoutLMvaImageProcessor

class 					a__						:
			"""simple docstring"""







			def __init__(    self      ,      lowercase      ,      lowercase=2      ,      lowercase=3      ,      lowercase=4      ,      lowercase=2      ,      lowercase=7      ,      lowercase=True      ,      lowercase=True      ,      lowercase=True      ,      lowercase=True      ,      lowercase=99      ,      lowercase=36      ,      lowercase=3      ,      lowercase=4      ,      lowercase=37      ,      lowercase="gelu"      ,      lowercase=0.1      ,      lowercase=0.1      ,      lowercase=512      ,      lowercase=16      ,      lowercase=2      ,      lowercase=0.02      ,      lowercase=6      ,      lowercase=6      ,      lowercase=3      ,      lowercase=4      ,      lowercase=None      ,      lowercase=1000      ,      )  ->						Dict:
							'''simple docstring'''






							A__        =			parent
							A__        =			batch_size
							A__        =			num_channels
							A__        =			image_size
							A__        =			patch_size
							A__        =			text_seq_length
							A__        =			is_training
							A__        =			use_input_mask
							A__        =			use_token_type_ids
							A__        =			use_labels
							A__        =			vocab_size
							A__        =			hidden_size
							A__        =			num_hidden_layers
							A__        =			num_attention_heads
							A__        =			intermediate_size
							A__        =			hidden_act
							A__        =			hidden_dropout_prob
							A__        =			attention_probs_dropout_prob
							A__        =			max_position_embeddings
							A__        =			type_vocab_size
							A__        =			type_sequence_label_size
							A__        =			initializer_range
							A__        =			coordinate_size
							A__        =			shape_size
							A__        =			num_labels
							A__        =			num_choices
							A__        =			scope
							A__        =			range_bbox

							# LayoutLMv3's sequence length equals the number of text tokens + number of patches + 1 (we add 1 for the CLS token)
							A__        =			text_seq_length
							A__        =			(image_size // patch_size) ** 2 + 1
							A__        =			self.text_seq_length + self.image_seq_length


			def      UpperCamelCase		(    self       )  ->						Any:
							'''simple docstring'''






							A__        =			ids_tensor([self.batch_size, self.text_seq_length]      ,      self.vocab_size       )

							A__        =			ids_tensor([self.batch_size, self.text_seq_length, 4]      ,      self.range_bbox       )
							# Ensure that bbox is legal
							for i in range(bbox.shape[0]       ):
											for j in range(bbox.shape[1]       ):
															if bbox[i, j, 3] < bbox[i, j, 1]:
																			A__        =			bbox[i, j, 3]
																			A__        =			bbox[i, j, 1]
																			A__        =			t
															if bbox[i, j, 2] < bbox[i, j, 0]:
																			A__        =			bbox[i, j, 2]
																			A__        =			bbox[i, j, 0]
																			A__        =			t

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

							A__        =			None
							if self.use_input_mask:
											A__        =			random_attention_mask([self.batch_size, self.text_seq_length]       )

							A__        =			None
							if self.use_token_type_ids:
											A__        =			ids_tensor([self.batch_size, self.text_seq_length]      ,      self.type_vocab_size       )

							A__        =			None
							A__        =			None
							if self.use_labels:
											A__        =			ids_tensor([self.batch_size]      ,      self.type_sequence_label_size       )
											A__        =			ids_tensor([self.batch_size, self.text_seq_length]      ,      self.num_labels       )

							A__        =			LayoutLMvaConfig(
							    vocab_size=self.vocab_size      ,      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      ,      max_position_embeddings=self.max_position_embeddings      ,      type_vocab_size=self.type_vocab_size      ,      initializer_range=self.initializer_range      ,      coordinate_size=self.coordinate_size      ,      shape_size=self.shape_size      ,      input_size=self.image_size      ,      patch_size=self.patch_size      ,      )

							return config, input_ids, bbox, pixel_values, token_type_ids, input_mask, sequence_labels, token_labels


			def      UpperCamelCase		(    self      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase       )  ->						Any:
							'''simple docstring'''






							A__        =			LayoutLMvaModel(config=lowercase       )
							model.to(lowercase       )
							model.eval()

							# text + image
							A__        =			model(lowercase      ,      pixel_values=lowercase       )
							A__        =			model(
							    lowercase      ,      bbox=lowercase      ,      pixel_values=lowercase      ,      attention_mask=lowercase      ,      token_type_ids=lowercase       )
							A__        =			model(lowercase      ,      bbox=lowercase      ,      pixel_values=lowercase      ,      token_type_ids=lowercase       )
							A__        =			model(lowercase      ,      bbox=lowercase      ,      pixel_values=lowercase       )

							self.parent.assertEqual(result.last_hidden_state.shape      ,      (self.batch_size, self.seq_length, self.hidden_size)       )

							# text only
							A__        =			model(lowercase       )
							self.parent.assertEqual(
							    result.last_hidden_state.shape      ,      (self.batch_size, self.text_seq_length, self.hidden_size)       )

							# image only
							A__        =			model(pixel_values=lowercase       )
							self.parent.assertEqual(
							    result.last_hidden_state.shape      ,      (self.batch_size, self.image_seq_length, self.hidden_size)       )


			def      UpperCamelCase		(    self      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase       )  ->						str:
							'''simple docstring'''






							A__        =			self.num_labels
							A__        =			LayoutLMvaForSequenceClassification(lowercase       )
							model.to(lowercase       )
							model.eval()
							A__        =			model(
							    lowercase      ,      bbox=lowercase      ,      pixel_values=lowercase      ,      attention_mask=lowercase      ,      token_type_ids=lowercase      ,      labels=lowercase      ,      )
							self.parent.assertEqual(result.logits.shape      ,      (self.batch_size, self.num_labels)       )


			def      UpperCamelCase		(    self      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase       )  ->						Dict:
							'''simple docstring'''






							A__        =			self.num_labels
							A__        =			LayoutLMvaForTokenClassification(config=lowercase       )
							model.to(lowercase       )
							model.eval()
							A__        =			model(
							    lowercase      ,      bbox=lowercase      ,      pixel_values=lowercase      ,      attention_mask=lowercase      ,      token_type_ids=lowercase      ,      labels=lowercase      ,      )
							self.parent.assertEqual(result.logits.shape      ,      (self.batch_size, self.text_seq_length, self.num_labels)       )


			def      UpperCamelCase		(    self      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase       )  ->						Union[str, Any]:
							'''simple docstring'''






							A__        =			LayoutLMvaForQuestionAnswering(config=lowercase       )
							model.to(lowercase       )
							model.eval()
							A__        =			model(
							    lowercase      ,      bbox=lowercase      ,      pixel_values=lowercase      ,      attention_mask=lowercase      ,      token_type_ids=lowercase      ,      start_positions=lowercase      ,      end_positions=lowercase      ,      )
							self.parent.assertEqual(result.start_logits.shape      ,      (self.batch_size, self.seq_length)       )
							self.parent.assertEqual(result.end_logits.shape      ,      (self.batch_size, self.seq_length)       )


			def      UpperCamelCase		(    self       )  ->						Any:
							'''simple docstring'''






							A__        =			self.prepare_config_and_inputs()
							(
							    (
							    A__
							)    ,				(
							    A__
							)    ,				(
							    A__
							)    ,				(
							    A__
							)    ,				(
							    A__
							)    ,				(
							    A__
							)    ,				(
							    A__
							)    ,				(
							    A__
							)    ,				
							)        =			config_and_inputs
							A__        =			{
							    "input_ids": input_ids,
							    "bbox": bbox,
							    "pixel_values": pixel_values,
							    "token_type_ids": token_type_ids,
							    "attention_mask": input_mask,
							}
							return config, inputs_dict

@require_torch
class 					a__						(					snake_case							,	snake_case							,	unittest.TestCase			):
			"""simple docstring"""







			__lowerCamelCase        =       False
			__lowerCamelCase        =       False
			__lowerCamelCase        =       False

			__lowerCamelCase        =       (
			    (
			        LayoutLMvaModel,
			        LayoutLMvaForSequenceClassification,
			        LayoutLMvaForTokenClassification,
			        LayoutLMvaForQuestionAnswering,
			    )
			    if is_torch_available()
			    else ()
			)
			__lowerCamelCase        =       (
			    {'document-question-answering': LayoutLMvaForQuestionAnswering, 'feature-extraction': LayoutLMvaModel}
			    if is_torch_available()
			    else {}
			)


			def      UpperCamelCase		(    self      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase      ,      lowercase       )  ->						List[Any]:
							'''simple docstring'''






							return True


			def      UpperCamelCase		(    self       )  ->						Optional[int]:
							'''simple docstring'''






							A__        =			LayoutLMvaModelTester(self       )
							A__        =			ConfigTester(self      ,      config_class=lowercase      ,      hidden_size=37       )


			def      UpperCamelCase		(    self      ,      lowercase      ,      lowercase      ,      lowercase=False       )  ->						Union[str, Any]:
							'''simple docstring'''






							A__        =			copy.deepcopy(lowercase       )
							if model_class in get_values(lowercase       ):
											A__        =			{
											    k: v.unsqueeze(1       ).expand(-1      ,      self.model_tester.num_choices      ,      -1       ).contiguous()
											    if isinstance(lowercase      ,      torch.Tensor       ) and v.ndim > 1
											    else v
											    for k, v in inputs_dict.items()
											}
							if return_labels:
											if model_class in get_values(lowercase       ):
															A__        =			torch.ones(self.model_tester.batch_size      ,      dtype=torch.long      ,      device=lowercase       )
											elif model_class in get_values(lowercase       ):
															A__        =			torch.zeros(
															    self.model_tester.batch_size      ,      dtype=torch.long      ,      device=lowercase       )
															A__        =			torch.zeros(
															    self.model_tester.batch_size      ,      dtype=torch.long      ,      device=lowercase       )
											elif model_class in [
											    *get_values(lowercase       ),
											]:
															A__        =			torch.zeros(
															    self.model_tester.batch_size      ,      dtype=torch.long      ,      device=lowercase       )
											elif model_class in [
											    *get_values(lowercase       ),
											]:
															A__        =			torch.zeros(
															    (self.model_tester.batch_size, self.model_tester.text_seq_length)      ,      dtype=torch.long      ,      device=lowercase      ,      )

							return inputs_dict


			def      UpperCamelCase		(    self       )  ->						Dict:
							'''simple docstring'''






							self.config_tester.run_common_tests()


			def      UpperCamelCase		(    self       )  ->						Optional[Any]:
							'''simple docstring'''






							A__        =			self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_model(*lowercase       )


			def      UpperCamelCase		(    self       )  ->						Optional[int]:
							'''simple docstring'''






							A__        =			self.model_tester.prepare_config_and_inputs()
							for type in ["absolute", "relative_key", "relative_key_query"]:
											A__        =			type
											self.model_tester.create_and_check_model(*lowercase       )


			def      UpperCamelCase		(    self       )  ->						int:
							'''simple docstring'''






							A__        =			self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_for_sequence_classification(*lowercase       )


			def      UpperCamelCase		(    self       )  ->						Dict:
							'''simple docstring'''






							A__        =			self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_for_token_classification(*lowercase       )


			def      UpperCamelCase		(    self       )  ->						Optional[Any]:
							'''simple docstring'''






							A__        =			self.model_tester.prepare_config_and_inputs()
							self.model_tester.create_and_check_for_question_answering(*lowercase       )


			@slow
			def      UpperCamelCase		(    self       )  ->						int:
							'''simple docstring'''






							for model_name in LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
											A__        =			LayoutLMvaModel.from_pretrained(lowercase       )
											self.assertIsNotNone(lowercase       )



def 					lowerCAmelCase__							(	)			->      Tuple:




				'''simple docstring'''





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





@require_torch
class 					a__						(					unittest.TestCase			):
			"""simple docstring"""







			@cached_property
			def      UpperCamelCase		(    self       )  ->						str:
							'''simple docstring'''






							return LayoutLMvaImageProcessor(apply_ocr=lowercase       ) if is_vision_available() else None


			@slow
			def      UpperCamelCase		(    self       )  ->						Tuple:
							'''simple docstring'''






							A__        =			LayoutLMvaModel.from_pretrained("microsoft/layoutlmv3-base"       ).to(lowercase       )

							A__        =			self.default_image_processor
							A__        =			prepare_img()
							A__        =			image_processor(images=lowercase      ,      return_tensors="pt"       ).pixel_values.to(lowercase       )

							A__        =			torch.tensor([[1, 2]]       )
							A__        =			torch.tensor([[1, 2, 3, 4], [5, 6, 7, 8]]       ).unsqueeze(0       )

							# forward pass
							A__        =			model(
							    input_ids=input_ids.to(lowercase       )      ,      bbox=bbox.to(lowercase       )      ,      pixel_values=pixel_values.to(lowercase       )      ,      )

							# verify the logits
							A__        =			torch.Size((1, 199, 768)       )
							self.assertEqual(outputs.last_hidden_state.shape      ,      lowercase       )

							A__        =			torch.tensor(
							    [[-0.0529, 0.3618, 0.1632], [-0.1587, -0.1667, -0.0400], [-0.1557, -0.1671, -0.0505]]       ).to(lowercase       )

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




lowerCAmelCase__	   = """ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"""



def 					lowerCAmelCase__							(	SCREAMING_SNAKE_CASE_:							bytes      )			->      bytes:




				'''simple docstring'''





				if not isinstance(SCREAMING_SNAKE_CASE_	,       SCREAMING_SNAKE_CASE_      ):
								A__        =			F'a bytes-like object is required, not \'{data.__class__.__name__}\''
								raise TypeError(SCREAMING_SNAKE_CASE_      )

				A__        =			"".join(bin(SCREAMING_SNAKE_CASE_      )[2:].zfill(8      ) for byte in data      )

				A__        =			len(SCREAMING_SNAKE_CASE_      ) % 6 != 0

				if padding_needed:
								# The padding that will be added later
								A__        =			b"=" * ((6 - len(SCREAMING_SNAKE_CASE_      ) % 6) // 2)

								# Append binary_stream with arbitrary binary digits (0's by default) to make its
								# length a multiple of 6.
								binary_stream += "0" * (6 - len(SCREAMING_SNAKE_CASE_      ) % 6)
				else:
								A__        =			b""

				# Encode every 6 binary digits to their corresponding Base64 character
				return (
				    "".join(
				        B64_CHARSET[int(binary_stream[index : index + 6]	,       2      )]
				        for index in range(0	,       len(SCREAMING_SNAKE_CASE_      )	,       6      )      ).encode()
				    + padding
				)



def 					lowerCAmelCase__							(	SCREAMING_SNAKE_CASE_:							str      )			->      bytes:




				'''simple docstring'''





				if not isinstance(SCREAMING_SNAKE_CASE_	,       SCREAMING_SNAKE_CASE_      ) and not isinstance(SCREAMING_SNAKE_CASE_	,       SCREAMING_SNAKE_CASE_      ):
								A__        =			(
								    "argument should be a bytes-like object or ASCII string, "
								    F'not \'{encoded_data.__class__.__name__}\''
								)
								raise TypeError(SCREAMING_SNAKE_CASE_      )

				# In case encoded_data is a bytes-like object, make sure it contains only
				# ASCII characters so we convert it to a string object
				if isinstance(SCREAMING_SNAKE_CASE_	,       SCREAMING_SNAKE_CASE_      ):
								try:
												A__        =			encoded_data.decode("utf-8"      )
								except UnicodeDecodeError:
												raise ValueError("base64 encoded data should only contain ASCII characters"      )

				A__        =			encoded_data.count("="      )

				# Check if the encoded string contains non base64 characters
				if padding:
								assert all(
								    char in B64_CHARSET for char in encoded_data[:-padding]      ), "Invalid base64 character(s) found."
				else:
								assert all(
								    char in B64_CHARSET for char in encoded_data      ), "Invalid base64 character(s) found."

				# Check the padding
				assert len(SCREAMING_SNAKE_CASE_      ) % 4 == 0 and padding < 3, "Incorrect padding"

				if padding:
								# Remove padding if there is one
								A__        =			encoded_data[:-padding]

								A__        =			"".join(
								    bin(B64_CHARSET.index(SCREAMING_SNAKE_CASE_      )      )[2:].zfill(6      ) for char in encoded_data      )[: -padding * 2]
				else:
								A__        =			"".join(
								    bin(B64_CHARSET.index(SCREAMING_SNAKE_CASE_      )      )[2:].zfill(6      ) for char in encoded_data      )

				A__        =			[
				    int(binary_stream[index : index + 8]	,       2      )
				    for index in range(0	,       len(SCREAMING_SNAKE_CASE_      )	,       8      )
				]

				return bytes(SCREAMING_SNAKE_CASE_      )


if __name__ == "__main__":
	import doctest

	doctest.testmod()

