
'''simple docstring'''


import os
import sys
import tempfile

import torch

from .state import AcceleratorState
from .utils import PrecisionType, PrepareForLaunch, is_mps_available, patch_environment




def lowercase_	(   _lowercase			,       _lowercase=()			,       _lowercase=None			,       _lowercase="no"			,       _lowercase="29500"				)     ->							Tuple:
					'''simple docstring'''

					lowerCamelCase_					:      Union[str, Any]     =		False
					lowerCamelCase_					:      List[Any]     =		False
					if any(key.startswith('''KAGGLE'''				) for key in os.environ.keys()				):
										lowerCamelCase_					:      Dict     =		True
					elif "IPython" in sys.modules:
										lowerCamelCase_					:      List[Any]     =		'''google.colab''' in str(sys.modules['''IPython'''].get_ipython()				)

					try:
										lowerCamelCase_					:      Optional[Any]     =		PrecisionType(mixed_precision.lower()				)
					except ValueError:
										raise ValueError(
										    F"""Unknown mixed_precision mode: {args.mixed_precision.lower()}. Choose between {PrecisionType.list()}."""				)

					if (in_colab or in_kaggle) and (os.environ.get('''TPU_NAME'''			,       _lowercase				) is not None):
										# TPU launch
										import torch_xla.distributed.xla_multiprocessing as xmp

										if len(AcceleratorState._shared_state				) > 0:
															raise ValueError(
															    '''To train on TPU in Colab or Kaggle Kernel, the `Accelerator` should only be initialized inside '''
															    '''your training function. Restart your notebook and make sure no cells initializes an '''
															    '''`Accelerator`.'''				)
										if num_processes is None:
															lowerCamelCase_					:      Optional[Any]     =		8

										lowerCamelCase_					:      str     =		PrepareForLaunch(_lowercase			,       distributed_type='''TPU'''				)
										print(F"""Launching a training on {num_processes} TPU cores."""				)
										xmp.spawn(_lowercase			,       args=_lowercase			,       nprocs=_lowercase			,       start_method='''fork'''				)
					elif in_colab:
										# No need for a distributed launch otherwise as it's either CPU or one GPU.
										if torch.cuda.is_available():
															print('''Launching training on one GPU.'''				)
										else:
															print('''Launching training on one CPU.'''				)
										function(*_lowercase				)
					else:
										if num_processes is None:
															raise ValueError(
															    '''You have to specify the number of GPUs you would like to use, add `num_processes=...` to your call.'''				)

										if num_processes > 1:
															# Multi-GPU launch
															from torch.multiprocessing import start_processes
															from torch.multiprocessing.spawn import ProcessRaisedException

															if len(AcceleratorState._shared_state				) > 0:
																				raise ValueError(
																				    '''To launch a multi-GPU training from your notebook, the `Accelerator` should only be initialized '''
																				    '''inside your training function. Restart your notebook and make sure no cells initializes an '''
																				    '''`Accelerator`.'''				)

															if torch.cuda.is_initialized():
																				raise ValueError(
																				    '''To launch a multi-GPU training from your notebook, you need to avoid running any instruction '''
																				    '''using `torch.cuda` in any cell. Restart your notebook and make sure no cells use any CUDA '''
																				    '''function.'''				)

															# torch.distributed will expect a few environment variable to be here. We set the ones common to each
															# process here (the other ones will be set be the launcher).
															with patch_environment(
															    world_size=_lowercase			,       master_addr='''127.0.01'''			,       master_port=_lowercase			,       mixed_precision=_lowercase				):
																				lowerCamelCase_					:      Union[str, Any]     =		PrepareForLaunch(_lowercase			,       distributed_type='''MULTI_GPU'''				)
																				print(F"""Launching training on {num_processes} GPUs."""				)
																				try:
																									start_processes(_lowercase			,       args=_lowercase			,       nprocs=_lowercase			,       start_method='''fork'''				)
																				except ProcessRaisedException as e:
																									if "Cannot re-initialize CUDA in forked subprocess" in e.args[0]:
																														raise RuntimeError(
																														    '''CUDA has been initialized before the `notebook_launcher` could create a forked subprocess. '''
																														    '''This likely stems from an outside import causing issues once the `notebook_launcher()` is called. '''
																														    '''Please review your imports and test them when running the `notebook_launcher()` to identify '''
																														    '''which one is problematic.'''				) from e

										else:
															# No need for a distributed launch otherwise as it's either CPU, GPU or MPS.
															if is_mps_available():
																				lowerCamelCase_					:      Tuple     =		'''1'''
																				print('''Launching training on MPS.'''				)
															elif torch.cuda.is_available():
																				print('''Launching training on one GPU.'''				)
															else:
																				print('''Launching training on CPU.'''				)
															function(*_lowercase				)






