



import logging
import math
from functools import partial
from typing import Any, Callable, Dict, Iterable, List, Optional, Sequence, Tuple, Union

import torch

from .tensor_utils import tensor_tree_map, tree_map






def 				A				(					_lowerCamelCase  ):





							'''simple docstring'''




							_lowerCAmelCase     :							Optional[int]    =    []
							if isinstance(_lowerCamelCase				, _lowerCamelCase  ):
														for v in tree.values():
																					shapes.extend(_fetch_dims(_lowerCamelCase  )  )
							elif isinstance(_lowerCamelCase				, (list, tuple)  ):
														for t in tree:
																					shapes.extend(_fetch_dims(_lowerCamelCase  )  )
							elif isinstance(_lowerCamelCase				, torch.Tensor  ):
														shapes.append(tree.shape  )
							else:
														raise ValueError("Not supported"  )

							return shapes






@torch.jit.ignore
def 				A				(					_lowerCamelCase				, _lowerCamelCase  ):





							'''simple docstring'''




							_lowerCAmelCase     :							str    =    []
							for d in reversed(_lowerCamelCase  ):
														idx.append(flat_idx % d  )
														_lowerCAmelCase     :							Dict    =    flat_idx // d

							return tuple(reversed(_lowerCamelCase  )  )






@torch.jit.ignore
def 				A				(					_lowerCamelCase				, _lowerCamelCase				, _lowerCamelCase				, _lowerCamelCase = None				, _lowerCamelCase = None				, ):





							'''simple docstring'''




							def reduce_edge_list(_lowerCamelCase  ) -> None:
														_lowerCAmelCase     :							List[str]    =    True
														for i in range(len(_lowerCamelCase  )  ):
																					_lowerCAmelCase     :							Any    =    -1 * (i + 1)
																					l[reversed_idx] &= tally
																					_lowerCAmelCase     :							str    =    l[reversed_idx]

							if start_edges is None:
														_lowerCAmelCase     :							Optional[int]    =    [s == 0 for s in start]
														reduce_edge_list(_lowerCamelCase  )
							if end_edges is None:
														_lowerCAmelCase     :							Dict    =    [e == (d - 1) for e, d in zip(_lowerCamelCase				, _lowerCamelCase  )]
														reduce_edge_list(_lowerCamelCase  )

							# Base cases. Either start/end are empty and we're done, or the final,
							# one-dimensional tensor can be simply sliced
							if len(_lowerCamelCase  ) == 0:
														return [()]
							elif len(_lowerCamelCase  ) == 1:
														return [(slice(start[0]				, end[0] + 1  ),)]

							_lowerCAmelCase     :							List[Tuple[slice, ...]]    =    []
							_lowerCAmelCase     :							List[slice]    =    []

							# Dimensions common to start and end can be selected directly
							for s, e in zip(_lowerCamelCase				, _lowerCamelCase  ):
														if s == e:
																					path_list.append(slice(_lowerCamelCase				, s + 1  )  )
														else:
																					break

							_lowerCAmelCase     :							Tuple[slice, ...]    =    tuple(_lowerCamelCase  )
							_lowerCAmelCase     :							Tuple    =    len(_lowerCamelCase  )

							# start == end, and we're done
							if divergence_idx == len(_lowerCamelCase  ):
														return [path]

							def upper() -> Tuple[Tuple[slice, ...], ...]:
														assert start_edges is not None
														assert end_edges is not None

														_lowerCAmelCase     :							Optional[int]    =    start[divergence_idx]
														return tuple(
														    path + (slice(_lowerCamelCase				, sdi + 1  ),) + s
														    for s in _get_minimal_slice_set(
														        start[divergence_idx + 1 :]				, [d - 1 for d in dims[divergence_idx + 1 :]]				, dims[divergence_idx + 1 :]				, start_edges=start_edges[divergence_idx + 1 :]				, end_edges=[True for _ in end_edges[divergence_idx + 1 :]]				, )  )

							def lower() -> Tuple[Tuple[slice, ...], ...]:
														assert start_edges is not None
														assert end_edges is not None

														_lowerCAmelCase     :							str    =    end[divergence_idx]
														return tuple(
														    path + (slice(_lowerCamelCase				, edi + 1  ),) + s
														    for s in _get_minimal_slice_set(
														        [0 for _ in start[divergence_idx + 1 :]]				, end[divergence_idx + 1 :]				, dims[divergence_idx + 1 :]				, start_edges=[True for _ in start_edges[divergence_idx + 1 :]]				, end_edges=end_edges[divergence_idx + 1 :]				, )  )

							# If both start and end are at the edges of the subtree rooted at
							# divergence_idx, we can just select the whole subtree at once
							if start_edges[divergence_idx] and end_edges[divergence_idx]:
														slices.append(path + (slice(start[divergence_idx]				, end[divergence_idx] + 1  ),)  )
							# If just start is at the edge, we can grab almost all of the subtree,
							# treating only the ragged bottom edge as an edge case
							elif start_edges[divergence_idx]:
														slices.append(path + (slice(start[divergence_idx]				, end[divergence_idx]  ),)  )
														slices.extend(lower()  )
							# Analogous to the previous case, but the top is ragged this time
							elif end_edges[divergence_idx]:
														slices.extend(upper()  )
														slices.append(path + (slice(start[divergence_idx] + 1				, end[divergence_idx] + 1  ),)  )
							# If both sides of the range are ragged, we need to handle both sides
							# separately. If there's contiguous meat in between them, we can index it
							# in one big chunk
							else:
														slices.extend(upper()  )
														_lowerCAmelCase     :							Tuple    =    end[divergence_idx] - start[divergence_idx]
														if middle_ground > 1:
																					slices.append(path + (slice(start[divergence_idx] + 1				, end[divergence_idx]  ),)  )
														slices.extend(lower()  )

							return slices






