






'''simple docstring'''







from copy import deepcopy

import torch
import torch.nn.functional as F
from torch.optim import AdamW
from torch.optim.lr_scheduler import LambdaLR
from torch.utils.data import DataLoader

from accelerate.accelerator import Accelerator
from accelerate.state import GradientState
from accelerate.test_utils import RegressionDataset, RegressionModel
from accelerate.utils import DistributedType, is_torch_version, set_seed
def 						A__			(				__lowerCAmelCase		:			Optional[Any]   ,    __lowerCAmelCase		:			Optional[Any]   ,    __lowerCAmelCase		:			Union[str, Any]   ,    __lowerCAmelCase		:			Tuple						):
						for param, grad_param in zip(model_a.parameters()   ,    model_b.parameters()						):
												if not param.requires_grad:
																		continue
												if not did_step:
																		# Grads should not be in sync
																		assert (
																		    torch.allclose(param.grad   ,    grad_param.grad						) is False
																		), F'''Gradients in sync when they should not be at iteration {iteration}:\nmodel_a grad ({param.grad}) == model_b grad ({grad_param.grad})'''
												else:
																		# Grads should be in sync
																		assert (
																		    torch.allclose(param.grad   ,    grad_param.grad						) is True
																		), F'''Gradients not in sync when they should be at iteration {iteration}:\nmodel_a grad ({param.grad}) != model_b grad ({grad_param.grad})'''
def 						A__			(				__lowerCAmelCase		:			Any   ,    __lowerCAmelCase		:			int   ,    __lowerCAmelCase		:			Any   ,    __lowerCAmelCase		:			str   ,    __lowerCAmelCase		:			Tuple=True						):
						model.train()
						lowerCamelCase__         =  model(__lowerCAmelCase						)
						lowerCamelCase__         =  F.mse_loss(__lowerCAmelCase   ,    target.to(output.device						)						)
						if not do_backward:
												loss /= accelerator.gradient_accumulation_steps
												loss.backward()
						else:
												accelerator.backward(__lowerCAmelCase						)
def 						A__			(				__lowerCAmelCase		:			Optional[Any]   ,    __lowerCAmelCase		:			Any=False						):
						set_seed(42						)
						lowerCamelCase__         =  RegressionModel()
						lowerCamelCase__         =  deepcopy(__lowerCAmelCase						)
						lowerCamelCase__         =  RegressionDataset(length=80						)
						lowerCamelCase__         =  DataLoader(__lowerCAmelCase   ,    batch_size=16						)
						model.to(accelerator.device						)
						if sched:
												lowerCamelCase__         =  AdamW(params=model.parameters()   ,    lr=1e-3						)
												lowerCamelCase__         =  AdamW(params=ddp_model.parameters()   ,    lr=1e-3						)
												lowerCamelCase__         =  LambdaLR(__lowerCAmelCase   ,    lr_lambda=lambda __lowerCAmelCase						: epoch**0.65						)
												lowerCamelCase__         =  LambdaLR(__lowerCAmelCase   ,    lr_lambda=lambda __lowerCAmelCase						: epoch**0.65						)
						# Make a copy of `model`
						if sched:
												lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__         =  accelerator.prepare(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)
						else:
												lowerCamelCase__       ,			lowerCamelCase__         =  accelerator.prepare(__lowerCAmelCase   ,    __lowerCAmelCase						)
						if sched:
												return (model, opt, sched, dataloader, ddp_model, ddp_opt, ddp_sched)
						return model, ddp_model, dataloader
