



"""simple docstring"""






from __future__ import absolute_import, division, print_function, unicode_literals

from torch import nn
from torch.nn import CrossEntropyLoss, MSELoss

from transformers import RobertaConfig
from transformers.file_utils import add_start_docstrings, add_start_docstrings_to_model_forward
from transformers.models.roberta.modeling_roberta import (
    ROBERTA_INPUTS_DOCSTRING,
    ROBERTA_START_DOCSTRING,
    RobertaEmbeddings,
)

from .modeling_highway_bert import BertPreTrainedModel, DeeBertModel, HighwayException, entropy






@add_start_docstrings(
    "The RoBERTa Model transformer with early exiting (DeeRoBERTa). "    ,	_lowercase    ,	)
class 			__snake_case			(      _lowercase):
  snake_case__							:  Any         =		RobertaConfig
  snake_case__							:  Optional[Any]         =		"roberta"




  def __init__(					self	:		int		,   __lowerCAmelCase	:		Optional[int]						):






         """simple docstring"""






         super().__init__(__lowerCAmelCase						)

         _lowerCamelCase		:							Optional[int]            =					RobertaEmbeddings(__lowerCAmelCase						)
         self.init_weights()






@add_start_docstrings(
    "RoBERTa Model (with early exiting - DeeRoBERTa) with a classifier on top,\n    also takes care of multi-layer training. "    ,	_lowercase    ,	)
class 			__snake_case			(      _lowercase):
  snake_case__							:  int         =		RobertaConfig
  snake_case__							:  Any         =		"roberta"




  def __init__(					self	:		List[str]		,   __lowerCAmelCase	:		List[str]						):






         """simple docstring"""






         super().__init__(__lowerCAmelCase						)
         _lowerCamelCase		:							Tuple            =					config.num_labels
         _lowerCamelCase		:							str            =					config.num_hidden_layers

         _lowerCamelCase		:							int            =					DeeRobertaModel(__lowerCAmelCase						)
         _lowerCamelCase		:							Optional[int]            =					nn.Dropout(config.hidden_dropout_prob						)
         _lowerCamelCase		:							Optional[int]            =					nn.Linear(config.hidden_size		,   self.config.num_labels						)




  @add_start_docstrings_to_model_forward(__lowerCAmelCase						)
  def 		SCREAMING_SNAKE_CASE							(					self	:		List[Any]		,   __lowerCAmelCase	:		List[str]=None		,   __lowerCAmelCase	:		Tuple=None		,   __lowerCAmelCase	:		int=None		,   __lowerCAmelCase	:		List[str]=None		,   __lowerCAmelCase	:		Any=None		,   __lowerCAmelCase	:		List[str]=None		,   __lowerCAmelCase	:		Optional[Any]=None		,   __lowerCAmelCase	:		Optional[Any]=-1		,   __lowerCAmelCase	:		Optional[int]=False		,   ):






         """simple docstring"""






         _lowerCamelCase		:							str            =					self.num_layers
         try:
                _lowerCamelCase		:							List[Any]            =					self.roberta(
                    __lowerCAmelCase		,   attention_mask=__lowerCAmelCase		,   token_type_ids=__lowerCAmelCase		,   position_ids=__lowerCAmelCase		,   head_mask=__lowerCAmelCase		,   inputs_embeds=__lowerCAmelCase		,   )

                _lowerCamelCase		:							int            =					outputs[1]

                _lowerCamelCase		:							List[str]            =					self.dropout(__lowerCAmelCase						)
                _lowerCamelCase		:							Optional[int]            =					self.classifier(__lowerCAmelCase						)
                _lowerCamelCase		:							Optional[int]            =					(logits,) + outputs[2:]  # add hidden states and attention if they are here
         except HighwayException as e:
                _lowerCamelCase		:							Optional[int]            =					e.message
                _lowerCamelCase		:							Dict            =					e.exit_layer
                _lowerCamelCase		:							int            =					outputs[0]

         if not self.training:
                _lowerCamelCase		:							Tuple            =					entropy(__lowerCAmelCase						)
                _lowerCamelCase		:							Optional[Any]            =					[]
                _lowerCamelCase		:							Dict            =					[]
         if labels is not None:
                if self.num_labels == 1:
                       #  We are doing regression
                       _lowerCamelCase		:							List[Any]            =					MSELoss()
                       _lowerCamelCase		:							Union[str, Any]            =					loss_fct(logits.view(-1						)		,   labels.view(-1						)						)
                else:
                       _lowerCamelCase		:							Any            =					CrossEntropyLoss()
                       _lowerCamelCase		:							Dict            =					loss_fct(logits.view(-1		,   self.num_labels						)		,   labels.view(-1						)						)

                # work with highway exits
                _lowerCamelCase		:							Union[str, Any]            =					[]
                for highway_exit in outputs[-1]:
                       _lowerCamelCase		:							Optional[int]            =					highway_exit[0]
                       if not self.training:
                              highway_logits_all.append(__lowerCAmelCase						)
                              highway_entropy.append(highway_exit[2]						)
                       if self.num_labels == 1:
                              #  We are doing regression
                              _lowerCamelCase		:							List[str]            =					MSELoss()
                              _lowerCamelCase		:							str            =					loss_fct(highway_logits.view(-1						)		,   labels.view(-1						)						)
                       else:
                              _lowerCamelCase		:							Tuple            =					CrossEntropyLoss()
                              _lowerCamelCase		:							Tuple            =					loss_fct(highway_logits.view(-1		,   self.num_labels						)		,   labels.view(-1						)						)
                       highway_losses.append(__lowerCAmelCase						)

                if train_highway:
                       _lowerCamelCase		:							Optional[int]            =					(sum(highway_losses[:-1]						),) + outputs
                       # exclude the final highway, of course
                else:
                       _lowerCamelCase		:							Any            =					(loss,) + outputs
         if not self.training:
                _lowerCamelCase		:							Optional[int]            =					outputs + ((original_entropy, highway_entropy), exit_layer)
                if output_layer >= 0:
                       _lowerCamelCase		:							Optional[int]            =					(
                           (outputs[0],) + (highway_logits_all[output_layer],) + outputs[2:]
                       )  # use the highway of the last layer

         return outputs  # (loss), logits, (hidden_states), (attentions), entropy




