

"""simple docstring"""




import unittest

from transformers import FunnelConfig, FunnelTokenizer, is_torch_available
from transformers.models.auto import get_values
from transformers.testing_utils import require_sentencepiece, require_tokenizers, require_torch, slow, torch_device

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 (
          MODEL_FOR_PRETRAINING_MAPPING,
          FunnelBaseModel,
          FunnelForMaskedLM,
          FunnelForMultipleChoice,
          FunnelForPreTraining,
          FunnelForQuestionAnswering,
          FunnelForSequenceClassification,
          FunnelForTokenClassification,
          FunnelModel,
      )







class        __lowercase     :

  def __init__(					self						:     Optional[int]   ,A						:     int   ,A						:     List[Any]=13   ,A						:     Dict=7   ,A						:     Tuple=True   ,A						:     Any=True   ,A						:     Tuple=True   ,A						:     List[Any]=True   ,A						:     List[str]=99   ,A						:     Optional[int]=[1, 1, 2]   ,A						:     Tuple=1   ,A						:     Tuple=32   ,A						:     List[str]=4   ,A						:     Union[str, Any]=8   ,A						:     Optional[int]=37   ,A						:     List[Any]="gelu_new"   ,A						:     str=0.1   ,A						:     int=0.1   ,A						:     str=0.0   ,A						:     List[Any]=512   ,A						:     Tuple=3   ,A						:     Union[str, Any]=0.0_2   ,A						:     Dict=3   ,A						:     str=4   ,A						:     Optional[Any]=None   ,A						:     str=False   ,):






   '''simple docstring'''
   UpperCAmelCase__   :					Tuple   				=   parent
   UpperCAmelCase__   :					Optional[int]   				=   batch_size
   UpperCAmelCase__   :					Optional[Any]   				=   seq_length
   UpperCAmelCase__   :					int   				=   is_training
   UpperCAmelCase__   :					List[str]   				=   use_input_mask
   UpperCAmelCase__   :					List[Any]   				=   use_token_type_ids
   UpperCAmelCase__   :					Union[str, Any]   				=   use_labels
   UpperCAmelCase__   :					Dict   				=   vocab_size
   UpperCAmelCase__   :					Tuple   				=   block_sizes
   UpperCAmelCase__   :					List[str]   				=   num_decoder_layers
   UpperCAmelCase__   :					int   				=   d_model
   UpperCAmelCase__   :					int   				=   n_head
   UpperCAmelCase__   :					List[Any]   				=   d_head
   UpperCAmelCase__   :					Union[str, Any]   				=   d_inner
   UpperCAmelCase__   :					int   				=   hidden_act
   UpperCAmelCase__   :					List[Any]   				=   hidden_dropout
   UpperCAmelCase__   :					str   				=   attention_dropout
   UpperCAmelCase__   :					Union[str, Any]   				=   activation_dropout
   UpperCAmelCase__   :					Tuple   				=   max_position_embeddings
   UpperCAmelCase__   :					Dict   				=   type_vocab_size
   UpperCAmelCase__   :					Any   				=   2
   UpperCAmelCase__   :					List[str]   				=   num_labels
   UpperCAmelCase__   :					Union[str, Any]   				=   num_choices
   UpperCAmelCase__   :					Dict   				=   scope
   UpperCAmelCase__   :					str   				=   initializer_std

   # Used in the tests to check the size of the first attention layer
   UpperCAmelCase__   :					int   				=   n_head
   # Used in the tests to check the size of the first hidden state
   UpperCAmelCase__   :					Union[str, Any]   				=   self.d_model
   # Used in the tests to check the number of output hidden states/attentions
   UpperCAmelCase__   :					Optional[Any]   				=   sum(self.block_sizes      ) + (0 if base else self.num_decoder_layers)
   # FunnelModel adds two hidden layers: input embeddings and the sum of the upsampled encoder hidden state with
   # the last hidden state of the first block (which is the first hidden state of the decoder).
   if not base:
    UpperCAmelCase__   :					List[str]   				=   self.num_hidden_layers + 2

  def 				__lowercase    (					self						:     Tuple      ):






   '''simple docstring'''
   UpperCAmelCase__   :					int   				=   ids_tensor([self.batch_size, self.seq_length]   ,self.vocab_size      )

   UpperCAmelCase__   :					Union[str, Any]   				=   None
   if self.use_input_mask:
    UpperCAmelCase__   :					Any   				=   ids_tensor([self.batch_size, self.seq_length]   ,vocab_size=2      )

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

   UpperCAmelCase__   :					Optional[int]   				=   None
   UpperCAmelCase__   :					int   				=   None
   UpperCAmelCase__   :					int   				=   None
   if self.use_labels:
    UpperCAmelCase__   :					int   				=   ids_tensor([self.batch_size]   ,self.type_sequence_label_size      )
    UpperCAmelCase__   :					int   				=   ids_tensor([self.batch_size, self.seq_length]   ,self.num_labels      )
    UpperCAmelCase__   :					Any   				=   ids_tensor([self.batch_size]   ,self.num_choices      )
    UpperCAmelCase__   :					Dict   				=   ids_tensor([self.batch_size, self.seq_length]   ,1      )

   UpperCAmelCase__   :					List[Any]   				=   self.get_config()

   return (
       config,
       input_ids,
       token_type_ids,
       input_mask,
       sequence_labels,
       token_labels,
       choice_labels,
       fake_token_labels,
   )

  def 				__lowercase    (					self						:     Dict      ):






   '''simple docstring'''
   return FunnelConfig(
       vocab_size=self.vocab_size   ,block_sizes=self.block_sizes   ,num_decoder_layers=self.num_decoder_layers   ,d_model=self.d_model   ,n_head=self.n_head   ,d_head=self.d_head   ,d_inner=self.d_inner   ,hidden_act=self.hidden_act   ,hidden_dropout=self.hidden_dropout   ,attention_dropout=self.attention_dropout   ,activation_dropout=self.activation_dropout   ,max_position_embeddings=self.max_position_embeddings   ,type_vocab_size=self.type_vocab_size   ,initializer_std=self.initializer_std   ,)

  def 				__lowercase    (					self						:     List[str]   ,A						:     Optional[Any]   ,A						:     Union[str, Any]   ,A						:     List[str]   ,A						:     Union[str, Any]   ,A						:     List[Any]   ,A						:     List[Any]   ,A						:     int   ,A						:     Tuple   ,):






   '''simple docstring'''
   UpperCAmelCase__   :					Optional[Any]   				=   FunnelModel(config=A      )
   model.to(A      )
   model.eval()
   UpperCAmelCase__   :					List[str]   				=   model(A   ,attention_mask=A   ,token_type_ids=A      )
   UpperCAmelCase__   :					Union[str, Any]   				=   model(A   ,token_type_ids=A      )
   UpperCAmelCase__   :					Tuple   				=   model(A      )
   self.parent.assertEqual(result.last_hidden_state.shape   ,(self.batch_size, self.seq_length, self.d_model)      )

   UpperCAmelCase__   :					List[str]   				=   False
   UpperCAmelCase__   :					str   				=   model(A      )
   self.parent.assertEqual(result.last_hidden_state.shape   ,(self.batch_size, self.seq_length, self.d_model)      )

   UpperCAmelCase__   :					Tuple   				=   False
   UpperCAmelCase__   :					Optional[int]   				=   model(A      )
   self.parent.assertEqual(result.last_hidden_state.shape   ,(self.batch_size, self.seq_length, self.d_model)      )

  def 				__lowercase    (					self						:     List[Any]   ,A						:     Any   ,A						:     Union[str, Any]   ,A						:     int   ,A						:     Dict   ,A						:     int   ,A						:     Tuple   ,A						:     List[str]   ,A						:     List[str]   ,):






   '''simple docstring'''
   UpperCAmelCase__   :					Optional[int]   				=   FunnelBaseModel(config=A      )
   model.to(A      )
   model.eval()
   UpperCAmelCase__   :					Optional[Any]   				=   model(A   ,attention_mask=A   ,token_type_ids=A      )
   UpperCAmelCase__   :					List[Any]   				=   model(A   ,token_type_ids=A      )
   UpperCAmelCase__   :					Any   				=   model(A      )
   self.parent.assertEqual(result.last_hidden_state.shape   ,(self.batch_size, 2, self.d_model)      )

   UpperCAmelCase__   :					List[str]   				=   False
   UpperCAmelCase__   :					Any   				=   model(A      )
   self.parent.assertEqual(result.last_hidden_state.shape   ,(self.batch_size, 3, self.d_model)      )

   UpperCAmelCase__   :					Union[str, Any]   				=   False
   UpperCAmelCase__   :					Optional[int]   				=   model(A      )
   self.parent.assertEqual(result.last_hidden_state.shape   ,(self.batch_size, 2, self.d_model)      )

  def 				__lowercase    (					self						:     Tuple   ,A						:     int   ,A						:     Union[str, Any]   ,A						:     Tuple   ,A						:     Tuple   ,A						:     str   ,A						:     Optional[int]   ,A						:     List[str]   ,A						:     List[Any]   ,):






   '''simple docstring'''
   UpperCAmelCase__   :					Tuple   				=   self.num_labels
   UpperCAmelCase__   :					List[str]   				=   FunnelForPreTraining(config=A      )
   model.to(A      )
   model.eval()
   UpperCAmelCase__   :					str   				=   model(A   ,attention_mask=A   ,token_type_ids=A   ,labels=A      )
   self.parent.assertEqual(result.logits.shape   ,(self.batch_size, self.seq_length)      )

  def 				__lowercase    (					self						:     int   ,A						:     Any   ,A						:     Dict   ,A						:     Any   ,A						:     str   ,A						:     Optional[int]   ,A						:     Any   ,A						:     List[str]   ,A						:     Tuple   ,):






   '''simple docstring'''
   UpperCAmelCase__   :					Tuple   				=   FunnelForMaskedLM(config=A      )
   model.to(A      )
   model.eval()
   UpperCAmelCase__   :					int   				=   model(A   ,attention_mask=A   ,token_type_ids=A   ,labels=A      )
   self.parent.assertEqual(result.logits.shape   ,(self.batch_size, self.seq_length, self.vocab_size)      )

  def 				__lowercase    (					self						:     int   ,A						:     List[str]   ,A						:     Dict   ,A						:     Optional[int]   ,A						:     List[Any]   ,A						:     Optional[Any]   ,A						:     Optional[Any]   ,A						:     Dict   ,A						:     List[str]   ,):






   '''simple docstring'''
   UpperCAmelCase__   :					int   				=   self.num_labels
   UpperCAmelCase__   :					int   				=   FunnelForSequenceClassification(A      )
   model.to(A      )
   model.eval()
   UpperCAmelCase__   :					Union[str, Any]   				=   model(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						:     Tuple   ,A						:     Union[str, Any]   ,A						:     Optional[int]   ,A						:     Dict   ,A						:     List[str]   ,A						:     Optional[Any]   ,A						:     Tuple   ,A						:     Optional[Any]   ,A						:     List[Any]   ,):






   '''simple docstring'''
   UpperCAmelCase__   :					Optional[Any]   				=   self.num_choices
   UpperCAmelCase__   :					str   				=   FunnelForMultipleChoice(config=A      )
   model.to(A      )
   model.eval()
   UpperCAmelCase__   :					List[str]   				=   input_ids.unsqueeze(1      ).expand(-1   ,self.num_choices   ,-1      ).contiguous()
   UpperCAmelCase__   :					List[str]   				=   token_type_ids.unsqueeze(1      ).expand(-1   ,self.num_choices   ,-1      ).contiguous()
   UpperCAmelCase__   :					Union[str, Any]   				=   input_mask.unsqueeze(1      ).expand(-1   ,self.num_choices   ,-1      ).contiguous()
   UpperCAmelCase__   :					List[Any]   				=   model(
       A   ,attention_mask=A   ,token_type_ids=A   ,labels=A   ,)
   self.parent.assertEqual(result.logits.shape   ,(self.batch_size, self.num_choices)      )

  def 				__lowercase    (					self						:     Tuple   ,A						:     Union[str, Any]   ,A						:     Tuple   ,A						:     Dict   ,A						:     Tuple   ,A						:     str   ,A						:     List[Any]   ,A						:     Optional[int]   ,A						:     Any   ,):






   '''simple docstring'''
   UpperCAmelCase__   :					Optional[Any]   				=   self.num_labels
   UpperCAmelCase__   :					Optional[Any]   				=   FunnelForTokenClassification(config=A      )
   model.to(A      )
   model.eval()
   UpperCAmelCase__   :					Tuple   				=   model(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						:     Optional[Any]   ,A						:     int   ,A						:     Optional[int]   ,A						:     Optional[int]   ,A						:     str   ,A						:     int   ,A						:     Any   ,A						:     List[Any]   ,A						:     str   ,):






   '''simple docstring'''
   UpperCAmelCase__   :					int   				=   FunnelForQuestionAnswering(config=A      )
   model.to(A      )
   model.eval()
   UpperCAmelCase__   :					str   				=   model(
       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						:     Tuple      ):






   '''simple docstring'''
   UpperCAmelCase__   :					Any   				=   self.prepare_config_and_inputs()
   (
       (
       UpperCAmelCase__
   )				, (
       UpperCAmelCase__
   )				, (
       UpperCAmelCase__
   )				, (
       UpperCAmelCase__
   )				, (
       UpperCAmelCase__
   )				, (
       UpperCAmelCase__
   )				, (
       UpperCAmelCase__
   )				, (
       UpperCAmelCase__
   )				, 
   )   :					str   				=   config_and_inputs
   UpperCAmelCase__   :					int   				=   {"""input_ids""": input_ids, """token_type_ids""": token_type_ids, """attention_mask""": input_mask}
   return config, inputs_dict