@torch.jit.ignore
def 				A				(					_lowerCamelCase				, _lowerCamelCase				, _lowerCamelCase				, _lowerCamelCase  ):





							'''simple docstring'''




							_lowerCAmelCase     :							Any    =    t.shape[:no_batch_dims]
							_lowerCAmelCase     :							List[str]    =    list(_flat_idx_to_idx(_lowerCamelCase				, _lowerCamelCase  )  )
							# _get_minimal_slice_set is inclusive
							_lowerCAmelCase     :							List[str]    =    list(_flat_idx_to_idx(flat_end - 1				, _lowerCamelCase  )  )

							# Get an ordered list of slices to perform
							_lowerCAmelCase     :							str    =    _get_minimal_slice_set(
							    _lowerCamelCase				, _lowerCamelCase				, _lowerCamelCase				, )

							_lowerCAmelCase     :							Optional[int]    =    [t[s] for s in slices]

							return torch.cat([s.view((-1,) + t.shape[no_batch_dims:]  ) for s in sliced_tensors]  )






def 				A				(					_lowerCamelCase				, _lowerCamelCase				, _lowerCamelCase				, _lowerCamelCase				, _lowerCamelCase = False				, _lowerCamelCase = None				, _lowerCamelCase = False				, ):





							'''simple docstring'''




							if not (len(_lowerCamelCase  ) > 0):
														raise ValueError("Must provide at least one input"  )

							_lowerCAmelCase     :							Tuple    =    [shape[:no_batch_dims] for shape in _fetch_dims(_lowerCamelCase  )]
							_lowerCAmelCase     :							Tuple    =    tuple([max(_lowerCamelCase  ) for s in zip(*_lowerCamelCase  )]  )

							def _prep_inputs(_lowerCamelCase  ) -> torch.Tensor:
														if not low_mem:
																					if not sum(t.shape[:no_batch_dims]  ) == no_batch_dims:
																												_lowerCAmelCase     :							Dict    =    t.expand(orig_batch_dims + t.shape[no_batch_dims:]  )
																					_lowerCAmelCase     :							Optional[Any]    =    t.reshape(-1				, *t.shape[no_batch_dims:]  )
														else:
																					_lowerCAmelCase     :							Union[str, Any]    =    t.expand(orig_batch_dims + t.shape[no_batch_dims:]  )
														return t

							_lowerCAmelCase     :							Dict[str, Any]    =    tensor_tree_map(_prep_inputs				, _lowerCamelCase  )
							_lowerCAmelCase     :							Tuple    =    None
							if _out is not None:
														_lowerCAmelCase     :							List[Any]    =    tensor_tree_map(lambda _lowerCamelCase  : t.view([-1] + list(t.shape[no_batch_dims:]  )  )				, _out  )

							_lowerCAmelCase     :							int    =    1
							for d in orig_batch_dims:
														flat_batch_dim *= d

							_lowerCAmelCase     :							Union[str, Any]    =    flat_batch_dim // chunk_size + (flat_batch_dim % chunk_size != 0)

							def _select_chunk(_lowerCamelCase  ) -> torch.Tensor:
														return t[i : i + chunk_size] if t.shape[0] != 1 else t

							_lowerCAmelCase     :							int    =    0
							_lowerCAmelCase     :							Any    =    prepped_outputs
							for _ in range(_lowerCamelCase  ):
														# Chunk the input
														if not low_mem:
																					_lowerCAmelCase     :							List[str]    =    _select_chunk
														else:
																					_lowerCAmelCase     :							Dict    =    partial(
																					    _chunk_slice				, flat_start=_lowerCamelCase				, flat_end=min(_lowerCamelCase				, i + chunk_size  )				, no_batch_dims=len(_lowerCamelCase  )				, )

														_lowerCAmelCase     :							Dict[str, Any]    =    tensor_tree_map(_lowerCamelCase				, _lowerCamelCase  )

														# Run the layer on the chunk
														_lowerCAmelCase     :							int    =    layer(**_lowerCamelCase  )

														# Allocate space for the output
														if out is None:
																					_lowerCAmelCase     :							Union[str, Any]    =    tensor_tree_map(lambda _lowerCamelCase  : t.new_zeros((flat_batch_dim,) + t.shape[1:]  )				, _lowerCamelCase  )

														# Put the chunk in its pre-allocated space
														if isinstance(_lowerCamelCase				, _lowerCamelCase  ):

																					def assign(_lowerCamelCase				, _lowerCamelCase  ) -> None:
																												for k, v in da.items():
																																			if isinstance(_lowerCamelCase				, _lowerCamelCase  ):
																																										assign(_lowerCamelCase				, da[k]  )
																																			else:
																																										if _add_into_out:
																																																	v[i : i + chunk_size] += da[k]
																																										else:
																																																	_lowerCAmelCase     :							Tuple    =    da[k]

																					assign(_lowerCamelCase				, _lowerCamelCase  )
														elif isinstance(_lowerCamelCase				, _lowerCamelCase  ):
																					for xa, xa in zip(_lowerCamelCase				, _lowerCamelCase  ):
																												if _add_into_out:
																																			xa[i : i + chunk_size] += xa
																												else:
																																			_lowerCAmelCase     :							int    =    xa
														elif isinstance(_lowerCamelCase				, torch.Tensor  ):
																					if _add_into_out:
																												out[i : i + chunk_size] += output_chunk
																					else:
																												_lowerCAmelCase     :							List[str]    =    output_chunk
														else:
																					raise ValueError("Not supported"  )

														i += chunk_size

							_lowerCAmelCase     :							Any    =    tensor_tree_map(lambda _lowerCamelCase  : t.view(orig_batch_dims + t.shape[1:]  )				, _lowerCamelCase  )

							return out



