
import re
import tempfile
import unittest
from pathlib import Path

from datasets.utils.metadata import DatasetMetadata






def  a_	( __lowercase     :			str				)				->						str:
			_snake_case						=    min(re.search('^ +' ,      __lowercase				).end() if t.startswith(' '				) else 0 for t in string.splitlines()				)
			return "\n".join([line[indent_level:] for line in string.splitlines() if indent_level < len(__lowercase				)]				)


_lowerCamelCase :       str     					=    '''\
---
language:
- zh
- en
task_ids:
- sentiment-classification
---
# Begin of markdown

Some cool dataset card
'''

_lowerCamelCase :       str     					=    '''\
---
---
# Begin of markdown

Some cool dataset card
'''


_lowerCamelCase :       List[str]     					=    '''\
# Begin of markdown

Some cool dataset card
'''




class      SCREAMING_SNAKE_CASE__  (			unittest.TestCase      ):





	'''simple docstring'''



	def 				A							(						self			:					Dict			):


				'''simple docstring'''


				with tempfile.TemporaryDirectory() as tmp_dir:
							_snake_case						=    Path(lowercase			) / 'README.md'
							with open(lowercase    ,						'w+'			) as readme_file:
										readme_file.write(lowercase			)
							_snake_case						=    DatasetMetadata.from_readme(lowercase			)
							self.assertDictEqual(lowercase    ,						{'language': ['zh', 'en'], 'task_ids': ['sentiment-classification']}			)

							with open(lowercase    ,						'w+'			) as readme_file:
										readme_file.write(lowercase			)
							_snake_case						=    DatasetMetadata.from_readme(lowercase			)
							self.assertDictEqual(lowercase    ,						{}			)

							with open(lowercase    ,						'w+'			) as readme_file:
										readme_file.write(lowercase			)
							_snake_case						=    DatasetMetadata.from_readme(lowercase			)
							self.assertEqual(lowercase    ,						{}			)





	def 				A							(						self			:					Tuple			):


				'''simple docstring'''


				_snake_case						=    _dedent(
				    '\\n            annotations_creators:\n            - found\n            language_creators:\n            - found\n            language:\n            - en\n            license:\n            - unknown\n            multilinguality:\n            - monolingual\n            pretty_name: Test Dataset\n            size_categories:\n            - 10K<n<100K\n            source_datasets:\n            - extended|other-yahoo-webscope-l6\n            task_categories:\n            - question-answering\n            task_ids:\n            - open-domain-qa\n            '			)
				assert DatasetMetadata.from_yaml_string(lowercase			)

				_snake_case						=    _dedent(
				    '\\n            annotations_creators:\n            - found\n            language:\n            - en\n            license:\n            - unknown\n            multilinguality:\n            - monolingual\n            pretty_name: Test Dataset\n            size_categories:\n            - 10K<n<100K\n            source_datasets:\n            - extended|other-yahoo-webscope-l6\n            task_categories:\n            - question-answering\n            task_ids:\n            - open-domain-qa\n            task_ids:\n            - open-domain-qa\n            '			)
				with self.assertRaises(lowercase			):
							DatasetMetadata.from_yaml_string(lowercase			)

				_snake_case						=    _dedent(
				    '\\n            annotations_creators:\n            - found\n            language_creators:\n            - found\n            language:\n            - en\n            license:\n            - unknown\n            multilinguality:\n            - monolingual\n            pretty_name: Test Dataset\n            size_categories:\n            - 10K<n<100K\n            source_datasets:\n            - extended|other-yahoo-webscope-l6\n            task_categories:\n            - text-classification\n            task_ids:\n            - multi-class-classification\n            paperswithcode_id:\n            - squad\n            configs:\n            - en\n            train-eval-index:\n            - config: en\n              task: text-classification\n              task_id: multi_class_classification\n              splits:\n                train_split: train\n                eval_split: test\n              col_mapping:\n                text: text\n                label: target\n              metrics:\n                - type: accuracy\n                  name: Accuracy\n            extra_gated_prompt: |\n              By clicking on “Access repository” below, you also agree to ImageNet Terms of Access:\n              [RESEARCHER_FULLNAME] (the "Researcher") has requested permission to use the ImageNet database (the "Database") at Princeton University and Stanford University. In exchange for such permission, Researcher hereby agrees to the following terms and conditions:\n              1. Researcher shall use the Database only for non-commercial research and educational purposes.\n            extra_gated_fields:\n              Company: text\n              Country: text\n              I agree to use this model for non-commerical use ONLY: checkbox\n            '			)
				assert DatasetMetadata.from_yaml_string(lowercase			)

