





import collections

from .utils import ExplicitEnum, is_torch_available, logging


if is_torch_available():
							import torch


UpperCAmelCase__    :      Any       					=logging.get_logger(__name__)

class    __A  :


				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   _lowercase       (    _UpperCAmelCase      ,   _UpperCAmelCase					)    ->	Optional[Any]:
				lowerCamelCase									=var.abs()
				return F"""{abs_var.min():8.2e} {abs_var.max():8.2e} {ctx}"""





def   _lowercase       (    _UpperCAmelCase      ,   _UpperCAmelCase					)    ->	Optional[int]:
				lowerCamelCase									=False
				if torch.isnan(_UpperCAmelCase					).any().item():
								lowerCamelCase									=True
								print(F"""{ctx} has nans"""					)
				if torch.isinf(_UpperCAmelCase					).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()      ,   1_00					)]
								if naaa.numel() > 0:
												print(F"""{ctx}:  n100={naaa.numel()}"""					)
								lowerCamelCase									=var[torch.ge(var.abs()      ,   10_00					)]
								if naaaa.numel() > 0:
												print(F"""{ctx}: n1000={naaaa.numel()}"""					)
								lowerCamelCase									=var[torch.ge(var.abs()      ,   1_00_00					)]
								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    __A  (    a     ):
				__A  =					"""underflow_overflow"""
				__A  =					"""tpu_metrics_debug"""












from typing import TYPE_CHECKING

from ...utils import OptionalDependencyNotAvailable, _LazyModule, is_torch_available, is_vision_available


UpperCAmelCase__    :      Optional[Any]       					={
    '''configuration_donut_swin''': ['''DONUT_SWIN_PRETRAINED_CONFIG_ARCHIVE_MAP''', '''DonutSwinConfig'''],
    '''processing_donut''': ['''DonutProcessor'''],
}

try:
							if not is_torch_available():
														raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
							pass
else:
							UpperCAmelCase__    :      Any       					=[
							    '''DONUT_SWIN_PRETRAINED_MODEL_ARCHIVE_LIST''',
							    '''DonutSwinModel''',
							    '''DonutSwinPreTrainedModel''',
							]

try:
							if not is_vision_available():
														raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
							pass
else:
							UpperCAmelCase__    :      Tuple       					=['''DonutFeatureExtractor''']
							UpperCAmelCase__    :      List[str]       					=['''DonutImageProcessor''']


if TYPE_CHECKING:
							from .configuration_donut_swin import DONUT_SWIN_PRETRAINED_CONFIG_ARCHIVE_MAP, DonutSwinConfig
							from .processing_donut import DonutProcessor

							try:
														if not is_torch_available():
																					raise OptionalDependencyNotAvailable()
							except OptionalDependencyNotAvailable:
														pass
							else:
														from .modeling_donut_swin import (
														    DONUT_SWIN_PRETRAINED_MODEL_ARCHIVE_LIST,
														    DonutSwinModel,
														    DonutSwinPreTrainedModel,
														)

							try:
														if not is_vision_available():
																					raise OptionalDependencyNotAvailable()
							except OptionalDependencyNotAvailable:
														pass
							else:
														from .feature_extraction_donut import DonutFeatureExtractor
														from .image_processing_donut import DonutImageProcessor

else:
							import sys

							UpperCAmelCase__    :      int       					=_LazyModule(__name__, globals()['''__file__'''], _import_structure, module_spec=__spec__)





