

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   lowercase_   :



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

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



      def 						UpperCamelCase_		(      self				:    Union[str, Any]		)   ->					Optional[int]:
        _snake_case						=							ids_tensor([self.batch_size, self.text_seq_length]      , self.vocab_size		)

        _snake_case						=							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]:
              _snake_case						=							bbox[i, j, 3]
              _snake_case						=							bbox[i, j, 1]
              _snake_case						=							t
            if bbox[i, j, 2] < bbox[i, j, 0]:
              _snake_case						=							bbox[i, j, 2]
              _snake_case						=							bbox[i, j, 0]
              _snake_case						=							t

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

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

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

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

        _snake_case						=							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				:    str      , A__				:    List[str]      , A__				:    Optional[Any]      , A__				:    int      , A__				:    List[Any]      , A__				:    Optional[int]      , A__				:    List[str]      , A__				:    List[str]      , A__				:    List[str]		)   ->					int:
        _snake_case						=							LayoutLMvaModel(config=A__		)
        model.to(A__		)
        model.eval()

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

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

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

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



      def 						UpperCamelCase_		(      self				:    Union[str, Any]      , A__				:    Dict      , A__				:    Any      , A__				:    List[str]      , A__				:    List[str]      , A__				:    Dict      , A__				:    Any      , A__				:    Any      , A__				:    List[str]		)   ->					Optional[Any]:
        _snake_case						=							self.num_labels
        _snake_case						=							LayoutLMvaForSequenceClassification(A__		)
        model.to(A__		)
        model.eval()
        _snake_case						=							model(
            A__      , bbox=A__      , pixel_values=A__      , attention_mask=A__      , token_type_ids=A__      , labels=A__      , )
        self.parent.assertEqual(result.logits.shape      , (self.batch_size, self.num_labels)		)



      def 						UpperCamelCase_		(      self				:    List[Any]      , A__				:    Optional[Any]      , A__				:    str      , A__				:    List[str]      , A__				:    int      , A__				:    Optional[int]      , A__				:    str      , A__				:    Union[str, Any]      , A__				:    str		)   ->					int:
        _snake_case						=							self.num_labels
        _snake_case						=							LayoutLMvaForTokenClassification(config=A__		)
        model.to(A__		)
        model.eval()
        _snake_case						=							model(
            A__      , bbox=A__      , pixel_values=A__      , attention_mask=A__      , token_type_ids=A__      , labels=A__      , )
        self.parent.assertEqual(result.logits.shape      , (self.batch_size, self.text_seq_length, self.num_labels)		)



      def 						UpperCamelCase_		(      self				:    Optional[Any]      , A__				:    int      , A__				:    int      , A__				:    List[str]      , A__				:    List[Any]      , A__				:    Optional[int]      , A__				:    Any      , A__				:    int      , A__				:    str		)   ->					Optional[int]:
        _snake_case						=							LayoutLMvaForQuestionAnswering(config=A__		)
        model.to(A__		)
        model.eval()
        _snake_case						=							model(
            A__      , bbox=A__      , pixel_values=A__      , attention_mask=A__      , token_type_ids=A__      , start_positions=A__      , end_positions=A__      , )
        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				:    str		)   ->					Optional[Any]:
        _snake_case						=							self.prepare_config_and_inputs()
        (
            (
            _snake_case
        ),					(
            _snake_case
        ),					(
            _snake_case
        ),					(
            _snake_case
        ),					(
            _snake_case
        ),					(
            _snake_case
        ),					(
            _snake_case
        ),					(
            _snake_case
        ),					
        )						=							config_and_inputs
        _snake_case						=							{
            '''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   lowercase_   (  __lowercase       ,							__lowercase       ,							unittest.TestCase					):
      UpperCamelCase_      :		Union[str, Any]										=    False
      UpperCamelCase_      :		Any										=    False
      UpperCamelCase_      :		str										=    False

      UpperCamelCase_      :		Optional[Any]										=    (
          (
              LayoutLMvaModel,
              LayoutLMvaForSequenceClassification,
              LayoutLMvaForTokenClassification,
              LayoutLMvaForQuestionAnswering,
          )
          if is_torch_available()
          else ()
      )
      UpperCamelCase_      :		Optional[int]										=    (
          {"document-question-answering": LayoutLMvaForQuestionAnswering, "feature-extraction": LayoutLMvaModel}
          if is_torch_available()
          else {}
      )



      def 						UpperCamelCase_		(      self				:    Optional[Any]      , A__				:    Optional[int]      , A__				:    int      , A__				:    str      , A__				:    Union[str, Any]      , A__				:    Optional[int]		)   ->					str:
        # `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 						UpperCamelCase_		(      self				:    Optional[int]		)   ->					Optional[int]:
        _snake_case						=							LayoutLMvaModelTester(self		)
        _snake_case						=							ConfigTester(self      , config_class=A__      , hidden_size=37		)



      def 						UpperCamelCase_		(      self				:    Union[str, Any]      , A__				:    Tuple      , A__				:    List[str]      , A__				:    List[str]=False		)   ->					Optional[int]:
        _snake_case						=							copy.deepcopy(A__		)
        if model_class in get_values(A__		):
          _snake_case						=							{
              k: v.unsqueeze(1		).expand(-1      , self.model_tester.num_choices      , -1		).contiguous()
              if isinstance(A__      , torch.Tensor		) and v.ndim > 1
              else v
              for k, v in inputs_dict.items()
          }
        if return_labels:
          if model_class in get_values(A__		):
            _snake_case						=							torch.ones(self.model_tester.batch_size      , dtype=torch.long      , device=A__		)
          elif model_class in get_values(A__		):
            _snake_case						=							torch.zeros(
                self.model_tester.batch_size      , dtype=torch.long      , device=A__		)
            _snake_case						=							torch.zeros(
                self.model_tester.batch_size      , dtype=torch.long      , device=A__		)
          elif model_class in [
              *get_values(A__		),
          ]:
            _snake_case						=							torch.zeros(
                self.model_tester.batch_size      , dtype=torch.long      , device=A__		)
          elif model_class in [
              *get_values(A__		),
          ]:
            _snake_case						=							torch.zeros(
                (self.model_tester.batch_size, self.model_tester.text_seq_length)      , dtype=torch.long      , device=A__      , )

        return inputs_dict



      def 						UpperCamelCase_		(      self				:    int		)   ->					Optional[int]:
        self.config_tester.run_common_tests()



      def 						UpperCamelCase_		(      self				:    Dict		)   ->					Optional[int]:
        _snake_case						=							self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_model(*A__		)



      def 						UpperCamelCase_		(      self				:    Union[str, Any]		)   ->					List[str]:
        _snake_case						=							self.model_tester.prepare_config_and_inputs()
        for type in ["absolute", "relative_key", "relative_key_query"]:
          _snake_case						=							type
          self.model_tester.create_and_check_model(*A__		)



      def 						UpperCamelCase_		(      self				:    Optional[int]		)   ->					List[Any]:
        _snake_case						=							self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_for_sequence_classification(*A__		)



      def 						UpperCamelCase_		(      self				:    int		)   ->					Optional[Any]:
        _snake_case						=							self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_for_token_classification(*A__		)



      def 						UpperCamelCase_		(      self				:    List[Any]		)   ->					Any:
        _snake_case						=							self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_for_question_answering(*A__		)







      @slow
      def 						UpperCamelCase_		(      self				:    List[str]		)   ->					Union[str, Any]:
        for model_name in LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
          _snake_case						=							LayoutLMvaModel.from_pretrained(A__		)
          self.assertIsNotNone(A__		)



def 				snake_case_()							->     Optional[int]:



  """simple docstring"""






  _snake_case						=							Image.open('''./tests/fixtures/tests_samples/COCO/000000039769.png'''					)
  return image



@require_torch
class   lowercase_   (  unittest.TestCase					):



      @cached_property
      def 						UpperCamelCase_		(      self				:    List[str]		)   ->					str:
        return LayoutLMvaImageProcessor(apply_ocr=A__		) if is_vision_available() else None







      @slow
      def 						UpperCamelCase_		(      self				:    Dict		)   ->					Union[str, Any]:
        _snake_case						=							LayoutLMvaModel.from_pretrained('''microsoft/layoutlmv3-base'''		).to(A__		)

        _snake_case						=							self.default_image_processor
        _snake_case						=							prepare_img()
        _snake_case						=							image_processor(images=A__      , return_tensors='''pt'''		).pixel_values.to(A__		)

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

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

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

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

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




def 				snake_case_(_UpperCamelCase			,	_UpperCamelCase					)							->     str:



  """simple docstring"""






  if a < 0 or b < 0:
    raise ValueError('''the value of both inputs must be positive'''					)
  _snake_case						=							str(bin(_UpperCamelCase					)					)[2:]  # remove the leading "0b"
  _snake_case						=							str(bin(_UpperCamelCase					)					)[2:]
  _snake_case						=							max(len(_UpperCamelCase					)			,	len(_UpperCamelCase					)					)
  return "0b" + "".join(
      str(int('''1''' in (char_a, char_b)					)					)
      for char_a, char_b in zip(a_binary.zfill(_UpperCamelCase					)			,	b_binary.zfill(_UpperCamelCase					)					)					)


if __name__ == "__main__":
 import doctest

 doctest.testmod()

