


'''simple docstring'''







import argparse

# utilities to import the model weights and config file
import os
import pickle as pkl

# PyTorch + new model classes
import torch
from torch import nn

from transformers import AutoTokenizer, MegaConfig, MegaForMaskedLM


# import the EncoderLayer class used to pretrain
# !! NOTE !! this requires the version of fairseq that is built when you install the Mega source
try:
		from fairseq.modules.mega_layer import MegaEncoderLayer
except ImportError:
		raise ImportError("You need to install the version of fairseq from the Mega repo!")






class 		_snake_case    (				nn.Module		):






						'''simple docstring'''







						def __init__(  self:	Union[str, Any]      ,							__UpperCamelCase:	Optional[int]      ,							__UpperCamelCase:	Tuple      ,							__UpperCamelCase:	Tuple     )							->	List[str]:
										super().__init__()
										__magic_name__				:					Any						       =       mega_args
										__magic_name__				:					str						       =       nn.Embedding(__UpperCamelCase      ,							self.mega_args.encoder_embed_dim     )
										__magic_name__				:					Tuple						       =       nn.ModuleList([MegaEncoderLayer(self.mega_args     ) for _ in range(__UpperCamelCase     )]     )
										__magic_name__				:					Union[str, Any]						       =       depth







						def lowerCAmelCase__ (  self:	List[Any]      ,							__UpperCamelCase:	List[str]      ,							__UpperCamelCase:	List[str]      ,							__UpperCamelCase:	Optional[Any]=True      ,							__UpperCamelCase:	Union[str, Any]=0     )							->	Optional[int]:

										# Mega expects embeddings to be (time, batch, embedding size), but
										# Hugging Face returns tokens as (batch, time)
										if batch_first:
														__magic_name__				:					Any						       =       input_ids.T

										# to make things more confusing, Mega expects the attention mask to
										# be (batch, time), but with values of 0 (normal token) and 1 (ignore token)
										# which is the opposite of what HF returns
										if ignore_mask_value == 0:
														__magic_name__				:					Dict						       =       1 - attention_mask

										# get token embeddings from IDs
										__magic_name__				:					List[Any]						       =       self.embedding_layer(__UpperCamelCase     )

										# pass through the Mega layers
										# input is (time, batch, encoder dim) and output is the same
										for encoder in self.encoders:
														__magic_name__				:					Tuple						       =       encoder(__UpperCamelCase      ,							__UpperCamelCase     )

										# return according to the shape specified
										if batch_first:
														# (T, B, H) --> (B, T, H)
														return torch.transpose(__UpperCamelCase      ,							0      ,							1     )
										else:
														return embeds






class 		_snake_case    (				nn.Module		):






						'''simple docstring'''







						def __init__(  self:	str      ,							__UpperCamelCase:	List[str]      ,							__UpperCamelCase:	Optional[Any]      ,							__UpperCamelCase:	str     )							->	Union[str, Any]:
										super().__init__()
										__magic_name__				:					str						       =       MegaLM(__UpperCamelCase      ,							__UpperCamelCase      ,							__UpperCamelCase     )
										__magic_name__				:					Any						       =       nn.Linear(mega_args.encoder_embed_dim      ,							__UpperCamelCase     )
										__magic_name__				:					Optional[Any]						       =       nn.Dropout(p=0.1     )







						def lowerCAmelCase__ (  self:	List[str]      ,							__UpperCamelCase:	List[str]      ,							__UpperCamelCase:	Tuple      ,							__UpperCamelCase:	str=True      ,							__UpperCamelCase:	int=0     )							->	Union[str, Any]:
										__magic_name__				:					List[str]						       =       self.mega(__UpperCamelCase      ,							__UpperCamelCase      ,							__UpperCamelCase      ,							__UpperCamelCase     )
										return self.mlm_head(self.dropout(__UpperCamelCase     )     )