def 						A__			(				__lowerCAmelCase		:			Any						):
						# Test when on a single CPU or GPU that the context manager does nothing
						lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__         =  get_training_setup(__lowerCAmelCase						)
						# Use a single batch
						lowerCamelCase__       ,			lowerCamelCase__         =  next(iter(__lowerCAmelCase						)						).values()
						for iteration in range(3						):
												# Gather the distributed inputs and targs for the base model
												lowerCamelCase__       ,			lowerCamelCase__         =  accelerator.gather((ddp_input, ddp_target)						)
												lowerCamelCase__       ,			lowerCamelCase__         =  input.to(accelerator.device						), target.to(accelerator.device						)
												# Perform our initial ground truth step in non "DDP"
												step_model(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)
												# Do "gradient accumulation" (noop)
												if iteration % 2 == 0:
																		# Accumulate grads locally
																		with accelerator.no_sync(__lowerCAmelCase						):
																								step_model(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)
												else:
																		# Sync grads
																		step_model(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)

												# Since `no_sync` is a noop, `ddp_model` and `model` grads should always be in sync
												check_model_parameters(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)
												for param, ddp_param in zip(model.parameters()   ,    ddp_model.parameters()						):
																		if not param.requires_grad:
																								continue
																		assert torch.allclose(
																		    param.grad   ,    ddp_param.grad						), F'''Gradients not in sync when they should be:\nModel grad ({param.grad}) != DDP grad ({ddp_param.grad})'''

												# Shuffle ddp_input on each iteration
												torch.manual_seed(1337 + iteration						)
												lowerCamelCase__         =  ddp_input[torch.randperm(len(__lowerCAmelCase						)						)]
def 						A__			(				__lowerCAmelCase		:			Tuple						):
						# Test on distributed setup that context manager behaves properly
						lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__         =  get_training_setup(__lowerCAmelCase						)
						# Use a single batch
						lowerCamelCase__       ,			lowerCamelCase__         =  next(iter(__lowerCAmelCase						)						).values()
						for iteration in range(3						):
												# Gather the distributed inputs and targs for the base model
												lowerCamelCase__       ,			lowerCamelCase__         =  accelerator.gather((ddp_input, ddp_target)						)
												lowerCamelCase__       ,			lowerCamelCase__         =  input.to(accelerator.device						), target.to(accelerator.device						)
												# Perform our initial ground truth step in non "DDP"
												step_model(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)
												# Do "gradient accumulation" (noop)
												if iteration % 2 == 0:
																		# Accumulate grads locally
																		with accelerator.no_sync(__lowerCAmelCase						):
																								step_model(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)
												else:
																		# Sync grads
																		step_model(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)

												# DDP model and model should only be in sync when not (iteration % 2 == 0)
												for param, ddp_param in zip(model.parameters()   ,    ddp_model.parameters()						):
																		if not param.requires_grad:
																								continue
																		if iteration % 2 == 0:
																								# Grads should not be in sync
																								assert (
																								    torch.allclose(param.grad   ,    ddp_param.grad						) is False
																								), F'''Gradients in sync when they should not be:\nModel grad ({param.grad}) == DDP grad ({ddp_param.grad})'''
																		else:
																								# Grads should be in sync
																								assert (
																								    torch.allclose(param.grad   ,    ddp_param.grad						) is True
																								), F'''Gradients not in sync when they should be:\nModel grad ({param.grad}) != DDP grad ({ddp_param.grad})'''

        # Shuffle ddp_input on each iteration
												torch.manual_seed(1337 + iteration						)
												lowerCamelCase__         =  ddp_input[torch.randperm(len(__lowerCAmelCase						)						)]