@require_torch
class        __lowercase     (      __lowerCamelCase		,     __lowerCamelCase		,     unittest.TestCase   ):
  snake_case_			    =    False
  snake_case_			    =    False
  snake_case_			    =    (
      (
          FunnelModel,
          FunnelForMaskedLM,
          FunnelForPreTraining,
          FunnelForQuestionAnswering,
          FunnelForTokenClassification,
      )
      if is_torch_available()
      else ()
  )
  snake_case_			    =    (
      {
          """feature-extraction""": (FunnelBaseModel, FunnelModel),
          """fill-mask""": FunnelForMaskedLM,
          """question-answering""": FunnelForQuestionAnswering,
          """text-classification""": FunnelForSequenceClassification,
          """token-classification""": FunnelForTokenClassification,
          """zero-shot""": FunnelForSequenceClassification,
      }
      if is_torch_available()
      else {}
  )

  def 				__lowercase    (					self						:     Optional[Any]   ,A						:     Optional[Any]   ,A						:     str   ,A						:     List[str]=False      ):






   '''simple docstring'''
   UpperCAmelCase__   :					Any   				=   super()._prepare_for_class(A   ,A   ,return_labels=A      )

   if return_labels:
    if model_class in get_values(A      ):
     UpperCAmelCase__   :					Union[str, Any]   				=   torch.zeros(
         (self.model_tester.batch_size, self.model_tester.seq_length)   ,dtype=torch.long   ,device=A      )
   return inputs_dict

  def 				__lowercase    (					self						:     Optional[Any]      ):






   '''simple docstring'''
   UpperCAmelCase__   :					int   				=   FunnelModelTester(self      )
   UpperCAmelCase__   :					str   				=   ConfigTester(self   ,config_class=A      )

  def 				__lowercase    (					self						:     Any      ):






   '''simple docstring'''
   self.config_tester.run_common_tests()

  def 				__lowercase    (					self						:     List[str]      ):






   '''simple docstring'''
   UpperCAmelCase__   :					List[Any]   				=   self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_model(*A      )

  def 				__lowercase    (					self						:     List[Any]      ):






   '''simple docstring'''
   UpperCAmelCase__   :					Optional[int]   				=   self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_for_pretraining(*A      )

  def 				__lowercase    (					self						:     List[str]      ):






   '''simple docstring'''
   UpperCAmelCase__   :					List[str]   				=   self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_for_masked_lm(*A      )

  def 				__lowercase    (					self						:     Tuple      ):






   '''simple docstring'''
   UpperCAmelCase__   :					List[str]   				=   self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_for_token_classification(*A      )

  def 				__lowercase    (					self						:     Union[str, Any]      ):






   '''simple docstring'''
   UpperCAmelCase__   :					Tuple   				=   self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_for_question_answering(*A      )




  def 				__lowercase    (					self						:     List[str]   ,A						:     Optional[int]      ):






   '''simple docstring'''
   if hasattr(A   ,"""weight"""      ) and module.weight is not None:
    module.weight.data.fill_(3      )
   if hasattr(A   ,"""bias"""      ) and module.bias is not None:
    module.bias.data.fill_(3      )

   for param in ["r_w_bias", "r_r_bias", "r_kernel", "r_s_bias", "seg_embed"]:
    if hasattr(A   ,A      ) and getattr(A   ,A      ) is not None:
     UpperCAmelCase__   :					Any   				=   getattr(A   ,A      )
     weight.data.fill_(3      )