class   UpperCAmelCase_    :







							def __init__(   self,			__a = 512,			):

														'''simple docstring'''

														_lowerCAmelCase     :							List[str]    =    max_chunk_size
														_lowerCAmelCase     :							Optional[int]    =    None
														_lowerCAmelCase     :							Optional[tuple]    =    None







							def    snake_case__      (   self,			__a,			__a,			__a):

														'''simple docstring'''

														logging.info("Tuning chunk size...")

														if min_chunk_size >= self.max_chunk_size:
																					return min_chunk_size

														_lowerCAmelCase     :							List[int]    =    [2**l for l in range(int(math.log(self.max_chunk_size,			2)) + 1)]
														_lowerCAmelCase     :							List[Any]    =    [c for c in candidates if c > min_chunk_size]
														_lowerCAmelCase     :							Union[str, Any]    =    [min_chunk_size] + candidates
														candidates[-1] += 4

														def test_chunk_size(__a) -> bool:
																					try:
																												with torch.no_grad():
																																			fn(*__a,			chunk_size=__a)
																												return True
																					except RuntimeError:
																												return False

														_lowerCAmelCase     :							List[Any]    =    0
														_lowerCAmelCase     :							List[str]    =    len(__a) - 1
														while i > min_viable_chunk_size_index:
																					_lowerCAmelCase     :							Tuple    =    test_chunk_size(candidates[i])
																					if not viable:
																												_lowerCAmelCase     :							int    =    (min_viable_chunk_size_index + i) // 2
																					else:
																												_lowerCAmelCase     :							Any    =    i
																												_lowerCAmelCase     :							Union[str, Any]    =    (i + len(__a) - 1) // 2

														return candidates[min_viable_chunk_size_index]







							def    snake_case__      (   self,			__a,			__a):

														'''simple docstring'''

														_lowerCAmelCase     :							Union[str, Any]    =    True
														for aa, aa in zip(__a,			__a):
																					assert type(__a) == type(__a)
																					if isinstance(__a,			(list, tuple)):
																												consistent &= self._compare_arg_caches(__a,			__a)
																					elif isinstance(__a,			__a):
																												_lowerCAmelCase     :							Optional[Any]    =    [v for _, v in sorted(aa.items(),			key=lambda __a: x[0])]
																												_lowerCAmelCase     :							Dict    =    [v for _, v in sorted(aa.items(),			key=lambda __a: x[0])]
																												consistent &= self._compare_arg_caches(__a,			__a)
																					else:
																												consistent &= aa == aa

														return consistent







							def    snake_case__      (   self,			__a,			__a,			__a,			):

														'''simple docstring'''

														_lowerCAmelCase     :							int    =    True
														_lowerCAmelCase     :							tuple    =    tree_map(lambda __a: a.shape if isinstance(__a,			torch.Tensor) else a,			__a,			__a)
														if self.cached_arg_data is not None:
																					# If args have changed shape/value, we need to re-tune
																					assert len(self.cached_arg_data) == len(__a)
																					_lowerCAmelCase     :							Tuple    =    self._compare_arg_caches(self.cached_arg_data,			__a)
														else:
																					# Otherwise, we can reuse the precomputed value
																					_lowerCAmelCase     :							Union[str, Any]    =    False

														if not consistent:
																					_lowerCAmelCase     :							Any    =    self._determine_favorable_chunk_size(
																					    __a,			__a,			__a,			)
																					_lowerCAmelCase     :							Any    =    arg_data

														assert self.cached_chunk_size is not None

														return self.cached_chunk_size







