'''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[Any]	       =       logging.getLogger(__name__)



class       UpperCAmelCase  (						a__ ):





       '''simple docstring'''



       def __init__(						self     ,       __lowerCAmelCase     ,       __lowerCAmelCase     ,       __lowerCAmelCase     ,       __lowerCAmelCase=None			)  ->  Optional[int]:
        super().__init__(
            __lowerCAmelCase     ,       question_encoder_tokenizer=__lowerCAmelCase     ,       generator_tokenizer=__lowerCAmelCase     ,       index=__lowerCAmelCase     ,       init_retrieval=__lowerCAmelCase     ,       )
        lowercase__    :   Union[str, Any]						= None

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

       def _lowerCAmelCase(						self     ,       __lowerCAmelCase     ,       __lowerCAmelCase     ,       __lowerCAmelCase=torch.floataa			)  ->  List[str]:
        lowercase__    :   Optional[int]						= torch.empty(__lowerCAmelCase     ,       dtype=__lowerCAmelCase			)
        dist.scatter(__lowerCAmelCase     ,       src=0     ,       scatter_list=__lowerCAmelCase     ,       group=self.process_group			)
        return target_tensor

       def _lowerCAmelCase(						self			)  ->  int:
        lowercase__    :   Optional[Any]						= psutil.net_if_addrs()
        # a hacky way to deal with varying network interface names
        lowercase__    :   Any						= next((addr for addr in addrs if addr.startswith('''e'''			))     ,       __lowerCAmelCase			)
        return ifname


       def _lowerCAmelCase(						self     ,       __lowerCAmelCase     ,       __lowerCAmelCase			)  ->  Tuple[np.ndarray, List[dict]]:

        # single GPU training
        if not dist.is_initialized():
         lowercase__			,							lowercase__    :   Optional[int]						= self._main_retrieve(__lowerCAmelCase     ,       __lowerCAmelCase			)
         return retrieved_doc_embeds, doc_ids, self.index.get_doc_dicts(__lowerCAmelCase			)

        # distributed training
        lowercase__    :   Any						= dist.get_world_size(group=self.process_group			)

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

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

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


'''simple docstring'''

def       __UpperCamelCase	(       UpperCAmelCase					):
 if not all(x.isalpha() for x in string					):
  raise ValueError('''String must only contain alphabetic characters.'''					)

 lowercase__    :   Tuple						= sorted(string.lower()					)
 return len(UpperCAmelCase					) == len(set(UpperCAmelCase					)					)


if __name__ == "__main__":
  __a:			Union[str, Any]	       =       input("""Enter a string """).strip()

  __a:			Tuple	       =       is_isogram(input_str)
  print(F'{input_str} is {"an" if isogram else "not an"} isogram.')

