
"""simple docstring"""





import logging
import os
import threading
import time


try:
				import warnings
except ImportError:
				_a								=						None

try:
				import msvcrt
except ImportError:
				_a								=						None

try:
				import fcntl
except ImportError:
				_a								=						None


# Backward compatibility
# ------------------------------------------------
try:
				TimeoutError
except NameError:
				_a								=						OSError


# Data
# ------------------------------------------------
_a								=						[
    """Timeout""",
    """BaseFileLock""",
    """WindowsFileLock""",
    """UnixFileLock""",
    """SoftFileLock""",
    """FileLock""",
]

_a								=						"""3.0.12"""


_a								=						None



def  lowerCamelCase__						(     )				->						List[Any]:


					"""simple docstring"""





					global _logger
					_UpperCamelCase									=    _logger or logging.getLogger(__name__      )
					return _logger






class        _UpperCAmelCase(       lowerCamelCase      ):



		def __init__(   self							,						__a)			->			Tuple:






							'''simple docstring'''
							_UpperCamelCase									=    lock_file
							return None




		def __str__(   self)			->			str:






							'''simple docstring'''
							_UpperCamelCase									=    F'''The file lock \'{self.lock_file}\' could not be acquired.'''
							return temp






class        _UpperCAmelCase:



		def __init__(   self							,						__a)			->			Optional[Any]:






							'''simple docstring'''
							_UpperCamelCase									=    lock
							return None



		def __enter__(   self)			->			List[Any]:






							'''simple docstring'''
							return self.lock




		def __exit__(   self							,						__a							,						__a							,						__a)			->			List[str]:






							'''simple docstring'''
							self.lock.release()
							return None






class        _UpperCAmelCase:



		def __init__(   self							,						__a							,						__a=-1							,						__a=None)			->			Optional[Any]:






							'''simple docstring'''
							_UpperCamelCase									=    max_filename_length if max_filename_length is not None else 2_55
							# Hash the filename if it's too long
							_UpperCamelCase									=    self.hash_filename_if_too_long(__a							,						__a)
							# The path to the lock file.
							_UpperCamelCase									=    lock_file

							# The file descriptor for the *_lock_file* as it is returned by the
							# os.open() function.
							# This file lock is only NOT None, if the object currently holds the
							# lock.
							_UpperCamelCase									=    None

							# The default timeout value.
							_UpperCamelCase									=    timeout

							# We use this lock primarily for the lock counter.
							_UpperCamelCase									=    threading.Lock()

							# The lock counter is used for implementing the nested locking
							# mechanism. Whenever the lock is acquired, the counter is increased and
							# the lock is only released, when this value is 0 again.
							_UpperCamelCase									=    0
							return None



		@property
		def 		UpperCAmelCase				(   self)			->			str:






							'''simple docstring'''
							return self._lock_file



		@property
		def 		UpperCAmelCase				(   self)			->			Tuple:






							'''simple docstring'''
							return self._timeout



		@timeout.setter
		def 		UpperCAmelCase				(   self							,						__a)			->			List[str]:






							'''simple docstring'''
							_UpperCamelCase									=    float(__a)
							return None



		def 		UpperCAmelCase				(   self)			->			Any:






							'''simple docstring'''
							raise NotImplementedError()



		def 		UpperCAmelCase				(   self)			->			int:






							'''simple docstring'''
							raise NotImplementedError()



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






							'''simple docstring'''
							return self._lock_file_fd is not None



		def 		UpperCAmelCase				(   self							,						__a=None							,						__a=0.05)			->			str:






							'''simple docstring'''
							# Use the default timeout, if no timeout is provided.
							if timeout is None:
												_UpperCamelCase									=    self.timeout

							# Increment the number right at the beginning.
							# We can still undo it, if something fails.
							with self._thread_lock:
												self._lock_counter += 1

							_UpperCamelCase									=    id(self)
							_UpperCamelCase									=    self._lock_file
							_UpperCamelCase									=    time.time()
							try:
												while True:
																	with self._thread_lock:
																						if not self.is_locked:
																											logger().debug(F'''Attempting to acquire lock {lock_id} on {lock_filename}''')
																											self._acquire()

																	if self.is_locked:
																						logger().debug(F'''Lock {lock_id} acquired on {lock_filename}''')
																						break
																	elif timeout >= 0 and time.time() - start_time > timeout:
																						logger().debug(F'''Timeout on acquiring lock {lock_id} on {lock_filename}''')
																						raise Timeout(self._lock_file)
																	else:
																						logger().debug(
																						    F'''Lock {lock_id} not acquired on {lock_filename}, waiting {poll_intervall} seconds ...''')
																						time.sleep(__a)
							except:  # noqa
												# Something did go wrong, so decrement the counter.
												with self._thread_lock:
																	_UpperCamelCase									=    max(0							,						self._lock_counter - 1)

												raise
							return _Acquire_ReturnProxy(lock=self)



		def 		UpperCAmelCase				(   self							,						__a=False)			->			Tuple:






							'''simple docstring'''
							with self._thread_lock:
												if self.is_locked:
																	self._lock_counter -= 1

																	if self._lock_counter == 0 or force:
																						_UpperCamelCase									=    id(self)
																						_UpperCamelCase									=    self._lock_file

																						logger().debug(F'''Attempting to release lock {lock_id} on {lock_filename}''')
																						self._release()
																						_UpperCamelCase									=    0
																						logger().debug(F'''Lock {lock_id} released on {lock_filename}''')

							return None



		def __enter__(   self)			->			Dict:






							'''simple docstring'''
							self.acquire()
							return self



		def __exit__(   self							,						__a							,						__a							,						__a)			->			List[str]:






							'''simple docstring'''
							self.release()
							return None



		def __del__(   self)			->			str:






							'''simple docstring'''
							self.release(force=__a)
							return None




		def 		UpperCAmelCase				(   self							,						__a							,						__a)			->			str:






							'''simple docstring'''
							_UpperCamelCase									=    os.path.basename(__a)
							if len(__a) > max_length and max_length > 0:
												_UpperCamelCase									=    os.path.dirname(__a)
												_UpperCamelCase									=    str(hash(__a))
												_UpperCamelCase									=    filename[: max_length - len(__a) - 8] + '''...''' + hashed_filename + '''.lock'''
												return os.path.join(__a							,						__a)
							else:
												return path






