




import unittest

import numpy as np

from transformers import ElectraConfig, is_flax_available
from transformers.testing_utils import require_flax, slow

from ...test_modeling_flax_common import FlaxModelTesterMixin, ids_tensor, random_attention_mask


if is_flax_available():
		from transformers.models.electra.modeling_flax_electra import (
		    FlaxElectraForCausalLM,
		    FlaxElectraForMaskedLM,
		    FlaxElectraForMultipleChoice,
		    FlaxElectraForPreTraining,
		    FlaxElectraForQuestionAnswering,
		    FlaxElectraForSequenceClassification,
		    FlaxElectraForTokenClassification,
		    FlaxElectraModel,
		)


class 				__UpperCamelCase      (			unittest.TestCase	):





				'''simple docstring'''



				def __init__(			self							,			UpperCAmelCase_							,			UpperCAmelCase_=13							,			UpperCAmelCase_=7							,			UpperCAmelCase_=True							,			UpperCAmelCase_=True							,			UpperCAmelCase_=True							,			UpperCAmelCase_=True							,			UpperCAmelCase_=99							,			UpperCAmelCase_=24							,			UpperCAmelCase_=32							,			UpperCAmelCase_=5							,			UpperCAmelCase_=4							,			UpperCAmelCase_=37							,			UpperCAmelCase_="gelu"							,			UpperCAmelCase_=0.1							,			UpperCAmelCase_=0.1							,			UpperCAmelCase_=5_12							,			UpperCAmelCase_=16							,			UpperCAmelCase_=2							,			UpperCAmelCase_=0.02							,			UpperCAmelCase_=4							,			):
											lowerCAmelCase =		parent
											lowerCAmelCase =		batch_size
											lowerCAmelCase =		seq_length
											lowerCAmelCase =		is_training
											lowerCAmelCase =		use_attention_mask
											lowerCAmelCase =		use_token_type_ids
											lowerCAmelCase =		use_labels
											lowerCAmelCase =		vocab_size
											lowerCAmelCase =		hidden_size
											lowerCAmelCase =		embedding_size
											lowerCAmelCase =		num_hidden_layers
											lowerCAmelCase =		num_attention_heads
											lowerCAmelCase =		intermediate_size
											lowerCAmelCase =		hidden_act
											lowerCAmelCase =		hidden_dropout_prob
											lowerCAmelCase =		attention_probs_dropout_prob
											lowerCAmelCase =		max_position_embeddings
											lowerCAmelCase =		type_vocab_size
											lowerCAmelCase =		type_sequence_label_size
											lowerCAmelCase =		initializer_range
											lowerCAmelCase =		num_choices



				def    __snake_case		(			self    ):
											lowerCAmelCase =		ids_tensor([self.batch_size, self.seq_length]							,			self.vocab_size    )

											lowerCAmelCase =		None
											if self.use_attention_mask:
																		lowerCAmelCase =		random_attention_mask([self.batch_size, self.seq_length]    )

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

											lowerCAmelCase =		ElectraConfig(
											    vocab_size=self.vocab_size							,			hidden_size=self.hidden_size							,			embedding_size=self.embedding_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							,			)

											return config, input_ids, token_type_ids, attention_mask






				def    __snake_case		(			self    ):
											lowerCAmelCase =		self.prepare_config_and_inputs()
											lowerCAmelCase ,  lowerCAmelCase ,  lowerCAmelCase ,  lowerCAmelCase =		config_and_inputs
											lowerCAmelCase =		{'''input_ids''': input_ids, '''token_type_ids''': token_type_ids, '''attention_mask''': attention_mask}
											return config, inputs_dict




@require_flax
class 				__UpperCamelCase      (			__UpperCAmelCase  ,       unittest.TestCase	):





				'''simple docstring'''



				__a				:			str					    =True

				__a				:			int					    =(
				    (
				        FlaxElectraModel,
				        FlaxElectraForCausalLM,
				        FlaxElectraForMaskedLM,
				        FlaxElectraForPreTraining,
				        FlaxElectraForTokenClassification,
				        FlaxElectraForQuestionAnswering,
				        FlaxElectraForMultipleChoice,
				        FlaxElectraForSequenceClassification,
				    )
				    if is_flax_available()
				    else ()
				)



				def    __snake_case		(			self    ):
											lowerCAmelCase =		FlaxElectraModelTester(self    )






				@slow
				def    __snake_case		(			self    ):
											for model_class_name in self.all_model_classes:
																		if model_class_name == FlaxElectraForMaskedLM:
																									lowerCAmelCase =		model_class_name.from_pretrained('''google/electra-small-generator'''    )
																		else:
																									lowerCAmelCase =		model_class_name.from_pretrained('''google/electra-small-discriminator'''    )
																		lowerCAmelCase =		model(np.ones((1, 1)    )    )
																		self.assertIsNotNone(UpperCAmelCase_    )