import logging
import os
from dataclasses import dataclass
from typing import List, Optional, Union

import tqdm
from filelock import FileLock

from transformers import (
    BartTokenizer,
    BartTokenizerFast,
    DataProcessor,
    PreTrainedTokenizer,
    RobertaTokenizer,
    RobertaTokenizerFast,
    XLMRobertaTokenizer,
    is_tf_available,
    is_torch_available,
)


snake_case_				=			logging.getLogger(__name__)

@dataclass(frozen=_UpperCAmelCase  )
class 		SCREAMING_SNAKE_CASE__				:
      A_						:				str
      A_						:				str
      A_						:				Optional[str]							=    None
      A_						:				Optional[str]							=    None
      A_						:				Optional[str]							=    None






@dataclass(frozen=_UpperCAmelCase  )
class 		SCREAMING_SNAKE_CASE__				:
      A_						:				List[int]
      A_						:				Optional[List[int]]							=    None
      A_						:				Optional[List[int]]							=    None
      A_						:				Optional[Union[int, float]]							=    None
      A_						:				Optional[int]							=    None


if is_torch_available():
    import torch
    from torch.utils.data import Dataset

    class 		SCREAMING_SNAKE_CASE__				(       _UpperCAmelCase  ):
          A_						:				List[InputFeatures]


          def __init__(self       :      int				,			a__       :      str				,			a__       :      PreTrainedTokenizer				,			a__       :      str				,			a__       :      Optional[int] = None				,			a__       :      List[Any]=False				,			a__       :      bool = False				,			):





             """simple docstring"""



             __snake_case							       =   hans_processors[task]()

             __snake_case							       =   os.path.join(
                 a__				,			'''cached_{}_{}_{}_{}'''.format(
                     '''dev''' if evaluate else '''train'''				,			tokenizer.__class__.__name__				,			str(a__      )				,			a__				,			)				,			)
             __snake_case							       =   processor.get_labels()
             if tokenizer.__class__ in (
                 RobertaTokenizer,
                 RobertaTokenizerFast,
                 XLMRobertaTokenizer,
                 BartTokenizer,
                 BartTokenizerFast,
             ):
                # HACK(label indices are swapped in RoBERTa pretrained model)
                __snake_case       ,	__snake_case							       =   label_list[2], label_list[1]
             __snake_case							       =   label_list

             # Make sure only the first process in distributed training processes the dataset,
             # and the others will use the cache.
             __snake_case							       =   cached_features_file + '''.lock'''
             with FileLock(a__      ):
                if os.path.exists(a__      ) and not overwrite_cache:
                   logger.info(f"""Loading features from cached file {cached_features_file}"""      )
                   __snake_case							       =   torch.load(a__      )
                else:
                   logger.info(f"""Creating features from dataset file at {data_dir}"""      )

                   __snake_case							       =   (
                       processor.get_dev_examples(a__      ) if evaluate else processor.get_train_examples(a__      )
                   )

                   logger.info('''Training examples: %s'''				,			len(a__      )      )
                   __snake_case							       =   hans_convert_examples_to_features(a__				,			a__				,			a__				,			a__      )
                   logger.info('''Saving features into cached file %s'''				,			a__      )
                   torch.save(self.features				,			a__      )


          def __len__(self       :      int      ):





             """simple docstring"""



             return len(self.features      )


          def __getitem__(self       :      Dict				,			a__       :      List[Any]      ):





             """simple docstring"""



             return self.features[i]


          def    a (self       :      List[Any]      ):





             """simple docstring"""



             return self.label_list


