

from typing import List, Union

import numpy as np

from ..tokenization_utils import TruncationStrategy
from ..utils import add_end_docstrings, logging
from .base import PIPELINE_INIT_ARGS, ArgumentHandler, ChunkPipeline


a_    :						Union[str, Any]    		=      logging.get_logger(__name__)




class      UpperCamelCase (     SCREAMING_SNAKE_CASE   ):

    def UpperCamelCase			(			self :      Dict							,    snake_case__ :      Tuple    ):

     """simple docstring"""






     if isinstance(snake_case__							,    snake_case__    ):
      SCREAMING_SNAKE_CASE								=			[label.strip() for label in labels.split(','    ) if label.strip()]
     return labels




    def __call__(			self :      List[Any]							,    snake_case__ :      Dict							,    snake_case__ :      Union[str, Any]							,    snake_case__ :      Dict    ):

     """simple docstring"""






     if len(snake_case__    ) == 0 or len(snake_case__    ) == 0:
      raise ValueError('You must include at least one label and at least one sequence.'    )
     if hypothesis_template.format(labels[0]    ) == hypothesis_template:
      raise ValueError(
          (
              'The provided hypothesis_template "{}" was not able to be formatted with the target labels. '
              'Make sure the passed template includes formatting syntax such as {{}} where the label should go.'
          ).format(snake_case__    )    )

     if isinstance(snake_case__							,    snake_case__    ):
      SCREAMING_SNAKE_CASE								=			[sequences]

     SCREAMING_SNAKE_CASE								=			[]
     for sequence in sequences:
      sequence_pairs.extend([[sequence, hypothesis_template.format(snake_case__    )] for label in labels]    )

     return sequence_pairs, sequences