import collections

from .utils import ExplicitEnum, is_torch_available, logging


if is_torch_available():
		import torch


UpperCAmelCase_    =logging.get_logger(__name__)


class 				__UpperCamelCase      :





				'''simple docstring'''



				def __init__(			self							,			UpperCAmelCase_							,			UpperCAmelCase_=21							,			UpperCAmelCase_=[]							,			UpperCAmelCase_=None    ):
											lowerCAmelCase =		model
											lowerCAmelCase =		trace_batch_nums
											lowerCAmelCase =		abort_after_batch_num

											# keep a LIFO buffer of frames to dump as soon as inf/nan is encountered to give context to the problem emergence
											lowerCAmelCase =		collections.deque([]							,			UpperCAmelCase_    )
											lowerCAmelCase =		[]
											lowerCAmelCase =		0
											lowerCAmelCase =		0
											lowerCAmelCase =		False
											lowerCAmelCase =		'''                 '''

											self.analyse_model()

											self.register_forward_hook()



				def    __snake_case		(			self							,			UpperCAmelCase_=None    ):
											if frame is not None:
																		self.expand_frame(UpperCAmelCase_    )
											self.frames.append('''\n'''.join(self.frame    )    )
											lowerCAmelCase =		[]  # start a new frame



				def    __snake_case		(			self							,			UpperCAmelCase_    ):
											self.frame.append(UpperCAmelCase_    )



				def    __snake_case		(			self    ):
											print('''\n'''.join(self.frames    )    )
											lowerCAmelCase =		[]



				def    __snake_case		(			self    ):
											lowerCAmelCase =		[]



				def    __snake_case		(			self    ):
											print(F"""\nDetected inf/nan during batch_number={self.batch_number}"""    )
											print(F"""Last {len(self.frames    )} forward frames:"""    )
											print(F"""{"abs min":8} {"abs max":8} metadata"""    )
											print('''\n'''.join(self.frames    )    )
											print('''\n\n'''    )
											lowerCAmelCase =		[]



				def    __snake_case		(			self    ):
											# extract the fully qualified module names, to be able to report at run time. e.g.:
											# encoder.block.2.layer.0.SelfAttention.o
											#
											# for shared weights only the first shared module name will be registered
											lowerCAmelCase =		{m: name for name, m in self.model.named_modules()}
											# self.longest_module_name = max(len(v) for v in self.module_names.values())



				def    __snake_case		(			self							,			UpperCAmelCase_							,			UpperCAmelCase_    ):
											if torch.is_tensor(UpperCAmelCase_    ):
																		self.expand_frame(get_abs_min_max(UpperCAmelCase_							,			UpperCAmelCase_    )    )
																		if detect_overflow(UpperCAmelCase_							,			UpperCAmelCase_    ):
																									lowerCAmelCase =		True
											elif var is None:
																		self.expand_frame(F"""{"None":>17} {ctx}"""    )
											else:
																		self.expand_frame(F"""{"not a tensor":>17} {ctx}"""    )



				def    __snake_case		(			self    ):
											self.expand_frame(F"""\n\n{self.prefix} *** Starting batch number={self.batch_number} ***"""    )
											self.expand_frame(F"""{"abs min":8} {"abs max":8} metadata"""    )



				def    __snake_case		(			self    ):
											self.expand_frame(F"""{self.prefix} *** Finished batch number={self.batch_number-1} ***\n\n"""    )



				def    __snake_case		(			self							,			UpperCAmelCase_							,			UpperCAmelCase_							,			UpperCAmelCase_    ):
											self.expand_frame(F"""{self.prefix} {self.module_names[module]} {module.__class__.__name__}"""    )

											# params
											for name, p in module.named_parameters(recurse=UpperCAmelCase_    ):
																		self.analyse_variable(UpperCAmelCase_							,			UpperCAmelCase_    )

											# inputs
											if isinstance(UpperCAmelCase_							,			UpperCAmelCase_    ):
																		for i, x in enumerate(UpperCAmelCase_    ):
																									self.analyse_variable(UpperCAmelCase_							,			F"""input[{i}]"""    )
											else:
																		self.analyse_variable(UpperCAmelCase_							,			'''input'''    )

											# outputs
											if isinstance(UpperCAmelCase_							,			UpperCAmelCase_    ):
																		for i, x in enumerate(UpperCAmelCase_    ):
																									# possibly a tuple of tuples
																									if isinstance(UpperCAmelCase_							,			UpperCAmelCase_    ):
																																for j, y in enumerate(UpperCAmelCase_    ):
																																							self.analyse_variable(UpperCAmelCase_							,			F"""output[{i}][{j}]"""    )
																									else:
																																self.analyse_variable(UpperCAmelCase_							,			F"""output[{i}]"""    )
											else:
																		self.analyse_variable(UpperCAmelCase_							,			'''output'''    )

											self.save_frame()



				def    __snake_case		(			self    ):
											self.model.apply(self._register_forward_hook    )



				def    __snake_case		(			self							,			UpperCAmelCase_    ):
											module.register_forward_hook(self.forward_hook    )






				def    __snake_case		(			self							,			UpperCAmelCase_							,			UpperCAmelCase_							,			UpperCAmelCase_    ):
											# - input is a tuple of packed inputs (could be non-Tensors)
											# - output could be a Tensor or a tuple of Tensors and non-Tensors

											lowerCAmelCase =		False

											lowerCAmelCase =		True if self.batch_number in self.trace_batch_nums else False
											if trace_mode:
																		self.reset_saved_frames()

											if self.total_calls == 0:
																		self.batch_start_frame()
											self.total_calls += 1

											# count batch numbers - the very first forward hook of the batch will be called when the
											# batch completes - i.e. it gets called very last - we know this batch has finished
											if module == self.model:
																		self.batch_number += 1
																		lowerCAmelCase =		True

											self.create_frame(UpperCAmelCase_							,			UpperCAmelCase_							,			UpperCAmelCase_    )

											# if last_frame_of_batch:
											#     self.batch_end_frame()

											if trace_mode:
																		self.trace_frames()

											if last_frame_of_batch:
																		self.batch_start_frame()

											if self.detected_overflow and not trace_mode:
																		self.dump_saved_frames()

																		# now we can abort, as it's pointless to continue running
																		raise ValueError(
																		    '''DebugUnderflowOverflow: inf/nan detected, aborting as there is no point running further. '''
																		    '''Please scroll up above this traceback to see the activation values prior to this event.'''    )

											# abort after certain batch if requested to do so
											if self.abort_after_batch_num is not None and self.batch_number > self.abort_after_batch_num:
																		raise ValueError(
																		    F"""DebugUnderflowOverflow: aborting after {self.batch_number} batches due to"""
																		    F""" `abort_after_batch_num={self.abort_after_batch_num}` arg"""    )




