import argparse
import collections
from pathlib import Path

import torch
from torch.serialization import default_restore_location

from transformers import BertConfig, DPRConfig, DPRContextEncoder, DPRQuestionEncoder, DPRReader


a_					      = collections.namedtuple(
    'CheckpointState', ['model_dict', 'optimizer_dict', 'scheduler_dict', 'offset', 'epoch', 'encoder_params']
)





def      __lowercase  (		lowerCamelCase      :  str			):
 print(F"Reading saved model from {model_file}"			)
 UpperCamelCase_      :		List[str]				=      torch.load(lowerCamelCase						,						map_location=lambda lowerCamelCase						,						lowerCamelCase			: default_restore_location(lowerCamelCase						,						'cpu'			)			)
 return CheckpointState(**lowerCamelCase			)





class 	_lowercase		:

 def __init__(				self			:							str     ,   snake_case			:							Path    )     ->		Dict:

  """simple docstring"""





  UpperCamelCase_      :		Optional[Any]				=      src_file

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

  """simple docstring"""





  raise NotImplementedError


 @staticmethod
 def 		SCREAMING_SNAKE_CASE__     (				snake_case			:							str     ,   *snake_case			:							Tuple     ,   **snake_case			:							Optional[Any]    )     ->		"DPRState":

  """simple docstring"""





  if comp_type.startswith('c'    ):
   return DPRContextEncoderState(*snake_case     ,   **snake_case    )
  if comp_type.startswith('q'    ):
   return DPRQuestionEncoderState(*snake_case     ,   **snake_case    )
  if comp_type.startswith('r'    ):
   return DPRReaderState(*snake_case     ,   **snake_case    )
  else:
   raise ValueError('Component type must be either \'ctx_encoder\', \'question_encoder\' or \'reader\'.'    )





class 	_lowercase		(      snake_case_ ):

 def 		SCREAMING_SNAKE_CASE__     (				self			:							Any    )     ->		Tuple:

  """simple docstring"""





  UpperCamelCase_      :		Optional[Any]				=      DPRContextEncoder(DPRConfig(**BertConfig.get_config_dict('bert-base-uncased'    )[0]    )    )
  print(f"Loading DPR biencoder from {self.src_file}"    )
  UpperCamelCase_      :		Any				=      load_states_from_checkpoint(self.src_file    )
  UpperCamelCase_,				UpperCamelCase_      :		Optional[int]				=      model.ctx_encoder, 'ctx_model.'
  # Fix changes from https://github.com/huggingface/transformers/commit/614fef1691edb806de976756d4948ecbcd0c0ca3
  UpperCamelCase_      :		List[Any]				=      {'bert_model.embeddings.position_ids': model.ctx_encoder.bert_model.embeddings.position_ids}
  for key, value in saved_state.model_dict.items():
   if key.startswith(snake_case    ):
    UpperCamelCase_      :		Tuple				=      key[len(snake_case    ) :]
    if not key.startswith('encode_proj.'    ):
     UpperCamelCase_      :		Union[str, Any]				=      'bert_model.' + key
    UpperCamelCase_      :		Union[str, Any]				=      value
  encoder.load_state_dict(snake_case    )
  return model





class 	_lowercase		(      snake_case_ ):

 def 		SCREAMING_SNAKE_CASE__     (				self			:							List[str]    )     ->		Optional[int]:

  """simple docstring"""





  UpperCamelCase_      :		Optional[Any]				=      DPRQuestionEncoder(DPRConfig(**BertConfig.get_config_dict('bert-base-uncased'    )[0]    )    )
  print(f"Loading DPR biencoder from {self.src_file}"    )
  UpperCamelCase_      :		Any				=      load_states_from_checkpoint(self.src_file    )
  UpperCamelCase_,				UpperCamelCase_      :		int				=      model.question_encoder, 'question_model.'
  # Fix changes from https://github.com/huggingface/transformers/commit/614fef1691edb806de976756d4948ecbcd0c0ca3
  UpperCamelCase_      :		int				=      {'bert_model.embeddings.position_ids': model.question_encoder.bert_model.embeddings.position_ids}
  for key, value in saved_state.model_dict.items():
   if key.startswith(snake_case    ):
    UpperCamelCase_      :		Optional[int]				=      key[len(snake_case    ) :]
    if not key.startswith('encode_proj.'    ):
     UpperCamelCase_      :		Union[str, Any]				=      'bert_model.' + key
    UpperCamelCase_      :		int				=      value
  encoder.load_state_dict(snake_case    )
  return model





