


'''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				(      __a       )  ->     List[Tuple[int, ...]]:



					'''simple docstring'''






					UpperCamelCase__       :List[str]							 =			[]
					if isinstance(__a			, __a       ):
										for v in tree.values():
															shapes.extend(_fetch_dims(__a       )       )
					elif isinstance(__a			, (list, tuple)       ):
										for t in tree:
															shapes.extend(_fetch_dims(__a       )       )
					elif isinstance(__a			, torch.Tensor       ):
										shapes.append(tree.shape       )
					else:
										raise ValueError('''Not supported'''       )

					return shapes


@torch.jit.ignore
def       a				(      __a			, __a       )  ->     Tuple[int, ...]:



					'''simple docstring'''






					UpperCamelCase__       :Union[str, Any]							 =			[]
					for d in reversed(__a       ):
										idx.append(flat_idx % d       )
										UpperCamelCase__       :List[str]							 =			flat_idx // d

					return tuple(reversed(__a       )       )


@torch.jit.ignore
def       a				(      __a			, __a			, __a			, __a = None			, __a = None			, )  ->     List[Tuple[slice, ...]]:



					'''simple docstring'''






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

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

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

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

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

					UpperCamelCase__       :Tuple[slice, ...]							 =			tuple(__a       )
					UpperCamelCase__       :Optional[Any]							 =			len(__a       )

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

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

										UpperCamelCase__       :int							 =			start[divergence_idx]
										return tuple(
										    path + (slice(__a			, 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

										UpperCamelCase__       :Optional[Any]							 =			end[divergence_idx]
										return tuple(
										    path + (slice(__a			, 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()       )
										UpperCamelCase__       :Optional[Any]							 =			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				(      __a			, __a			, __a			, __a       )  ->     torch.Tensor:



					'''simple docstring'''






					UpperCamelCase__       :int							 =			t.shape[:no_batch_dims]
					UpperCamelCase__       :List[str]							 =			list(_flat_idx_to_idx(__a			, __a       )       )
					# _get_minimal_slice_set is inclusive
					UpperCamelCase__       :Dict							 =			list(_flat_idx_to_idx(flat_end - 1			, __a       )       )

					# Get an ordered list of slices to perform
					UpperCamelCase__       :Dict							 =			_get_minimal_slice_set(
					    __a			, __a			, __a			, )

					UpperCamelCase__       :Any							 =			[t[s] for s in slices]

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


def       a				(      __a			, __a			, __a			, __a			, __a = False			, __a = None			, __a = False			, )  ->     Any:



					'''simple docstring'''






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

					UpperCamelCase__       :int							 =			[shape[:no_batch_dims] for shape in _fetch_dims(__a       )]
					UpperCamelCase__       :Union[str, Any]							 =			tuple([max(__a       ) for s in zip(*__a       )]       )

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

					UpperCamelCase__       :Dict[str, Any]							 =			tensor_tree_map(_prep_inputs			, __a       )
					UpperCamelCase__       :Any							 =			None
					if _out is not None:
										UpperCamelCase__       :Optional[int]							 =			tensor_tree_map(lambda __a       : t.view([-1] + list(t.shape[no_batch_dims:]       )       )			, _out       )

					UpperCamelCase__       :Dict							 =			1
					for d in orig_batch_dims:
										flat_batch_dim *= d

					UpperCamelCase__       :str							 =			flat_batch_dim // chunk_size + (flat_batch_dim % chunk_size != 0)

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

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

										UpperCamelCase__       :Dict[str, Any]							 =			tensor_tree_map(__a			, __a       )

										# Run the layer on the chunk
										UpperCamelCase__       :str							 =			layer(**__a       )

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

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

															def assign(__a			, __a       ) -> None:
																				for k, v in da.items():
																									if isinstance(__a			, __a       ):
																														assign(__a			, da[k]       )
																									else:
																														if _add_into_out:
																																			v[i : i + chunk_size] += da[k]
																														else:
																																			UpperCamelCase__       :Union[str, Any]							 =			da[k]

															assign(__a			, __a       )
										elif isinstance(__a			, __a       ):
															for xa, xa in zip(__a			, __a       ):
																				if _add_into_out:
																									xa[i : i + chunk_size] += xa
																				else:
																									UpperCamelCase__       :Optional[int]							 =			xa
										elif isinstance(__a			, torch.Tensor       ):
															if _add_into_out:
																				out[i : i + chunk_size] += output_chunk
															else:
																				UpperCamelCase__       :Optional[Any]							 =			output_chunk
										else:
															raise ValueError('''Not supported'''       )

										i += chunk_size

					UpperCamelCase__       :List[Any]							 =			tensor_tree_map(lambda __a       : t.view(orig_batch_dims + t.shape[1:]       )			, __a       )

					return out







class        lowercase     :

		"""simple docstring"""

		def __init__(		self   ,       UpperCamelCase_ = 512   ,       ):

							'''simple docstring'''


							UpperCamelCase__       :Union[str, Any]							 =			max_chunk_size
							UpperCamelCase__       :Optional[int]							 =			None
							UpperCamelCase__       :Optional[tuple]							 =			None




		def    lowerCAmelCase__    (		self   ,       UpperCamelCase_   ,       UpperCamelCase_   ,       UpperCamelCase_							):

							'''simple docstring'''


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

							if min_chunk_size >= self.max_chunk_size:
												return min_chunk_size

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

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

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

							return candidates[min_viable_chunk_size_index]




		def    lowerCAmelCase__    (		self   ,       UpperCamelCase_   ,       UpperCamelCase_							):

							'''simple docstring'''


							UpperCamelCase__       :Optional[int]							 =			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_							):
																	UpperCamelCase__       :List[str]							 =			[v for _, v in sorted(aa.items()   ,       key=lambda UpperCamelCase_							: x[0]							)]
																	UpperCamelCase__       :int							 =			[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    lowerCAmelCase__    (		self   ,       UpperCamelCase_   ,       UpperCamelCase_   ,       UpperCamelCase_   ,       ):

							'''simple docstring'''


							UpperCamelCase__       :str							 =			True
							UpperCamelCase__       :tuple							 =			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_							)
												UpperCamelCase__       :Tuple							 =			self._compare_arg_caches(self.cached_arg_data   ,       UpperCamelCase_							)
							else:
												# Otherwise, we can reuse the precomputed value
												UpperCamelCase__       :Optional[Any]							 =			False

							if not consistent:
												UpperCamelCase__       :str							 =			self._determine_favorable_chunk_size(
												    UpperCamelCase_   ,       UpperCamelCase_   ,       UpperCamelCase_   ,       )
												UpperCamelCase__       :List[str]							 =			arg_data

							assert self.cached_chunk_size is not None

							return self.cached_chunk_size



'''simple docstring'''
import argparse
from collections import defaultdict

import yaml


__snake_case											=					'''docs/source/en/_toctree.yml'''


def       a				(      __a       )  ->     int:



					'''simple docstring'''






					UpperCamelCase__       :int							 =			defaultdict(__a       )
					UpperCamelCase__       :int							 =			[]
					UpperCamelCase__       :int							 =			[]
					for doc in doc_list:
										if "local" in doc:
															counts[doc["local"]] += 1

										if doc["title"].lower() == "overview":
															overview_doc.append({'''local''': doc['''local'''], '''title''': doc['''title''']}       )
										else:
															new_doc_list.append(__a       )

					UpperCamelCase__       :Union[str, Any]							 =			new_doc_list
					UpperCamelCase__       :Tuple							 =			[key for key, value in counts.items() if value > 1]

					UpperCamelCase__       :Union[str, Any]							 =			[]
					for duplicate_key in duplicates:
										UpperCamelCase__       :Dict							 =			list({doc['''title'''] for doc in doc_list if doc['''local'''] == duplicate_key}       )
										if len(__a       ) > 1:
															raise ValueError(
															    f'''{duplicate_key} is present several times in the documentation table of content at '''
															    '''`docs/source/en/_toctree.yml` with different *Title* values. Choose one of those and remove the '''
															    '''others.'''       )
										# Only add this once
										new_doc.append({'''local''': duplicate_key, '''title''': titles[0]}       )

					# Add none duplicate-keys
					new_doc.extend([doc for doc in doc_list if '''local''' not in counts or counts[doc['''local''']] == 1]       )
					UpperCamelCase__       :Union[str, Any]							 =			sorted(__a			, key=lambda __a       : s["title"].lower()       )

					# "overview" gets special treatment and is always first
					if len(__a       ) > 1:
										raise ValueError('''{doc_list} has two \'overview\' docs which is not allowed.'''       )

					overview_doc.extend(__a       )

					# Sort
					return overview_doc