@add_end_docstrings(SCREAMING_SNAKE_CASE   )
class      UpperCamelCase (     SCREAMING_SNAKE_CASE   ):

    def __init__(			self :      List[str]							,    snake_case__ :      List[Any]=ZeroShotClassificationArgumentHandler()							,    *snake_case__ :      Optional[int]							,    **snake_case__ :      Union[str, Any]    ):

     """simple docstring"""






     SCREAMING_SNAKE_CASE								=			args_parser
     super().__init__(*snake_case__							,    **snake_case__    )
     if self.entailment_id == -1:
      logger.warning(
          'Failed to determine \'entailment\' label id from the label2id mapping in the model config. Setting to '
          '-1. Define a descriptive label2id mapping in the model config to ensure correct outputs.'    )

    @property
    def UpperCamelCase			(			self :      str    ):

     """simple docstring"""






     for label, ind in self.model.config.labelaid.items():
      if label.lower().startswith('entail'    ):
       return ind
     return -1

    def UpperCamelCase			(			self :      int							,    snake_case__ :      Union[str, Any]							,    snake_case__ :      int=True							,    snake_case__ :      Tuple=True							,    snake_case__ :      str=TruncationStrategy.ONLY_FIRST							,    **snake_case__ :      str    ):

     """simple docstring"""






     SCREAMING_SNAKE_CASE								=			self.framework
     if self.tokenizer.pad_token is None:
      # Override for tokenizers not supporting padding
      logger.error(
          'Tokenizer was not supporting padding necessary for zero-shot, attempting to use '
          ' `pad_token=eos_token`'    )
      SCREAMING_SNAKE_CASE								=			self.tokenizer.eos_token
     try:
      SCREAMING_SNAKE_CASE								=			self.tokenizer(
          snake_case__							,    add_special_tokens=snake_case__							,    return_tensors=snake_case__							,    padding=snake_case__							,    truncation=snake_case__							,    )
     except Exception as e:
      if "too short" in str(snake_case__    ):
       # tokenizers might yell that we want to truncate
       # to a value that is not even reached by the input.
       # In that case we don't want to truncate.
       # It seems there's not a really better way to catch that
       # exception.

       SCREAMING_SNAKE_CASE								=			self.tokenizer(
           snake_case__							,    add_special_tokens=snake_case__							,    return_tensors=snake_case__							,    padding=snake_case__							,    truncation=TruncationStrategy.DO_NOT_TRUNCATE							,    )
      else:
       raise e

     return inputs

    def UpperCamelCase			(			self :      Tuple							,    **snake_case__ :      Any    ):

     """simple docstring"""






     if kwargs.get('multi_class'							,    snake_case__    ) is not None:
      SCREAMING_SNAKE_CASE								=			kwargs['multi_class']
      logger.warning(
          'The `multi_class` argument has been deprecated and renamed to `multi_label`. '
          '`multi_class` will be removed in a future version of Transformers.'    )
     SCREAMING_SNAKE_CASE								=			{}
     if "candidate_labels" in kwargs:
      SCREAMING_SNAKE_CASE								=			self._args_parser._parse_labels(kwargs['candidate_labels']    )
     if "hypothesis_template" in kwargs:
      SCREAMING_SNAKE_CASE								=			kwargs['hypothesis_template']

     SCREAMING_SNAKE_CASE								=			{}
     if "multi_label" in kwargs:
      SCREAMING_SNAKE_CASE								=			kwargs['multi_label']
     return preprocess_params, {}, postprocess_params

    def __call__(			self :      Tuple							,    snake_case__ :      Union[str, List[str]]							,    *snake_case__ :      int							,    **snake_case__ :      int							,    ):

     """simple docstring"""






     if len(snake_case__    ) == 0:
      pass
     elif len(snake_case__    ) == 1 and "candidate_labels" not in kwargs:
      SCREAMING_SNAKE_CASE								=			args[0]
     else:
      raise ValueError(F"""Unable to understand extra arguments {args}"""    )

     return super().__call__(snake_case__							,    **snake_case__    )

    def UpperCamelCase			(			self :      Tuple							,    snake_case__ :      Any							,    snake_case__ :      Union[str, Any]=None							,    snake_case__ :      str="This example is {}."    ):

     """simple docstring"""






     SCREAMING_SNAKE_CASE						,	SCREAMING_SNAKE_CASE								=			self._args_parser(snake_case__							,    snake_case__							,    snake_case__    )

     for i, (candidate_label, sequence_pair) in enumerate(zip(snake_case__							,    snake_case__    )    ):
      SCREAMING_SNAKE_CASE								=			self._parse_and_tokenize([sequence_pair]    )

      yield {
          "candidate_label": candidate_label,
          "sequence": sequences[0],
          "is_last": i == len(snake_case__    ) - 1,
          **model_input,
      }

    def UpperCamelCase			(			self :      Union[str, Any]							,    snake_case__ :      str    ):

     """simple docstring"""






     SCREAMING_SNAKE_CASE								=			inputs['candidate_label']
     SCREAMING_SNAKE_CASE								=			inputs['sequence']
     SCREAMING_SNAKE_CASE								=			{k: inputs[k] for k in self.tokenizer.model_input_names}
     SCREAMING_SNAKE_CASE								=			self.model(**snake_case__    )

     SCREAMING_SNAKE_CASE								=			{
         'candidate_label': candidate_label,
         'sequence': sequence,
         'is_last': inputs['is_last'],
         **outputs,
     }
     return model_outputs




    def UpperCamelCase			(			self :      Optional[int]							,    snake_case__ :      Tuple							,    snake_case__ :      Tuple=False    ):

     """simple docstring"""






     SCREAMING_SNAKE_CASE								=			[outputs['candidate_label'] for outputs in model_outputs]
     SCREAMING_SNAKE_CASE								=			[outputs['sequence'] for outputs in model_outputs]
     SCREAMING_SNAKE_CASE								=			np.concatenate([output['logits'].numpy() for output in model_outputs]    )
     SCREAMING_SNAKE_CASE								=			logits.shape[0]
     SCREAMING_SNAKE_CASE								=			len(snake_case__    )
     SCREAMING_SNAKE_CASE								=			N // n
     SCREAMING_SNAKE_CASE								=			logits.reshape((num_sequences, n, -1)    )

     if multi_label or len(snake_case__    ) == 1:
      # softmax over the entailment vs. contradiction dim for each label independently
      SCREAMING_SNAKE_CASE								=			self.entailment_id
      SCREAMING_SNAKE_CASE								=			-1 if entailment_id == 0 else 0
      SCREAMING_SNAKE_CASE								=			reshaped_outputs[..., [contradiction_id, entailment_id]]
      SCREAMING_SNAKE_CASE								=			np.exp(snake_case__    ) / np.exp(snake_case__    ).sum(-1							,    keepdims=snake_case__    )
      SCREAMING_SNAKE_CASE								=			scores[..., 1]
     else:
      # softmax the "entailment" logits over all candidate labels
      SCREAMING_SNAKE_CASE								=			reshaped_outputs[..., self.entailment_id]
      SCREAMING_SNAKE_CASE								=			np.exp(snake_case__    ) / np.exp(snake_case__    ).sum(-1							,    keepdims=snake_case__    )

     SCREAMING_SNAKE_CASE								=			list(reversed(scores[0].argsort()    )    )
     return {
         "sequence": sequences[0],
         "labels": [candidate_labels[i] for i in top_inds],
         "scores": scores[0, top_inds].tolist(),
     }