import inspect
from typing import Callable, List, Optional, Set, Tuple, Union

import torch
from packaging import version
from safetensors.torch import storage_ptr, storage_size
from torch import nn

from .utils import logging


_lowerCamelCase :       Optional[Any]     					=    [nn.LayerNorm]

_lowerCamelCase :       Optional[int]     					=    logging.get_logger(__name__)

_lowerCamelCase :       Optional[int]     					=    version.parse(version.parse(torch.__version__).base_version)

_lowerCamelCase :       Dict     					=    parsed_torch_version_base >= version.parse('''2.0''')
_lowerCamelCase :       str     					=    parsed_torch_version_base >= version.parse('''1.12''')
_lowerCamelCase :       str     					=    parsed_torch_version_base >= version.parse('''1.11''')
_lowerCamelCase :       Dict     					=    parsed_torch_version_base < version.parse('''1.11''')






def  a_	( __lowercase     :			Optional[int] ,      __lowercase     :			Optional[int] ,      __lowercase     :			Optional[Any] ,      __lowercase     :			Union[str, Any] ,      self     :			Optional[int]				)				->						Dict:
			from torch import _softmax_backward_data

			if is_torch_less_than_1_11:
						return _softmax_backward_data(__lowercase ,      __lowercase ,      parent.dim ,      self				)
			else:
						return _softmax_backward_data(__lowercase ,      __lowercase ,      parent.dim ,      self.dtype				)






def  a_	( __lowercase     :			nn.Linear ,      __lowercase     :			torch.LongTensor ,      __lowercase     :			int = 0				)				->						nn.Linear:
			_snake_case						=    index.to(layer.weight.device				)
			_snake_case						=    layer.weight.index_select(__lowercase ,      __lowercase				).clone().detach()
			if layer.bias is not None:
						if dim == 1:
									_snake_case						=    layer.bias.clone().detach()
						else:
									_snake_case						=    layer.bias[index].clone().detach()
			_snake_case						=    list(layer.weight.size()				)
			_snake_case						=    len(__lowercase				)
			_snake_case						=    nn.Linear(new_size[1] ,      new_size[0] ,      bias=layer.bias is not None				).to(layer.weight.device				)
			_snake_case						=    False
			new_layer.weight.copy_(W.contiguous()				)
			_snake_case						=    True
			if layer.bias is not None:
						_snake_case						=    False
						new_layer.bias.copy_(b.contiguous()				)
						_snake_case						=    True
			return new_layer




class      SCREAMING_SNAKE_CASE__  (			nn.Module      ):





	'''simple docstring'''



	def __init__(						self			:					Optional[Any]    ,						lowercase			:					List[str]    ,						lowercase			:					Tuple			):


				'''simple docstring'''


				super().__init__()
				_snake_case						=    nf
				_snake_case						=    nn.Parameter(torch.empty(lowercase    ,						lowercase			)			)
				_snake_case						=    nn.Parameter(torch.zeros(lowercase			)			)
				nn.init.normal_(self.weight    ,						std=0.02			)





	def 				A							(						self			:					List[Any]    ,						lowercase			:					int			):


				'''simple docstring'''


				_snake_case						=    x.size()[:-1] + (self.nf,)
				_snake_case						=    torch.addmm(self.bias    ,						x.view(-1    ,						x.size(-1			)			)    ,						self.weight			)
				_snake_case						=    x.view(lowercase			)
				return x






def  a_	( __lowercase     :			ConvaD ,      __lowercase     :			torch.LongTensor ,      __lowercase     :			int = 1				)				->						ConvaD:
			_snake_case						=    index.to(layer.weight.device				)
			_snake_case						=    layer.weight.index_select(__lowercase ,      __lowercase				).clone().detach()
			if dim == 0:
						_snake_case						=    layer.bias.clone().detach()
			else:
						_snake_case						=    layer.bias[index].clone().detach()
			_snake_case						=    list(layer.weight.size()				)
			_snake_case						=    len(__lowercase				)
			_snake_case						=    ConvaD(new_size[1] ,      new_size[0]				).to(layer.weight.device				)
			_snake_case						=    False
			new_layer.weight.copy_(W.contiguous()				)
			_snake_case						=    True
			_snake_case						=    False
			new_layer.bias.copy_(b.contiguous()				)
			_snake_case						=    True
			return new_layer