class        _UpperCAmelCase(       lowerCamelCase      ):



		def __init__(   self							,						__a							,						__a=-1							,						__a=None)			->			Union[str, Any]:






							'''simple docstring'''
							from .file_utils import relative_to_absolute_path

							super().__init__(__a							,						timeout=__a							,						max_filename_length=__a)
							_UpperCamelCase									=    '''\\\\?\\''' + relative_to_absolute_path(self.lock_file)



		def 		UpperCAmelCase				(   self)			->			List[Any]:






							'''simple docstring'''
							_UpperCamelCase									=    os.O_RDWR | os.O_CREAT | os.O_TRUNC

							try:
												_UpperCamelCase									=    os.open(self._lock_file							,						__a)
							except OSError:
												pass
							else:
												try:
																	msvcrt.locking(__a							,						msvcrt.LK_NBLCK							,						1)
												except OSError:
																	os.close(__a)
												else:
																	_UpperCamelCase									=    fd
							return None




		def 		UpperCAmelCase				(   self)			->			Any:






							'''simple docstring'''
							_UpperCamelCase									=    self._lock_file_fd
							_UpperCamelCase									=    None
							msvcrt.locking(__a							,						msvcrt.LK_UNLCK							,						1)
							os.close(__a)

							try:
												os.remove(self._lock_file)
							# Probably another instance of the application
							# that acquired the file lock.
							except OSError:
												pass
							return None






class        _UpperCAmelCase(       lowerCamelCase      ):



		def __init__(   self							,						__a							,						__a=-1							,						__a=None)			->			str:






							'''simple docstring'''
							_UpperCamelCase									=    os.statvfs(os.path.dirname(__a)).f_namemax
							super().__init__(__a							,						timeout=__a							,						max_filename_length=__a)



		def 		UpperCAmelCase				(   self)			->			List[Any]:






							'''simple docstring'''
							_UpperCamelCase									=    os.O_RDWR | os.O_CREAT | os.O_TRUNC
							_UpperCamelCase									=    os.open(self._lock_file							,						__a)

							try:
												fcntl.flock(__a							,						fcntl.LOCK_EX | fcntl.LOCK_NB)
							except OSError:
												os.close(__a)
							else:
												_UpperCamelCase									=    fd
							return None




		def 		UpperCAmelCase				(   self)			->			List[str]:






							'''simple docstring'''
							# Do not remove the lockfile:
							#
							#   https://github.com/benediktschmitt/py-filelock/issues/31
							#   https://stackoverflow.com/questions/17708885/flock-removing-locked-file-without-race-condition
							_UpperCamelCase									=    self._lock_file_fd
							_UpperCamelCase									=    None
							fcntl.flock(__a							,						fcntl.LOCK_UN)
							os.close(__a)
							return None






