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


__lowercase							 =					logging.getLogger(__name__)


class 	lowerCamelCase_     (   UpperCAmelCase_ ):






    '''simple docstring'''






    def __init__(	self , __lowercase , __lowercase , __lowercase , __lowercase=None)       ->	Any:
        super().__init__(
            __lowercase , question_encoder_tokenizer=__lowercase , generator_tokenizer=__lowercase , index=__lowercase , init_retrieval=__lowercase , )
        __UpperCamelCase     :int			  =		None







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







    def 			UpperCamelCase__   (	self , __lowercase , __lowercase , __lowercase=torch.floataa)       ->	List[str]:
        __UpperCamelCase     :List[str]			  =		torch.empty(__lowercase , dtype=__lowercase)
        dist.scatter(__lowercase , src=0 , scatter_list=__lowercase , group=self.process_group)
        return target_tensor







    def 			UpperCamelCase__   (	self)       ->	List[Any]:
        __UpperCamelCase     :List[str]			  =		psutil.net_if_addrs()
        # a hacky way to deal with varying network interface names
        __UpperCamelCase     :List[Any]			  =		next((addr for addr in addrs if addr.startswith('''e''')) , __lowercase)
        return ifname







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

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

        # distributed training
        __UpperCamelCase     :str			  =		dist.get_world_size(group=self.process_group)

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

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

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






# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import torch

from ..models.auto import AutoModelForSequenceClassification, AutoTokenizer
from .base import PipelineTool


class 	lowerCamelCase_     (   UpperCAmelCase_ ):






    '''simple docstring'''






    a__	:						Optional[Any]						=      """facebook/bart-large-mnli"""
    a__	:						int						=      (
        """This is a tool that classifies an English text using provided labels. It takes two inputs: `text`, which """
        """should be the text to classify, and `labels`, which should be the list of labels to use for classification. """
        """It returns the most likely label in the list of provided `labels` for the input text."""
    )
    a__	:						Optional[Any]						=      """text_classifier"""
    a__	:						Any						=      AutoTokenizer
    a__	:						str						=      AutoModelForSequenceClassification

    a__	:						str						=      ["""text""", ["""text"""]]
    a__	:						Optional[int]						=      ["""text"""]







    def 			UpperCamelCase__   (	self)       ->	Union[str, Any]:
        super().setup()
        __UpperCamelCase     :int			  =		self.model.config
        __UpperCamelCase     :Optional[Any]			  =		-1
        for idx, label in config.idalabel.items():
            if label.lower().startswith('''entail'''):
                __UpperCamelCase     :List[Any]			  =		int(__lowercase)
        if self.entailment_id == -1:
            raise ValueError('''Could not determine the entailment ID from the model config, please pass it at init.''')







    def 			UpperCamelCase__   (	self , __lowercase , __lowercase)       ->	Union[str, Any]:
        __UpperCamelCase     :Any			  =		labels
        return self.pre_processor(
            [text] * len(__lowercase) , [f"""This example is {label}""" for label in labels] , return_tensors='''pt''' , padding='''max_length''' , )







    def 			UpperCamelCase__   (	self , __lowercase)       ->	Optional[Any]:
        __UpperCamelCase     :List[Any]			  =		outputs.logits
        __UpperCamelCase     :Any			  =		torch.argmax(logits[:, 2]).item()
        return self._labels[label_id]