class 	_lowercase		(      snake_case_ ):

 def 		SCREAMING_SNAKE_CASE__     (				self			:							str    )     ->		Tuple:

  """simple docstring"""





  UpperCamelCase_      :		int				=      DPRReader(DPRConfig(**BertConfig.get_config_dict('bert-base-uncased'    )[0]    )    )
  print(f"Loading DPR reader from {self.src_file}"    )
  UpperCamelCase_      :		str				=      load_states_from_checkpoint(self.src_file    )
  # Fix changes from https://github.com/huggingface/transformers/commit/614fef1691edb806de976756d4948ecbcd0c0ca3
  UpperCamelCase_      :		List[str]				=      {
      'encoder.bert_model.embeddings.position_ids': model.span_predictor.encoder.bert_model.embeddings.position_ids
  }
  for key, value in saved_state.model_dict.items():
   if key.startswith('encoder.'    ) and not key.startswith('encoder.encode_proj'    ):
    UpperCamelCase_      :		Dict				=      'encoder.bert_model.' + key[len('encoder.'    ) :]
   UpperCamelCase_      :		Optional[int]				=      value
  model.span_predictor.load_state_dict(snake_case    )
  return model





def      __lowercase  (		lowerCamelCase      :  str						,						lowerCamelCase      :  Path						,						lowerCamelCase      :  Path			):
 UpperCamelCase_      :		int				=      Path(lowerCamelCase			)
 dest_dir.mkdir(exist_ok=lowerCamelCase			)

 UpperCamelCase_      :		Dict				=      DPRState.from_type(lowerCamelCase						,						src_file=lowerCamelCase			)
 UpperCamelCase_      :		Union[str, Any]				=      dpr_state.load_dpr_model()
 model.save_pretrained(lowerCamelCase			)
 model.from_pretrained(lowerCamelCase			)  # sanity check


if __name__ == "__main__":
   a_					      = argparse.ArgumentParser()
   # Required parameters
   parser.add_argument(
       '--type', type=str, help='Type of the component to convert: \'ctx_encoder\', \'question_encoder\' or \'reader\'.'
   )
   parser.add_argument(
       '--src',
       type=str,
       help=(
           'Path to the dpr checkpoint file. They can be downloaded from the official DPR repo'
           ' https://github.com/facebookresearch/DPR. Note that in the official repo, both encoders are stored in the'
           ' \'retriever\' checkpoints.'
       ),
   )
   parser.add_argument('--dest', type=str, default=None, help='Path to the output PyTorch model directory.')
   a_					      = parser.parse_args()

   a_					      = Path(args.src)
   a_					      = F"""converted-{src_file.name}""" if args.dest is None else args.dest
   a_					      = Path(dest_dir)
   assert src_file.exists()
   assert (
       args.type is not None
   ), "Please specify the component type of the DPR model to convert: 'ctx_encoder', 'question_encoder' or 'reader'."
   convert(args.type, src_file, dest_dir)




def      __lowercase  (		lowerCamelCase      :  int = 998001			):
 UpperCamelCase_      :		int				=      0
 for i in range(999						,						99						,						-1			):  # 3 digit numbers range from 999 down to 100
  for j in range(999						,						99						,						-1			):
   UpperCamelCase_      :		str				=      str(i * j			)
   if product_string == product_string[::-1] and i * j < n:
    UpperCamelCase_      :		str				=      max(lowerCamelCase						,						i * j			)
 return answer


if __name__ == "__main__":
   print(F"""{solution() = }""")



