


import unittest

from transformers import MarkupLMConfig, is_torch_available
from transformers.testing_utils import require_torch, slow, torch_device
from transformers.utils import cached_property

from ...test_configuration_common import ConfigTester
from ...test_modeling_common import ModelTesterMixin, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
   import torch

   from transformers import (
       MarkupLMForQuestionAnswering,
       MarkupLMForSequenceClassification,
       MarkupLMForTokenClassification,
       MarkupLMModel,
   )

# TODO check dependencies
from transformers import MarkupLMFeatureExtractor, MarkupLMProcessor, MarkupLMTokenizer






class    UpperCamelCase    :


   '''simple docstring'''







   def __init__(   self      ,							UpperCamelCase_      ,							UpperCamelCase_=13      ,							UpperCamelCase_=7      ,							UpperCamelCase_=True      ,							UpperCamelCase_=True      ,							UpperCamelCase_=True      ,							UpperCamelCase_=True      ,							UpperCamelCase_=99      ,							UpperCamelCase_=32      ,							UpperCamelCase_=5      ,							UpperCamelCase_=4      ,							UpperCamelCase_=37      ,							UpperCamelCase_="gelu"      ,							UpperCamelCase_=0.1      ,							UpperCamelCase_=0.1      ,							UpperCamelCase_=512      ,							UpperCamelCase_=16      ,							UpperCamelCase_=2      ,							UpperCamelCase_=0.02      ,							UpperCamelCase_=3      ,							UpperCamelCase_=None      ,							UpperCamelCase_=20      ,							UpperCamelCase_=30      ,							UpperCamelCase_=2      ,							UpperCamelCase_=2      ,							UpperCamelCase_=10      ,							):
        lowercase_				:Optional[Any]       			=				parent
        lowercase_				:Tuple       			=				batch_size
        lowercase_				:int       			=				seq_length
        lowercase_				:Dict       			=				is_training
        lowercase_				:List[Any]       			=				use_input_mask
        lowercase_				:List[Any]       			=				use_token_type_ids
        lowercase_				:Union[str, Any]       			=				use_labels
        lowercase_				:List[str]       			=				vocab_size
        lowercase_				:int       			=				hidden_size
        lowercase_				:List[Any]       			=				num_hidden_layers
        lowercase_				:Union[str, Any]       			=				num_attention_heads
        lowercase_				:int       			=				intermediate_size
        lowercase_				:List[str]       			=				hidden_act
        lowercase_				:Optional[int]       			=				hidden_dropout_prob
        lowercase_				:str       			=				attention_probs_dropout_prob
        lowercase_				:Optional[Any]       			=				max_position_embeddings
        lowercase_				:Optional[int]       			=				type_vocab_size
        lowercase_				:Tuple       			=				type_sequence_label_size
        lowercase_				:Union[str, Any]       			=				initializer_range
        lowercase_				:List[str]       			=				num_labels
        lowercase_				:int       			=				scope
        lowercase_				:Tuple       			=				max_xpath_tag_unit_embeddings
        lowercase_				:Optional[int]       			=				max_xpath_subs_unit_embeddings
        lowercase_				:Dict       			=				tag_pad_id
        lowercase_				:Dict       			=				subs_pad_id
        lowercase_				:Union[str, Any]       			=				max_depth
   def 						UpperCamelCase     (   self						):
        lowercase_				:List[Any]       			=				ids_tensor([self.batch_size, self.seq_length]      ,							self.vocab_size						)

        lowercase_				:Optional[int]       			=				ids_tensor(
            [self.batch_size, self.seq_length, self.max_depth]      ,							self.max_xpath_tag_unit_embeddings						)

        lowercase_				:Any       			=				ids_tensor(
            [self.batch_size, self.seq_length, self.max_depth]      ,							self.max_xpath_subs_unit_embeddings						)

        lowercase_				:List[str]       			=				None
        if self.use_input_mask:
             lowercase_				:Optional[Any]       			=				ids_tensor([self.batch_size, self.seq_length]      ,							vocab_size=2						)

        lowercase_				:List[str]       			=				None
        if self.use_token_type_ids:
             lowercase_				:int       			=				ids_tensor([self.batch_size, self.seq_length]      ,							self.type_vocab_size						)

        lowercase_				:List[str]       			=				None
        lowercase_				:List[str]       			=				None
        if self.use_labels:
             lowercase_				:int       			=				ids_tensor([self.batch_size]      ,							self.type_sequence_label_size						)
             lowercase_				:List[str]       			=				ids_tensor([self.batch_size, self.seq_length]      ,							self.num_labels						)

        lowercase_				:Any       			=				self.get_config()

        return (
            config,
            input_ids,
            xpath_tags_seq,
            xpath_subs_seq,
            token_type_ids,
            input_mask,
            sequence_labels,
            token_labels,
        )
   def 						UpperCamelCase     (   self						):
        return MarkupLMConfig(
            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      ,							max_xpath_tag_unit_embeddings=self.max_xpath_tag_unit_embeddings      ,							max_xpath_subs_unit_embeddings=self.max_xpath_subs_unit_embeddings      ,							tag_pad_id=self.tag_pad_id      ,							subs_pad_id=self.subs_pad_id      ,							max_depth=self.max_depth      ,							)
   def 						UpperCamelCase     (   self      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							):
        lowercase_				:Dict       			=				MarkupLMModel(config=lowercase_						)
        model.to(lowercase_						)
        model.eval()
        print('''Configs:'''      ,							model.config.tag_pad_id      ,							model.config.subs_pad_id						)
        lowercase_				:List[Any]       			=				model(lowercase_      ,							attention_mask=lowercase_      ,							token_type_ids=lowercase_						)
        lowercase_				:Optional[Any]       			=				model(lowercase_      ,							token_type_ids=lowercase_						)
        lowercase_				:List[str]       			=				model(lowercase_						)
        self.parent.assertEqual(result.last_hidden_state.shape      ,							(self.batch_size, self.seq_length, self.hidden_size)						)
        self.parent.assertEqual(result.pooler_output.shape      ,							(self.batch_size, self.hidden_size)						)
   def 						UpperCamelCase     (   self      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							):
        lowercase_				:Dict       			=				self.num_labels
        lowercase_				:Dict       			=				MarkupLMForSequenceClassification(lowercase_						)
        model.to(lowercase_						)
        model.eval()
        lowercase_				:List[str]       			=				model(
            lowercase_      ,							xpath_tags_seq=lowercase_      ,							xpath_subs_seq=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      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							):
        lowercase_				:int       			=				self.num_labels
        lowercase_				:Tuple       			=				MarkupLMForTokenClassification(config=lowercase_						)
        model.to(lowercase_						)
        model.eval()
        lowercase_				:Optional[int]       			=				model(
            lowercase_      ,							xpath_tags_seq=lowercase_      ,							xpath_subs_seq=lowercase_      ,							attention_mask=lowercase_      ,							token_type_ids=lowercase_      ,							labels=lowercase_      ,							)
        self.parent.assertEqual(result.logits.shape      ,							(self.batch_size, self.seq_length, self.num_labels)						)
   def 						UpperCamelCase     (   self      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							):
        lowercase_				:Union[str, Any]       			=				MarkupLMForQuestionAnswering(config=lowercase_						)
        model.to(lowercase_						)
        model.eval()
        lowercase_				:Optional[Any]       			=				model(
            lowercase_      ,							xpath_tags_seq=lowercase_      ,							xpath_subs_seq=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						):
        lowercase_				:Optional[Any]       			=				self.prepare_config_and_inputs()
        (
            (
            lowercase_							
        )			,					(
            lowercase_							
        )			,					(
            lowercase_							
        )			,					(
            lowercase_							
        )			,					(
            lowercase_							
        )			,					(
            lowercase_							
        )			,					(
            lowercase_							
        )			,					(
            lowercase_							
        )			,												
        )				:Tuple       			=				config_and_inputs
        lowercase_				:Union[str, Any]       			=				{
            '''input_ids''': input_ids,
            '''xpath_tags_seq''': xpath_tags_seq,
            '''xpath_subs_seq''': xpath_subs_seq,
            '''token_type_ids''': token_type_ids,
            '''attention_mask''': input_mask,
        }
        return config, inputs_dict