def       a				(      __a=False       )  ->     Any:



					'''simple docstring'''






					with open(__a			, encoding='''utf-8'''       ) as f:
										UpperCamelCase__       :Any							 =			yaml.safe_load(f.read()       )

					# Get to the API doc
					UpperCamelCase__       :str							 =			0
					while content[api_idx]["title"] != "API":
										api_idx += 1
					UpperCamelCase__       :str							 =			content[api_idx]['''sections''']

					# Then to the model doc
					UpperCamelCase__       :Optional[Any]							 =			0
					while api_doc[scheduler_idx]["title"] != "Schedulers":
										scheduler_idx += 1

					UpperCamelCase__       :List[Any]							 =			api_doc[scheduler_idx]['''sections''']
					UpperCamelCase__       :Union[str, Any]							 =			clean_doc_toc(__a       )

					UpperCamelCase__       :List[Any]							 =			False
					if new_scheduler_doc != scheduler_doc:
										UpperCamelCase__       :Optional[int]							 =			True
										if overwrite:
															UpperCamelCase__       :Dict							 =			new_scheduler_doc

					if diff:
										if overwrite:
															UpperCamelCase__       :Any							 =			api_doc
															with open(__a			, '''w'''			, encoding='''utf-8'''       ) as f:
																				f.write(yaml.dump(__a			, allow_unicode=__a       )       )
										else:
															raise ValueError(
															    '''The model doc part of the table of content is not properly sorted, run `make style` to fix this.'''       )