def  a_	( __lowercase     :			Union[nn.Linear, ConvaD] ,      __lowercase     :			torch.LongTensor ,      __lowercase     :			Optional[int] = None				)				->						Union[nn.Linear, ConvaD]:
			if isinstance(__lowercase ,      nn.Linear				):
						return prune_linear_layer(__lowercase ,      __lowercase ,      dim=0 if dim is None else dim				)
			elif isinstance(__lowercase ,      __lowercase				):
						return prune_convad_layer(__lowercase ,      __lowercase ,      dim=1 if dim is None else dim				)
			else:
						raise ValueError(f'''Can\'t prune layer of class {layer.__class__}'''				)






def  a_	( __lowercase     :			Callable[..., torch.Tensor] ,      __lowercase     :			int ,      __lowercase     :			int ,      *__lowercase     :			List[str]				)				->						torch.Tensor:
			assert len(__lowercase				) > 0, f'''{input_tensors} has to be a tuple/list of tensors'''

			# inspect.signature exist since python 3.5 and is a python method -> no problem with backward compatibility
			_snake_case						=    len(inspect.signature(__lowercase				).parameters				)
			if num_args_in_forward_chunk_fn != len(__lowercase				):
						raise ValueError(
						    f'''forward_chunk_fn expects {num_args_in_forward_chunk_fn} arguments, but only {len(__lowercase				)} input '''
						    'tensors are given'				)

			if chunk_size > 0:
						_snake_case						=    input_tensors[0].shape[chunk_dim]
						for input_tensor in input_tensors:
									if input_tensor.shape[chunk_dim] != tensor_shape:
												raise ValueError(
												    f'''All input tenors have to be of the same shape: {tensor_shape}, '''
												    f'''found shape {input_tensor.shape[chunk_dim]}'''				)

						if input_tensors[0].shape[chunk_dim] % chunk_size != 0:
									raise ValueError(
									    f'''The dimension to be chunked {input_tensors[0].shape[chunk_dim]} has to be a multiple of the chunk '''
									    f'''size {chunk_size}'''				)

						_snake_case						=    input_tensors[0].shape[chunk_dim] // chunk_size

						# chunk input tensor into tuples
						_snake_case						=    tuple(input_tensor.chunk(__lowercase ,      dim=__lowercase				) for input_tensor in input_tensors				)
						# apply forward fn to every tuple
						_snake_case						=    tuple(forward_fn(*__lowercase				) for input_tensors_chunk in zip(*__lowercase				)				)
						# concatenate output at same dimension
						return torch.cat(__lowercase ,      dim=__lowercase				)

			return forward_fn(*__lowercase				)






def  a_	( __lowercase     :			List[int] ,      __lowercase     :			int ,      __lowercase     :			int ,      __lowercase     :			Set[int]				)				->						Tuple[Set[int], torch.LongTensor]:
			_snake_case						=    torch.ones(__lowercase ,      __lowercase				)
			_snake_case						=    set(__lowercase				) - already_pruned_heads  # Convert to set and remove already pruned heads
			for head in heads:
						# Compute how many pruned heads are before the head and move the index accordingly
						_snake_case						=    head - sum(1 if h < head else 0 for h in already_pruned_heads				)
						_snake_case						=    0
			_snake_case						=    mask.view(-1				).contiguous().eq(1				)
			_snake_case						=    torch.arange(len(__lowercase				)				)[mask].long()
			return heads, index






def  a_	( *__lowercase     :			Union[torch.Tensor, List[torch.Tensor]] ,      __lowercase     :			Optional[str] = None				)				->						Tuple[torch.Tensor, ...]:
			return torch.meshgrid(*__lowercase ,      indexing=__lowercase				)






def  a_	( __lowercase     :			torch.Tensor				)				->						Tuple[torch.device, int, int]:
			return tensor.device, storage_ptr(__lowercase				), storage_size(__lowercase				)