@require_torch
class    UpperCamelCase    (						SCREAMING_SNAKE_CASE_  ,					SCREAMING_SNAKE_CASE_  ,					unittest.TestCase   ):


   '''simple docstring'''







   lowercase    :		Any	  =(
       (
           MarkupLMModel,
           MarkupLMForSequenceClassification,
           MarkupLMForTokenClassification,
           MarkupLMForQuestionAnswering,
       )
       if is_torch_available()
       else None
   )
   lowercase    :		Tuple	  =(
       {
           "feature-extraction": MarkupLMModel,
           "question-answering": MarkupLMForQuestionAnswering,
           "text-classification": MarkupLMForSequenceClassification,
           "token-classification": MarkupLMForTokenClassification,
           "zero-shot": MarkupLMForSequenceClassification,
       }
       if is_torch_available()
       else {}
   )
   def 						UpperCamelCase     (   self      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_      ,							UpperCamelCase_						):
        # ValueError: Nodes must be of type `List[str]` (single pretokenized example), or `List[List[str]]`
        # (batch of pretokenized examples).
        return True
   def 						UpperCamelCase     (   self						):
        lowercase_				:Dict       			=				MarkupLMModelTester(self						)
        lowercase_				:Any       			=				ConfigTester(self      ,							config_class=lowercase_      ,							hidden_size=37						)
   def 						UpperCamelCase     (   self						):
        self.config_tester.run_common_tests()
   def 						UpperCamelCase     (   self						):
        lowercase_				:Optional[Any]       			=				self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_model(*lowercase_						)
   def 						UpperCamelCase     (   self						):
        lowercase_				:List[Any]       			=				self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_for_sequence_classification(*lowercase_						)
   def 						UpperCamelCase     (   self						):
        lowercase_				:str       			=				self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_for_token_classification(*lowercase_						)




   def 						UpperCamelCase     (   self						):
        lowercase_				:Optional[int]       			=				self.model_tester.prepare_config_and_inputs()
        self.model_tester.create_and_check_for_question_answering(*lowercase_						)




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





     lowercase_				:int       			=				'''\n    <!DOCTYPE html>\n    <html>\n    <head>\n    <title>Page Title</title>\n    </head>\n    <body>\n\n    <h1>This is a Heading</h1>\n    <p>This is a paragraph.</p>\n\n    </body>\n    </html>\n    '''

     return html_string






