



import collections

from .utils import ExplicitEnum, is_torch_available, logging


if is_torch_available():
							import torch


UpperCamelCase_      			=  logging.get_logger(__name__)







class 				a_    :

						def __init__(       self      :str  ,		_lowercase      :Optional[int]  ,		_lowercase      :Optional[int]=21  ,		_lowercase      :Union[str, Any]=[]  ,		_lowercase      :List[str]=None)						->   Any:
												UpperCAmelCase_					=	model
												UpperCAmelCase_					=	trace_batch_nums
												UpperCAmelCase_					=	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
												UpperCAmelCase_					=	collections.deque([]  ,		lowerCAmelCase__)
												UpperCAmelCase_					=	[]
												UpperCAmelCase_					=	0
												UpperCAmelCase_					=	0
												UpperCAmelCase_					=	False
												UpperCAmelCase_					=	'''                 '''

												self.analyse_model()

												self.register_forward_hook()

						def       __a			(       self      :List[Any]  ,		_lowercase      :List[str]=None)						->   Optional[Any]:
												if frame is not None:
																		self.expand_frame(lowerCAmelCase__)
												self.frames.append('''\n'''.join(self.frame))
												UpperCAmelCase_					=	[]  # start a new frame

						def       __a			(       self      :Any  ,		_lowercase      :List[str])						->   Tuple:
												self.frame.append(lowerCAmelCase__)

						def       __a			(       self      :Union[str, Any])						->   Optional[Any]:
												print('''\n'''.join(self.frames))
												UpperCAmelCase_					=	[]

						def       __a			(       self      :Optional[int])						->   Dict:
												UpperCAmelCase_					=	[]

						def       __a			(       self      :Tuple)						->   Any:
												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''')
												UpperCAmelCase_					=	[]

						def       __a			(       self      :Optional[int])						->   int:
												# 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
												UpperCAmelCase_					=	{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       __a			(       self      :Dict  ,		_lowercase      :str  ,		_lowercase      :List[Any])						->   Tuple:
												if torch.is_tensor(lowerCAmelCase__):
																		self.expand_frame(get_abs_min_max(lowerCAmelCase__  ,		lowerCAmelCase__))
																		if detect_overflow(lowerCAmelCase__  ,		lowerCAmelCase__):
																								UpperCAmelCase_					=	True
												elif var is None:
																		self.expand_frame(f"{'None':>17} {ctx}")
												else:
																		self.expand_frame(f"{'not a tensor':>17} {ctx}")

						def       __a			(       self      :Union[str, Any])						->   List[Any]:
												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       __a			(       self      :Optional[int])						->   Optional[int]:
												self.expand_frame(f"{self.prefix} *** Finished batch number={self.batch_number-1} ***\n\n")

						def       __a			(       self      :str  ,		_lowercase      :Dict  ,		_lowercase      :Any  ,		_lowercase      :List[str])						->   Any:
												self.expand_frame(f"{self.prefix} {self.module_names[module]} {module.__class__.__name__}")

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

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

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

												self.save_frame()

						def       __a			(       self      :Union[str, Any])						->   Tuple:
												self.model.apply(self._register_forward_hook)

						def       __a			(       self      :Union[str, Any]  ,		_lowercase      :List[Any])						->   List[Any]:
												module.register_forward_hook(self.forward_hook)




						def       __a			(       self      :List[str]  ,		_lowercase      :List[str]  ,		_lowercase      :int  ,		_lowercase      :Optional[int])						->   Any:
												# - input is a tuple of packed inputs (could be non-Tensors)
												# - output could be a Tensor or a tuple of Tensors and non-Tensors

												UpperCAmelCase_					=	False

												UpperCAmelCase_					=	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
																		UpperCAmelCase_					=	True

												self.create_frame(lowerCAmelCase__  ,		lowerCAmelCase__  ,		lowerCAmelCase__)

												# 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 							A     (						__UpperCAmelCase				,   __UpperCAmelCase      )			->			int:



						'''simple docstring'''






						UpperCAmelCase_					=	var.abs()
						return f"{abs_var.min():8.2e} {abs_var.max():8.2e} {ctx}"







def 							A     (						__UpperCAmelCase				,   __UpperCAmelCase      )			->			str:



						'''simple docstring'''






						UpperCAmelCase_					=	False
						if torch.isnan(lowerCAmelCase_      ).any().item():
												UpperCAmelCase_					=	True
												print(f"{ctx} has nans"      )
						if torch.isinf(lowerCAmelCase_      ).any().item():
												UpperCAmelCase_					=	True
												print(f"{ctx} has infs"      )

						# if needed to monitor large elements can enable the following
						if 0:  # and detected:
												UpperCAmelCase_					=	var[torch.ge(var.abs()				,   100      )]
												if naaa.numel() > 0:
																		print(f"{ctx}:  n100={naaa.numel()}"      )
												UpperCAmelCase_					=	var[torch.ge(var.abs()				,   1000      )]
												if naaaa.numel() > 0:
																		print(f"{ctx}: n1000={naaaa.numel()}"      )
												UpperCAmelCase_					=	var[torch.ge(var.abs()				,   1_0000      )]
												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							):
						UpperCamelCase__ :		Any										="""underflow_overflow"""
						UpperCamelCase__ :		Optional[int]										="""tpu_metrics_debug"""






import argparse
import os


UpperCAmelCase_    		=				{
    '''pytorch''': {
        '''1.13''': {
            '''torch''': '''1.13.1''',
            '''torchvision''': '''0.14.1''',
            '''torchaudio''': '''0.13.1''',
            '''python''': 3.9,
            '''cuda''': '''cu116''',
            '''install''': (
                '''python3 -m pip install --no-cache-dir -U torch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1'''
                ''' --extra-index-url https://download.pytorch.org/whl/cu116'''
            ),
            '''base_image''': '''nvidia/cuda:11.6.2-cudnn8-devel-ubuntu20.04''',
        },
        '''1.12''': {
            '''torch''': '''1.12.1''',
            '''torchvision''': '''0.13.1''',
            '''torchaudio''': '''0.12.1''',
            '''python''': 3.9,
            '''cuda''': '''cu113''',
            '''install''': (
                '''python3 -m pip install --no-cache-dir -U torch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1'''
                ''' --extra-index-url https://download.pytorch.org/whl/cu113'''
            ),
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
        '''1.11''': {
            '''torch''': '''1.11.0''',
            '''torchvision''': '''0.12.0''',
            '''torchaudio''': '''0.11.0''',
            '''python''': 3.9,
            '''cuda''': '''cu113''',
            '''install''': (
                '''python3 -m pip install --no-cache-dir -U torch==1.11.0 torchvision==0.12.0 torchaudio==0.11.0'''
                ''' --extra-index-url https://download.pytorch.org/whl/cu113'''
            ),
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
        '''1.10''': {
            '''torch''': '''1.10.2''',
            '''torchvision''': '''0.11.3''',
            '''torchaudio''': '''0.10.2''',
            '''python''': 3.9,
            '''cuda''': '''cu113''',
            '''install''': (
                '''python3 -m pip install --no-cache-dir -U torch==1.10.2 torchvision==0.11.3 torchaudio==0.10.2'''
                ''' --extra-index-url https://download.pytorch.org/whl/cu113'''
            ),
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
        # torchaudio < 0.10 has no CUDA-enabled binary distributions
        '''1.9''': {
            '''torch''': '''1.9.1''',
            '''torchvision''': '''0.10.1''',
            '''torchaudio''': '''0.9.1''',
            '''python''': 3.9,
            '''cuda''': '''cu111''',
            '''install''': (
                '''python3 -m pip install --no-cache-dir -U torch==1.9.1 torchvision==0.10.1 torchaudio==0.9.1'''
                ''' --extra-index-url https://download.pytorch.org/whl/cu111'''
            ),
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
    },
    '''tensorflow''': {
        '''2.11''': {
            '''tensorflow''': '''2.11.1''',
            '''install''': '''python3 -m pip install --no-cache-dir -U tensorflow==2.11.1''',
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
        '''2.10''': {
            '''tensorflow''': '''2.10.1''',
            '''install''': '''python3 -m pip install --no-cache-dir -U tensorflow==2.10.1''',
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
        '''2.9''': {
            '''tensorflow''': '''2.9.3''',
            '''install''': '''python3 -m pip install --no-cache-dir -U tensorflow==2.9.3''',
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
        '''2.8''': {
            '''tensorflow''': '''2.8.2''',
            '''install''': '''python3 -m pip install --no-cache-dir -U tensorflow==2.8.2''',
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
        '''2.7''': {
            '''tensorflow''': '''2.7.3''',
            '''install''': '''python3 -m pip install --no-cache-dir -U tensorflow==2.7.3''',
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
        '''2.6''': {
            '''tensorflow''': '''2.6.5''',
            '''install''': '''python3 -m pip install --no-cache-dir -U tensorflow==2.6.5''',
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
        '''2.5''': {
            '''tensorflow''': '''2.5.3''',
            '''install''': '''python3 -m pip install --no-cache-dir -U tensorflow==2.5.3''',
            '''base_image''': '''nvidia/cuda:11.2.2-cudnn8-devel-ubuntu20.04''',
        },
    },
}


if __name__ == "__main__":
      UpperCAmelCase_    		=				argparse.ArgumentParser('''Choose the framework and version to install''')
      parser.add_argument(
          '''--framework''', help='''The framework to install. Should be `torch` or `tensorflow`''', type=str, required=True
      )
      parser.add_argument('''--version''', help='''The version of the framework to install.''', type=str, required=True)
      UpperCAmelCase_    		=				parser.parse_args()

      UpperCAmelCase_    		=				past_versions_testing[args.framework][args.version]

      os.system(F"echo \"export INSTALL_CMD=\'{info['install']}\'\" >> ~/.profile")
      print(F"echo \"export INSTALL_CMD=\'{info['install']}\'\" >> ~/.profile")

      UpperCAmelCase_    		=				''''''
      if args.framework == "pytorch":
            UpperCAmelCase_    		=				info['''cuda''']
      os.system(F"echo \"export CUDA='{cuda}'\" >> ~/.profile")
      print(F"echo \"export CUDA='{cuda}'\" >> ~/.profile")