def lowercase_	(   _lowercase			,       _lowercase=()			,       _lowercase=2				)     ->							Dict:
					'''simple docstring'''

					from torch.multiprocessing import start_processes

					with tempfile.NamedTemporaryFile() as tmp_file:
										# torch.distributed will expect a few environment variable to be here. We set the ones common to each
										# process here (the other ones will be set be the launcher).
										with patch_environment(
										    world_size=_lowercase			,       master_addr='''127.0.01'''			,       master_port='''29500'''			,       accelerate_mixed_precision='''no'''			,       accelerate_debug_rdv_file=tmp_file.name			,       accelerate_use_cpu='''yes'''			,       ):
															lowerCamelCase_					:      int     =		PrepareForLaunch(_lowercase			,       debug=_lowercase				)
															start_processes(_lowercase			,       args=_lowercase			,       nprocs=_lowercase			,       start_method='''fork'''				)




'''simple docstring'''


import os
import shutil
import tempfile
from unittest import TestCase
from unittest.mock import patch

import numpy as np
from datasets import Dataset

from transformers.models.realm.configuration_realm import RealmConfig
from transformers.models.realm.retrieval_realm import _REALM_BLOCK_RECORDS_FILENAME, RealmRetriever
from transformers.models.realm.tokenization_realm import VOCAB_FILES_NAMES, RealmTokenizer

