





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 			A_ :
	def __init__(					self							,      _A							,      _A=1_3							,      _A=7							,      _A=True							,      _A=True							,      _A=True							,      _A=True							,      _A=9_9							,      _A=3_2							,      _A=5							,      _A=4							,      _A=3_7							,      _A="gelu"							,      _A=0.1							,      _A=0.1							,      _A=5_1_2							,      _A=1_6							,      _A=2							,      _A=0.02							,      _A=3							,      _A=None							,      _A=2_0							,      _A=3_0							,      _A=2							,      _A=2							,      _A=1_0							,      ):






				'''simple docstring'''







				UpperCAmelCase     	=       parent
				UpperCAmelCase     	=       batch_size
				UpperCAmelCase     	=       seq_length
				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     	=       num_labels
				UpperCAmelCase     	=       scope
				UpperCAmelCase     	=       max_xpath_tag_unit_embeddings
				UpperCAmelCase     	=       max_xpath_subs_unit_embeddings
				UpperCAmelCase     	=       tag_pad_id
				UpperCAmelCase     	=       subs_pad_id
				UpperCAmelCase     	=       max_depth
	def   _lowercase       (					self	):






				'''simple docstring'''







				UpperCAmelCase     	=       ids_tensor([self.batch_size, self.seq_length]							,      self.vocab_size	)

				UpperCAmelCase     	=       ids_tensor(
				    [self.batch_size, self.seq_length, self.max_depth]							,      self.max_xpath_tag_unit_embeddings	)

				UpperCAmelCase     	=       ids_tensor(
				    [self.batch_size, self.seq_length, self.max_depth]							,      self.max_xpath_subs_unit_embeddings	)

				UpperCAmelCase     	=       None
				if self.use_input_mask:
							UpperCAmelCase     	=       ids_tensor([self.batch_size, self.seq_length]							,      vocab_size=2	)

				UpperCAmelCase     	=       None
				if self.use_token_type_ids:
							UpperCAmelCase     	=       ids_tensor([self.batch_size, self.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.seq_length]							,      self.num_labels	)

				UpperCAmelCase     	=       self.get_config()

				return (
				    config,
				    input_ids,
				    xpath_tags_seq,
				    xpath_subs_seq,
				    token_type_ids,
				    input_mask,
				    sequence_labels,
				    token_labels,
				)
	def   _lowercase       (					self	):






				'''simple docstring'''







				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   _lowercase       (					self							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      ):






				'''simple docstring'''







				UpperCAmelCase     	=       MarkupLMModel(config=_A	)
				model.to(_A	)
				model.eval()
				print('''Configs:'''							,      model.config.tag_pad_id							,      model.config.subs_pad_id	)
				UpperCAmelCase     	=       model(_A							,      attention_mask=_A							,      token_type_ids=_A	)
				UpperCAmelCase     	=       model(_A							,      token_type_ids=_A	)
				UpperCAmelCase     	=       model(_A	)
				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   _lowercase       (					self							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      ):






				'''simple docstring'''







				UpperCAmelCase     	=       self.num_labels
				UpperCAmelCase     	=       MarkupLMForSequenceClassification(_A	)
				model.to(_A	)
				model.eval()
				UpperCAmelCase     	=       model(
				    _A							,      xpath_tags_seq=_A							,      xpath_subs_seq=_A							,      attention_mask=_A							,      token_type_ids=_A							,      labels=_A							,      )
				self.parent.assertEqual(result.logits.shape							,      (self.batch_size, self.num_labels)	)
	def   _lowercase       (					self							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      ):






				'''simple docstring'''







				UpperCAmelCase     	=       self.num_labels
				UpperCAmelCase     	=       MarkupLMForTokenClassification(config=_A	)
				model.to(_A	)
				model.eval()
				UpperCAmelCase     	=       model(
				    _A							,      xpath_tags_seq=_A							,      xpath_subs_seq=_A							,      attention_mask=_A							,      token_type_ids=_A							,      labels=_A							,      )
				self.parent.assertEqual(result.logits.shape							,      (self.batch_size, self.seq_length, self.num_labels)	)
	def   _lowercase       (					self							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      _A							,      ):






				'''simple docstring'''







				UpperCAmelCase     	=       MarkupLMForQuestionAnswering(config=_A	)
				model.to(_A	)
				model.eval()
				UpperCAmelCase     	=       model(
				    _A							,      xpath_tags_seq=_A							,      xpath_subs_seq=_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   _lowercase       (					self	):






				'''simple docstring'''







				UpperCAmelCase     	=       self.prepare_config_and_inputs()
				(
				    (
				    UpperCAmelCase
				)	,    (
				    UpperCAmelCase
				)	,    (
				    UpperCAmelCase
				)	,    (
				    UpperCAmelCase
				)	,    (
				    UpperCAmelCase
				)	,    (
				    UpperCAmelCase
				)	,    (
				    UpperCAmelCase
				)	,    (
				    UpperCAmelCase
				)	,    
				)     	=       config_and_inputs
				UpperCAmelCase     	=       {
				    '''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 			A_ (a_  ,							a_  ,							unittest.TestCase    ):
	UpperCAmelCase__      =    (
	    (
	        MarkupLMModel,
	        MarkupLMForSequenceClassification,
	        MarkupLMForTokenClassification,
	        MarkupLMForQuestionAnswering,
	    )
	    if is_torch_available()
	    else None
	)
	UpperCAmelCase__      =    (
	    {
	        '''feature-extraction''': MarkupLMModel,
	        '''question-answering''': MarkupLMForQuestionAnswering,
	        '''text-classification''': MarkupLMForSequenceClassification,
	        '''token-classification''': MarkupLMForTokenClassification,
	        '''zero-shot''': MarkupLMForSequenceClassification,
	    }
	    if is_torch_available()
	    else {}
	)
	def   _lowercase       (					self							,      _A							,      _A							,      _A							,      _A							,      _A	):






				'''simple docstring'''







				return True
	def   _lowercase       (					self	):






				'''simple docstring'''







				UpperCAmelCase     	=       MarkupLMModelTester(self	)
				UpperCAmelCase     	=       ConfigTester(self							,      config_class=_A							,      hidden_size=3_7	)
	def   _lowercase       (					self	):






				'''simple docstring'''







				self.config_tester.run_common_tests()
	def   _lowercase       (					self	):






				'''simple docstring'''







				UpperCAmelCase     	=       self.model_tester.prepare_config_and_inputs()
				self.model_tester.create_and_check_model(*_A	)
	def   _lowercase       (					self	):






				'''simple docstring'''







				UpperCAmelCase     	=       self.model_tester.prepare_config_and_inputs()
				self.model_tester.create_and_check_for_sequence_classification(*_A	)
	def   _lowercase       (					self	):






				'''simple docstring'''







				UpperCAmelCase     	=       self.model_tester.prepare_config_and_inputs()
				self.model_tester.create_and_check_for_token_classification(*_A	)







	def   _lowercase       (					self	):






				'''simple docstring'''







				UpperCAmelCase     	=       self.model_tester.prepare_config_and_inputs()
				self.model_tester.create_and_check_for_question_answering(*_A	)





def 		__SCREAMING_SNAKE_CASE						(       )						->       Dict:







			'''simple docstring'''

			UpperCAmelCase     	=       '''
    <!DOCTYPE html>
    <html>
    <head>
    <title>Page Title</title>
    </head>
    <body>

    <h1>This is a Heading</h1>
    <p>This is a paragraph.</p>

    </body>
    </html>
    '''

			return html_string






@require_torch
class 			A_ (unittest.TestCase    ):
	@cached_property
	def   _lowercase       (					self	):






				'''simple docstring'''







				UpperCAmelCase     	=       MarkupLMFeatureExtractor()
				UpperCAmelCase     	=       MarkupLMTokenizer.from_pretrained('''microsoft/markuplm-base'''	)

				return MarkupLMProcessor(_A							,      _A	)







	@slow
	def   _lowercase       (					self	):






				'''simple docstring'''







				UpperCAmelCase     	=       MarkupLMModel.from_pretrained('''microsoft/markuplm-base'''	).to(_A	)

				UpperCAmelCase     	=       self.default_processor

				UpperCAmelCase     	=       processor(prepare_html_string()							,      return_tensors='''pt'''	)
				UpperCAmelCase     	=       inputs.to(_A	)

				# forward pass
				with torch.no_grad():
							UpperCAmelCase     	=       model(**_A	)

				# verify the last hidden states
				UpperCAmelCase     	=       torch.Size([1, 1_4, 7_6_8]	)
				self.assertEqual(outputs.last_hidden_state.shape							,      _A	)

				UpperCAmelCase     	=       torch.tensor(
				    [[0.06_75, -0.00_52, 0.50_01], [-0.22_81, 0.08_02, 0.21_92], [-0.05_83, -0.33_11, 0.11_85]]	).to(_A	)

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










import numpy as np





def 		__SCREAMING_SNAKE_CASE						(       UpperCamelCase__    ,    UpperCamelCase__="utf-8"    ,    UpperCamelCase__="surrogatepass"				)						->       Optional[Any]:







			'''simple docstring'''

			UpperCAmelCase     	=       bin(int.from_bytes(text.encode(UpperCamelCase__    ,    UpperCamelCase__				)    ,    '''big'''				)				)[2:]
			return bits.zfill(8 * ((len(UpperCamelCase__				) + 7) // 8)				)





def 		__SCREAMING_SNAKE_CASE						(       UpperCamelCase__    ,    UpperCamelCase__="utf-8"    ,    UpperCamelCase__="surrogatepass"				)						->       str:







			'''simple docstring'''

			UpperCAmelCase     	=       int(UpperCamelCase__    ,    2				)
			return n.to_bytes((n.bit_length() + 7) // 8    ,    '''big'''				).decode(UpperCamelCase__    ,    UpperCamelCase__				) or "\0"





def 		__SCREAMING_SNAKE_CASE						(       UpperCamelCase__    ,    UpperCamelCase__				)						->       Tuple:







			'''simple docstring'''

			if size_par + len(UpperCamelCase__				) <= 2**size_par - (len(UpperCamelCase__				) - 1):
						raise ValueError('''size of parity don\'t match with size of data'''				)

			UpperCAmelCase     	=       []
			UpperCAmelCase     	=       []
			UpperCAmelCase     	=       [bin(UpperCamelCase__				)[2:] for x in range(1    ,    size_par + len(UpperCamelCase__				) + 1				)]

			# sorted information data for the size of the output data
			UpperCAmelCase     	=       []
			# data position template + parity
			UpperCAmelCase     	=       []
			# parity bit counter
			UpperCAmelCase     	=       0
			# counter position of data bits
			UpperCAmelCase     	=       0

			for x in range(1    ,    size_par + len(UpperCamelCase__				) + 1				):
						# Performs a template of bit positions - who should be given,
						# and who should be parity
						if qtd_bp < size_par:
									if (np.log(UpperCamelCase__				) / np.log(2				)).is_integer():
												data_out_gab.append('''P'''				)
												UpperCAmelCase     	=       qtd_bp + 1
									else:
												data_out_gab.append('''D'''				)
						else:
									data_out_gab.append('''D'''				)

						# Sorts the data to the new output size
						if data_out_gab[-1] == "D":
									data_ord.append(data[cont_data]				)
									cont_data += 1
						else:
									data_ord.append(UpperCamelCase__				)

    # Calculates parity
			UpperCAmelCase     	=       0  # parity bit counter
			for bp in range(1    ,    size_par + 1				):
						# Bit counter one for a given parity
						UpperCAmelCase     	=       0
						# counter to control the loop reading
						UpperCAmelCase     	=       0
						for x in data_ord:
									if x is not None:
												try:
															UpperCAmelCase     	=       (bin_pos[cont_loop])[-1 * (bp)]
												except IndexError:
															UpperCAmelCase     	=       '''0'''
												if aux == "1" and x == "1":
															cont_bo += 1
									cont_loop += 1
						parity.append(cont_bo % 2				)

						qtd_bp += 1

			# Mount the message
			UpperCAmelCase     	=       0  # parity bit counter
			for x in range(0    ,    size_par + len(UpperCamelCase__				)				):
						if data_ord[x] is None:
									data_out.append(str(parity[cont_bp]				)				)
									cont_bp += 1
						else:
									data_out.append(data_ord[x]				)

			return data_out





def 		__SCREAMING_SNAKE_CASE						(       UpperCamelCase__    ,    UpperCamelCase__				)						->       Optional[int]:







			'''simple docstring'''

			UpperCAmelCase     	=       []
			# Parity bit counter
			UpperCAmelCase     	=       0
			# Counter p data bit reading
			UpperCAmelCase     	=       0
			# list of parity received
			UpperCAmelCase     	=       []
			UpperCAmelCase     	=       []

			for x in range(1    ,    len(UpperCamelCase__				) + 1				):
						# Performs a template of bit positions - who should be given,
						#  and who should be parity
						if qtd_bp < size_par and (np.log(UpperCamelCase__				) / np.log(2				)).is_integer():
									data_out_gab.append('''P'''				)
									UpperCAmelCase     	=       qtd_bp + 1
						else:
									data_out_gab.append('''D'''				)

						# Sorts the data to the new output size
						if data_out_gab[-1] == "D":
									data_output.append(data[cont_data]				)
						else:
									parity_received.append(data[cont_data]				)
						cont_data += 1

			# -----------calculates the parity with the data
			UpperCAmelCase     	=       []
			UpperCAmelCase     	=       []
			UpperCAmelCase     	=       [bin(UpperCamelCase__				)[2:] for x in range(1    ,    size_par + len(UpperCamelCase__				) + 1				)]

			#  sorted information data for the size of the output data
			UpperCAmelCase     	=       []
			# Data position feedback + parity
			UpperCAmelCase     	=       []
			# Parity bit counter
			UpperCAmelCase     	=       0
			# Counter p data bit reading
			UpperCAmelCase     	=       0

			for x in range(1    ,    size_par + len(UpperCamelCase__				) + 1				):
						# Performs a template position of bits - who should be given,
						# and who should be parity
						if qtd_bp < size_par and (np.log(UpperCamelCase__				) / np.log(2				)).is_integer():
									data_out_gab.append('''P'''				)
									UpperCAmelCase     	=       qtd_bp + 1
						else:
									data_out_gab.append('''D'''				)

						# Sorts the data to the new output size
						if data_out_gab[-1] == "D":
									data_ord.append(data_output[cont_data]				)
									cont_data += 1
						else:
									data_ord.append(UpperCamelCase__				)

    # Calculates parity
			UpperCAmelCase     	=       0  # parity bit counter
			for bp in range(1    ,    size_par + 1				):
						# Bit counter one for a certain parity
						UpperCAmelCase     	=       0
						# Counter to control loop reading
						UpperCAmelCase     	=       0
						for x in data_ord:
									if x is not None:
												try:
															UpperCAmelCase     	=       (bin_pos[cont_loop])[-1 * (bp)]
												except IndexError:
															UpperCAmelCase     	=       '''0'''
												if aux == "1" and x == "1":
															cont_bo += 1
									cont_loop += 1
						parity.append(str(cont_bo % 2				)				)

						qtd_bp += 1

			# Mount the message
			UpperCAmelCase     	=       0  # Parity bit counter
			for x in range(0    ,    size_par + len(UpperCamelCase__				)				):
						if data_ord[x] is None:
									data_out.append(str(parity[cont_bp]				)				)
									cont_bp += 1
						else:
									data_out.append(data_ord[x]				)

			UpperCAmelCase     	=       parity_received == parity
			return data_output, ack



