



import importlib.util
import json
import os
import warnings
from dataclasses import dataclass, field

import torch

from ..training_args import TrainingArguments
from ..utils import cached_property, is_sagemaker_dp_enabled, logging


UpperCAmelCase__       =	logging.get_logger(__name__)





def 							A     (					)    ->			List[str]:







			'''simple docstring'''
			_UpperCAmelCase			=       os.getenv('SM_HP_MP_PARAMETERS'							,       '{}'   )
			try:
						# Parse it and check the field "partitions" is included, it is required for model parallel.
						_UpperCAmelCase			=       json.loads(_lowercase   )
						if "partitions" not in smp_options:
									return False
			except json.JSONDecodeError:
						return False

			# Get the sagemaker specific framework parameters from mpi_options variable.
			_UpperCAmelCase			=       os.getenv('SM_FRAMEWORK_PARAMS'							,       '{}'   )
			try:
						# Parse it and check the field "sagemaker_distributed_dataparallel_enabled".
						_UpperCAmelCase			=       json.loads(_lowercase   )
						if not mpi_options.get('sagemaker_mpi_enabled'							,       _lowercase   ):
									return False
			except json.JSONDecodeError:
						return False
			# Lastly, check if the `smdistributed` module is present.
			return importlib.util.find_spec('smdistributed'   ) is not None


if is_sagemaker_model_parallel_available():
						import smdistributed.modelparallel.torch as smp

						smp.init()







@dataclass
class       __lowerCAmelCase   (      A						):
			UpperCamelCase        =					field(
			    default=''''''    ,						metadata={'''help''': '''Used by the SageMaker launcher to send mp-specific args. Ignored in SageMakerTrainer'''}    ,						)



			def    _lowerCamelCase	(						self       :  List[Any])       ->   str:



						"""simple docstring"""






						super().__post_init__()
						warnings.warn(
						    '`SageMakerTrainingArguments` is deprecated and will be removed in v5 of Transformers. You can use '
						    '`TrainingArguments` instead.'			,		__A			,		)



			@cached_property
			def    _lowerCamelCase	(						self       :  Tuple)       ->   "torch.device":



						"""simple docstring"""






						logger.info('PyTorch: setting up devices')
						if torch.distributed.is_available() and torch.distributed.is_initialized() and self.local_rank == -1:
									logger.warning(
									    'torch.distributed process group is initialized, but local_rank == -1. '
									    'In order to use Torch DDP, launch your script with `python -m torch.distributed.launch')
						if self.no_cuda:
									_UpperCAmelCase			=       torch.device('cpu')
									_UpperCAmelCase			=       0
						elif is_sagemaker_model_parallel_available():
									_UpperCAmelCase			=       smp.local_rank()
									_UpperCAmelCase			=       torch.device('cuda'			,		__A)
									_UpperCAmelCase			=       1
						elif is_sagemaker_dp_enabled():
									import smdistributed.dataparallel.torch.torch_smddp  # noqa: F401

									torch.distributed.init_process_group(backend='smddp'			,		timeout=self.ddp_timeout_delta)
									_UpperCAmelCase			=       int(os.getenv('SMDATAPARALLEL_LOCAL_RANK'))
									_UpperCAmelCase			=       torch.device('cuda'			,		self.local_rank)
									_UpperCAmelCase			=       1
						elif self.local_rank == -1:
									# if n_gpu is > 1 we'll use nn.DataParallel.
									# If you only want to use a specific subset of GPUs use `CUDA_VISIBLE_DEVICES=0`
									# Explicitly set CUDA to the first (index 0) CUDA device, otherwise `set_device` will
									# trigger an error that a device index is missing. Index 0 takes into account the
									# GPUs available in the environment, so `CUDA_VISIBLE_DEVICES=1,2` with `cuda:0`
									# will use the first GPU in that env, i.e. GPU#1
									_UpperCAmelCase			=       torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
									# Sometimes the line in the postinit has not been run before we end up here, so just checking we're not at
									# the default value.
									_UpperCAmelCase			=       torch.cuda.device_count()
						else:
									# Here, we'll use torch.distributed.
									# Initializes the distributed backend which will take care of synchronizing nodes/GPUs
									if not torch.distributed.is_initialized():
												torch.distributed.init_process_group(backend='nccl'			,		timeout=self.ddp_timeout_delta)
									_UpperCAmelCase			=       torch.device('cuda'			,		self.local_rank)
									_UpperCAmelCase			=       1

						if device.type == "cuda":
									torch.cuda.set_device(__A)

						return device



			@property
			def    _lowerCamelCase	(						self       :  Optional[int])       ->   List[str]:



						"""simple docstring"""






						if is_sagemaker_model_parallel_available():
									return smp.dp_size()

						return super().world_size



			@property
			def    _lowerCamelCase	(						self       :  str)       ->   List[Any]:



						"""simple docstring"""






						return not is_sagemaker_model_parallel_available()



			@property
			def    _lowerCamelCase	(						self       :  int)       ->   str:



						"""simple docstring"""






						return False





import string

import numpy





def 							A     (					_UpperCAmelCase    :       int							,       _UpperCAmelCase    :       int   )    ->			int:







			'''simple docstring'''
			return b if a == 0 else greatest_common_divisor(b % a							,       _UpperCAmelCase   )