@require_torch
class    UpperCamelCase    (						unittest.TestCase   ):


   '''simple docstring'''







   @cached_property
   def 						UpperCamelCase     (   self						):
        # TODO use from_pretrained here
        lowercase_				:Dict       			=				MarkupLMFeatureExtractor()
        lowercase_				:Optional[Any]       			=				MarkupLMTokenizer.from_pretrained('''microsoft/markuplm-base'''						)

        return MarkupLMProcessor(lowercase_      ,							lowercase_						)




   @slow
   def 						UpperCamelCase     (   self						):
        lowercase_				:int       			=				MarkupLMModel.from_pretrained('''microsoft/markuplm-base'''						).to(lowercase_						)

        lowercase_				:Any       			=				self.default_processor

        lowercase_				:List[str]       			=				processor(prepare_html_string()      ,							return_tensors='''pt'''						)
        lowercase_				:Optional[Any]       			=				inputs.to(lowercase_						)

        # forward pass
        with torch.no_grad():
             lowercase_				:Dict       			=				model(**lowercase_						)

        # verify the last hidden states
        lowercase_				:List[str]       			=				torch.Size([1, 14, 768]						)
        self.assertEqual(outputs.last_hidden_state.shape      ,							lowercase_						)

        lowercase_				:str       			=				torch.tensor(
            [[0.0675, -0.0052, 0.5001], [-0.2281, 0.0802, 0.2192], [-0.0583, -0.3311, 0.1185]]						).to(lowercase_						)

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