def 						_UpperCamelCase							( UpperCamelCase__     ,   UpperCamelCase__     ,   UpperCamelCase__		):






				"""simple docstring"""



				with open(os.path.join(UpperCamelCase__     ,   "model_args.pkl"		)     ,   "rb"		) as f:
								__magic_name__				:					Dict						       =       pkl.load(UpperCamelCase__		)

				# load the original encoder
				__magic_name__				:					int						       =       OriginalMegaForMaskedLM(**UpperCamelCase__		).eval()

				# load its weights
				print(
				    "Original Mega encoder:"     ,   original_mlm.mega.load_state_dict(
				        torch.load(os.path.join(UpperCamelCase__     ,   "encoder_weights.pt"		)     ,   map_location="cpu"		)		)     ,   )
				print(
				    "Original Mega MLM layer:"     ,   original_mlm.mlm_head.load_state_dict(
				        torch.load(os.path.join(UpperCamelCase__     ,   "mlm_head_weights.pt"		)     ,   map_location="cpu"		)		)     ,   )

				# create a new config from the old one
				__magic_name__				:					List[str]						       =       MegaConfig(
				    num_hidden_layers=mega_original_args["depth"]     ,   vocab_size=mega_original_args["vocab_size"]     ,   hidden_size=mega_original_args["mega_args"].encoder_embed_dim     ,   shared_representation_size=mega_original_args["mega_args"].encoder_z_dim     ,   intermediate_size=mega_original_args["mega_args"].encoder_hidden_dim     ,   ema_projection_size=mega_original_args["mega_args"].encoder_n_dim     ,   dropout_prob=mega_original_args["mega_args"].dropout     ,   attention_probs_dropout_prob=mega_original_args["mega_args"].attention_dropout     ,   hidden_dropout_prob=mega_original_args["mega_args"].hidden_dropout     ,   activation=mega_original_args["mega_args"].activation_fn     ,   attention_activation=mega_original_args["mega_args"].attention_activation_fn     ,   bidirectional=mega_original_args["mega_args"].bidirectional     ,   use_chunking=mega_original_args["mega_args"].encoder_chunk_size > 0     ,   chunk_size=mega_original_args["mega_args"].encoder_chunk_size     ,   truncation=mega_original_args["mega_args"].truncation_length     ,   normalization_type=mega_original_args["mega_args"].normalization_type     ,   normalize_before_mega=UpperCamelCase__     ,   norm_affine=UpperCamelCase__     ,   use_feature_dropout=mega_original_args["mega_args"].feature_dropout     ,   relative_positional_bias=mega_original_args["mega_args"].rel_pos_bias     ,   max_positions=mega_original_args["mega_args"].max_source_positions     ,   nffn_hidden_size=mega_original_args["mega_args"].encoder_ffn_embed_dim     ,   normalize_before_ffn=mega_original_args["mega_args"].normalize_before     ,   nffn_activation_dropout_prob=0.0     ,   add_token_type_embeddings=UpperCamelCase__     ,   add_lm_hidden_dense_layer=UpperCamelCase__     ,   )

				__magic_name__				:					Any						       =       MegaForMaskedLM(UpperCamelCase__		).eval()

				# the originl checkpoint just uses nn.Embedding for the word embeddings
				# we use a wrapper module for embeddings to add support for positional embeddings
				__magic_name__				:					str						       =       original_mlm.mega.embedding_layer.weight

				# modify the state dictionary of the original checkpoint to account for naming issues in the Hugging Face
				# ecosystem -- any names containing "beta" or "gamma" aren't safe to use and are renamed upon _load_pretrained,
				# also renaming previously confusing parameter names
				__magic_name__				:					List[Any]						       =       original_mlm.mega.encoders.state_dict()
				__magic_name__				:					List[str]						       =       {}
				for module_name in original_state_dict.keys():
								__magic_name__				:					Tuple						       =       None
								# have to handle gamma, beta, and alpha differently due to their use
								# in multiple modules within the original repository;
								# beta is used in EMA, MovingAverageGatedAttention, and RotaryRelativePositionalBias, and must be renamed due to flax/tf weights
								# the EMA sublayer was renamed from "move" to "ema_gate" for readability, so that is also done here
								if "beta" in module_name:
												# EMA sub-layers were always called "move" in the original repo
												if "move.beta" in module_name:
																__magic_name__				:					Union[str, Any]						       =       module_name.replace("move.beta"     ,   "ema_gate.ema_expansion_matrix"		)
												elif "mega_layer.beta" in module_name:
																__magic_name__				:					Union[str, Any]						       =       module_name.replace("beta"     ,   "qk_bias"		)
												else:
																__magic_name__				:					Optional[int]						       =       module_name.replace("beta"     ,   "b_param"		)
        # beta is used in EMA and MovingAverageGatedAttention, and must be renamed due to flax/tf weights
								elif "gamma" in module_name:
												if "move.gamma" in module_name:
																__magic_name__				:					Optional[Any]						       =       module_name.replace("move.gamma"     ,   "ema_gate.kernel_projection_matrix"		)
												elif "mega_layer.gamma" in module_name:
																__magic_name__				:					Optional[Any]						       =       module_name.replace("gamma"     ,   "qk_weight"		)
												else:
																__magic_name__				:					Optional[int]						       =       module_name.replace("gamma"     ,   "g_param"		)
        # alpha is used in EMA and positional bias; renaming to improve readability
								elif "move.alpha" in module_name:
												__magic_name__				:					Any						       =       module_name.replace("move.alpha"     ,   "ema_gate.decay_factor"		)
								# delta is only used in EMA; renaming to improve readability
								elif "move.delta" in module_name:
												__magic_name__				:					Optional[Any]						       =       module_name.replace("move.delta"     ,   "ema_gate.damping_factor"		)
								# omega is only used in EMA; renaming to improve readability
								elif "omega" in module_name:
												__magic_name__				:					List[str]						       =       module_name.replace("move.omega"     ,   "ema_gate.residual_weight"		)

								if new_module_name:
												__magic_name__				:					str						       =       new_module_name

				if len(UpperCamelCase__		) != 0:
								print(F"""Renaming these keys: {updated_keys.keys()}"""		)
				else:
								print("No need to rename state dict entries"		)
				for old, new in updated_keys.items():
								__magic_name__				:					Dict						       =       original_state_dict.pop(UpperCamelCase__		)

				# now attempt to load the state dictionary with updated names
				# note that we now call it `mega.layers` instead of `mega.encoders` due to hugging face style
				print("HF Mega encoder:"     ,   hf_mlm.mega.layers.load_state_dict(UpperCamelCase__		)		)

				# load the MLM head weights directly
				print(
				    "HF Mega MLM layer:"     ,   hf_mlm.mlm_head.load_state_dict(
				        torch.load(os.path.join(UpperCamelCase__     ,   "mlm_head_weights.pt"		)     ,   map_location="cpu"		)		)     ,   )

				# test on a randomly generated input sequence
				__magic_name__				:					Any						       =       torch.randint(0     ,   hf_config.vocab_size     ,   size=(4, 256)		)
				__magic_name__				:					Optional[int]						       =       torch.ones_like(UpperCamelCase__		)
				# mask a few tokens to make sure masking is applied appropriately :)
				__magic_name__				:					List[Any]						       =       0

				# run forward passes
				__magic_name__				:					str						       =       original_mlm(UpperCamelCase__     ,   UpperCamelCase__     ,   batch_first=UpperCamelCase__     ,   ignore_mask_value=0		)
				__magic_name__				:					Any						       =       hf_mlm(UpperCamelCase__     ,   UpperCamelCase__		)[0]

				# print shapes and diff
				print(F"""original output {original_output.shape}"""		)
				print(F"""hf output {hf_output.shape}"""		)
				print(F"""max diff: {(original_output - hf_output).max()}"""		)  # 0.0
				__magic_name__				:					Union[str, Any]						       =       torch.allclose(UpperCamelCase__     ,   UpperCamelCase__     ,   atol=1E-3		)

				if success:
								print("Yay!"		)
								hf_mlm.save_pretrained(UpperCamelCase__		)
				else:
								raise RuntimeError(F"""Something's broken :(\nOriginal:\n{original_output}\n\nHF\n{hf_output}\n{hf_mlm}"""		)

				if includes_tokenizer:
								print("Transferring tokenizer"		)
								__magic_name__				:					Optional[int]						       =       AutoTokenizer.from_pretrained(UpperCamelCase__		)
								tokenizer.save_pretrained(UpperCamelCase__		)