#
# This a `torch.distributed` diagnostics script that checks that all GPUs in the cluster (one or
# many nodes) can talk to each other via nccl and allocate gpu memory.
#
# To run first adjust the number of processes and nodes:
#
# python -m torch.distributed.run --nproc_per_node 2 --nnodes 1 torch-distributed-gpu-test.py
#
# You may need to add --master_addr $MASTER_ADDR --master_port $MASTER_PORT if using a custom addr:port
#
# You can also use the rdzv API: --rdzv_endpoint $MASTER_ADDR:$MASTER_PORT --rdzv_backend c10d
#
# use torch.distributed.launch instead of torch.distributed.run for torch < 1.9
#
# If you get a hanging in `barrier` calls you have some network issues, you may try to debug this with:
#
# NCCL_DEBUG=INFO python -m torch.distributed.run --nproc_per_node 2 --nnodes 1 torch-distributed-gpu-test.py
#
# which should tell you what's going on behind the scenes.
#
#
# This script can be run via `srun` in the SLURM environment as well. Here is a SLURM script that
# runs on 2 nodes of 4 gpus per node:
#
# #SBATCH --job-name=test-nodes        # name
# #SBATCH --nodes=2                    # nodes
# #SBATCH --ntasks-per-node=1          # crucial - only 1 task per dist per node!
# #SBATCH --cpus-per-task=10           # number of cores per tasks
# #SBATCH --gres=gpu:4                 # number of gpus
# #SBATCH --time 0:05:00               # maximum execution time (HH:MM:SS)
# #SBATCH --output=%x-%j.out           # output file name
#
# GPUS_PER_NODE=4
# MASTER_ADDR=$(scontrol show hostnames $SLURM_JOB_NODELIST | head -n 1)
# MASTER_PORT=6000
#
# srun --jobid $SLURM_JOBID bash -c 'python -m torch.distributed.run \
# --nproc_per_node $GPUS_PER_NODE --nnodes $SLURM_NNODES --node_rank $SLURM_PROCID \
# --master_addr $MASTER_ADDR --master_port $MASTER_PORT \
# torch-distributed-gpu-test.py'
#

import fcntl
import os
import socket

import torch
import torch.distributed as dist


def        __lowerCAmelCase    (       *_UpperCamelCase		:  Optional[Any]	)		->							Optional[int]:
 '''simple docstring'''


 with open(_UpperCamelCase		,							'r'	) as fh:
  fcntl.flock(_UpperCamelCase		,							fcntl.LOCK_EX	)
  try:
   print(*_UpperCamelCase	)
  finally:
   fcntl.flock(_UpperCamelCase		,							fcntl.LOCK_UN	)


a_    :						int    		=      int(os.environ["LOCAL_RANK"])
torch.cuda.set_device(local_rank)
a_    :						str    		=      torch.device("cuda", local_rank)
a_    :						Optional[int]    		=      socket.gethostname()

a_    :						Union[str, Any]    		=      F"""[{hostname}-{local_rank}]"""

try:
      # test distributed
      dist.init_process_group("nccl")
      dist.all_reduce(torch.ones(1).to(device), op=dist.ReduceOp.SUM)
      dist.barrier()

      # test cuda is available and can allocate memory
      torch.cuda.is_available()
      torch.ones(1).cuda(local_rank)

      # global rank
      a_    :						Dict    		=      dist.get_rank()
      a_    :						Any    		=      dist.get_world_size()

      printflock(F"""{gpu} is OK (global rank: {rank}/{world_size})""")

      dist.barrier()
      if rank == 0:
            printflock(F"""pt={torch.__version__}, cuda={torch.version.cuda}, nccl={torch.cuda.nccl.version()}""")

except Exception:
      printflock(F"""{gpu} is broken""")
      raise

