from __future__ import annotations

import copy
import inspect
import unittest

import numpy as np

from transformers import is_tf_available, is_vision_available
from transformers.models.auto import get_values
from transformers.testing_utils import require_tf, slow
from transformers.utils import cached_property

from ...test_configuration_common import ConfigTester
from ...test_modeling_tf_common import TFModelTesterMixin, floats_tensor, ids_tensor, random_attention_mask
from ...test_pipeline_mixin import PipelineTesterMixin


if is_tf_available():
   import tensorflow as tf

   from transformers import (
       TF_LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST,
       TF_MODEL_FOR_MULTIPLE_CHOICE_MAPPING,
       TF_MODEL_FOR_QUESTION_ANSWERING_MAPPING,
       TF_MODEL_FOR_SEQUENCE_CLASSIFICATION_MAPPING,
       TF_MODEL_FOR_TOKEN_CLASSIFICATION_MAPPING,
       LayoutLMvaConfig,
       TFLayoutLMvaForQuestionAnswering,
       TFLayoutLMvaForSequenceClassification,
       TFLayoutLMvaForTokenClassification,
       TFLayoutLMvaModel,
   )

if is_vision_available():
   from PIL import Image

   from transformers import LayoutLMvaImageProcessor




class 					_UpperCAmelCase			:



 '''simple docstring'''




 def __init__(		self				:   Any							, lowercase_				:   List[Any]							, lowercase_				:   int=2							, lowercase_				:   Any=3							, lowercase_				:   Optional[Any]=4							, lowercase_				:   str=2							, lowercase_				:   Any=7							, lowercase_				:   List[Any]=True							, lowercase_				:   Optional[Any]=True							, lowercase_				:   Optional[Any]=True							, lowercase_				:   Optional[Any]=True							, lowercase_				:   int=99							, lowercase_				:   str=36							, lowercase_				:   List[str]=2							, lowercase_				:   List[Any]=4							, lowercase_				:   Union[str, Any]=37							, lowercase_				:   List[str]="gelu"							, lowercase_				:   Dict=0.1							, lowercase_				:   str=0.1							, lowercase_				:   Optional[Any]=512							, lowercase_				:   str=16							, lowercase_				:   Any=2							, lowercase_				:   Tuple=0.02							, lowercase_				:   Tuple=6							, lowercase_				:   Optional[Any]=6							, lowercase_				:   Optional[int]=3							, lowercase_				:   Optional[Any]=4							, lowercase_				:   Union[str, Any]=None							, lowercase_				:   Any=1000							, )						->	Optional[Any]:


   """simple docstring"""







   _UpperCamelCase           =    parent
   _UpperCamelCase           =    batch_size
   _UpperCamelCase           =    num_channels
   _UpperCamelCase           =    image_size
   _UpperCamelCase           =    patch_size
   _UpperCamelCase           =    is_training
   _UpperCamelCase           =    use_input_mask
   _UpperCamelCase           =    use_token_type_ids
   _UpperCamelCase           =    use_labels
   _UpperCamelCase           =    vocab_size
   _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           =    max_position_embeddings
   _UpperCamelCase           =    type_vocab_size
   _UpperCamelCase           =    type_sequence_label_size
   _UpperCamelCase           =    initializer_range
   _UpperCamelCase           =    coordinate_size
   _UpperCamelCase           =    shape_size
   _UpperCamelCase           =    num_labels
   _UpperCamelCase           =    num_choices
   _UpperCamelCase           =    scope
   _UpperCamelCase           =    range_bbox

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







 def 		__UpperCAmelCase				(		self				:   Union[str, Any])						->	List[str]:


   """simple docstring"""







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

   _UpperCamelCase           =    ids_tensor([self.batch_size, self.text_seq_length, 4]							, self.range_bbox)
   _UpperCamelCase           =    bbox.numpy()
   # 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           =    bbox[i, j, 3]
         _UpperCamelCase           =    bbox[i, j, 1]
         _UpperCamelCase           =    tmp_coordinate
       if bbox[i, j, 2] < bbox[i, j, 0]:
         _UpperCamelCase           =    bbox[i, j, 2]
         _UpperCamelCase           =    bbox[i, j, 0]
         _UpperCamelCase           =    tmp_coordinate
   _UpperCamelCase           =    tf.constant(lowercase_)

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

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

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

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

   _UpperCamelCase           =    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				:   Optional[int]							, lowercase_				:   List[Any]							, lowercase_				:   int							, lowercase_				:   List[str]							, lowercase_				:   Optional[int]							, lowercase_				:   List[str]							, lowercase_				:   List[str])						->	Union[str, Any]:


   """simple docstring"""







   _UpperCamelCase           =    TFLayoutLMvaModel(config=lowercase_)

   # text + image
   _UpperCamelCase           =    model(lowercase_							, pixel_values=lowercase_							, training=lowercase_)
   _UpperCamelCase           =    model(
       lowercase_							, bbox=lowercase_							, pixel_values=lowercase_							, attention_mask=lowercase_							, token_type_ids=lowercase_							, training=lowercase_							, )
   _UpperCamelCase           =    model(lowercase_							, bbox=lowercase_							, pixel_values=lowercase_							, training=lowercase_)

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

   # text only
   _UpperCamelCase           =    model(lowercase_							, training=lowercase_)
   self.parent.assertEqual(
       result.last_hidden_state.shape							, (self.batch_size, self.text_seq_length, self.hidden_size))

   # image only
   _UpperCamelCase           =    model({"pixel_values": pixel_values}							, training=lowercase_)
   self.parent.assertEqual(
       result.last_hidden_state.shape							, (self.batch_size, self.image_seq_length, self.hidden_size))







 def 		__UpperCAmelCase				(		self				:   Optional[int]							, lowercase_				:   Optional[int]							, lowercase_				:   List[str]							, lowercase_				:   Optional[Any]							, lowercase_				:   str							, lowercase_				:   Optional[Any]							, lowercase_				:   Any							, lowercase_				:   Optional[int])						->	List[Any]:


   """simple docstring"""







   _UpperCamelCase           =    self.num_labels
   _UpperCamelCase           =    TFLayoutLMvaForSequenceClassification(config=lowercase_)
   _UpperCamelCase           =    model(
       lowercase_							, bbox=lowercase_							, pixel_values=lowercase_							, attention_mask=lowercase_							, token_type_ids=lowercase_							, labels=lowercase_							, training=lowercase_							, )
   self.parent.assertEqual(result.logits.shape							, (self.batch_size, self.num_labels))







 def 		__UpperCAmelCase				(		self				:   Optional[Any]							, lowercase_				:   Any							, lowercase_				:   List[str]							, lowercase_				:   Dict							, lowercase_				:   Optional[int]							, lowercase_				:   Dict							, lowercase_				:   Optional[int]							, lowercase_				:   List[Any])						->	List[str]:


   """simple docstring"""







   _UpperCamelCase           =    self.num_labels
   _UpperCamelCase           =    TFLayoutLMvaForTokenClassification(config=lowercase_)
   _UpperCamelCase           =    model(
       lowercase_							, bbox=lowercase_							, pixel_values=lowercase_							, attention_mask=lowercase_							, token_type_ids=lowercase_							, labels=lowercase_							, training=lowercase_							, )
   self.parent.assertEqual(result.logits.shape							, (self.batch_size, self.text_seq_length, self.num_labels))







 def 		__UpperCAmelCase				(		self				:   int							, lowercase_				:   Tuple							, lowercase_				:   Optional[Any]							, lowercase_				:   Optional[Any]							, lowercase_				:   Tuple							, lowercase_				:   int							, lowercase_				:   Optional[Any]							, lowercase_				:   List[str])						->	str:


   """simple docstring"""







   _UpperCamelCase           =    2
   _UpperCamelCase           =    TFLayoutLMvaForQuestionAnswering(config=lowercase_)
   _UpperCamelCase           =    model(
       lowercase_							, bbox=lowercase_							, pixel_values=lowercase_							, attention_mask=lowercase_							, token_type_ids=lowercase_							, start_positions=lowercase_							, end_positions=lowercase_							, training=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				:   str)						->	Union[str, Any]:


   """simple docstring"""







   _UpperCamelCase           =    self.prepare_config_and_inputs()
   ((_UpperCamelCase)      ,						(_UpperCamelCase)      ,						(_UpperCamelCase)      ,						(_UpperCamelCase)      ,						(_UpperCamelCase)      ,						(_UpperCamelCase)      ,						(_UpperCamelCase)      ,						(_UpperCamelCase))           =    config_and_inputs
   _UpperCamelCase           =    {
       "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_tf
class 					_UpperCAmelCase			(     lowerCAmelCase,			lowerCAmelCase,			unittest.TestCase  ):



 '''simple docstring'''




 __A			       =					(
     (
         TFLayoutLMvaModel,
         TFLayoutLMvaForQuestionAnswering,
         TFLayoutLMvaForSequenceClassification,
         TFLayoutLMvaForTokenClassification,
     )
     if is_tf_available()
     else ()
 )
 __A			       =					(
     {'''document-question-answering''': TFLayoutLMvaForQuestionAnswering, '''feature-extraction''': TFLayoutLMvaModel}
     if is_tf_available()
     else {}
 )

 __A			       =					False
 __A			       =					False
 __A			       =					False







 def 		__UpperCAmelCase				(		self				:   List[str]							, lowercase_				:   int							, lowercase_				:   Tuple							, lowercase_				:   List[Any]							, lowercase_				:   Tuple							, lowercase_				:   Dict)						->	List[str]:


   """simple docstring"""







   return True







 def 		__UpperCAmelCase				(		self				:   List[Any]							, lowercase_				:   Tuple							, lowercase_				:   Tuple							, lowercase_				:   Dict=False)						->	dict:


   """simple docstring"""







   _UpperCamelCase           =    copy.deepcopy(lowercase_)

   if model_class in get_values(lowercase_):
     _UpperCamelCase           =    {
         k: tf.tile(tf.expand_dims(lowercase_							, 1)							, (1, self.model_tester.num_choices) + (1,) * (v.ndim - 1))
         if isinstance(lowercase_							, tf.Tensor) and v.ndim > 0
         else v
         for k, v in inputs_dict.items()
     }

   if return_labels:
     if model_class in get_values(lowercase_):
       _UpperCamelCase           =    tf.ones(self.model_tester.batch_size							, dtype=tf.intaa)
     elif model_class in get_values(lowercase_):
       _UpperCamelCase           =    tf.zeros(self.model_tester.batch_size							, dtype=tf.intaa)
       _UpperCamelCase           =    tf.zeros(self.model_tester.batch_size							, dtype=tf.intaa)
     elif model_class in get_values(lowercase_):
       _UpperCamelCase           =    tf.zeros(self.model_tester.batch_size							, dtype=tf.intaa)
     elif model_class in get_values(lowercase_):
       _UpperCamelCase           =    tf.zeros(
           (self.model_tester.batch_size, self.model_tester.text_seq_length)							, dtype=tf.intaa)

   return inputs_dict







 def 		__UpperCAmelCase				(		self				:   List[str])						->	int:


   """simple docstring"""







   _UpperCamelCase           =    TFLayoutLMvaModelTester(self)
   _UpperCamelCase           =    ConfigTester(self							, config_class=lowercase_							, hidden_size=37)







 def 		__UpperCAmelCase				(		self				:   List[str])						->	Dict:


   """simple docstring"""







   self.config_tester.run_common_tests()







 def 		__UpperCAmelCase				(		self				:   Union[str, Any])						->	List[str]:


   """simple docstring"""







   _UpperCamelCase      ,						_UpperCamelCase           =    self.model_tester.prepare_config_and_inputs_for_common()
   for model_class in self.all_model_classes:
     _UpperCamelCase           =    model_class(lowercase_)
     if getattr(lowercase_							, "hf_compute_loss"							, lowercase_):
       # The number of elements in the loss should be the same as the number of elements in the label
       _UpperCamelCase           =    self._prepare_for_class(inputs_dict.copy()							, lowercase_							, return_labels=lowercase_)
       _UpperCamelCase           =    prepared_for_class[
           sorted(prepared_for_class.keys() - inputs_dict.keys()							, reverse=lowercase_)[0]
       ]
       _UpperCamelCase           =    added_label.shape.as_list()[:1]

       # Test that model correctly compute the loss with kwargs
       _UpperCamelCase           =    self._prepare_for_class(inputs_dict.copy()							, lowercase_							, return_labels=lowercase_)
       _UpperCamelCase           =    prepared_for_class.pop("input_ids")

       _UpperCamelCase           =    model(lowercase_							, **lowercase_)[0]
       self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1])

       # Test that model correctly compute the loss when we mask some positions
       _UpperCamelCase           =    self._prepare_for_class(inputs_dict.copy()							, lowercase_							, return_labels=lowercase_)
       _UpperCamelCase           =    prepared_for_class.pop("input_ids")
       if "labels" in prepared_for_class:
         _UpperCamelCase           =    prepared_for_class["labels"].numpy()
         if len(labels.shape) > 1 and labels.shape[1] != 1:
           _UpperCamelCase           =    -100
           _UpperCamelCase           =    tf.convert_to_tensor(lowercase_)
           _UpperCamelCase           =    model(lowercase_							, **lowercase_)[0]
           self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1])
           self.assertTrue(not np.any(np.isnan(loss.numpy())))

                # Test that model correctly compute the loss with a dict
       _UpperCamelCase           =    self._prepare_for_class(inputs_dict.copy()							, lowercase_							, return_labels=lowercase_)
       _UpperCamelCase           =    model(lowercase_)[0]
       self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1])

       # Test that model correctly compute the loss with a tuple
       _UpperCamelCase           =    self._prepare_for_class(inputs_dict.copy()							, lowercase_							, return_labels=lowercase_)

       # Get keys that were added with the _prepare_for_class function
       _UpperCamelCase           =    prepared_for_class.keys() - inputs_dict.keys()
       _UpperCamelCase           =    inspect.signature(model.call).parameters
       _UpperCamelCase           =    list(signature.keys())

       # Create a dictionary holding the location of the tensors in the tuple
       _UpperCamelCase           =    {0: "input_ids"}
       for label_key in label_keys:
         _UpperCamelCase           =    signature_names.index(lowercase_)
         _UpperCamelCase           =    label_key
       _UpperCamelCase           =    sorted(tuple_index_mapping.items())
       # Initialize a list with their default values, update the values and convert to a tuple
       _UpperCamelCase           =    []

       for name in signature_names:
         if name != "kwargs":
           list_input.append(signature[name].default)

       for index, value in sorted_tuple_index_mapping:
         _UpperCamelCase           =    prepared_for_class[value]

       _UpperCamelCase           =    tuple(lowercase_)

       # Send to model
       _UpperCamelCase           =    model(tuple_input[:-1])[0]

       self.assertTrue(loss.shape.as_list() == expected_loss_size or loss.shape.as_list() == [1])







 def 		__UpperCAmelCase				(		self				:   Any)						->	Tuple:


   """simple docstring"""







   (
       (
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						
   )           =    self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_model(lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_)







 def 		__UpperCAmelCase				(		self				:   List[str])						->	Any:


   """simple docstring"""







   (
       (
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						
   )           =    self.model_tester.prepare_config_and_inputs()
   for type in ["absolute", "relative_key", "relative_key_query"]:
     _UpperCamelCase           =    type
     self.model_tester.create_and_check_model(lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_)







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


   """simple docstring"""







   (
       (
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						
   )           =    self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_for_sequence_classification(
       lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_)







 def 		__UpperCAmelCase				(		self				:   Optional[Any])						->	List[str]:


   """simple docstring"""







   (
       (
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						
   )           =    self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_for_token_classification(
       lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_)







 def 		__UpperCAmelCase				(		self				:   Optional[Any])						->	str:


   """simple docstring"""







   (
       (
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						(
       _UpperCamelCase
   )      ,						
   )           =    self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_for_question_answering(
       lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_							, lowercase_)







 @slow
 def 		__UpperCAmelCase				(		self				:   List[str])						->	Dict:


   """simple docstring"""







   for model_name in TF_LAYOUTLMV3_PRETRAINED_MODEL_ARCHIVE_LIST[:1]:
     _UpperCamelCase           =    TFLayoutLMvaModel.from_pretrained(lowercase_)
     self.assertIsNotNone(lowercase_)


def 				lowerCAmelCase__       (			)      ->int:




  '''simple docstring'''

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







@require_tf
class 					_UpperCAmelCase			(     unittest.TestCase  ):



 '''simple docstring'''




 @cached_property
 def 		__UpperCAmelCase				(		self				:   List[Any])						->	Union[str, Any]:


   """simple docstring"""







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







 @slow
 def 		__UpperCAmelCase				(		self				:   int)						->	List[Any]:


   """simple docstring"""







   _UpperCamelCase           =    TFLayoutLMvaModel.from_pretrained("microsoft/layoutlmv3-base")

   _UpperCamelCase           =    self.default_image_processor
   _UpperCamelCase           =    prepare_img()
   _UpperCamelCase           =    image_processor(images=lowercase_							, return_tensors="tf").pixel_values

   _UpperCamelCase           =    tf.constant([[1, 2]])
   _UpperCamelCase           =    tf.expand_dims(tf.constant([[1, 2, 3, 4], [5, 6, 7, 8]])							, axis=0)

   # forward pass
   _UpperCamelCase           =    model(input_ids=lowercase_							, bbox=lowercase_							, pixel_values=lowercase_							, training=lowercase_)

   # verify the logits
   _UpperCamelCase           =    (1, 199, 768)
   self.assertEqual(outputs.last_hidden_state.shape							, lowercase_)

   _UpperCamelCase           =    tf.constant(
       [[-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]])

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





def 				lowerCAmelCase__       (			a__    ,     a__    ,     a__    ,     a__    ,     a__ )      ->int:




  '''simple docstring'''

  if index == number_of_items:
    return 0
  _UpperCamelCase           =    0
  _UpperCamelCase           =    0
  _UpperCamelCase           =    knapsack(a__    ,     a__    ,     a__    ,     a__    ,     index + 1 )
  if weights[index] <= max_weight:
    _UpperCamelCase           =    values[index] + knapsack(
        a__    ,     a__    ,     a__    ,     max_weight - weights[index]    ,     index + 1 )
  return max(a__    ,     a__ )


if __name__ == "__main__":
   import doctest

   doctest.testmod()