class 	__lowercase				(  _lowercase    ):

			def        UpperCAmelCase__ (self      ):
								lowerCamelCase_					:      Any     =		tempfile.mkdtemp()
								lowerCamelCase_					:      Optional[int]     =		5

								# Realm tok
								lowerCamelCase_					:      Any     =		[
								    '''[UNK]''',
								    '''[CLS]''',
								    '''[SEP]''',
								    '''[PAD]''',
								    '''[MASK]''',
								    '''test''',
								    '''question''',
								    '''this''',
								    '''is''',
								    '''the''',
								    '''first''',
								    '''second''',
								    '''third''',
								    '''fourth''',
								    '''fifth''',
								    '''record''',
								    '''want''',
								    '''##want''',
								    '''##ed''',
								    '''wa''',
								    '''un''',
								    '''runn''',
								    '''##ing''',
								    ''',''',
								    '''low''',
								    '''lowest''',
								]
								lowerCamelCase_					:      Optional[int]     =		os.path.join(self.tmpdirname			,   '''realm_tokenizer'''      )
								os.makedirs(A			,   exist_ok=A      )
								lowerCamelCase_					:      str     =		os.path.join(A			,   VOCAB_FILES_NAMES['''vocab_file''']      )
								with open(self.vocab_file			,   '''w'''			,   encoding='''utf-8'''      ) as vocab_writer:
													vocab_writer.write(''''''.join([x + '''\n''' for x in vocab_tokens]      )      )

								lowerCamelCase_					:      List[Any]     =		os.path.join(self.tmpdirname			,   '''realm_block_records'''      )
								os.makedirs(A			,   exist_ok=A      )

			def        UpperCAmelCase__ (self      ):
								return RealmTokenizer.from_pretrained(os.path.join(self.tmpdirname			,   '''realm_tokenizer'''      )      )

			def        UpperCAmelCase__ (self      ):
								shutil.rmtree(self.tmpdirname      )

			def        UpperCAmelCase__ (self      ):
								lowerCamelCase_					:      int     =		RealmConfig(num_block_records=self.num_block_records      )
								return config

			def        UpperCAmelCase__ (self      ):
								lowerCamelCase_					:      Optional[int]     =		Dataset.from_dict(
								    {
								        '''id''': ['''0''', '''1'''],
								        '''question''': ['''foo''', '''bar'''],
								        '''answers''': [['''Foo''', '''Bar'''], ['''Bar''']],
								    }      )
								return dataset

			def        UpperCAmelCase__ (self      ):
								lowerCamelCase_					:      Any     =		np.array(
								    [
								        B'''This is the first record''',
								        B'''This is the second record''',
								        B'''This is the third record''',
								        B'''This is the fourth record''',
								        B'''This is the fifth record''',
								        B'''This is a longer longer longer record''',
								    ]			,   dtype=A			,   )
								return block_records

			def        UpperCAmelCase__ (self      ):
								lowerCamelCase_					:      Dict     =		RealmRetriever(
								    block_records=self.get_dummy_block_records()			,   tokenizer=self.get_tokenizer()			,   )
								return retriever

			def        UpperCAmelCase__ (self      ):
								lowerCamelCase_					:      Optional[Any]     =		self.get_config()
								lowerCamelCase_					:      List[Any]     =		self.get_dummy_retriever()
								lowerCamelCase_					:      Dict     =		retriever.tokenizer

								lowerCamelCase_					:      List[Any]     =		np.array([0, 3]			,   dtype='''long'''      )
								lowerCamelCase_					:      int     =		tokenizer(['''Test question''']      ).input_ids
								lowerCamelCase_					:      Any     =		tokenizer(
								    ['''the fourth''']			,   add_special_tokens=A			,   return_token_type_ids=A			,   return_attention_mask=A			,   ).input_ids
								lowerCamelCase_					:      Any     =		config.reader_seq_len

								lowerCamelCase_,      lowerCamelCase_,      lowerCamelCase_,      lowerCamelCase_					:      Tuple     =		retriever(
								    A			,   A			,   answer_ids=A			,   max_length=A			,   return_tensors='''np'''      )

								self.assertEqual(len(A      )			,   2      )
								self.assertEqual(len(A      )			,   2      )
								self.assertEqual(len(A      )			,   2      )
								self.assertEqual(concat_inputs.input_ids.shape			,   (2, 1_0)      )
								self.assertEqual(concat_inputs.attention_mask.shape			,   (2, 1_0)      )
								self.assertEqual(concat_inputs.token_type_ids.shape			,   (2, 1_0)      )
								self.assertEqual(concat_inputs.special_tokens_mask.shape			,   (2, 1_0)      )
								self.assertEqual(
								    tokenizer.convert_ids_to_tokens(concat_inputs.input_ids[0]      )			,   ['''[CLS]''', '''test''', '''question''', '''[SEP]''', '''this''', '''is''', '''the''', '''first''', '''record''', '''[SEP]''']			,   )
								self.assertEqual(
								    tokenizer.convert_ids_to_tokens(concat_inputs.input_ids[1]      )			,   ['''[CLS]''', '''test''', '''question''', '''[SEP]''', '''this''', '''is''', '''the''', '''fourth''', '''record''', '''[SEP]''']			,   )

			def        UpperCAmelCase__ (self      ):
								lowerCamelCase_					:      str     =		self.get_config()
								lowerCamelCase_					:      Optional[Any]     =		self.get_dummy_retriever()
								lowerCamelCase_					:      Optional[int]     =		retriever.tokenizer

								lowerCamelCase_					:      int     =		np.array([0, 3, 5]			,   dtype='''long'''      )
								lowerCamelCase_					:      List[Any]     =		tokenizer(['''Test question''']      ).input_ids
								lowerCamelCase_					:      int     =		tokenizer(
								    ['''the fourth''', '''longer longer''']			,   add_special_tokens=A			,   return_token_type_ids=A			,   return_attention_mask=A			,   ).input_ids
								lowerCamelCase_					:      Tuple     =		config.reader_seq_len

								lowerCamelCase_,      lowerCamelCase_,      lowerCamelCase_,      lowerCamelCase_					:      int     =		retriever(
								    A			,   A			,   answer_ids=A			,   max_length=A			,   return_tensors='''np'''      )

								self.assertEqual([False, True, True]			,   A      )
								self.assertEqual([[-1, -1, -1], [6, -1, -1], [6, 7, 8]]			,   A      )
								self.assertEqual([[-1, -1, -1], [7, -1, -1], [7, 8, 9]]			,   A      )






			def        UpperCAmelCase__ (self      ):
								lowerCamelCase_					:      Any     =		self.get_dummy_retriever()
								retriever.save_pretrained(os.path.join(self.tmpdirname			,   '''realm_block_records'''      )      )

								# Test local path
								lowerCamelCase_					:      str     =		retriever.from_pretrained(os.path.join(self.tmpdirname			,   '''realm_block_records'''      )      )
								self.assertEqual(retriever.block_records[0]			,   B'''This is the first record'''      )

								# Test mocked remote path
								with patch('''transformers.models.realm.retrieval_realm.hf_hub_download'''      ) as mock_hf_hub_download:
													lowerCamelCase_					:      Dict     =		os.path.join(
													    os.path.join(self.tmpdirname			,   '''realm_block_records'''      )			,   _REALM_BLOCK_RECORDS_FILENAME      )
													lowerCamelCase_					:      str     =		RealmRetriever.from_pretrained('''google/realm-cc-news-pretrained-openqa'''      )

								self.assertEqual(retriever.block_records[0]			,   B'''This is the first record'''      )


