



'''simple docstring'''

import logging
import os
from typing import List, Tuple

import numpy as np
import psutil
import torch
import torch.distributed as dist

from transformers import RagRetriever


_A				:    List[str]     						=logging.getLogger(__name__)



class 		lowerCamelCase__      (						A     ):




					'''simple docstring'''



					def __init__(  self				:	Any     ,  UpperCamelCase_				:	List[str]     ,  UpperCamelCase_				:	List[str]     ,  UpperCamelCase_				:	int     ,  UpperCamelCase_				:	Optional[Any]=None					)  ->       Optional[int]:



						'''simple docstring'''





						super().__init__(
						    UpperCamelCase_     ,  question_encoder_tokenizer=UpperCamelCase_     ,  generator_tokenizer=UpperCamelCase_     ,  index=UpperCamelCase_     ,  init_retrieval=UpperCamelCase_     ,  )
						_lowercase					:       Optional[int]       =		None




					def 						__UpperCAmelCase     (  self				:	str     ,  UpperCamelCase_				:	int					)  ->       Any:



						'''simple docstring'''





						logger.info('initializing retrieval'					)

						# initializing a separate process group for retrieval as the default
						# nccl backend doesn't support gather/scatter operations while gloo
						# is too slow to replace nccl for the core gpu communication
						if dist.is_initialized():
							logger.info('dist initialized'					)
							# needs to be set manually
							_lowercase					:       int       =		self._infer_socket_ifname()
							# avoid clash with the NCCL port
							_lowercase					:       Union[str, Any]       =		str(distributed_port + 1					)
							_lowercase					:       Optional[int]       =		dist.new_group(ranks=UpperCamelCase_     ,  backend='gloo'					)

						# initialize retriever only on the main worker
						if not dist.is_initialized() or self._is_main():
							logger.info('dist not initialized / main'					)
							self.index.init_index()

						# all processes wait untill the retriever is initialized by the main process
						if dist.is_initialized():
							torch.distributed.barrier(group=self.process_group					)




					def 						__UpperCAmelCase     (  self				:	Dict					)  ->       Dict:



						'''simple docstring'''





						return dist.get_rank(group=self.process_group					) == 0




					def 						__UpperCAmelCase     (  self				:	Union[str, Any]     ,  UpperCamelCase_				:	int     ,  UpperCamelCase_				:	Tuple     ,  UpperCamelCase_				:	Optional[Any]=torch.floataa					)  ->       Tuple:



						'''simple docstring'''





						_lowercase					:       Union[str, Any]       =		torch.empty(UpperCamelCase_     ,  dtype=UpperCamelCase_					)
						dist.scatter(UpperCamelCase_     ,  src=0     ,  scatter_list=UpperCamelCase_     ,  group=self.process_group					)
						return target_tensor




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



						'''simple docstring'''





						_lowercase					:       Union[str, Any]       =		psutil.net_if_addrs()
						# a hacky way to deal with varying network interface names
						_lowercase					:       List[str]       =		next((addr for addr in addrs if addr.startswith('e'					))     ,  UpperCamelCase_					)
						return ifname




					def 						__UpperCAmelCase     (  self				:	str     ,  UpperCamelCase_				:	np.ndarray     ,  UpperCamelCase_				:	int					)  ->       Tuple[np.ndarray, List[dict]]:



						'''simple docstring'''





						if not dist.is_initialized():
							_lowercase  ,    _lowercase					:       Optional[Any]       =		self._main_retrieve(UpperCamelCase_     ,  UpperCamelCase_					)
							return retrieved_doc_embeds, doc_ids, self.index.get_doc_dicts(UpperCamelCase_					)

						# distributed training
						_lowercase					:       int       =		dist.get_world_size(group=self.process_group					)

						# gather logic
						_lowercase					:       Any       =		None
						if self._is_main():
							_lowercase					:       Optional[int]       =		[torch.empty(question_hidden_states.shape     ,  dtype=torch.floataa					) for _ in range(UpperCamelCase_					)]
						dist.gather(torch.tensor(UpperCamelCase_					)     ,  dst=0     ,  gather_list=UpperCamelCase_     ,  group=self.process_group					)

						# scatter logic
						_lowercase					:       Optional[Any]       =		question_hidden_states.shape[0]
						_lowercase					:       Optional[Any]       =		[]
						_lowercase					:       int       =		[]
						if self._is_main():
							assert len(UpperCamelCase_					) == world_size
							_lowercase  ,    _lowercase					:       Any       =		self._main_retrieve(torch.cat(UpperCamelCase_					).numpy()     ,  UpperCamelCase_					)
							_lowercase  ,    _lowercase					:       int       =		torch.tensor(UpperCamelCase_					), torch.tensor(UpperCamelCase_					)
							_lowercase					:       str       =		self._chunk_tensor(UpperCamelCase_     ,  UpperCamelCase_					)
							_lowercase					:       int       =		self._chunk_tensor(UpperCamelCase_     ,  UpperCamelCase_					)
						_lowercase					:       List[Any]       =		self._scattered(UpperCamelCase_     ,  [n_queries, n_docs]     ,  target_type=torch.intaa					)
						_lowercase					:       List[Any]       =		self._scattered(UpperCamelCase_     ,  [n_queries, n_docs, question_hidden_states.shape[1]]					)

						return retrieved_doc_embeds.numpy(), doc_ids.numpy(), self.index.get_doc_dicts(UpperCamelCase_					)





