






import tempfile
import unittest

from transformers import TaConfig, is_torch_available
from transformers.testing_utils import (
    require_sentencepiece,
    require_tokenizers,
    require_torch,
    slow,
    torch_device,
)

from ...generation.test_utils import GenerationTesterMixin
from ...test_modeling_common import ModelTesterMixin, ids_tensor
from ...test_pipeline_mixin import PipelineTesterMixin


if is_torch_available():
    import torch

    from transformers import AutoTokenizer, UMTaForConditionalGeneration, UMTaForQuestionAnswering, UMTaModel





class 		UpperCAmelCase						:





   def __init__(	self       ,     _lowerCAmelCase       ,     _lowerCAmelCase=99       ,     _lowerCAmelCase=13       ,     _lowerCAmelCase=7       ,     _lowerCAmelCase=9       ,     _lowerCAmelCase=True       ,     _lowerCAmelCase=True       ,     _lowerCAmelCase=False       ,     _lowerCAmelCase=32       ,     _lowerCAmelCase=5       ,     _lowerCAmelCase=4       ,     _lowerCAmelCase=37       ,     _lowerCAmelCase=8       ,     _lowerCAmelCase=0.1       ,     _lowerCAmelCase=0.002       ,     _lowerCAmelCase=1       ,     _lowerCAmelCase=0       ,     _lowerCAmelCase=0       ,     _lowerCAmelCase=None       ,     _lowerCAmelCase=None       ,     ):
         _lowerCAmelCase 			=  parent
         _lowerCAmelCase 			=  batch_size
         _lowerCAmelCase 			=  encoder_seq_length
         _lowerCAmelCase 			=  decoder_seq_length
         # For common tests
         _lowerCAmelCase 			=  self.decoder_seq_length
         _lowerCAmelCase 			=  is_training
         _lowerCAmelCase 			=  use_attention_mask
         _lowerCAmelCase 			=  use_labels
         _lowerCAmelCase 			=  vocab_size
         _lowerCAmelCase 			=  hidden_size
         _lowerCAmelCase 			=  num_hidden_layers
         _lowerCAmelCase 			=  num_attention_heads
         _lowerCAmelCase 			=  d_ff
         _lowerCAmelCase 			=  relative_attention_num_buckets
         _lowerCAmelCase 			=  dropout_rate
         _lowerCAmelCase 			=  initializer_factor
         _lowerCAmelCase 			=  eos_token_id
         _lowerCAmelCase 			=  pad_token_id
         _lowerCAmelCase 			=  decoder_start_token_id
         _lowerCAmelCase 			=  None
         _lowerCAmelCase 			=  decoder_layers





   def 	__lowerCAmelCase							(	self			):
         return TaConfig.from_pretrained('''google/umt5-base'''			)





   def 	__lowerCAmelCase							(	self       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     _lowerCAmelCase=None       ,     _lowerCAmelCase=None       ,     _lowerCAmelCase=None       ,     _lowerCAmelCase=None       ,     _lowerCAmelCase=None       ,     ):
         if attention_mask is None:
               _lowerCAmelCase 			=  input_ids.ne(config.pad_token_id			)
         if decoder_attention_mask is None:
               _lowerCAmelCase 			=  decoder_input_ids.ne(config.pad_token_id			)
         if head_mask is None:
               _lowerCAmelCase 			=  torch.ones(config.num_hidden_layers       ,     config.num_attention_heads       ,     device=UpperCAmelCase__			)
         if decoder_head_mask is None:
               _lowerCAmelCase 			=  torch.ones(config.num_decoder_layers       ,     config.num_attention_heads       ,     device=UpperCAmelCase__			)
         if cross_attn_head_mask is None:
               _lowerCAmelCase 			=  torch.ones(
                   config.num_decoder_layers       ,     config.num_attention_heads       ,     device=UpperCAmelCase__			)
         return {
             "input_ids": input_ids,
             "decoder_input_ids": decoder_input_ids,
             "attention_mask": attention_mask,
             "decoder_attention_mask": decoder_attention_mask,
             "head_mask": head_mask,
             "decoder_head_mask": decoder_head_mask,
             "cross_attn_head_mask": cross_attn_head_mask,
         }





   def 	__lowerCAmelCase							(	self			):
         _lowerCAmelCase 			=  ids_tensor([self.batch_size, self.encoder_seq_length]       ,     self.vocab_size			)
         _lowerCAmelCase 			=  ids_tensor([self.batch_size, self.decoder_seq_length]       ,     self.vocab_size			)

         # we need to clamp the input ids here to avoid having pad token in between
         # this is because for NllbMoe the position_ids are prepared such that
         # all pad tokens have pos id = 2 and rest are between 2..seq_length
         # and the seq_length here is seq_length - num_pad_tokens
         # but when using past, there is no way of knowing if the past input ids had
         # pad tokens in them, which results in incorrect seq_lenth and which in turn results in
         # position_ids being off by num_pad_tokens in past input
         _lowerCAmelCase 			=  input_ids.clamp(self.pad_token_id + 1			)
         _lowerCAmelCase 			=  decoder_input_ids.clamp(self.pad_token_id + 1			)

         _lowerCAmelCase 			=  self.get_config()
         _lowerCAmelCase 			=  config.num_attention_heads
         _lowerCAmelCase 			=  self.prepare_inputs_dict(UpperCAmelCase__       ,     UpperCAmelCase__       ,     UpperCAmelCase__			)
         return config, input_dict





   def 	__lowerCAmelCase							(	self			):
         _lowerCAmelCase 			=  self.prepare_config_and_inputs()
         return config, inputs_dict





   def 	__lowerCAmelCase							(	self			):
         return TaConfig(
             vocab_size=166       ,     d_model=self.hidden_size       ,     d_ff=self.d_ff       ,     d_kv=self.hidden_size // self.num_attention_heads       ,     num_layers=self.num_hidden_layers       ,     num_decoder_layers=self.decoder_layers       ,     num_heads=self.num_attention_heads       ,     relative_attention_num_buckets=self.relative_attention_num_buckets       ,     dropout_rate=self.dropout_rate       ,     initializer_factor=self.initializer_factor       ,     eos_token_id=self.eos_token_id       ,     bos_token_id=self.pad_token_id       ,     pad_token_id=self.pad_token_id       ,     decoder_start_token_id=self.decoder_start_token_id       ,     )





   def 	__lowerCAmelCase							(	self			):
         return TaConfig(
             vocab_size=self.vocab_size       ,     d_model=self.hidden_size       ,     d_ff=self.d_ff       ,     d_kv=self.hidden_size // self.num_attention_heads       ,     num_layers=self.num_hidden_layers       ,     num_decoder_layers=self.decoder_layers       ,     num_heads=self.num_attention_heads       ,     relative_attention_num_buckets=self.relative_attention_num_buckets       ,     dropout_rate=self.dropout_rate       ,     initializer_factor=self.initializer_factor       ,     eos_token_id=self.eos_token_id       ,     bos_token_id=self.pad_token_id       ,     pad_token_id=self.pad_token_id       ,     decoder_start_token_id=self.decoder_start_token_id       ,     )





   def 	__lowerCAmelCase							(	self       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     ):
         _lowerCAmelCase 			=  UMTaModel(config=UpperCAmelCase__			)
         model.to(UpperCAmelCase__			)
         model.eval()
         _lowerCAmelCase 			=  model(
             input_ids=UpperCAmelCase__       ,     decoder_input_ids=UpperCAmelCase__       ,     attention_mask=UpperCAmelCase__       ,     decoder_attention_mask=UpperCAmelCase__       ,     )
         _lowerCAmelCase 			=  model(input_ids=UpperCAmelCase__       ,     decoder_input_ids=UpperCAmelCase__			)
         _lowerCAmelCase 			=  result.last_hidden_state
         _lowerCAmelCase 			=  result.past_key_values
         _lowerCAmelCase 			=  result.encoder_last_hidden_state

         self.parent.assertEqual(encoder_output.size()       ,     (self.batch_size, self.encoder_seq_length, self.hidden_size)			)
         self.parent.assertEqual(decoder_output.size()       ,     (self.batch_size, self.decoder_seq_length, self.hidden_size)			)
         # There should be `num_layers` key value embeddings stored in decoder_past
         self.parent.assertEqual(len(UpperCAmelCase__			)       ,     config.num_layers			)
         # There should be a self attn key, a self attn value, a cross attn key and a cross attn value stored in each decoder_past tuple
         self.parent.assertEqual(len(decoder_past[0]			)       ,     4			)





   def 	__lowerCAmelCase							(	self       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     ):
         _lowerCAmelCase 			=  UMTaModel(config=UpperCAmelCase__			).get_decoder().to(UpperCAmelCase__			).eval()
         # first forward pass
         _lowerCAmelCase 			=  model(UpperCAmelCase__       ,     use_cache=UpperCAmelCase__			)
         _lowerCAmelCase 			=  model(UpperCAmelCase__			)
         _lowerCAmelCase 			=  model(UpperCAmelCase__       ,     use_cache=UpperCAmelCase__			)

         self.parent.assertTrue(len(UpperCAmelCase__			) == len(UpperCAmelCase__			)			)
         self.parent.assertTrue(len(UpperCAmelCase__			) == len(UpperCAmelCase__			) + 1			)

         _lowerCAmelCase 			=  outputs.to_tuple()

         # create hypothetical next token and extent to next_input_ids
         _lowerCAmelCase 			=  ids_tensor((self.batch_size, 1)       ,     config.vocab_size			)

         # append to next input_ids and
         _lowerCAmelCase 			=  torch.cat([input_ids, next_tokens]       ,     dim=-1			)

         _lowerCAmelCase 			=  model(UpperCAmelCase__			)['''last_hidden_state''']
         _lowerCAmelCase 			=  model(UpperCAmelCase__       ,     past_key_values=UpperCAmelCase__			)['''last_hidden_state''']

         # select random slice
         _lowerCAmelCase 			=  ids_tensor((1,)       ,     output_from_past.shape[-1]			).item()
         _lowerCAmelCase 			=  output_from_no_past[:, -1, random_slice_idx].detach()
         _lowerCAmelCase 			=  output_from_past[:, 0, random_slice_idx].detach()

         # test that outputs are equal for slice
         self.parent.assertTrue(torch.allclose(UpperCAmelCase__       ,     UpperCAmelCase__       ,     atol=1E-3			)			)





   def 	__lowerCAmelCase							(	self       ,     _lowerCAmelCase       ,     _lowerCAmelCase       ,     ):
         _lowerCAmelCase 			=  UMTaModel(config=UpperCAmelCase__			).to(UpperCAmelCase__			).half().eval()
         _lowerCAmelCase 			=  model(**UpperCAmelCase__			)['''last_hidden_state''']
         self.parent.assertFalse(torch.isnan(UpperCAmelCase__			).any().item()			)






@require_torch
class 		UpperCAmelCase						(						snake_case_       ,snake_case_       ,snake_case_       ,unittest.TestCase				):
   SCREAMING_SNAKE_CASE__							=     (
       (UMTaModel, UMTaForConditionalGeneration, UMTaForQuestionAnswering) if is_torch_available() else ()
   )
   SCREAMING_SNAKE_CASE__							=     (UMTaForConditionalGeneration,) if is_torch_available() else ()
   SCREAMING_SNAKE_CASE__							=     (
       {
           'conversational': UMTaForConditionalGeneration,
           'feature-extraction': UMTaModel,
           'summarization': UMTaForConditionalGeneration,
           'text2text-generation': UMTaForConditionalGeneration,
           'translation': UMTaForConditionalGeneration,
           'question-answering': UMTaForQuestionAnswering,
       }
       if is_torch_available()
       else {}
   )
   SCREAMING_SNAKE_CASE__							=     True
   SCREAMING_SNAKE_CASE__							=     False
   SCREAMING_SNAKE_CASE__							=     False
   SCREAMING_SNAKE_CASE__							=     True
   SCREAMING_SNAKE_CASE__							=     True
   # The small UMT5 model needs higher percentages for CPU/MP tests
   SCREAMING_SNAKE_CASE__							=     [0.8, 0.9]





   def 	__lowerCAmelCase							(	self			):
         _lowerCAmelCase 			=  UMTaModelTester(self			)





   @unittest.skip('''Test has a segmentation fault on torch 1.8.0'''			)
   def 	__lowerCAmelCase							(	self			):
         _lowerCAmelCase 			=  self.model_tester.prepare_config_and_inputs()
         _lowerCAmelCase 			=  UMTaModel(config_and_inputs[0]			).to(UpperCAmelCase__			)
         with tempfile.TemporaryDirectory() as tmpdirname:
               torch.onnx.export(
                   UpperCAmelCase__       ,     (config_and_inputs[1], config_and_inputs[3], config_and_inputs[2])       ,     F'''{tmpdirname}/t5_test.onnx'''       ,     export_params=UpperCAmelCase__       ,     opset_version=9       ,     input_names=['''input_ids''', '''decoder_input_ids''']       ,     )





   @unittest.skipIf(torch_device == '''cpu'''       ,     '''Cant do half precision'''			)
   def 	__lowerCAmelCase							(	self			):
         _lowerCAmelCase 			=  self.model_tester.prepare_config_and_inputs()
         self.model_tester.create_and_check_model_fpaa_forward(*UpperCAmelCase__			)





   def 	__lowerCAmelCase							(	self			):
         _lowerCAmelCase 			=  ['''encoder_attentions''', '''decoder_attentions''', '''cross_attentions''']
         _lowerCAmelCase 			=  self.model_tester.prepare_config_and_inputs()
         _lowerCAmelCase 			=  config_and_inputs[0]
         _lowerCAmelCase 			=  UMTaForConditionalGeneration(UpperCAmelCase__			).eval()
         model.to(UpperCAmelCase__			)

         _lowerCAmelCase 			=  {
             '''head_mask''': torch.zeros(config.num_layers       ,     config.num_heads       ,     device=UpperCAmelCase__			),
             '''decoder_head_mask''': torch.zeros(config.num_decoder_layers       ,     config.num_heads       ,     device=UpperCAmelCase__			),
             '''cross_attn_head_mask''': torch.zeros(config.num_decoder_layers       ,     config.num_heads       ,     device=UpperCAmelCase__			),
         }

         for attn_name, (name, mask) in zip(UpperCAmelCase__       ,     head_masking.items()			):
               _lowerCAmelCase 			=  {name: mask}
               # Explicitly pass decoder_head_mask as it is required from T5 model when head_mask specified
               if name == "head_mask":
                     _lowerCAmelCase 			=  torch.ones(
                         config.num_decoder_layers       ,     config.num_heads       ,     device=UpperCAmelCase__			)

               _lowerCAmelCase 			=  model.generate(
                   config_and_inputs[1]['''input_ids''']       ,     num_beams=1       ,     max_length=3       ,     output_attentions=UpperCAmelCase__       ,     return_dict_in_generate=UpperCAmelCase__       ,     **UpperCAmelCase__       ,     )
               # We check the state of decoder_attentions and cross_attentions just from the last step
               _lowerCAmelCase 			=  out[attn_name] if attn_name == attention_names[0] else out[attn_name][-1]
               self.assertEqual(sum([w.sum().item() for w in attn_weights]			)       ,     0.0			)





   @unittest.skip('''Does not work on the tiny model as we keep hitting edge cases.'''			)
   def 	__lowerCAmelCase							(	self			):
         pass






@require_torch
@require_sentencepiece
@require_tokenizers
class 		UpperCAmelCase						(						unittest.TestCase				):





   @slow
   @unittest.skip(
       '''Unless we stop stripping left and right by default for all special tokens, the expected ids obtained here will not match the original ones. Wait for https://github.com/huggingface/transformers/pull/23909 to be merged'''			)
   def 	__lowerCAmelCase							(	self			):
         _lowerCAmelCase 			=  UMTaForConditionalGeneration.from_pretrained('''google/umt5-small'''       ,     return_dict=UpperCAmelCase__			).to(UpperCAmelCase__			)
         _lowerCAmelCase 			=  AutoTokenizer.from_pretrained('''google/umt5-small'''       ,     use_fast=UpperCAmelCase__       ,     legacy=UpperCAmelCase__			)
         _lowerCAmelCase 			=  [
             '''Bonjour monsieur <extra_id_0> bien <extra_id_1>.''',
             '''No se como puedo <extra_id_0>.''',
             '''This is the reason why we <extra_id_0> them.''',
             '''The <extra_id_0> walks in <extra_id_1>, seats''',
             '''A <extra_id_0> walks into a bar and orders a <extra_id_1> with <extra_id_2> pinch of <extra_id_3>.''',
         ]
         _lowerCAmelCase 			=  tokenizer(UpperCAmelCase__       ,     return_tensors='''pt'''       ,     padding=UpperCAmelCase__			).input_ids
         # fmt: off
         _lowerCAmelCase 			=  torch.tensor(
             [
                 [ 38_530, 210_703, 256_299, 1_410, 256_298, 274, 1, 0,0, 0, 0, 0, 0, 0, 0, 0,0, 0],
                 [   826, 321, 671, 25_922, 256_299, 274, 1, 0,0, 0, 0, 0, 0, 0, 0, 0,0, 0],
                 [  1_460, 339, 312, 19_014, 10_620, 758, 256_299, 2_355,274, 1, 0, 0, 0, 0, 0, 0,0, 0],
                 [   517, 256_299, 14_869, 281, 301, 256_298, 275, 119_983,1, 0, 0, 0, 0, 0, 0, 0,0, 0],
                 [   320, 256_299, 14_869, 281, 2_234, 289, 2_275, 333,61_391, 289, 256_298, 543, 256_297, 168_714, 329, 256_296,274, 1],
             ]			)
         # fmt: on
         torch.testing.assert_allclose(UpperCAmelCase__       ,     UpperCAmelCase__			)

         _lowerCAmelCase 			=  model.generate(input_ids.to(UpperCAmelCase__			)			)
         _lowerCAmelCase 			=  [
             '''<pad><extra_id_0> et<extra_id_1> [eod] <extra_id_2><extra_id_55>.. [eod] 💐 💐 💐 💐 💐 💐 💐 💐 💐 💐 💐 <extra_id_56>ajšietosto<extra_id_56>lleux<extra_id_19><extra_id_6>ajšie</s>''',
             '''<pad><extra_id_0>.<extra_id_1>.,<0x0A>...spech <0x0A><extra_id_20> <extra_id_21></s><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad>''',
             '''<pad><extra_id_0> are not going to be a part of the world. We are not going to be a part of<extra_id_1> and<extra_id_2><0x0A><extra_id_48>.<extra_id_48></s><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad>''',
             '''<pad><extra_id_0> door<extra_id_1>, the door<extra_id_2> 피해[/</s><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad>''',
             '''<pad><extra_id_0>nyone who<extra_id_1> drink<extra_id_2> a<extra_id_3> alcohol<extra_id_4> A<extra_id_5> A. This<extra_id_6> I<extra_id_7><extra_id_52><extra_id_53></s><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad><pad>''',
         ]
         _lowerCAmelCase 			=  tokenizer.batch_decode(UpperCAmelCase__			)
         self.assertEqual(UpperCAmelCase__       ,     UpperCAmelCase__			)




def 							UpperCAmelCase__		(				_SCREAMING_SNAKE_CASE   :	Optional[Any]				)->Any:  # noqa: E741
      _lowerCAmelCase 			=  len(_SCREAMING_SNAKE_CASE				)
      _lowerCAmelCase 			=  0
      _lowerCAmelCase 			=  [0] * n
      _lowerCAmelCase 			=  [False] * n
      _lowerCAmelCase 			=  [False] * n

      def dfs(_SCREAMING_SNAKE_CASE   :	List[str]     ,				_SCREAMING_SNAKE_CASE   :	List[Any]     ,				_SCREAMING_SNAKE_CASE   :	Optional[int]     ,				_SCREAMING_SNAKE_CASE   :	int				):
            if parent == root:
                  out_edge_count += 1
            _lowerCAmelCase 			=  True
            _lowerCAmelCase 			=  at

            for to in l[at]:
                  if to == parent:
                        pass
                  elif not visited[to]:
                        _lowerCAmelCase 			=  dfs(_SCREAMING_SNAKE_CASE     ,				_SCREAMING_SNAKE_CASE     ,				_SCREAMING_SNAKE_CASE     ,				_SCREAMING_SNAKE_CASE				)
                        _lowerCAmelCase 			=  min(low[at]     ,				low[to]				)

                        # AP found via bridge
                        if at < low[to]:
                              _lowerCAmelCase 			=  True
                        # AP found via cycle
                        if at == low[to]:
                              _lowerCAmelCase 			=  True
                  else:
                        _lowerCAmelCase 			=  min(low[at]     ,				_SCREAMING_SNAKE_CASE				)
            return out_edge_count

      for i in range(_SCREAMING_SNAKE_CASE				):
            if not visited[i]:
                  _lowerCAmelCase 			=  0
                  _lowerCAmelCase 			=  dfs(_SCREAMING_SNAKE_CASE     ,				_SCREAMING_SNAKE_CASE     ,				-1     ,				_SCREAMING_SNAKE_CASE				)
                  _lowerCAmelCase 			=  out_edge_count > 1

      for x in range(len(_SCREAMING_SNAKE_CASE				)				):
            if is_art[x] is True:
                  print(_SCREAMING_SNAKE_CASE				)


# Adjacency list of graph
UpperCAmelCase_									=							{
    0: [1, 2],
    1: [0, 2],
    2: [0, 1, 3, 5],
    3: [2, 4],
    4: [3],
    5: [2, 6, 8],
    6: [5, 7],
    7: [6, 8],
    8: [5, 7],
}


compute_ap(data)