





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


__UpperCAmelCase	:       Any    	=							logging.getLogger(__name__)







class    __snake_case	(							__lowerCamelCase      ):





       '''simple docstring'''







       def __init__(  self			:   Dict							,    A			:   Any							,    A			:   Tuple							,    A			:   List[str]							,    A			:   Dict=None		):
         super().__init__(
             A							,    question_encoder_tokenizer=A							,    generator_tokenizer=A							,    index=A							,    init_retrieval=A							,    )
         __snake_case:						List[str]			  =						None




       def 							UpperCAmelCase__			(  self			:   List[str]							,    A			:   int		):
         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
           __snake_case:						Union[str, Any]			  =						self._infer_socket_ifname()
           # avoid clash with the NCCL port
           __snake_case:						Optional[int]			  =						str(distributed_port + 1		)
           __snake_case:						Tuple			  =						dist.new_group(ranks=A							,    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			:   Optional[Any]		):
         return dist.get_rank(group=self.process_group		) == 0




       def 							UpperCAmelCase__			(  self			:   Tuple							,    A			:   Union[str, Any]							,    A			:   Tuple							,    A			:   int=torch.floataa		):
         __snake_case:						Tuple			  =						torch.empty(A							,    dtype=A		)
         dist.scatter(A							,    src=0							,    scatter_list=A							,    group=self.process_group		)
         return target_tensor




       def 							UpperCAmelCase__			(  self			:   Any		):
         __snake_case:						Union[str, Any]			  =						psutil.net_if_addrs()
         # a hacky way to deal with varying network interface names
         __snake_case:						Optional[Any]			  =						next((addr for addr in addrs if addr.startswith("""e"""		))							,    A		)
         return ifname






       def 							UpperCAmelCase__			(  self			:   Dict							,    A			:   np.ndarray							,    A			:   int		):

         # single GPU training
         if not dist.is_initialized():
           __snake_case:						str			  =						self._main_retrieve(A							,    A		)
           return retrieved_doc_embeds, doc_ids, self.index.get_doc_dicts(A		)

         # distributed training
         __snake_case:						Union[str, Any]			  =						dist.get_world_size(group=self.process_group		)

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

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

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













import math







def       A__							(   SCREAMING_SNAKE_CASE__)       ->   int:

  if not isinstance(SCREAMING_SNAKE_CASE__ , SCREAMING_SNAKE_CASE__):
    __snake_case:						Optional[int]			  =						F'''Input value of [number={number}] must be an integer'''
    raise TypeError(SCREAMING_SNAKE_CASE__)

  if number < 1:
    __snake_case:						Optional[int]			  =						F'''Input value of [number={number}] must be > 0'''
    raise ValueError(SCREAMING_SNAKE_CASE__)
  elif number == 1:
    return 3
  elif number == 2:
    return 5
  else:
    __snake_case:						List[Any]			  =						int(math.log(number // 3 , 2)) + 2

    __snake_case:						str			  =						[3, 5]
    __snake_case:						int			  =						2
    __snake_case:						List[str]			  =						3
    for block in range(1 , SCREAMING_SNAKE_CASE__):
      for _ in range(SCREAMING_SNAKE_CASE__):
        proth_list.append(2 ** (block + 1) + proth_list[proth_index - 1])
        proth_index += 1
      increment *= 2

  return proth_list[number - 1]


if __name__ == "__main__":
      import doctest

      doctest.testmod()

      for number in range(11):
            __UpperCAmelCase	:       Optional[int]    	=							0
            try:
                  __UpperCAmelCase	:       int    	=							proth(number)
            except ValueError:
                  print(f'ValueError: there is no {number}th Proth number')
                  continue

            print(f'The {number}th Proth number: {value}')