'''simple docstring'''

from typing import TYPE_CHECKING

from ...utils import (
    OptionalDependencyNotAvailable,
    _LazyModule,
    is_sentencepiece_available,
    is_tokenizers_available,
    is_torch_available,
)


_A				:    Union[str, Any]     						={'''configuration_reformer''': ['''REFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP''', '''ReformerConfig''']}

try:
		if not is_sentencepiece_available():
				raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
		pass
else:
		_A				:    Dict     						=['''ReformerTokenizer''']

try:
		if not is_tokenizers_available():
				raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
		pass
else:
		_A				:    Union[str, Any]     						=['''ReformerTokenizerFast''']

try:
		if not is_torch_available():
				raise OptionalDependencyNotAvailable()
except OptionalDependencyNotAvailable:
		pass
else:
		_A				:    str     						=[
		    '''REFORMER_PRETRAINED_MODEL_ARCHIVE_LIST''',
		    '''ReformerAttention''',
		    '''ReformerForMaskedLM''',
		    '''ReformerForQuestionAnswering''',
		    '''ReformerForSequenceClassification''',
		    '''ReformerLayer''',
		    '''ReformerModel''',
		    '''ReformerModelWithLMHead''',
		    '''ReformerPreTrainedModel''',
		]


if TYPE_CHECKING:
		from .configuration_reformer import REFORMER_PRETRAINED_CONFIG_ARCHIVE_MAP, ReformerConfig

		try:
				if not is_sentencepiece_available():
						raise OptionalDependencyNotAvailable()
		except OptionalDependencyNotAvailable:
				pass
		else:
				from .tokenization_reformer import ReformerTokenizer

		try:
				if not is_tokenizers_available():
						raise OptionalDependencyNotAvailable()
		except OptionalDependencyNotAvailable:
				pass
		else:
				from .tokenization_reformer_fast import ReformerTokenizerFast

		try:
				if not is_torch_available():
						raise OptionalDependencyNotAvailable()
		except OptionalDependencyNotAvailable:
				pass
		else:
				from .modeling_reformer import (
				    REFORMER_PRETRAINED_MODEL_ARCHIVE_LIST,
				    ReformerAttention,
				    ReformerForMaskedLM,
				    ReformerForQuestionAnswering,
				    ReformerForSequenceClassification,
				    ReformerLayer,
				    ReformerModel,
				    ReformerModelWithLMHead,
				    ReformerPreTrainedModel,
				)

else:
		import sys

		_A				:    Union[str, Any]     						=_LazyModule(__name__, globals()['''__file__'''], _import_structure, module_spec=__spec__)
