



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     lowerCAmelCase_		:
       def __init__(      self,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_=2,      SCREAMING_SNAKE_CASE_=3,      SCREAMING_SNAKE_CASE_=4,      SCREAMING_SNAKE_CASE_=2,      SCREAMING_SNAKE_CASE_=7,      SCREAMING_SNAKE_CASE_=True,      SCREAMING_SNAKE_CASE_=True,      SCREAMING_SNAKE_CASE_=True,      SCREAMING_SNAKE_CASE_=True,      SCREAMING_SNAKE_CASE_=99,      SCREAMING_SNAKE_CASE_=36,      SCREAMING_SNAKE_CASE_=3,      SCREAMING_SNAKE_CASE_=4,      SCREAMING_SNAKE_CASE_=37,      SCREAMING_SNAKE_CASE_="gelu",      SCREAMING_SNAKE_CASE_=0.1,      SCREAMING_SNAKE_CASE_=0.1,      SCREAMING_SNAKE_CASE_=512,      SCREAMING_SNAKE_CASE_=16,      SCREAMING_SNAKE_CASE_=2,      SCREAMING_SNAKE_CASE_=0.02,      SCREAMING_SNAKE_CASE_=6,      SCREAMING_SNAKE_CASE_=6,      SCREAMING_SNAKE_CASE_=3,      SCREAMING_SNAKE_CASE_=4,      SCREAMING_SNAKE_CASE_=None,      SCREAMING_SNAKE_CASE_=1000,      )					->		Optional[int]:
          UpperCamelCase   :  Any						     =     parent
          UpperCamelCase   :  int						     =     batch_size
          UpperCamelCase   :  Dict						     =     num_channels
          UpperCamelCase   :  Any						     =     image_size
          UpperCamelCase   :  Any						     =     patch_size
          UpperCamelCase   :  Any						     =     text_seq_length
          UpperCamelCase   :  Optional[Any]						     =     is_training
          UpperCamelCase   :  Any						     =     use_input_mask
          UpperCamelCase   :  Dict						     =     use_token_type_ids
          UpperCamelCase   :  Optional[Any]						     =     use_labels
          UpperCamelCase   :  str						     =     vocab_size
          UpperCamelCase   :  List[str]						     =     hidden_size
          UpperCamelCase   :  Tuple						     =     num_hidden_layers
          UpperCamelCase   :  Union[str, Any]						     =     num_attention_heads
          UpperCamelCase   :  str						     =     intermediate_size
          UpperCamelCase   :  Union[str, Any]						     =     hidden_act
          UpperCamelCase   :  Optional[Any]						     =     hidden_dropout_prob
          UpperCamelCase   :  Optional[int]						     =     attention_probs_dropout_prob
          UpperCamelCase   :  Dict						     =     max_position_embeddings
          UpperCamelCase   :  Union[str, Any]						     =     type_vocab_size
          UpperCamelCase   :  Union[str, Any]						     =     type_sequence_label_size
          UpperCamelCase   :  Optional[Any]						     =     initializer_range
          UpperCamelCase   :  List[Any]						     =     coordinate_size
          UpperCamelCase   :  Union[str, Any]						     =     shape_size
          UpperCamelCase   :  Any						     =     num_labels
          UpperCamelCase   :  int						     =     num_choices
          UpperCamelCase   :  Optional[int]						     =     scope
          UpperCamelCase   :  Dict						     =     range_bbox

          # LayoutLMv3's sequence length equals the number of text tokens + number of patches + 1 (we add 1 for the CLS token)
          UpperCamelCase   :  List[str]						     =     text_seq_length
          UpperCamelCase   :  Any						     =     (image_size // patch_size) ** 2 + 1
          UpperCamelCase   :  Optional[int]						     =     self.text_seq_length + self.image_seq_length
       def  snake_case_	(      self	)					->		Dict:
          UpperCamelCase   :  str						     =     ids_tensor([self.batch_size, self.text_seq_length],      self.vocab_size	)

          UpperCamelCase   :  Any						     =     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]:
                   UpperCamelCase   :  List[Any]						     =     bbox[i, j, 3]
                   UpperCamelCase   :  Any						     =     bbox[i, j, 1]
                   UpperCamelCase   :  List[str]						     =     t
                if bbox[i, j, 2] < bbox[i, j, 0]:
                   UpperCamelCase   :  Optional[Any]						     =     bbox[i, j, 2]
                   UpperCamelCase   :  List[Any]						     =     bbox[i, j, 0]
                   UpperCamelCase   :  Optional[int]						     =     t

          UpperCamelCase   :  Union[str, Any]						     =     floats_tensor([self.batch_size, self.num_channels, self.image_size, self.image_size]	)

          UpperCamelCase   :  Dict						     =     None
          if self.use_input_mask:
             UpperCamelCase   :  Optional[Any]						     =     random_attention_mask([self.batch_size, self.text_seq_length]	)

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

          UpperCamelCase   :  Tuple						     =     None
          UpperCamelCase   :  List[str]						     =     None
          if self.use_labels:
             UpperCamelCase   :  Optional[Any]						     =     ids_tensor([self.batch_size],      self.type_sequence_label_size	)
             UpperCamelCase   :  Any						     =     ids_tensor([self.batch_size, self.text_seq_length],      self.num_labels	)

          UpperCamelCase   :  List[str]						     =     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  snake_case_	(      self,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_	)					->		int:
          UpperCamelCase   :  Tuple						     =     LayoutLMvaModel(config=SCREAMING_SNAKE_CASE_	)
          model.to(SCREAMING_SNAKE_CASE_	)
          model.eval()

          # text + image
          UpperCamelCase   :  List[str]						     =     model(SCREAMING_SNAKE_CASE_,      pixel_values=SCREAMING_SNAKE_CASE_	)
          UpperCamelCase   :  Any						     =     model(
              SCREAMING_SNAKE_CASE_,      bbox=SCREAMING_SNAKE_CASE_,      pixel_values=SCREAMING_SNAKE_CASE_,      attention_mask=SCREAMING_SNAKE_CASE_,      token_type_ids=SCREAMING_SNAKE_CASE_	)
          UpperCamelCase   :  Tuple						     =     model(SCREAMING_SNAKE_CASE_,      bbox=SCREAMING_SNAKE_CASE_,      pixel_values=SCREAMING_SNAKE_CASE_,      token_type_ids=SCREAMING_SNAKE_CASE_	)
          UpperCamelCase   :  List[str]						     =     model(SCREAMING_SNAKE_CASE_,      bbox=SCREAMING_SNAKE_CASE_,      pixel_values=SCREAMING_SNAKE_CASE_	)

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

          # text only
          UpperCamelCase   :  Tuple						     =     model(SCREAMING_SNAKE_CASE_	)
          self.parent.assertEqual(
              result.last_hidden_state.shape,      (self.batch_size, self.text_seq_length, self.hidden_size)	)

          # image only
          UpperCamelCase   :  List[str]						     =     model(pixel_values=SCREAMING_SNAKE_CASE_	)
          self.parent.assertEqual(
              result.last_hidden_state.shape,      (self.batch_size, self.image_seq_length, self.hidden_size)	)
       def  snake_case_	(      self,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_	)					->		Tuple:
          UpperCamelCase   :  Optional[int]						     =     self.num_labels
          UpperCamelCase   :  List[str]						     =     LayoutLMvaForSequenceClassification(SCREAMING_SNAKE_CASE_	)
          model.to(SCREAMING_SNAKE_CASE_	)
          model.eval()
          UpperCamelCase   :  List[str]						     =     model(
              SCREAMING_SNAKE_CASE_,      bbox=SCREAMING_SNAKE_CASE_,      pixel_values=SCREAMING_SNAKE_CASE_,      attention_mask=SCREAMING_SNAKE_CASE_,      token_type_ids=SCREAMING_SNAKE_CASE_,      labels=SCREAMING_SNAKE_CASE_,      )
          self.parent.assertEqual(result.logits.shape,      (self.batch_size, self.num_labels)	)
       def  snake_case_	(      self,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_	)					->		List[str]:
          UpperCamelCase   :  Tuple						     =     self.num_labels
          UpperCamelCase   :  Tuple						     =     LayoutLMvaForTokenClassification(config=SCREAMING_SNAKE_CASE_	)
          model.to(SCREAMING_SNAKE_CASE_	)
          model.eval()
          UpperCamelCase   :  Dict						     =     model(
              SCREAMING_SNAKE_CASE_,      bbox=SCREAMING_SNAKE_CASE_,      pixel_values=SCREAMING_SNAKE_CASE_,      attention_mask=SCREAMING_SNAKE_CASE_,      token_type_ids=SCREAMING_SNAKE_CASE_,      labels=SCREAMING_SNAKE_CASE_,      )
          self.parent.assertEqual(result.logits.shape,      (self.batch_size, self.text_seq_length, self.num_labels)	)
       def  snake_case_	(      self,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_	)					->		Optional[int]:
          UpperCamelCase   :  Optional[int]						     =     LayoutLMvaForQuestionAnswering(config=SCREAMING_SNAKE_CASE_	)
          model.to(SCREAMING_SNAKE_CASE_	)
          model.eval()
          UpperCamelCase   :  Any						     =     model(
              SCREAMING_SNAKE_CASE_,      bbox=SCREAMING_SNAKE_CASE_,      pixel_values=SCREAMING_SNAKE_CASE_,      attention_mask=SCREAMING_SNAKE_CASE_,      token_type_ids=SCREAMING_SNAKE_CASE_,      start_positions=SCREAMING_SNAKE_CASE_,      end_positions=SCREAMING_SNAKE_CASE_,      )
          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  snake_case_	(      self	)					->		List[str]:
          UpperCamelCase   :  Tuple						     =     self.prepare_config_and_inputs()
          (
              UpperCamelCase					
          )   :  Optional[int]						     =     config_and_inputs
          UpperCamelCase   :  str						     =     {
              '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     lowerCAmelCase_		(  a__	,   a__	,   unittest.TestCase							):
       UpperCAmelCase__    : Any       					=  False
       UpperCAmelCase__    : List[str]       					=  False
       UpperCAmelCase__    : Union[str, Any]       					=  False

       UpperCAmelCase__    : str       					=  (
           (
               LayoutLMvaModel,
               LayoutLMvaForSequenceClassification,
               LayoutLMvaForTokenClassification,
               LayoutLMvaForQuestionAnswering,
           )
           if is_torch_available()
           else ()
       )
       UpperCAmelCase__    : Tuple       					=  (
           {"document-question-answering": LayoutLMvaForQuestionAnswering, "feature-extraction": LayoutLMvaModel}
           if is_torch_available()
           else {}
       )
       def  snake_case_	(      self,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_	)					->		List[Any]:
          # `DocumentQuestionAnsweringPipeline` is expected to work with this model, but it combines the text and visual
          # embedding along the sequence dimension (dim 1), which causes an error during post-processing as `p_mask` has
          # the sequence dimension of the text embedding only.
          # (see the line `embedding_output = torch.cat([embedding_output, visual_embeddings], dim=1)`)
          return True
       def  snake_case_	(      self	)					->		Optional[Any]:
          UpperCamelCase   :  Optional[int]						     =     LayoutLMvaModelTester(self	)
          UpperCamelCase   :  List[str]						     =     ConfigTester(self,      config_class=SCREAMING_SNAKE_CASE_,      hidden_size=37	)
       def  snake_case_	(      self,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_,      SCREAMING_SNAKE_CASE_=False	)					->		str:
          UpperCamelCase   :  Optional[int]						     =     copy.deepcopy(SCREAMING_SNAKE_CASE_	)
          if model_class in get_values(SCREAMING_SNAKE_CASE_	):
             UpperCamelCase   :  Tuple						     =     {
                 k: v.unsqueeze(1	).expand(-1,      self.model_tester.num_choices,      -1	).contiguous()
                 if isinstance(SCREAMING_SNAKE_CASE_,      torch.Tensor	) and v.ndim > 1
                 else v
                 for k, v in inputs_dict.items()
             }
          if return_labels:
             if model_class in get_values(SCREAMING_SNAKE_CASE_	):
                UpperCamelCase   :  Tuple						     =     torch.ones(self.model_tester.batch_size,      dtype=torch.long,      device=SCREAMING_SNAKE_CASE_	)
             elif model_class in get_values(SCREAMING_SNAKE_CASE_	):
                UpperCamelCase   :  Tuple						     =     torch.zeros(
                    self.model_tester.batch_size,      dtype=torch.long,      device=SCREAMING_SNAKE_CASE_	)
                UpperCamelCase   :  List[Any]						     =     torch.zeros(
                    self.model_tester.batch_size,      dtype=torch.long,      device=SCREAMING_SNAKE_CASE_	)
             elif model_class in [
                 *get_values(SCREAMING_SNAKE_CASE_	),
             ]:
                UpperCamelCase   :  Union[str, Any]						     =     torch.zeros(
                    self.model_tester.batch_size,      dtype=torch.long,      device=SCREAMING_SNAKE_CASE_	)
             elif model_class in [
                 *get_values(SCREAMING_SNAKE_CASE_	),
             ]:
                UpperCamelCase   :  List[str]						     =     torch.zeros(
                    (self.model_tester.batch_size, self.model_tester.text_seq_length),      dtype=torch.long,      device=SCREAMING_SNAKE_CASE_,      )

          return inputs_dict
       def  snake_case_	(      self	)					->		Tuple:
          self.config_tester.run_common_tests()
       def  snake_case_	(      self	)					->		List[Any]:
          UpperCamelCase   :  List[str]						     =     self.model_tester.prepare_config_and_inputs()
          self.model_tester.create_and_check_model(*SCREAMING_SNAKE_CASE_	)
       def  snake_case_	(      self	)					->		Optional[int]:
          UpperCamelCase   :  List[Any]						     =     self.model_tester.prepare_config_and_inputs()
          for type in ["absolute", "relative_key", "relative_key_query"]:
             UpperCamelCase   :  int						     =     type
             self.model_tester.create_and_check_model(*SCREAMING_SNAKE_CASE_	)
       def  snake_case_	(      self	)					->		Tuple:
          UpperCamelCase   :  int						     =     self.model_tester.prepare_config_and_inputs()
          self.model_tester.create_and_check_for_sequence_classification(*SCREAMING_SNAKE_CASE_	)
       def  snake_case_	(      self	)					->		Optional[Any]:
          UpperCamelCase   :  int						     =     self.model_tester.prepare_config_and_inputs()
          self.model_tester.create_and_check_for_token_classification(*SCREAMING_SNAKE_CASE_	)
       def  snake_case_	(      self	)					->		Any:
          UpperCamelCase   :  Optional[int]						     =     self.model_tester.prepare_config_and_inputs()
          self.model_tester.create_and_check_for_question_answering(*SCREAMING_SNAKE_CASE_	)






       @slow
       def  snake_case_	(      self	)					->		Optional[Any]:
          for model_name in LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
             UpperCamelCase   :  Dict						     =     LayoutLMvaModel.from_pretrained(SCREAMING_SNAKE_CASE_	)
             self.assertIsNotNone(SCREAMING_SNAKE_CASE_	)






def 		UpperCamelCase     (       )     ->					Dict:
   UpperCamelCase   :  Optional[int]						     =     Image.open('./tests/fixtures/tests_samples/COCO/000000039769.png'     )
   return image



@require_torch
class     lowerCAmelCase_		(  unittest.TestCase							):
       @cached_property
       def  snake_case_	(      self	)					->		str:
          return LayoutLMvaImageProcessor(apply_ocr=SCREAMING_SNAKE_CASE_	) if is_vision_available() else None






       @slow
       def  snake_case_	(      self	)					->		Optional[int]:
          UpperCamelCase   :  Any						     =     LayoutLMvaModel.from_pretrained('microsoft/layoutlmv3-base'	).to(SCREAMING_SNAKE_CASE_	)

          UpperCamelCase   :  Any						     =     self.default_image_processor
          UpperCamelCase   :  Optional[int]						     =     prepare_img()
          UpperCamelCase   :  Optional[Any]						     =     image_processor(images=SCREAMING_SNAKE_CASE_,      return_tensors='pt'	).pixel_values.to(SCREAMING_SNAKE_CASE_	)

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

          # forward pass
          UpperCamelCase   :  Any						     =     model(
              input_ids=input_ids.to(SCREAMING_SNAKE_CASE_	),      bbox=bbox.to(SCREAMING_SNAKE_CASE_	),      pixel_values=pixel_values.to(SCREAMING_SNAKE_CASE_	),      )

          # verify the logits
          UpperCamelCase   :  str						     =     torch.Size((1, 199, 768)	)
          self.assertEqual(outputs.last_hidden_state.shape,      SCREAMING_SNAKE_CASE_	)

          UpperCamelCase   :  int						     =     torch.tensor(
              [[-0.05_29, 0.36_18, 0.16_32], [-0.15_87, -0.16_67, -0.04_00], [-0.15_57, -0.16_71, -0.05_05]]	).to(SCREAMING_SNAKE_CASE_	)

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









from abc import ABC, abstractmethod
from argparse import ArgumentParser



class     lowerCAmelCase_		(  a__							):
       @staticmethod
       @abstractmethod
       def  snake_case_	(      SCREAMING_SNAKE_CASE_	)					->		int:
          raise NotImplementedError()






       @abstractmethod
       def  snake_case_	(      self	)					->		str:
          raise NotImplementedError()



