

"""simple docstring"""




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       (     snake_case__    ):




			'''simple docstring'''


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

			return shapes

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




			'''simple docstring'''


			SCREAMING_SNAKE_CASE__								=      []
			for d in reversed(snake_case__    ):
						idx.append(flat_idx % d    )
						SCREAMING_SNAKE_CASE__								=      flat_idx // d

			return tuple(reversed(snake_case__    )    )

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




			'''simple docstring'''


			def reduce_edge_list(snake_case__    ) -> None:
						SCREAMING_SNAKE_CASE__								=      True
						for i in range(len(snake_case__    )    ):
									SCREAMING_SNAKE_CASE__								=      -1 * (i + 1)
									l[reversed_idx] &= tally
									SCREAMING_SNAKE_CASE__								=      l[reversed_idx]

			if start_edges is None:
						SCREAMING_SNAKE_CASE__								=      [s == 0 for s in start]
						reduce_edge_list(snake_case__    )
			if end_edges is None:
						SCREAMING_SNAKE_CASE__								=      [e == (d - 1) for e, d in zip(snake_case__		,				snake_case__    )]
						reduce_edge_list(snake_case__    )

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

			SCREAMING_SNAKE_CASE__								=      []
			SCREAMING_SNAKE_CASE__								=      []

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

			SCREAMING_SNAKE_CASE__								=      tuple(snake_case__    )
			SCREAMING_SNAKE_CASE__								=      len(snake_case__    )

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

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

						SCREAMING_SNAKE_CASE__								=      start[divergence_idx]
						return tuple(
						    path + (slice(snake_case__		,				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

						SCREAMING_SNAKE_CASE__								=      end[divergence_idx]
						return tuple(
						    path + (slice(snake_case__		,				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()    )
						SCREAMING_SNAKE_CASE__								=      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       (     snake_case__		,				snake_case__		,				snake_case__		,				snake_case__    ):




			'''simple docstring'''


			SCREAMING_SNAKE_CASE__								=      t.shape[:no_batch_dims]
			SCREAMING_SNAKE_CASE__								=      list(_flat_idx_to_idx(snake_case__		,				snake_case__    )    )
			# _get_minimal_slice_set is inclusive
			SCREAMING_SNAKE_CASE__								=      list(_flat_idx_to_idx(flat_end - 1		,				snake_case__    )    )

			# Get an ordered list of slices to perform
			SCREAMING_SNAKE_CASE__								=      _get_minimal_slice_set(
			    snake_case__		,				snake_case__		,				snake_case__		,				)

			SCREAMING_SNAKE_CASE__								=      [t[s] for s in slices]

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

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




			'''simple docstring'''


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

			SCREAMING_SNAKE_CASE__								=      [shape[:no_batch_dims] for shape in _fetch_dims(snake_case__    )]
			SCREAMING_SNAKE_CASE__								=      tuple([max(snake_case__    ) for s in zip(*snake_case__    )]    )

			def _prep_inputs(snake_case__    ) -> torch.Tensor:
						if not low_mem:
									if not sum(t.shape[:no_batch_dims]    ) == no_batch_dims:
												SCREAMING_SNAKE_CASE__								=      t.expand(orig_batch_dims + t.shape[no_batch_dims:]    )
									SCREAMING_SNAKE_CASE__								=      t.reshape(-1		,				*t.shape[no_batch_dims:]    )
						else:
									SCREAMING_SNAKE_CASE__								=      t.expand(orig_batch_dims + t.shape[no_batch_dims:]    )
						return t

			SCREAMING_SNAKE_CASE__								=      tensor_tree_map(_prep_inputs		,				snake_case__    )
			SCREAMING_SNAKE_CASE__								=      None
			if _out is not None:
						SCREAMING_SNAKE_CASE__								=      tensor_tree_map(lambda snake_case__    : t.view([-1] + list(t.shape[no_batch_dims:]    )    )		,				_out    )

			SCREAMING_SNAKE_CASE__								=      1
			for d in orig_batch_dims:
						flat_batch_dim *= d

			SCREAMING_SNAKE_CASE__								=      flat_batch_dim // chunk_size + (flat_batch_dim % chunk_size != 0)

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

			SCREAMING_SNAKE_CASE__								=      0
			SCREAMING_SNAKE_CASE__								=      prepped_outputs
			for _ in range(snake_case__    ):
						# Chunk the input
						if not low_mem:
									SCREAMING_SNAKE_CASE__								=      _select_chunk
						else:
									SCREAMING_SNAKE_CASE__								=      partial(
									    _chunk_slice		,				flat_start=snake_case__		,				flat_end=min(snake_case__		,				i + chunk_size    )		,				no_batch_dims=len(snake_case__    )		,				)

						SCREAMING_SNAKE_CASE__								=      tensor_tree_map(snake_case__		,				snake_case__    )

						# Run the layer on the chunk
						SCREAMING_SNAKE_CASE__								=      layer(**snake_case__    )

						# Allocate space for the output
						if out is None:
									SCREAMING_SNAKE_CASE__								=      tensor_tree_map(lambda snake_case__    : t.new_zeros((flat_batch_dim,) + t.shape[1:]    )		,				snake_case__    )

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

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

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

						i += chunk_size

			SCREAMING_SNAKE_CASE__								=      tensor_tree_map(lambda snake_case__    : t.view(orig_batch_dims + t.shape[1:]    )		,				snake_case__    )

			return out





class    lowerCamelCase						:

			def __init__(					self				:						Any    ,				__UpperCAmelCase				:						int = 5_1_2    ,				)   ->    Optional[int]:
						SCREAMING_SNAKE_CASE__								=      max_chunk_size
						SCREAMING_SNAKE_CASE__								=      None
						SCREAMING_SNAKE_CASE__								=      None

			def 					SCREAMING_SNAKE_CASE				(					self				:						Tuple    ,				__UpperCAmelCase				:						Callable    ,				__UpperCAmelCase				:						tuple    ,				__UpperCAmelCase				:						int       )   ->    int:
						logging.info("""Tuning chunk size..."""       )

						if min_chunk_size >= self.max_chunk_size:
									return min_chunk_size

						SCREAMING_SNAKE_CASE__								=      [2**l for l in range(int(math.log(self.max_chunk_size    ,				2       )       ) + 1       )]
						SCREAMING_SNAKE_CASE__								=      [c for c in candidates if c > min_chunk_size]
						SCREAMING_SNAKE_CASE__								=      [min_chunk_size] + candidates
						candidates[-1] += 4

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

						SCREAMING_SNAKE_CASE__								=      0
						SCREAMING_SNAKE_CASE__								=      len(__UpperCAmelCase       ) - 1
						while i > min_viable_chunk_size_index:
									SCREAMING_SNAKE_CASE__								=      test_chunk_size(candidates[i]       )
									if not viable:
												SCREAMING_SNAKE_CASE__								=      (min_viable_chunk_size_index + i) // 2
									else:
												SCREAMING_SNAKE_CASE__								=      i
												SCREAMING_SNAKE_CASE__								=      (i + len(__UpperCAmelCase       ) - 1) // 2

						return candidates[min_viable_chunk_size_index]

			def 					SCREAMING_SNAKE_CASE				(					self				:						Optional[Any]    ,				__UpperCAmelCase				:						Iterable    ,				__UpperCAmelCase				:						Iterable       )   ->    bool:
						SCREAMING_SNAKE_CASE__								=      True
						for aa, aa in zip(__UpperCAmelCase    ,				__UpperCAmelCase       ):
									assert type(__UpperCAmelCase       ) == type(__UpperCAmelCase       )
									if isinstance(__UpperCAmelCase    ,				(list, tuple)       ):
												consistent &= self._compare_arg_caches(__UpperCAmelCase    ,				__UpperCAmelCase       )
									elif isinstance(__UpperCAmelCase    ,				__UpperCAmelCase       ):
												SCREAMING_SNAKE_CASE__								=      [v for _, v in sorted(aa.items()    ,				key=lambda __UpperCAmelCase       : x[0]       )]
												SCREAMING_SNAKE_CASE__								=      [v for _, v in sorted(aa.items()    ,				key=lambda __UpperCAmelCase       : x[0]       )]
												consistent &= self._compare_arg_caches(__UpperCAmelCase    ,				__UpperCAmelCase       )
									else:
												consistent &= aa == aa

						return consistent





			def 					SCREAMING_SNAKE_CASE				(					self				:						Optional[int]    ,				__UpperCAmelCase				:						Callable    ,				__UpperCAmelCase				:						tuple    ,				__UpperCAmelCase				:						int    ,				)   ->    int:
						SCREAMING_SNAKE_CASE__								=      True
						SCREAMING_SNAKE_CASE__								=      tree_map(lambda __UpperCAmelCase       : a.shape if isinstance(__UpperCAmelCase    ,				torch.Tensor       ) else a    ,				__UpperCAmelCase    ,				__UpperCAmelCase       )
						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(__UpperCAmelCase       )
									SCREAMING_SNAKE_CASE__								=      self._compare_arg_caches(self.cached_arg_data    ,				__UpperCAmelCase       )
						else:
									# Otherwise, we can reuse the precomputed value
									SCREAMING_SNAKE_CASE__								=      False

						if not consistent:
									SCREAMING_SNAKE_CASE__								=      self._determine_favorable_chunk_size(
									    __UpperCAmelCase    ,				__UpperCAmelCase    ,				__UpperCAmelCase    ,				)
									SCREAMING_SNAKE_CASE__								=      arg_data

						assert self.cached_chunk_size is not None

						return self.cached_chunk_size





"""simple docstring"""




from .glue import GlueDataset, GlueDataTrainingArguments
from .language_modeling import (
    LineByLineTextDataset,
    LineByLineWithRefDataset,
    LineByLineWithSOPTextDataset,
    TextDataset,
    TextDatasetForNextSentencePrediction,
)
from .squad import SquadDataset, SquadDataTrainingArguments