def 						A__			(				__lowerCAmelCase		:			int=False   ,    __lowerCAmelCase		:			Optional[int]=False						):
						lowerCamelCase__         =  Accelerator(
						    split_batches=__lowerCAmelCase   ,    dispatch_batches=__lowerCAmelCase   ,    gradient_accumulation_steps=2						)
						# Test that context manager behaves properly
						lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__         =  get_training_setup(__lowerCAmelCase						)
						for iteration, batch in enumerate(__lowerCAmelCase						):
												lowerCamelCase__       ,			lowerCamelCase__         =  batch.values()
												# Gather the distributed inputs and targs for the base model
												lowerCamelCase__       ,			lowerCamelCase__         =  accelerator.gather((ddp_input, ddp_target)						)
												lowerCamelCase__       ,			lowerCamelCase__         =  input.to(accelerator.device						), target.to(accelerator.device						)
												# Perform our initial ground truth step in non "DDP"
												step_model(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)
												# Do "gradient accumulation" (noop)
												with accelerator.accumulate(__lowerCAmelCase						):
																		step_model(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)

												# DDP model and model should only be in sync when not (iteration % 2 == 0)
												for param, ddp_param in zip(model.parameters()   ,    ddp_model.parameters()						):
																		if not param.requires_grad:
																								continue
																		if ((iteration + 1) % 2 == 0) or (iteration == len(__lowerCAmelCase						) - 1):
																								# Grads should be in sync
																								assert (
																								    torch.allclose(param.grad   ,    ddp_param.grad						) is True
																								), F'''Gradients not in sync when they should be at iteration {iteration}:\nModel grad ({param.grad}) != DDP grad ({ddp_param.grad})'''
																		else:
																								# Grads should not be in sync
																								assert (
																								    torch.allclose(param.grad   ,    ddp_param.grad						) is False
																								), F'''Gradients in sync when they should not be at iteration {iteration}:\nModel grad ({param.grad}) == DDP grad ({ddp_param.grad})'''

        # Shuffle ddp_input on each iteration
												torch.manual_seed(1337 + iteration						)
												lowerCamelCase__         =  ddp_input[torch.randperm(len(__lowerCAmelCase						)						)]
						GradientState._reset_state()
def 						A__			(				__lowerCAmelCase		:			Optional[Any]=False   ,    __lowerCAmelCase		:			Union[str, Any]=False						):
						lowerCamelCase__         =  Accelerator(
						    split_batches=__lowerCAmelCase   ,    dispatch_batches=__lowerCAmelCase   ,    gradient_accumulation_steps=2						)
						# Test that context manager behaves properly
						lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__         =  get_training_setup(__lowerCAmelCase   ,    __lowerCAmelCase						)
						for iteration, batch in enumerate(__lowerCAmelCase						):
												lowerCamelCase__       ,			lowerCamelCase__         =  batch.values()
												# Gather the distributed inputs and targs for the base model
												lowerCamelCase__       ,			lowerCamelCase__         =  accelerator.gather((ddp_input, ddp_target)						)
												lowerCamelCase__       ,			lowerCamelCase__         =  input.to(accelerator.device						), target.to(accelerator.device						)
												# Perform our initial ground truth step in non "DDP"
												model.train()
												ddp_model.train()
												step_model(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)
												opt.step()

												if ((iteration + 1) % 2 == 0) or ((iteration + 1) == len(__lowerCAmelCase						)):
																		if split_batches:
																								sched.step()
																		else:
																								for _ in range(accelerator.num_processes						):
																														sched.step()
												opt.zero_grad()
												# Perform gradient accumulation under wrapper
												with accelerator.accumulate(__lowerCAmelCase						):
																		step_model(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)
																		ddp_opt.step()
																		ddp_sched.step()
																		ddp_opt.zero_grad()

												# Learning rates should be the same
												assert (
												    opt.param_groups[0]["lr"] == ddp_opt.param_groups[0]["lr"]
												), F'''Learning rates found in each optimizer did not align\nopt: {opt.param_groups[0]["lr"]}\nDDP opt: {ddp_opt.param_groups[0]["lr"]}\n'''
												lowerCamelCase__         =  (((iteration + 1) % 2) == 0) or ((iteration + 1) == len(__lowerCAmelCase						))
												if accelerator.num_processes > 1:
																		check_model_parameters(__lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase   ,    __lowerCAmelCase						)
												# Shuffle ddp_input on each iteration
												torch.manual_seed(1337 + iteration						)
						GradientState._reset_state()