if __name__ == "__main__":
		_SCREAMING_SNAKE_CASE       :   Union[str, Any]        = argparse.ArgumentParser()

		parser.add_argument(
		    "--pretrained_checkpoint_path",
		    default=None,
		    type=str,
		    required=True,
		    help="Point to the directory containing your model weights using the official Mega repo",
		)

		parser.add_argument(
		    "--output_path", default=None, type=str, required=True, help="Location to save the Hugging Face version"
		)

		parser.add_argument(
		    "--includes_tokenizer",
		    action="store_true",
		    help="Use this flag if there is a Hugging Face tokenizer in the original checkpoint repo",
		)

		_SCREAMING_SNAKE_CASE       :   Union[str, Any]        = parser.parse_args()

		convert_checkpoint_to_huggingface(args.pretrained_checkpoint_path, args.output_path, args.includes_tokenizer)



'''simple docstring'''







def 						_UpperCamelCase							( UpperCamelCase__     ,   UpperCamelCase__		):






				"""simple docstring"""



				if not isinstance(UpperCamelCase__     ,   UpperCamelCase__		):
								raise TypeError("plaintext must be a string"		)
				if not isinstance(UpperCamelCase__     ,   UpperCamelCase__		):
								raise TypeError("key must be a string"		)

				if not plaintext:
								raise ValueError("plaintext is empty"		)
				if not key:
								raise ValueError("key is empty"		)

				key += plaintext
				__magic_name__				:					List[str]						       =       plaintext.lower()
				__magic_name__				:					Tuple						       =       key.lower()
				__magic_name__				:					Dict						       =       0
				__magic_name__				:					Optional[int]						       =       0
				__magic_name__				:					List[str]						       =       ""
				while plaintext_iterator < len(UpperCamelCase__		):
								if (
								    ord(plaintext[plaintext_iterator]		) < 97
								    or ord(plaintext[plaintext_iterator]		) > 122
								):
												ciphertext += plaintext[plaintext_iterator]
												plaintext_iterator += 1
								elif ord(key[key_iterator]		) < 97 or ord(key[key_iterator]		) > 122:
												key_iterator += 1
								else:
												ciphertext += chr(
												    (
												        (ord(plaintext[plaintext_iterator]		) - 97 + ord(key[key_iterator]		))
												        - 97
												    )
												    % 26
												    + 97		)
												key_iterator += 1
												plaintext_iterator += 1
				return ciphertext