"""simple docstring"""

from typing import SupportsIndex

import numpy as np
from scipy.ndimage import convolve




def 			lowercase__  (    lowerCAmelCase :    np.ndarray       , lowerCAmelCase :    np.ndarray       , lowerCAmelCase :    np.ndarray       )       ->					np.ndarray:






    """simple docstring"""




    UpperCAmelCase  	=    np.stack((horizontal_flow, vertical_flow)       , 2       )

    # Create a grid of all pixel coordinates and subtract the flow to get the
    # target pixels coordinates
    UpperCAmelCase  	=    np.stack(
        np.meshgrid(np.arange(0       , image.shape[1]       )       , np.arange(0       , image.shape[0]       )       )       , 2       )
    UpperCAmelCase  	=    np.round(grid - flow       ).astype(np.intaa       )

    # Find the locations outside of the original image
    UpperCAmelCase  	=    (grid < 0) | (grid >= np.array([image.shape[1], image.shape[0]]       ))
    UpperCAmelCase  	=    0

    UpperCAmelCase  	=    image[grid[:, :, 1], grid[:, :, 0]]

    # Set pixels at invalid locations to 0
    UpperCAmelCase  	=    0

    return warped




def 			lowercase__  (    lowerCAmelCase :    np.ndarray       , lowerCAmelCase :    np.ndarray       , lowerCAmelCase :    SupportsIndex       , lowerCAmelCase :    float | None = None       , )       ->					tuple[np.ndarray, np.ndarray]:






    """simple docstring"""




    if alpha is None:
        UpperCAmelCase  	=    0.1

    # Initialize flow
    UpperCAmelCase  	=    np.zeros_like(lowerCAmelCase       )
    UpperCAmelCase  	=    np.zeros_like(lowerCAmelCase       )

    # Prepare kernels for the calculation of the derivatives and the average velocity
    UpperCAmelCase  	=    np.array([[-1, 1], [-1, 1]]       ) * 0.25
    UpperCAmelCase  	=    np.array([[-1, -1], [1, 1]]       ) * 0.25
    UpperCAmelCase  	=    np.array([[1, 1], [1, 1]]       ) * 0.25
    UpperCAmelCase  	=    np.array(
        [[1 / 12, 1 / 6, 1 / 12], [1 / 6, 0, 1 / 6], [1 / 12, 1 / 6, 1 / 12]]       )

    # Iteratively refine the flow
    for _ in range(lowerCAmelCase       ):
        UpperCAmelCase  	=    warp(lowerCAmelCase       , lowerCAmelCase       , lowerCAmelCase       )
        UpperCAmelCase  	=    convolve(lowerCAmelCase       , lowerCAmelCase       ) + convolve(lowerCAmelCase       , lowerCAmelCase       )
        UpperCAmelCase  	=    convolve(lowerCAmelCase       , lowerCAmelCase       ) + convolve(lowerCAmelCase       , lowerCAmelCase       )
        UpperCAmelCase  	=    convolve(lowerCAmelCase       , lowerCAmelCase       ) + convolve(lowerCAmelCase       , -kernel_t       )

        UpperCAmelCase  	=    convolve(lowerCAmelCase       , lowerCAmelCase       )
        UpperCAmelCase  	=    convolve(lowerCAmelCase       , lowerCAmelCase       )

        # This updates the flow as proposed in the paper (Step 12)
        UpperCAmelCase  	=    (
            derivative_x * avg_horizontal_velocity
            + derivative_y * avg_vertical_velocity
            + derivative_t
        )
        UpperCAmelCase  	=    update / (alpha**2 + derivative_x**2 + derivative_y**2)

        UpperCAmelCase  	=    avg_horizontal_velocity - derivative_x * update
        UpperCAmelCase  	=    avg_vertical_velocity - derivative_y * update

    return horizontal_flow, vertical_flow


if __name__ == "__main__":
   import doctest

   doctest.testmod()