def 						A__			(				):
						lowerCamelCase__         =  Accelerator()

						lowerCamelCase__         =  RegressionDataset(length=80						)
						lowerCamelCase__         =  DataLoader(__lowerCAmelCase   ,    batch_size=16						)
						lowerCamelCase__         =  RegressionDataset(length=96						)
						lowerCamelCase__         =  DataLoader(__lowerCAmelCase   ,    batch_size=16						)
						lowerCamelCase__       ,			lowerCamelCase__         =  accelerator.prepare(__lowerCAmelCase   ,    __lowerCAmelCase						)
						assert accelerator.gradient_state.active_dataloader is None
						for iteration, _ in enumerate(__lowerCAmelCase						):
												assert id(accelerator.gradient_state.active_dataloader						) == id(__lowerCAmelCase						)
												if iteration < len(__lowerCAmelCase						) - 1:
																		assert not accelerator.gradient_state.end_of_dataloader
																		if iteration == 1:
																								for batch_num, _ in enumerate(__lowerCAmelCase						):
																														assert id(accelerator.gradient_state.active_dataloader						) == id(__lowerCAmelCase						)
																														if batch_num < len(__lowerCAmelCase						) - 1:
																																				assert not accelerator.gradient_state.end_of_dataloader
																														else:
																																				assert accelerator.gradient_state.end_of_dataloader
												else:
																		assert accelerator.gradient_state.end_of_dataloader
						assert accelerator.gradient_state.active_dataloader is None
def 						A__			(				):
						lowerCamelCase__         =  Accelerator()
						lowerCamelCase__         =  accelerator.state
						if state.local_process_index == 0:
												print("""**Test `accumulate` gradient accumulation with dataloader break**"""						)
						test_dataloader_break()
						if state.distributed_type == DistributedType.NO:
												if state.local_process_index == 0:
																		print("""**Test NOOP `no_sync` context manager**"""						)
												test_noop_sync(__lowerCAmelCase						)
						if state.distributed_type in (DistributedType.MULTI_GPU, DistributedType.MULTI_CPU):
												if state.local_process_index == 0:
																		print("""**Test Distributed `no_sync` context manager**"""						)
												test_distributed_sync(__lowerCAmelCase						)
						if state.distributed_type == DistributedType.MULTI_GPU:
												for split_batch in [True, False]:
																		for dispatch_batches in [True, False]:
																								if state.local_process_index == 0:
																														print(
																														    """**Test `accumulate` gradient accumulation, """   ,    F'''`split_batches={split_batch}` and `dispatch_batches={dispatch_batches}`**'''   ,    )
																								test_gradient_accumulation(__lowerCAmelCase   ,    __lowerCAmelCase						)

    # Currently will break on torch 2.0 +, need to investigate why
						if is_torch_version("""<"""   ,    """2.0"""						) or state.distributed_type == DistributedType.NO:
												if state.local_process_index == 0:
																		print(
																		    """**Test `accumulate` gradient accumulation with optimizer and scheduler, """   ,    """`split_batches=False`, `dispatch_batches=False`**"""   ,    )
												test_gradient_accumulation_with_opt_and_scheduler()
												if state.distributed_type == DistributedType.MULTI_GPU:
																		for split_batch in [True, False]:
																								for dispatch_batches in [True, False]:
																														if not split_batch and not dispatch_batches:
																																				continue
																														if state.local_process_index == 0:
																																				print(
																																				    """**Test `accumulate` gradient accumulation with optimizer and scheduler, """   ,    F'''`split_batches={split_batch}` and `dispatch_batches={dispatch_batches}`**'''   ,    )
																														test_gradient_accumulation_with_opt_and_scheduler(__lowerCAmelCase   ,    __lowerCAmelCase						)
def 						A__			(				__lowerCAmelCase		:			Any						):
						# For xla_spawn (TPUs)
						main()


if __name__ == "__main__":
							main()









'''simple docstring'''







import argparse
import struct
import unittest