def       a				(      __a=False       )  ->     Optional[Any]:



					'''simple docstring'''






					with open(__a			, encoding='''utf-8'''       ) as f:
										UpperCamelCase__       :str							 =			yaml.safe_load(f.read()       )

					# Get to the API doc
					UpperCamelCase__       :Optional[Any]							 =			0
					while content[api_idx]["title"] != "API":
										api_idx += 1
					UpperCamelCase__       :Any							 =			content[api_idx]['''sections''']

					# Then to the model doc
					UpperCamelCase__       :str							 =			0
					while api_doc[pipeline_idx]["title"] != "Pipelines":
										pipeline_idx += 1

					UpperCamelCase__       :Any							 =			False
					UpperCamelCase__       :Union[str, Any]							 =			api_doc[pipeline_idx]['''sections''']
					UpperCamelCase__       :Tuple							 =			[]

					# sort sub pipeline docs
					for pipeline_doc in pipeline_docs:
										if "section" in pipeline_doc:
															UpperCamelCase__       :Dict							 =			pipeline_doc['''section''']
															UpperCamelCase__       :Optional[Any]							 =			clean_doc_toc(__a       )
															if overwrite:
																				UpperCamelCase__       :Optional[int]							 =			new_sub_pipeline_doc
										new_pipeline_docs.append(__a       )

					# sort overall pipeline doc
					UpperCamelCase__       :Optional[Any]							 =			clean_doc_toc(__a       )

					if new_pipeline_docs != pipeline_docs:
										UpperCamelCase__       :int							 =			True
										if overwrite:
															UpperCamelCase__       :Union[str, Any]							 =			new_pipeline_docs

					if diff:
										if overwrite:
															UpperCamelCase__       :Dict							 =			api_doc
															with open(__a			, '''w'''			, encoding='''utf-8'''       ) as f:
																				f.write(yaml.dump(__a			, allow_unicode=__a       )       )
										else:
															raise ValueError(
															    '''The model doc part of the table of content is not properly sorted, run `make style` to fix this.'''       )


if __name__ == "__main__":
		__snake_case											=					argparse.ArgumentParser()
		parser.add_argument('''--fix_and_overwrite''', action='''store_true''', help='''Whether to fix inconsistencies.''')
		__snake_case											=					parser.parse_args()

		check_scheduler_doc(args.fix_and_overwrite)
		check_pipeline_doc(args.fix_and_overwrite)