import html

from ...feature_extraction_utils import BatchFeature, FeatureExtractionMixin
from ...utils import is_bsa_available, logging, requires_backends


if is_bsa_available():
    import bsa
    from bsa import BeautifulSoup


__lowerCAmelCase     :	int       			=  logging.get_logger(__name__)




class 			UpperCAmelCase_     (					_A	):


  '''simple docstring'''







  def __init__(					self     :					Union[str, Any]     ,				**UpperCamelCase__     :					Union[str, Any]       )     ->      Union[str, Any]:







    """simple docstring"""






    requires_backends(self     ,				["""bs4"""]       )
    super().__init__(**UpperCamelCase__       )
  def 				_lowercase				(					self     :					Dict     ,				UpperCamelCase__     :					Union[str, Any]       )     ->      Optional[Any]:







    """simple docstring"""






    __magic_name__								=			[]
    __magic_name__								=			[]
    __magic_name__								=			element if element.name else element.parent
    for parent in child.parents:  # type: bs4.element.Tag
      __magic_name__								=			parent.find_all(child.name     ,				recursive=UpperCamelCase__       )
      xpath_tags.append(child.name       )
      xpath_subscripts.append(
          0 if 1 == len(UpperCamelCase__       ) else next(i for i, s in enumerate(UpperCamelCase__     ,				1       ) if s is child       )       )
      __magic_name__								=			parent
    xpath_tags.reverse()
    xpath_subscripts.reverse()
    return xpath_tags, xpath_subscripts
  def 				_lowercase				(					self     :					Union[str, Any]     ,				UpperCamelCase__     :					List[Any]       )     ->      str:







    """simple docstring"""






    __magic_name__								=			BeautifulSoup(UpperCamelCase__     ,				"""html.parser"""       )

    __magic_name__								=			[]
    __magic_name__								=			[]
    __magic_name__								=			[]

    for element in html_code.descendants:
      if type(UpperCamelCase__       ) == bsa.element.NavigableString:
        if type(element.parent       ) != bsa.element.Tag:
          continue

        __magic_name__								=			html.unescape(UpperCamelCase__       ).strip()
        if not text_in_this_tag:
          continue

        all_doc_strings.append(UpperCamelCase__       )

        __magic_name__	,       __magic_name__								=			self.xpath_soup(UpperCamelCase__       )
        stringaxtag_seq.append(UpperCamelCase__       )
        stringaxsubs_seq.append(UpperCamelCase__       )

    if len(UpperCamelCase__       ) != len(UpperCamelCase__       ):
      raise ValueError("""Number of doc strings and xtags does not correspond"""       )
    if len(UpperCamelCase__       ) != len(UpperCamelCase__       ):
      raise ValueError("""Number of doc strings and xsubs does not correspond"""       )

    return all_doc_strings, stringaxtag_seq, stringaxsubs_seq
  def 				_lowercase				(					self     :					List[Any]     ,				UpperCamelCase__     :					Dict     ,				UpperCamelCase__     :					List[Any]       )     ->      Optional[Any]:







    """simple docstring"""






    __magic_name__								=			""""""
    for tagname, subs in zip(UpperCamelCase__     ,				UpperCamelCase__       ):
      xpath += F'''/{tagname}'''
      if subs != 0:
        xpath += F'''[{subs}]'''
    return xpath





  def __call__(					self     :					str     ,				UpperCamelCase__     :					Tuple       )     ->      BatchFeature:







    """simple docstring"""






    __magic_name__								=			False

    # Check that strings has a valid type
    if isinstance(UpperCamelCase__     ,				UpperCamelCase__       ):
      __magic_name__								=			True
    elif isinstance(UpperCamelCase__     ,				(list, tuple)       ):
      if len(UpperCamelCase__       ) == 0 or isinstance(html_strings[0]     ,				UpperCamelCase__       ):
        __magic_name__								=			True

    if not valid_strings:
      raise ValueError(
          """HTML strings must of type `str`, `List[str]` (batch of examples), """
          F'''but is of type {type(UpperCamelCase__       )}.'''       )

    __magic_name__								=			bool(isinstance(UpperCamelCase__     ,				(list, tuple)       ) and (isinstance(html_strings[0]     ,				UpperCamelCase__       ))       )

    if not is_batched:
      __magic_name__								=			[html_strings]

    # Get nodes + xpaths
    __magic_name__								=			[]
    __magic_name__								=			[]
    for html_string in html_strings:
      __magic_name__	,       __magic_name__	,       __magic_name__								=			self.get_three_from_single(UpperCamelCase__       )
      nodes.append(UpperCamelCase__       )
      __magic_name__								=			[]
      for node, tag_list, sub_list in zip(UpperCamelCase__     ,				UpperCamelCase__     ,				UpperCamelCase__       ):
        __magic_name__								=			self.construct_xpath(UpperCamelCase__     ,				UpperCamelCase__       )
        xpath_strings.append(UpperCamelCase__       )
      xpaths.append(UpperCamelCase__       )

    # return as Dict
    __magic_name__								=			{"""nodes""": nodes, """xpaths""": xpaths}
    __magic_name__								=			BatchFeature(data=UpperCamelCase__     ,				tensor_type=UpperCamelCase__       )

    return encoded_inputs