class        _UpperCAmelCase(       lowerCamelCase      ):



		def 		UpperCAmelCase				(   self)			->			Any:






							'''simple docstring'''
							_UpperCamelCase									=    os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_TRUNC
							try:
												_UpperCamelCase									=    os.open(self._lock_file							,						__a)
							except OSError:
												pass
							else:
												_UpperCamelCase									=    fd
							return None




		def 		UpperCAmelCase				(   self)			->			Optional[Any]:






							'''simple docstring'''
							os.close(self._lock_file_fd)
							_UpperCamelCase									=    None

							try:
												os.remove(self._lock_file)
							# The file is already deleted and that's what we want.
							except OSError:
												pass
							return None





_a								=						None

if msvcrt:
				_a								=						WindowsFileLock
elif fcntl:
				_a								=						UnixFileLock
else:
				_a								=						SoftFileLock

				if warnings is not None:
								warnings.warn("""only soft file lock is available""")










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()
_SCREAMING_SNAKE_CASE     :					int      =       logging.get_logger(__name__)

_SCREAMING_SNAKE_CASE     :					Any      =       "The Nymphenburg Palace is a beautiful palace in Munich!"
def      UpperCAmelCase__		(UpperCamelCase_				,UpperCamelCase_							):



     """simple docstring"""






     snake_case											=							{
         '''attention_cell''': '''multi_head''',
         '''num_layers''': 4,
         '''units''': 10_24,
         '''hidden_size''': 7_68,
         '''max_length''': 5_12,
         '''num_heads''': 8,
         '''scaled''': True,
         '''dropout''': 0.1,
         '''use_residual''': True,
         '''embed_size''': 10_24,
         '''embed_dropout''': 0.1,
         '''word_embed''': None,
         '''layer_norm_eps''': 1e-5,
         '''token_type_vocab_size''': 2,
     }

     snake_case											=							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
     snake_case											=							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
     snake_case											=							'''openwebtext_ccnews_stories_books_cased'''

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

     snake_case											=							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_							)
     snake_case											=							original_bort._collect_params_with_prefix()

     # Build our config 🤗
     snake_case											=							{
         '''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_							),
     }

     snake_case											=							BertConfig.from_dict(UpperCamelCase_							)
     snake_case											=							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_							) -> 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_				,UpperCamelCase_							):
          snake_case											=							hf_param.shape

          snake_case											=							to_torch(params[gluon_param]							)
          snake_case											=							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

     snake_case											=							check_and_map_params(
         hf_bort_model.bert.embeddings.word_embeddings.weight				,'''word_embed.0.weight'''							)
     snake_case											=							check_and_map_params(
         hf_bort_model.bert.embeddings.position_embeddings.weight				,'''encoder.position_weight'''							)
     snake_case											=							check_and_map_params(
         hf_bort_model.bert.embeddings.LayerNorm.bias				,'''encoder.layer_norm.beta'''							)
     snake_case											=							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)
     snake_case											=							torch.zeros_like(
         hf_bort_model.bert.embeddings.token_type_embeddings.weight.data							)

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

          # self attention
          snake_case											=							layer.attention.self

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

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

          # self attention output
          snake_case											=							layer.attention.output

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

          # intermediate
          snake_case											=							layer.intermediate

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

          # output
          snake_case											=							layer.output

          snake_case											=							check_and_map_params(
              bert_output.dense.bias				,F'''encoder.transformer_cells.{i}.ffn.ffn_2.bias'''							)
          snake_case											=							check_and_map_params(
              bert_output.dense.weight				,F'''encoder.transformer_cells.{i}.ffn.ffn_2.weight'''							)
          snake_case											=							check_and_map_params(
              bert_output.LayerNorm.bias				,F'''encoder.transformer_cells.{i}.ffn.layer_norm.beta'''							)
          snake_case											=							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
     snake_case											=							RobertaTokenizer.from_pretrained('''roberta-base'''							)

     snake_case											=							tokenizer.encode_plus(UpperCamelCase_							)['''input_ids''']

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

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

     snake_case											=							tokenizer.encode_plus(UpperCamelCase_				,return_tensors='''pt'''							)
     snake_case											=							hf_bort_model(**UpperCamelCase_							)[0]

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

     snake_case											=							np.max(np.abs(hf_layer - gluon_layer							)							).item()
     snake_case											=							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__":
 _SCREAMING_SNAKE_CASE     :					List[Any]      =       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."
 )
 _SCREAMING_SNAKE_CASE     :					Optional[int]      =       parser.parse_args()
 convert_bort_checkpoint_to_pytorch(args.bort_checkpoint_path, args.pytorch_dump_folder_path)