if is_tf_available():
    import tensorflow as tf

    class 		SCREAMING_SNAKE_CASE__				:
          A_						:				List[InputFeatures]


          def __init__(self       :      Tuple				,			a__       :      str				,			a__       :      PreTrainedTokenizer				,			a__       :      str				,			a__       :      Optional[int] = 128				,			a__       :      Any=False				,			a__       :      bool = False				,			):





             """simple docstring"""



             __snake_case							       =   hans_processors[task]()
             __snake_case							       =   processor.get_labels()
             if tokenizer.__class__ in (
                 RobertaTokenizer,
                 RobertaTokenizerFast,
                 XLMRobertaTokenizer,
                 BartTokenizer,
                 BartTokenizerFast,
             ):
                # HACK(label indices are swapped in RoBERTa pretrained model)
                __snake_case       ,	__snake_case							       =   label_list[2], label_list[1]
             __snake_case							       =   label_list

             __snake_case							       =   processor.get_dev_examples(a__      ) if evaluate else processor.get_train_examples(a__      )
             __snake_case							       =   hans_convert_examples_to_features(a__				,			a__				,			a__				,			a__      )

             def gen():
                for ex_index, ex in tqdm.tqdm(enumerate(self.features      )				,			desc='''convert examples to features'''      ):
                   if ex_index % 1_0000 == 0:
                      logger.info('''Writing example %d of %d''' % (ex_index, len(a__      ))      )

                   yield (
                       {
                           "example_id": 0,
                           "input_ids": ex.input_ids,
                           "attention_mask": ex.attention_mask,
                           "token_type_ids": ex.token_type_ids,
                       },
                       ex.label,
                   )

             __snake_case							       =   tf.data.Dataset.from_generator(
                 a__				,			(
                     {
                         '''example_id''': tf.intaa,
                         '''input_ids''': tf.intaa,
                         '''attention_mask''': tf.intaa,
                         '''token_type_ids''': tf.intaa,
                     },
                     tf.intaa,
                 )				,			(
                     {
                         '''example_id''': tf.TensorShape([]      ),
                         '''input_ids''': tf.TensorShape([None, None]      ),
                         '''attention_mask''': tf.TensorShape([None, None]      ),
                         '''token_type_ids''': tf.TensorShape([None, None]      ),
                     },
                     tf.TensorShape([]      ),
                 )				,			)


          def    a (self       :      Union[str, Any]      ):





             """simple docstring"""



             return self.dataset


          def __len__(self       :      Dict      ):





             """simple docstring"""



             return len(self.features      )


          def __getitem__(self       :      Any				,			a__       :      Dict      ):





             """simple docstring"""



             return self.features[i]


          def    a (self       :      str      ):





             """simple docstring"""



             return self.label_list