@require_torch
class        __lowercase     (      __lowerCamelCase		,     unittest.TestCase   ):
  snake_case_			    =    False
  snake_case_			    =    False
  snake_case_			    =    (
      (FunnelBaseModel, FunnelForMultipleChoice, FunnelForSequenceClassification) if is_torch_available() else ()
  )

  def 				__lowercase    (					self						:     str      ):






   '''simple docstring'''
   UpperCAmelCase__   :					Optional[int]   				=   FunnelModelTester(self   ,base=A      )
   UpperCAmelCase__   :					Any   				=   ConfigTester(self   ,config_class=A      )

  def 				__lowercase    (					self						:     List[Any]      ):






   '''simple docstring'''
   self.config_tester.run_common_tests()

  def 				__lowercase    (					self						:     List[Any]      ):






   '''simple docstring'''
   UpperCAmelCase__   :					Union[str, Any]   				=   self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_base_model(*A      )

  def 				__lowercase    (					self						:     Any      ):






   '''simple docstring'''
   UpperCAmelCase__   :					str   				=   self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_for_sequence_classification(*A      )

  def 				__lowercase    (					self						:     Union[str, Any]      ):






   '''simple docstring'''
   UpperCAmelCase__   :					Dict   				=   self.model_tester.prepare_config_and_inputs()
   self.model_tester.create_and_check_for_multiple_choice(*A      )

  def 				__lowercase    (					self						:     str      ):






   '''simple docstring'''
   UpperCAmelCase__				, UpperCAmelCase__   :					Union[str, Any]   				=   self.model_tester.prepare_config_and_inputs_for_common()
   UpperCAmelCase__   :					List[str]   				=   True

   for model_class in self.all_model_classes:
    if model_class.__name__ == "FunnelBaseModel":
     continue
    UpperCAmelCase__   :					Tuple   				=   model_class(A      )
    model.to(A      )
    model.train()
    UpperCAmelCase__   :					Optional[Any]   				=   self._prepare_for_class(A   ,A   ,return_labels=A      )
    UpperCAmelCase__   :					List[Any]   				=   model(**A      ).loss
    loss.backward()




  def 				__lowercase    (					self						:     List[Any]   ,A						:     Optional[int]      ):






   '''simple docstring'''
   if hasattr(A   ,"""weight"""      ) and module.weight is not None:
    module.weight.data.fill_(3      )
   if hasattr(A   ,"""bias"""      ) and module.bias is not None:
    module.bias.data.fill_(3      )

   for param in ["r_w_bias", "r_r_bias", "r_kernel", "r_s_bias", "seg_embed"]:
    if hasattr(A   ,A      ) and getattr(A   ,A      ) is not None:
     UpperCAmelCase__   :					List[str]   				=   getattr(A   ,A      )
     weight.data.fill_(3      )







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

  def 				__lowercase    (					self						:     int      ):






   '''simple docstring'''
   UpperCAmelCase__   :					Union[str, Any]   				=   13
   UpperCAmelCase__   :					Any   				=   7
   UpperCAmelCase__   :					Any   				=   torch.arange(0   ,batch_size * sequence_length      ).long().reshape(A   ,A      )
   UpperCAmelCase__   :					Any   				=   [0, 1, 2, 3, 4, 5, 6, 4, 1, 3, 5, 0, 1]
   UpperCAmelCase__   :					Dict   				=   torch.tensor([[2] + [0] * a + [1] * (sequence_length - a - 1) for a in lengths]      )

   UpperCAmelCase__   :					Union[str, Any]   				=   FunnelModel.from_pretrained("""sgugger/funnel-random-tiny"""      )
   UpperCAmelCase__   :					Union[str, Any]   				=   model(A   ,token_type_ids=A      )[0].abs()

   UpperCAmelCase__   :					Optional[Any]   				=   torch.tensor(2_3_4_4.8_3_5_2      )
   UpperCAmelCase__   :					List[str]   				=   torch.tensor(0.8_0_5_2      )
   self.assertTrue(torch.allclose(output.sum()   ,A   ,atol=1e-4      )      )
   self.assertTrue(torch.allclose(output.mean()   ,A   ,atol=1e-4      )      )

   UpperCAmelCase__   :					List[str]   				=   torch.tensor([[1] * 7, [1] * 4 + [0] * 3] * 6 + [[0, 1, 1, 0, 0, 1, 1]]      )
   UpperCAmelCase__   :					List[str]   				=   model(A   ,attention_mask=A   ,token_type_ids=A      )[0].abs()

   UpperCAmelCase__   :					int   				=   torch.tensor(2_3_4_3.8_4_2_5      )
   UpperCAmelCase__   :					List[Any]   				=   torch.tensor(0.8_0_4_9      )
   self.assertTrue(torch.allclose(output.sum()   ,A   ,atol=1e-4      )      )
   self.assertTrue(torch.allclose(output.mean()   ,A   ,atol=1e-4      )      )




  @slow
  def 				__lowercase    (					self						:     Tuple      ):






   '''simple docstring'''
   UpperCAmelCase__   :					Optional[Any]   				=   FunnelTokenizer.from_pretrained("""huggingface/funnel-small"""      )
   UpperCAmelCase__   :					int   				=   FunnelModel.from_pretrained("""huggingface/funnel-small"""      )
   UpperCAmelCase__   :					List[Any]   				=   tokenizer("""Hello! I am the Funnel Transformer model."""   ,return_tensors="""pt"""      )
   UpperCAmelCase__   :					Dict   				=   model(**A      )[0]

   UpperCAmelCase__   :					Tuple   				=   torch.tensor(2_3_5.7_2_4_6      )
   UpperCAmelCase__   :					Dict   				=   torch.tensor(0.0_2_5_6      )
   self.assertTrue(torch.allclose(output.sum()   ,A   ,atol=1e-4      )      )
   self.assertTrue(torch.allclose(output.mean()   ,A   ,atol=1e-4      )      )








"""simple docstring"""




from __future__ import annotations
def 					lowerCAmelCase  (   __UpperCamelCase							,      __UpperCamelCase							,      __UpperCamelCase							,      __UpperCamelCase ):
 '''simple docstring'''





 UpperCAmelCase__				, UpperCAmelCase__   :					Optional[Any]   				=   m - 1, 0
 while i >= 0 and j < n:
  if key == mat[i][j]:
   print(F"Key {key} found at row- {i + 1} column- {j + 1}" )
   return
  if key < mat[i][j]:
   i -= 1
  else:
   j += 1
 print(F"Key {key} not found" )
def 					lowerCAmelCase  (   ):
 '''simple docstring'''





 UpperCAmelCase__   :					Union[str, Any]   				=   [[2, 5, 7], [4, 8, 13], [9, 11, 15], [12, 17, 20]]
 UpperCAmelCase__   :					int   				=   int(input("""Enter the element to be searched:""" ) )
 print(__UpperCamelCase )
 search_in_a_sorted_matrix(__UpperCamelCase							,      len(__UpperCamelCase )							,      len(mat[0] )							,      __UpperCamelCase )


if __name__ == "__main__":
      import doctest

      doctest.testmod()
      main()