def    UpperCAmelCase							(  _snake_case    ,			_snake_case				):
							lowerCAmelCase =		var.abs()
							return F"""{abs_var.min():8.2e} {abs_var.max():8.2e} {ctx}"""



def    UpperCAmelCase							(  _snake_case    ,			_snake_case				):
							lowerCAmelCase =		False
							if torch.isnan(_snake_case				).any().item():
														lowerCAmelCase =		True
														print(F"""{ctx} has nans"""				)
							if torch.isinf(_snake_case				).any().item():
														lowerCAmelCase =		True
														print(F"""{ctx} has infs"""				)

							# if needed to monitor large elements can enable the following
							if 0:  # and detected:
														lowerCAmelCase =		var[torch.ge(var.abs()    ,			100				)]
														if naaa.numel() > 0:
																					print(F"""{ctx}:  n100={naaa.numel()}"""				)
														lowerCAmelCase =		var[torch.ge(var.abs()    ,			1000				)]
														if naaaa.numel() > 0:
																					print(F"""{ctx}: n1000={naaaa.numel()}"""				)
														lowerCAmelCase =		var[torch.ge(var.abs()    ,			10000				)]
														if naaaaa.numel() > 0:
																					print(F"""{ctx}: n10000={naaaaa.numel()}"""				)

							if 0:
														print(F"""min={var.min():9.2e} max={var.max():9.2e}"""				)

							if 0:
														print(F"""min={var.min():9.2e} max={var.max():9.2e} var={var.var():9.2e} mean={var.mean():9.2e} ({ctx})"""				)

							return detected


class 				__UpperCamelCase      (			__UpperCAmelCase	):





				'''simple docstring'''



				__a				:			Tuple					    ="""underflow_overflow"""
				__a				:			Dict					    ="""tpu_metrics_debug"""



