




import argparse
import os

import gluonnlp as nlp
import mxnet as mx
import numpy as np
import torch
from gluonnlp.base import get_home_dir
from gluonnlp.model.bert import BERTEncoder
from gluonnlp.model.utils import _load_vocab
from gluonnlp.vocab import Vocab
from packaging import version
from torch import nn

from transformers import BertConfig, BertForMaskedLM, BertModel, RobertaTokenizer
from transformers.models.bert.modeling_bert import (
    BertIntermediate,
    BertLayer,
    BertOutput,
    BertSelfAttention,
    BertSelfOutput,
)
from transformers.utils import logging


if version.parse(nlp.__version__) != version.parse("0.8.3"):
					raise Exception("requires gluonnlp == 0.8.3")

if version.parse(mx.__version__) != version.parse("1.5.0"):
					raise Exception("requires mxnet == 1.5.0")

logging.set_verbosity_info()
__A        =    logging.get_logger(__name__)

__A        =    "The Nymphenburg Palace is a beautiful palace in Munich!"







def 			lowerCamelCase_		(       UpperCamelCase__				:      str ,     UpperCamelCase__				:      str      )     ->       List[str]:





				"""simple docstring"""


				__lowerCamelCase		       =    {
				    'attention_cell': 'multi_head',
				    'num_layers': 4,
				    'units': 1024,
				    'hidden_size': 768,
				    'max_length': 512,
				    'num_heads': 8,
				    'scaled': True,
				    'dropout': 0.1,
				    'use_residual': True,
				    'embed_size': 1024,
				    'embed_dropout': 0.1,
				    'word_embed': None,
				    'layer_norm_eps': 1E-5,
				    'token_type_vocab_size': 2,
				}

				__lowerCamelCase		       =    bort_4_8_768_1024_hparams

				# Let's construct the original Bort model here
				# Taken from official BERT implementation, see:
				# https://github.com/alexa/bort/blob/master/bort/bort.py
				__lowerCamelCase		       =    BERTEncoder(
				    attention_cell=predefined_args['attention_cell'] ,     num_layers=predefined_args['num_layers'] ,     units=predefined_args['units'] ,     hidden_size=predefined_args['hidden_size'] ,     max_length=predefined_args['max_length'] ,     num_heads=predefined_args['num_heads'] ,     scaled=predefined_args['scaled'] ,     dropout=predefined_args['dropout'] ,     output_attention=UpperCamelCase__ ,     output_all_encodings=UpperCamelCase__ ,     use_residual=predefined_args['use_residual'] ,     activation=predefined_args.get('activation' ,     'gelu'      ) ,     layer_norm_eps=predefined_args.get('layer_norm_eps' ,     UpperCamelCase__      ) ,     )

				# Vocab information needs to be fetched first
				# It's the same as RoBERTa, so RobertaTokenizer can be used later
				__lowerCamelCase		       =    'openwebtext_ccnews_stories_books_cased'

				# Specify download folder to Gluonnlp's vocab
				__lowerCamelCase		       =    os.path.join(get_home_dir() ,     'models'      )
				__lowerCamelCase		       =    _load_vocab(UpperCamelCase__ ,     UpperCamelCase__ ,     UpperCamelCase__ ,     cls=UpperCamelCase__      )

				__lowerCamelCase		       =    nlp.model.BERTModel(
				    UpperCamelCase__ ,     len(UpperCamelCase__      ) ,     units=predefined_args['units'] ,     embed_size=predefined_args['embed_size'] ,     embed_dropout=predefined_args['embed_dropout'] ,     word_embed=predefined_args['word_embed'] ,     use_pooler=UpperCamelCase__ ,     use_token_type_embed=UpperCamelCase__ ,     token_type_vocab_size=predefined_args['token_type_vocab_size'] ,     use_classifier=UpperCamelCase__ ,     use_decoder=UpperCamelCase__ ,     )

				original_bort.load_parameters(UpperCamelCase__ ,     cast_dtype=UpperCamelCase__ ,     ignore_extra=UpperCamelCase__      )
				__lowerCamelCase		       =    original_bort._collect_params_with_prefix()

				# Build our config 🤗
				__lowerCamelCase		       =    {
				    'architectures': ['BertForMaskedLM'],
				    'attention_probs_dropout_prob': predefined_args['dropout'],
				    'hidden_act': 'gelu',
				    'hidden_dropout_prob': predefined_args['dropout'],
				    'hidden_size': predefined_args['embed_size'],
				    'initializer_range': 0.02,
				    'intermediate_size': predefined_args['hidden_size'],
				    'layer_norm_eps': predefined_args['layer_norm_eps'],
				    'max_position_embeddings': predefined_args['max_length'],
				    'model_type': 'bort',
				    'num_attention_heads': predefined_args['num_heads'],
				    'num_hidden_layers': predefined_args['num_layers'],
				    'pad_token_id': 1,  # 2 = BERT, 1 = RoBERTa
				    'type_vocab_size': 1,  # 2 = BERT, 1 = RoBERTa
				    'vocab_size': len(UpperCamelCase__      ),
				}

				__lowerCamelCase		       =    BertConfig.from_dict(UpperCamelCase__      )
				__lowerCamelCase		       =    BertForMaskedLM(UpperCamelCase__      )
				hf_bort_model.eval()

				# Parameter mapping table (Gluonnlp to Transformers)
				# * denotes layer index
				#
				# | Gluon Parameter                                                | Transformers Parameter
				# | -------------------------------------------------------------- | ----------------------
				# | `encoder.layer_norm.beta`                                      | `bert.embeddings.LayerNorm.bias`
				# | `encoder.layer_norm.gamma`                                     | `bert.embeddings.LayerNorm.weight`
				# | `encoder.position_weight`                                      | `bert.embeddings.position_embeddings.weight`
				# | `word_embed.0.weight`                                          | `bert.embeddings.word_embeddings.weight`
				# | `encoder.transformer_cells.*.attention_cell.proj_key.bias`     | `bert.encoder.layer.*.attention.self.key.bias`
				# | `encoder.transformer_cells.*.attention_cell.proj_key.weight`   | `bert.encoder.layer.*.attention.self.key.weight`
				# | `encoder.transformer_cells.*.attention_cell.proj_query.bias`   | `bert.encoder.layer.*.attention.self.query.bias`
				# | `encoder.transformer_cells.*.attention_cell.proj_query.weight` | `bert.encoder.layer.*.attention.self.query.weight`
				# | `encoder.transformer_cells.*.attention_cell.proj_value.bias`   | `bert.encoder.layer.*.attention.self.value.bias`
				# | `encoder.transformer_cells.*.attention_cell.proj_value.weight` | `bert.encoder.layer.*.attention.self.value.weight`
				# | `encoder.transformer_cells.*.ffn.ffn_2.bias`                   | `bert.encoder.layer.*.attention.output.dense.bias`
				# | `encoder.transformer_cells.*.ffn.ffn_2.weight`                 | `bert.encoder.layer.*.attention.output.dense.weight`
				# | `encoder.transformer_cells.*.layer_norm.beta`                  | `bert.encoder.layer.*.attention.output.LayerNorm.bias`
				# | `encoder.transformer_cells.*.layer_norm.gamma`                 | `bert.encoder.layer.*.attention.output.LayerNorm.weight`
				# | `encoder.transformer_cells.*.ffn.ffn_1.bias`                   | `bert.encoder.layer.*.intermediate.dense.bias`
				# | `encoder.transformer_cells.*.ffn.ffn_1.weight`                 | `bert.encoder.layer.*.intermediate.dense.weight`
				# | `encoder.transformer_cells.*.ffn.layer_norm.beta`              | `bert.encoder.layer.*.output.LayerNorm.bias`
				# | `encoder.transformer_cells.*.ffn.layer_norm.gamma`             | `bert.encoder.layer.*.output.LayerNorm.weight`
				# | `encoder.transformer_cells.*.proj.bias`                        | `bert.encoder.layer.*.output.dense.bias`
				# | `encoder.transformer_cells.*.proj.weight`                      | `bert.encoder.layer.*.output.dense.weight`

				# Helper function to convert MXNET Arrays to PyTorch
				def to_torch(UpperCamelCase__				:      int      ) -> nn.Parameter:
								return nn.Parameter(torch.FloatTensor(mx_array.data().asnumpy()      )      )

				# Check param shapes and map new HF param back
				def check_and_map_params(UpperCamelCase__				:      Union[str, Any] ,     UpperCamelCase__				:      Dict      ):
								__lowerCamelCase		       =    hf_param.shape

								__lowerCamelCase		       =    to_torch(params[gluon_param]      )
								__lowerCamelCase		       =    gluon_param.shape

								assert (
								    shape_hf == shape_gluon
								), F"""The gluon parameter {gluon_param} has shape {shape_gluon}, but expects shape {shape_hf} for Transformers"""

								return gluon_param

				__lowerCamelCase		       =    check_and_map_params(
				    hf_bort_model.bert.embeddings.word_embeddings.weight ,     'word_embed.0.weight'      )
				__lowerCamelCase		       =    check_and_map_params(
				    hf_bort_model.bert.embeddings.position_embeddings.weight ,     'encoder.position_weight'      )
				__lowerCamelCase		       =    check_and_map_params(
				    hf_bort_model.bert.embeddings.LayerNorm.bias ,     'encoder.layer_norm.beta'      )
				__lowerCamelCase		       =    check_and_map_params(
				    hf_bort_model.bert.embeddings.LayerNorm.weight ,     'encoder.layer_norm.gamma'      )

				# Inspired by RoBERTa conversion script, we just zero them out (Bort does not use them)
				__lowerCamelCase		       =    torch.zeros_like(
				    hf_bort_model.bert.embeddings.token_type_embeddings.weight.data      )

				for i in range(hf_bort_config.num_hidden_layers      ):
								__lowerCamelCase		       =    hf_bort_model.bert.encoder.layer[i]

								# self attention
								__lowerCamelCase		       =    layer.attention.self

								__lowerCamelCase		       =    check_and_map_params(
								    self_attn.key.bias.data ,     F"""encoder.transformer_cells.{i}.attention_cell.proj_key.bias"""      )

								__lowerCamelCase		       =    check_and_map_params(
								    self_attn.key.weight.data ,     F"""encoder.transformer_cells.{i}.attention_cell.proj_key.weight"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    self_attn.query.bias.data ,     F"""encoder.transformer_cells.{i}.attention_cell.proj_query.bias"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    self_attn.query.weight.data ,     F"""encoder.transformer_cells.{i}.attention_cell.proj_query.weight"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    self_attn.value.bias.data ,     F"""encoder.transformer_cells.{i}.attention_cell.proj_value.bias"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    self_attn.value.weight.data ,     F"""encoder.transformer_cells.{i}.attention_cell.proj_value.weight"""      )

								# self attention output
								__lowerCamelCase		       =    layer.attention.output

								__lowerCamelCase		       =    check_and_map_params(
								    self_output.dense.bias ,     F"""encoder.transformer_cells.{i}.proj.bias"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    self_output.dense.weight ,     F"""encoder.transformer_cells.{i}.proj.weight"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    self_output.LayerNorm.bias ,     F"""encoder.transformer_cells.{i}.layer_norm.beta"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    self_output.LayerNorm.weight ,     F"""encoder.transformer_cells.{i}.layer_norm.gamma"""      )

								# intermediate
								__lowerCamelCase		       =    layer.intermediate

								__lowerCamelCase		       =    check_and_map_params(
								    intermediate.dense.bias ,     F"""encoder.transformer_cells.{i}.ffn.ffn_1.bias"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    intermediate.dense.weight ,     F"""encoder.transformer_cells.{i}.ffn.ffn_1.weight"""      )

								# output
								__lowerCamelCase		       =    layer.output

								__lowerCamelCase		       =    check_and_map_params(
								    bert_output.dense.bias ,     F"""encoder.transformer_cells.{i}.ffn.ffn_2.bias"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    bert_output.dense.weight ,     F"""encoder.transformer_cells.{i}.ffn.ffn_2.weight"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    bert_output.LayerNorm.bias ,     F"""encoder.transformer_cells.{i}.ffn.layer_norm.beta"""      )
								__lowerCamelCase		       =    check_and_map_params(
								    bert_output.LayerNorm.weight ,     F"""encoder.transformer_cells.{i}.ffn.layer_norm.gamma"""      )

				# Save space and energy 🎄
				hf_bort_model.half()

				# Compare output of both models
				__lowerCamelCase		       =    RobertaTokenizer.from_pretrained('roberta-base'      )

				__lowerCamelCase		       =    tokenizer.encode_plus(UpperCamelCase__      )['input_ids']

				# Get gluon output
				__lowerCamelCase		       =    mx.nd.array([input_ids]      )
				__lowerCamelCase		       =    original_bort(inputs=UpperCamelCase__ ,     token_types=[]      )

				# Get Transformer output (save and reload model again)
				hf_bort_model.save_pretrained(UpperCamelCase__      )
				__lowerCamelCase		       =    BertModel.from_pretrained(UpperCamelCase__      )
				hf_bort_model.eval()

				__lowerCamelCase		       =    tokenizer.encode_plus(UpperCamelCase__ ,     return_tensors='pt'      )
				__lowerCamelCase		       =    hf_bort_model(**UpperCamelCase__      )[0]

				__lowerCamelCase		       =    output_gluon[0].asnumpy()
				__lowerCamelCase		       =    output_hf[0].detach().numpy()

				__lowerCamelCase		       =    np.max(np.abs(hf_layer - gluon_layer      )      ).item()
				__lowerCamelCase		       =    np.allclose(UpperCamelCase__ ,     UpperCamelCase__ ,     atol=1E-3      )

				if success:
								print('✔️ Both model do output the same tensors'      )
				else:
								print('❌ Both model do **NOT** output the same tensors'      )
								print('Absolute difference is:' ,     UpperCamelCase__      )


if __name__ == "__main__":
					__A        =    argparse.ArgumentParser()
					# Required parameters
					parser.add_argument(
					    "--bort_checkpoint_path", default=None, type=str, required=True, help="Path the official Bort params file."
					)
					parser.add_argument(
					    "--pytorch_dump_folder_path", default=None, type=str, required=True, help="Path to the output PyTorch model."
					)
					__A        =    parser.parse_args()
					convert_bort_checkpoint_to_pytorch(args.bort_checkpoint_path, args.pytorch_dump_folder_path)








from math import pi, sqrt, tan







def 			lowerCamelCase_		(       UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if side_length < 0:
								raise ValueError('surface_area_cube() only accepts non-negative values'      )
				return 6 * side_length**2







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if length < 0 or breadth < 0 or height < 0:
								raise ValueError('surface_area_cuboid() only accepts non-negative values'      )
				return 2 * ((length * breadth) + (breadth * height) + (length * height))







def 			lowerCamelCase_		(       UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if radius < 0:
								raise ValueError('surface_area_sphere() only accepts non-negative values'      )
				return 4 * pi * radius**2







def 			lowerCamelCase_		(       UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if radius < 0:
								raise ValueError('surface_area_hemisphere() only accepts non-negative values'      )
				return 3 * pi * radius**2







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if radius < 0 or height < 0:
								raise ValueError('surface_area_cone() only accepts non-negative values'      )
				return pi * radius * (radius + (height**2 + radius**2) ** 0.5)







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if radius_a < 0 or radius_a < 0 or height < 0:
								raise ValueError(
								    'surface_area_conical_frustum() only accepts non-negative values'      )
				__lowerCamelCase		       =    (height**2 + (radius_a - radius_a) ** 2) ** 0.5
				return pi * ((slant_height * (radius_a + radius_a)) + radius_a**2 + radius_a**2)







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if radius < 0 or height < 0:
								raise ValueError('surface_area_cylinder() only accepts non-negative values'      )
				return 2 * pi * radius * (height + radius)







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if torus_radius < 0 or tube_radius < 0:
								raise ValueError('surface_area_torus() only accepts non-negative values'      )
				if torus_radius < tube_radius:
								raise ValueError(
								    'surface_area_torus() does not support spindle or self intersecting tori'      )
				return 4 * pow(UpperCamelCase__ ,     2      ) * torus_radius * tube_radius







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if length < 0 or width < 0:
								raise ValueError('area_rectangle() only accepts non-negative values'      )
				return length * width







def 			lowerCamelCase_		(       UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if side_length < 0:
								raise ValueError('area_square() only accepts non-negative values'      )
				return side_length**2







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if base < 0 or height < 0:
								raise ValueError('area_triangle() only accepts non-negative values'      )
				return (base * height) / 2







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if sidea < 0 or sidea < 0 or sidea < 0:
								raise ValueError('area_triangle_three_sides() only accepts non-negative values'      )
				elif sidea + sidea < sidea or sidea + sidea < sidea or sidea + sidea < sidea:
								raise ValueError('Given three sides do not form a triangle'      )
				__lowerCamelCase		       =    (sidea + sidea + sidea) / 2
				__lowerCamelCase		       =    sqrt(
				    semi_perimeter
				    * (semi_perimeter - sidea)
				    * (semi_perimeter - sidea)
				    * (semi_perimeter - sidea)      )
				return area







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if base < 0 or height < 0:
								raise ValueError('area_parallelogram() only accepts non-negative values'      )
				return base * height







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if basea < 0 or basea < 0 or height < 0:
								raise ValueError('area_trapezium() only accepts non-negative values'      )
				return 1 / 2 * (basea + basea) * height







def 			lowerCamelCase_		(       UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if radius < 0:
								raise ValueError('area_circle() only accepts non-negative values'      )
				return pi * radius**2







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if radius_x < 0 or radius_y < 0:
								raise ValueError('area_ellipse() only accepts non-negative values'      )
				return pi * radius_x * radius_y







def 			lowerCamelCase_		(       UpperCamelCase__				:      float ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if diagonal_a < 0 or diagonal_a < 0:
								raise ValueError('area_rhombus() only accepts non-negative values'      )
				return 1 / 2 * diagonal_a * diagonal_a







def 			lowerCamelCase_		(       UpperCamelCase__				:      int ,     UpperCamelCase__				:      float      )     ->       float:





				"""simple docstring"""


				if not isinstance(UpperCamelCase__ ,     UpperCamelCase__      ) or sides < 3:
								raise ValueError(
								    'area_reg_polygon() only accepts integers greater than or \
equal to three as number of sides'      )
				elif length < 0:
								raise ValueError(
								    'area_reg_polygon() only accepts non-negative values as \
length of a side'      )
				return (sides * length**2) / (4 * tan(pi / sides      ))
				return (sides * length**2) / (4 * tan(pi / sides      ))


if __name__ == "__main__":
					import doctest

					doctest.testmod(verbose=True)  # verbose so we can see methods missing tests

					print("[DEMO] Areas of various geometric shapes: \n")
					print(f'''Rectangle: {area_rectangle(10, 20) = }''')
					print(f'''Square: {area_square(10) = }''')
					print(f'''Triangle: {area_triangle(10, 10) = }''')
					print(f'''Triangle: {area_triangle_three_sides(5, 12, 13) = }''')
					print(f'''Parallelogram: {area_parallelogram(10, 20) = }''')
					print(f'''Rhombus: {area_rhombus(10, 20) = }''')
					print(f'''Trapezium: {area_trapezium(10, 20, 30) = }''')
					print(f'''Circle: {area_circle(20) = }''')
					print(f'''Ellipse: {area_ellipse(10, 20) = }''')
					print("\nSurface Areas of various geometric shapes: \n")
					print(f'''Cube: {surface_area_cube(20) = }''')
					print(f'''Cuboid: {surface_area_cuboid(10, 20, 30) = }''')
					print(f'''Sphere: {surface_area_sphere(20) = }''')
					print(f'''Hemisphere: {surface_area_hemisphere(20) = }''')
					print(f'''Cone: {surface_area_cone(10, 20) = }''')
					print(f'''Conical Frustum: {surface_area_conical_frustum(10, 20, 30) = }''')
					print(f'''Cylinder: {surface_area_cylinder(10, 20) = }''')
					print(f'''Torus: {surface_area_torus(20, 10) = }''')
					print(f'''Equilateral Triangle: {area_reg_polygon(3, 10) = }''')
					print(f'''Square: {area_reg_polygon(4, 10) = }''')
					print(f'''Reqular Pentagon: {area_reg_polygon(5, 10) = }''')