def 						_UpperCamelCase							( UpperCamelCase__     ,   UpperCamelCase__		):






				"""simple docstring"""



				if not isinstance(UpperCamelCase__     ,   UpperCamelCase__		):
								raise TypeError("ciphertext must be a string"		)
				if not isinstance(UpperCamelCase__     ,   UpperCamelCase__		):
								raise TypeError("key must be a string"		)

				if not ciphertext:
								raise ValueError("ciphertext is empty"		)
				if not key:
								raise ValueError("key is empty"		)

				__magic_name__				:					List[str]						       =       key.lower()
				__magic_name__				:					str						       =       0
				__magic_name__				:					Optional[Any]						       =       0
				__magic_name__				:					Tuple						       =       ""
				while ciphertext_iterator < len(UpperCamelCase__		):
								if (
								    ord(ciphertext[ciphertext_iterator]		) < 97
								    or ord(ciphertext[ciphertext_iterator]		) > 122
								):
												plaintext += ciphertext[ciphertext_iterator]
								else:
												plaintext += chr(
												    (ord(ciphertext[ciphertext_iterator]		) - ord(key[key_iterator]		)) % 26
												    + 97		)
												key += chr(
												    (ord(ciphertext[ciphertext_iterator]		) - ord(key[key_iterator]		)) % 26
												    + 97		)
												key_iterator += 1
								ciphertext_iterator += 1
				return plaintext


if __name__ == "__main__":
		import doctest

		doctest.testmod()
		_SCREAMING_SNAKE_CASE       :   Tuple        = int(input("Type 1 to encrypt or 2 to decrypt:"))
		if operation == 1:
				_SCREAMING_SNAKE_CASE       :   Optional[Any]        = input("Typeplaintext to be encrypted:\n")
				_SCREAMING_SNAKE_CASE       :   Tuple        = input("Type the key:\n")
				print(encrypt(plaintext, key))
		elif operation == 2:
				_SCREAMING_SNAKE_CASE       :   Optional[Any]        = input("Type the ciphertext to be decrypted:\n")
				_SCREAMING_SNAKE_CASE       :   List[str]        = input("Type the key:\n")
				print(decrypt(ciphertext, key))
		decrypt("jsqqs avvwo", "coffee")