class 		UpperCamelCase__    :




		'''simple docstring'''





		def __init__(      self   ,_lowerCAmelCase       ):
								lowerCamelCase__         =  data

								# Initialize hash values
								lowerCamelCase__         =  [
								    0x6a_09_e6_67,
								    0xbb_67_ae_85,
								    0x3c_6e_f3_72,
								    0xa5_4f_f5_3a,
								    0x51_0e_52_7f,
								    0x9b_05_68_8c,
								    0x1f_83_d9_ab,
								    0x5b_e0_cd_19,
								]

								# Initialize round constants
								lowerCamelCase__         =  [
								    0x42_8a_2f_98,
								    0x71_37_44_91,
								    0xb5_c0_fb_cf,
								    0xe9_b5_db_a5,
								    0x39_56_c2_5b,
								    0x59_f1_11_f1,
								    0x92_3f_82_a4,
								    0xab_1c_5e_d5,
								    0xd8_07_aa_98,
								    0x12_83_5b_01,
								    0x24_31_85_be,
								    0x55_0c_7d_c3,
								    0x72_be_5d_74,
								    0x80_de_b1_fe,
								    0x9b_dc_06_a7,
								    0xc1_9b_f1_74,
								    0xe4_9b_69_c1,
								    0xef_be_47_86,
								    0x0f_c1_9d_c6,
								    0x24_0c_a1_cc,
								    0x2d_e9_2c_6f,
								    0x4a_74_84_aa,
								    0x5c_b0_a9_dc,
								    0x76_f9_88_da,
								    0x98_3e_51_52,
								    0xa8_31_c6_6d,
								    0xb0_03_27_c8,
								    0xbf_59_7f_c7,
								    0xc6_e0_0b_f3,
								    0xd5_a7_91_47,
								    0x06_ca_63_51,
								    0x14_29_29_67,
								    0x27_b7_0a_85,
								    0x2e_1b_21_38,
								    0x4d_2c_6d_fc,
								    0x53_38_0d_13,
								    0x65_0a_73_54,
								    0x76_6a_0a_bb,
								    0x81_c2_c9_2e,
								    0x92_72_2c_85,
								    0xa2_bf_e8_a1,
								    0xa8_1a_66_4b,
								    0xc2_4b_8b_70,
								    0xc7_6c_51_a3,
								    0xd1_92_e8_19,
								    0xd6_99_06_24,
								    0xf4_0e_35_85,
								    0x10_6a_a0_70,
								    0x19_a4_c1_16,
								    0x1e_37_6c_08,
								    0x27_48_77_4c,
								    0x34_b0_bc_b5,
								    0x39_1c_0c_b3,
								    0x4e_d8_aa_4a,
								    0x5b_9c_ca_4f,
								    0x68_2e_6f_f3,
								    0x74_8f_82_ee,
								    0x78_a5_63_6f,
								    0x84_c8_78_14,
								    0x8c_c7_02_08,
								    0x90_be_ff_fa,
								    0xa4_50_6c_eb,
								    0xbe_f9_a3_f7,
								    0xc6_71_78_f2,
								]

								lowerCamelCase__         =  self.preprocessing(self.data       )
								self.final_hash()






		@staticmethod
		def 			UpperCamelCase_					(      _lowerCAmelCase       ):
								lowerCamelCase__         =  B"""\x80""" + (B"""\x00""" * (63 - (len(_lowerCAmelCase       ) + 8) % 64))
								lowerCamelCase__         =  struct.pack(""">Q"""   ,(len(_lowerCAmelCase       ) * 8)       )
								return data + padding + big_endian_integer






		def 			UpperCamelCase_					(      self       ):
								# Convert into blocks of 64 bytes
								lowerCamelCase__         =  [
								    self.preprocessed_data[x : x + 64]
								    for x in range(0   ,len(self.preprocessed_data       )   ,64       )
								]

								for block in self.blocks:
														# Convert the given block into a list of 4 byte integers
														lowerCamelCase__         =  list(struct.unpack(""">16L"""   ,_lowerCAmelCase       )       )
														# add 48 0-ed integers
														words += [0] * 48

														lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__         =  self.hashes

														for index in range(0   ,64       ):
																				if index > 15:
																										# modify the zero-ed indexes at the end of the array
																										lowerCamelCase__         =  (
																										    self.ror(words[index - 15]   ,7       )
																										    ^ self.ror(words[index - 15]   ,18       )
																										    ^ (words[index - 15] >> 3)
																										)
																										lowerCamelCase__         =  (
																										    self.ror(words[index - 2]   ,17       )
																										    ^ self.ror(words[index - 2]   ,19       )
																										    ^ (words[index - 2] >> 10)
																										)

																										lowerCamelCase__         =  (
																										    words[index - 16] + sa + words[index - 7] + sa
																										) % 0x1_00_00_00_00

																				# Compression
																				lowerCamelCase__         =  self.ror(_lowerCAmelCase   ,6       ) ^ self.ror(_lowerCAmelCase   ,11       ) ^ self.ror(_lowerCAmelCase   ,25       )
																				lowerCamelCase__         =  (e & f) ^ ((~e & 0xff_ff_ff_ff) & g)
																				lowerCamelCase__         =  (
																				    h + sa + ch + self.round_constants[index] + words[index]
																				) % 0x1_00_00_00_00
																				lowerCamelCase__         =  self.ror(_lowerCAmelCase   ,2       ) ^ self.ror(_lowerCAmelCase   ,13       ) ^ self.ror(_lowerCAmelCase   ,22       )
																				lowerCamelCase__         =  (a & b) ^ (a & c) ^ (b & c)
																				lowerCamelCase__         =  (sa + maj) % 0x1_00_00_00_00

																				lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__       ,			lowerCamelCase__         =  (
																				    g,
																				    f,
																				    e,
																				    ((d + tempa) % 0x1_00_00_00_00),
																				    c,
																				    b,
																				    a,
																				    ((tempa + tempa) % 0x1_00_00_00_00),
																				)

														lowerCamelCase__         =  [a, b, c, d, e, f, g, h]

														# Modify final values
														lowerCamelCase__         =  [
														    ((element + mutated_hash_values[index]) % 0x1_00_00_00_00)
														    for index, element in enumerate(self.hashes       )
														]

								lowerCamelCase__         =  """""".join([hex(_lowerCAmelCase       )[2:].zfill(8       ) for value in self.hashes]       )






		def 			UpperCamelCase_					(      self   ,_lowerCAmelCase   ,_lowerCAmelCase       ):
								return 0xff_ff_ff_ff & (value << (32 - rotations)) | (value >> rotations)