class 		SCREAMING_SNAKE_CASE__				(       _UpperCAmelCase  ):


      def    a (self       :      Dict				,			a__       :      Dict      ):





         """simple docstring"""



         return self._create_examples(self._read_tsv(os.path.join(a__				,			'''heuristics_train_set.txt'''      )      )				,			'''train'''      )


      def    a (self       :      Optional[int]				,			a__       :      Tuple      ):





         """simple docstring"""



         return self._create_examples(self._read_tsv(os.path.join(a__				,			'''heuristics_evaluation_set.txt'''      )      )				,			'''dev'''      )


      def    a (self       :      int      ):





         """simple docstring"""



         return ["contradiction", "entailment", "neutral"]


      def    a (self       :      Any				,			a__       :      Optional[int]				,			a__       :      List[Any]      ):





         """simple docstring"""



         __snake_case							       =   []
         for i, line in enumerate(a__      ):
            if i == 0:
               continue
            __snake_case							       =   '''%s-%s''' % (set_type, line[0])
            __snake_case							       =   line[5]
            __snake_case							       =   line[6]
            __snake_case							       =   line[7][2:] if line[7].startswith('''ex'''      ) else line[7]
            __snake_case							       =   line[0]
            examples.append(InputExample(guid=a__				,			text_a=a__				,			text_b=a__				,			label=a__				,			pairID=a__      )      )
         return examples






def lowerCamelCase__    (							snake_case_	:  List[InputExample]       ,      snake_case_	:  List[str]       ,      snake_case_	:  int       ,      snake_case_	:  PreTrainedTokenizer       ,      )      ->				List[str]:
   __snake_case							       =   {label: i for i, label in enumerate(snake_case_       )}

   __snake_case							       =   []
   for ex_index, example in tqdm.tqdm(enumerate(snake_case_       )       ,      desc='''convert examples to features'''       ):
      if ex_index % 1_0000 == 0:
         logger.info('''Writing example %d''' % (ex_index)       )

      __snake_case							       =   tokenizer(
          example.text_a       ,      example.text_b       ,      add_special_tokens=snake_case_       ,      max_length=snake_case_       ,      padding='''max_length'''       ,      truncation=snake_case_       ,      return_overflowing_tokens=snake_case_       ,      )

      __snake_case							       =   label_map[example.label] if example.label in label_map else 0

      __snake_case							       =   int(example.pairID       )

      features.append(InputFeatures(**snake_case_       ,      label=snake_case_       ,      pairID=snake_case_       )       )

   for i, example in enumerate(examples[:5]       ):
      logger.info('''*** Example ***'''       )
      logger.info(f"""guid: {example}"""       )
      logger.info(f"""features: {features[i]}"""       )

   return features


snake_case_				=			{
    'hans': 3,
}







snake_case_				=			{
    'hans': HansProcessor,
}