class       __lowerCAmelCase   :
			UpperCamelCase        =					string.ascii_uppercase + string.digits
			# This cipher takes alphanumerics into account
			# i.e. a total of 36 characters

			# take x and return x % len(key_string)
			UpperCamelCase        =					numpy.vectorize(lambda A						: x % 3_6						)

			UpperCamelCase        =					numpy.vectorize(A						)



			def __init__(						self       :  Tuple			,		A       :  numpy.ndarray)       ->   None:



						"""simple docstring"""






						_UpperCAmelCase			=       self.modulus(A)  # mod36 calc's on the encrypt key
						self.check_determinant()  # validate the determinant of the encryption key
						_UpperCAmelCase			=       encrypt_key.shape[0]



			def    _lowerCamelCase	(						self       :  str			,		A       :  str)       ->   int:



						"""simple docstring"""






						return self.key_string.index(A)



			def    _lowerCamelCase	(						self       :  Any			,		A       :  int)       ->   str:



						"""simple docstring"""






						return self.key_string[round(A)]



			def    _lowerCamelCase	(						self       :  Union[str, Any])       ->   None:



						"""simple docstring"""






						_UpperCAmelCase			=       round(numpy.linalg.det(self.encrypt_key))

						if det < 0:
									_UpperCAmelCase			=       det % len(self.key_string)

						_UpperCAmelCase			=       len(self.key_string)
						if greatest_common_divisor(A			,		len(self.key_string)) != 1:
									_UpperCAmelCase			=       (
									    F"determinant modular {req_l} of encryption key({det}) "
									    F"is not co prime w.r.t {req_l}.\nTry another key."
									)
									raise ValueError(A)



			def    _lowerCamelCase	(						self       :  Union[str, Any]			,		A       :  str)       ->   str:



						"""simple docstring"""






						_UpperCAmelCase			=       [char for char in text.upper() if char in self.key_string]

						_UpperCAmelCase			=       chars[-1]
						while len(A) % self.break_key != 0:
									chars.append(A)

						return "".join(A)



			def    _lowerCamelCase	(						self       :  Union[str, Any]			,		A       :  str)       ->   str:



						"""simple docstring"""






						_UpperCAmelCase			=       self.process_text(text.upper())
						_UpperCAmelCase			=       ''

						for i in range(0			,		len(A) - self.break_key + 1			,		self.break_key):
									_UpperCAmelCase			=       text[i : i + self.break_key]
									_UpperCAmelCase			=       [self.replace_letters(A) for char in batch]
									_UpperCAmelCase			=       numpy.array([vec]).T
									_UpperCAmelCase			=       self.modulus(self.encrypt_key.dot(A)).T.tolist()[
									    0
									]
									_UpperCAmelCase			=       ''.join(
									    self.replace_digits(A) for num in batch_encrypted)
									encrypted += encrypted_batch

						return encrypted



			def    _lowerCamelCase	(						self       :  Optional[Any])       ->   numpy.ndarray:



						"""simple docstring"""






						_UpperCAmelCase			=       round(numpy.linalg.det(self.encrypt_key))

						if det < 0:
									_UpperCAmelCase			=       det % len(self.key_string)
						_UpperCAmelCase			=       None
						for i in range(len(self.key_string)):
									if (det * i) % len(self.key_string) == 1:
												_UpperCAmelCase			=       i
												break

						_UpperCAmelCase			=       (
						    det_inv
						    * numpy.linalg.det(self.encrypt_key)
						    * numpy.linalg.inv(self.encrypt_key)
						)

						return self.to_int(self.modulus(A))



			def    _lowerCamelCase	(						self       :  Tuple			,		A       :  str)       ->   str:



						"""simple docstring"""






						_UpperCAmelCase			=       self.make_decrypt_key()
						_UpperCAmelCase			=       self.process_text(text.upper())
						_UpperCAmelCase			=       ''

						for i in range(0			,		len(A) - self.break_key + 1			,		self.break_key):
									_UpperCAmelCase			=       text[i : i + self.break_key]
									_UpperCAmelCase			=       [self.replace_letters(A) for char in batch]
									_UpperCAmelCase			=       numpy.array([vec]).T
									_UpperCAmelCase			=       self.modulus(decrypt_key.dot(A)).T.tolist()[0]
									_UpperCAmelCase			=       ''.join(
									    self.replace_digits(A) for num in batch_decrypted)
									decrypted += decrypted_batch

						return decrypted





def 							A     (					)    ->			None:







			'''simple docstring'''
			_UpperCAmelCase			=       int(input('Enter the order of the encryption key: '   )   )
			_UpperCAmelCase			=       []

			print('Enter each row of the encryption key with space separated integers'   )
			for _ in range(_UpperCAmelCase   ):
						_UpperCAmelCase			=       [int(_UpperCAmelCase   ) for x in input().split()]
						hill_matrix.append(_UpperCAmelCase   )

			_UpperCAmelCase			=       HillCipher(numpy.array(_UpperCAmelCase   )   )

			print('Would you like to encrypt or decrypt some text? (1 or 2)'   )
			_UpperCAmelCase			=       input('\n1. Encrypt\n2. Decrypt\n'   )
			if option == "1":
						_UpperCAmelCase			=       input('What text would you like to encrypt?: '   )
						print('Your encrypted text is:'   )
						print(hc.encrypt(_UpperCAmelCase   )   )
			elif option == "2":
						_UpperCAmelCase			=       input('What text would you like to decrypt?: '   )
						print('Your decrypted text is:'   )
						print(hc.decrypt(_UpperCAmelCase   )   )


if __name__ == "__main__":
							import doctest

							doctest.testmod()

							main()