class 		UpperCamelCase__    (unittest.TestCase			):




		'''simple docstring'''





		def 			UpperCamelCase_					(      self       ):
								import hashlib

								lowerCamelCase__         =  bytes("""Test String"""   ,"""utf-8"""       )
								self.assertEqual(SHAaaa(_lowerCAmelCase       ).hash   ,hashlib.shaaaa(_lowerCAmelCase       ).hexdigest()       )



def 						A__			(				):
						import doctest

						doctest.testmod()

						lowerCamelCase__         =  argparse.ArgumentParser()
						parser.add_argument(
						    """-s"""   ,    """--string"""   ,    dest="""input_string"""   ,    default="""Hello World!! Welcome to Cryptography"""   ,    help="""Hash the string"""   ,    )
						parser.add_argument(
						    """-f"""   ,    """--file"""   ,    dest="""input_file"""   ,    help="""Hash contents of a file"""						)

						lowerCamelCase__         =  parser.parse_args()

						lowerCamelCase__         =  args.input_string

						# hash input should be a bytestring
						if args.input_file:
												with open(args.input_file   ,    """rb"""						) as f:
																		lowerCamelCase__         =  f.read()
						else:
												lowerCamelCase__         =  bytes(__lowerCAmelCase   ,    """utf-8"""						)

						print(SHAaaa(__lowerCAmelCase						).hash						)


if __name__ == "__main__":
							main()

