
import argparse
import json
from pathlib import Path

import torch
import torchaudio
from datasets import load_dataset
from huggingface_hub import hf_hub_download

from transformers import ASTConfig, ASTFeatureExtractor, ASTForAudioClassification
from transformers.utils import logging


logging.set_verbosity_info()
_lowerCamelCase	:    str          =      logging.get_logger(__name__)






def 	a_		(	__lowercase       :     Optional[Any]			)			->  Dict:
			_snake_case          =      ASTConfig()

			if "10-10" in model_name:
						pass
			elif "speech-commands" in model_name:
						_snake_case          =      128
			elif "12-12" in model_name:
						_snake_case          =      12
						_snake_case          =      12
			elif "14-14" in model_name:
						_snake_case          =      14
						_snake_case          =      14
			elif "16-16" in model_name:
						_snake_case          =      16
						_snake_case          =      16
			else:
						raise ValueError('Model not supported'			)

			_snake_case          =      'huggingface/label-files'
			if "speech-commands" in model_name:
						_snake_case          =      35
						_snake_case          =      'speech-commands-v2-id2label.json'
			else:
						_snake_case          =      527
						_snake_case          =      'audioset-id2label.json'

			_snake_case          =      json.load(open(hf_hub_download(__lowercase	, __lowercase	, repo_type='dataset'			)	, 'r'			)			)
			_snake_case          =      {int(__lowercase			): v for k, v in idalabel.items()}
			_snake_case          =      idalabel
			_snake_case          =      {v: k for k, v in idalabel.items()}

			return config






def 	a_		(	__lowercase       :     Tuple			)			->  Any:
			if "module.v" in name:
						_snake_case          =      name.replace('module.v'	, 'audio_spectrogram_transformer'			)
			if "cls_token" in name:
						_snake_case          =      name.replace('cls_token'	, 'embeddings.cls_token'			)
			if "dist_token" in name:
						_snake_case          =      name.replace('dist_token'	, 'embeddings.distillation_token'			)
			if "pos_embed" in name:
						_snake_case          =      name.replace('pos_embed'	, 'embeddings.position_embeddings'			)
			if "patch_embed.proj" in name:
						_snake_case          =      name.replace('patch_embed.proj'	, 'embeddings.patch_embeddings.projection'			)
			# transformer blocks
			if "blocks" in name:
						_snake_case          =      name.replace('blocks'	, 'encoder.layer'			)
			if "attn.proj" in name:
						_snake_case          =      name.replace('attn.proj'	, 'attention.output.dense'			)
			if "attn" in name:
						_snake_case          =      name.replace('attn'	, 'attention.self'			)
			if "norm1" in name:
						_snake_case          =      name.replace('norm1'	, 'layernorm_before'			)
			if "norm2" in name:
						_snake_case          =      name.replace('norm2'	, 'layernorm_after'			)
			if "mlp.fc1" in name:
						_snake_case          =      name.replace('mlp.fc1'	, 'intermediate.dense'			)
			if "mlp.fc2" in name:
						_snake_case          =      name.replace('mlp.fc2'	, 'output.dense'			)
			# final layernorm
			if "audio_spectrogram_transformer.norm" in name:
						_snake_case          =      name.replace('audio_spectrogram_transformer.norm'	, 'audio_spectrogram_transformer.layernorm'			)
			# classifier head
			if "module.mlp_head.0" in name:
						_snake_case          =      name.replace('module.mlp_head.0'	, 'classifier.layernorm'			)
			if "module.mlp_head.1" in name:
						_snake_case          =      name.replace('module.mlp_head.1'	, 'classifier.dense'			)

			return name






def 	a_		(	__lowercase       :     Dict	, __lowercase       :     Dict			)			->  Tuple:
			for key in orig_state_dict.copy().keys():
						_snake_case          =      orig_state_dict.pop(__lowercase			)

						if "qkv" in key:
									_snake_case          =      key.split('.'			)
									_snake_case          =      int(key_split[3]			)
									_snake_case          =      config.hidden_size
									if "weight" in key:
												_snake_case          =      val[:dim, :]
												_snake_case          =      val[dim : dim * 2, :]
												_snake_case          =      val[-dim:, :]
									else:
												_snake_case          =      val[:dim]
												_snake_case          =      val[dim : dim * 2]
												_snake_case          =      val[-dim:]
						else:
									_snake_case          =      val

			return orig_state_dict






def 	a_		(	__lowercase       :     List[str]			)			->  Union[str, Any]:
			_snake_case          =      [
			    'module.v.head.weight',
			    'module.v.head.bias',
			    'module.v.head_dist.weight',
			    'module.v.head_dist.bias',
			]
			for k in ignore_keys:
						state_dict.pop(__lowercase	, __lowercase			)






@torch.no_grad()
def 	a_		(	__lowercase       :     Union[str, Any]	, __lowercase       :     int	, __lowercase       :     Any=False			)			->  str:
			_snake_case          =      get_audio_spectrogram_transformer_config(__lowercase			)

			_snake_case          =      {
			    'ast-finetuned-audioset-10-10-0.4593': (
			        'https://www.dropbox.com/s/ca0b1v2nlxzyeb4/audioset_10_10_0.4593.pth?dl=1'
			    ),
			    'ast-finetuned-audioset-10-10-0.450': (
			        'https://www.dropbox.com/s/1tv0hovue1bxupk/audioset_10_10_0.4495.pth?dl=1'
			    ),
			    'ast-finetuned-audioset-10-10-0.448': (
			        'https://www.dropbox.com/s/6u5sikl4b9wo4u5/audioset_10_10_0.4483.pth?dl=1'
			    ),
			    'ast-finetuned-audioset-10-10-0.448-v2': (
			        'https://www.dropbox.com/s/kt6i0v9fvfm1mbq/audioset_10_10_0.4475.pth?dl=1'
			    ),
			    'ast-finetuned-audioset-12-12-0.447': (
			        'https://www.dropbox.com/s/snfhx3tizr4nuc8/audioset_12_12_0.4467.pth?dl=1'
			    ),
			    'ast-finetuned-audioset-14-14-0.443': (
			        'https://www.dropbox.com/s/z18s6pemtnxm4k7/audioset_14_14_0.4431.pth?dl=1'
			    ),
			    'ast-finetuned-audioset-16-16-0.442': (
			        'https://www.dropbox.com/s/mdsa4t1xmcimia6/audioset_16_16_0.4422.pth?dl=1'
			    ),
			    'ast-finetuned-speech-commands-v2': (
			        'https://www.dropbox.com/s/q0tbqpwv44pquwy/speechcommands_10_10_0.9812.pth?dl=1'
			    ),
			}

			# load original state_dict
			_snake_case          =      model_name_to_url[model_name]
			_snake_case          =      torch.hub.load_state_dict_from_url(__lowercase	, map_location='cpu'			)
			# remove some keys
			remove_keys(__lowercase			)
			# rename some keys
			_snake_case          =      convert_state_dict(__lowercase	, __lowercase			)

			# load 🤗 model
			_snake_case          =      ASTForAudioClassification(__lowercase			)
			model.eval()

			model.load_state_dict(__lowercase			)

			# verify outputs on dummy input
			# source: https://github.com/YuanGongND/ast/blob/79e873b8a54d0a3b330dd522584ff2b9926cd581/src/run.py#L62
			_snake_case          =      -4.2_6_7_7_3_9_3 if 'speech-commands' not in model_name else -6.8_4_5_9_7_8
			_snake_case          =      4.5_6_8_9_9_7_4 if 'speech-commands' not in model_name else 5.5_6_5_4_5_2_6
			_snake_case          =      1_024 if 'speech-commands' not in model_name else 128
			_snake_case          =      ASTFeatureExtractor(mean=__lowercase	, std=__lowercase	, max_length=__lowercase			)

			if "speech-commands" in model_name:
						_snake_case          =      load_dataset('speech_commands'	, 'v0.02'	, split='validation'			)
						_snake_case          =      dataset[0]['audio']['array']
			else:
						_snake_case          =      hf_hub_download(
						    repo_id='nielsr/audio-spectogram-transformer-checkpoint'	, filename='sample_audio.flac'	, repo_type='dataset'	, )

						_snake_case     , _snake_case          =      torchaudio.load(__lowercase			)
						_snake_case          =      waveform.squeeze().numpy()

			_snake_case          =      feature_extractor(__lowercase	, sampling_rate=16_000	, return_tensors='pt'			)

			# forward pass
			_snake_case          =      model(**__lowercase			)
			_snake_case          =      outputs.logits

			if model_name == "ast-finetuned-audioset-10-10-0.4593":
						_snake_case          =      torch.tensor([-0.8_7_6_0, -7.0_0_4_2, -8.6_6_0_2]			)
			elif model_name == "ast-finetuned-audioset-10-10-0.450":
						_snake_case          =      torch.tensor([-1.1_9_8_6, -7.0_9_0_3, -8.2_7_1_8]			)
			elif model_name == "ast-finetuned-audioset-10-10-0.448":
						_snake_case          =      torch.tensor([-2.6_1_2_8, -8.0_0_8_0, -9.4_3_4_4]			)
			elif model_name == "ast-finetuned-audioset-10-10-0.448-v2":
						_snake_case          =      torch.tensor([-1.5_0_8_0, -7.4_5_3_4, -8.8_9_1_7]			)
			elif model_name == "ast-finetuned-audioset-12-12-0.447":
						_snake_case          =      torch.tensor([-0.5_0_5_0, -6.5_8_3_3, -8.0_8_4_3]			)
			elif model_name == "ast-finetuned-audioset-14-14-0.443":
						_snake_case          =      torch.tensor([-0.3_8_2_6, -7.0_3_3_6, -8.2_4_1_3]			)
			elif model_name == "ast-finetuned-audioset-16-16-0.442":
						_snake_case          =      torch.tensor([-1.2_1_1_3, -6.9_1_0_1, -8.3_4_7_0]			)
			elif model_name == "ast-finetuned-speech-commands-v2":
						_snake_case          =      torch.tensor([6.1_5_8_9, -8.0_5_6_6, -8.7_9_8_4]			)
			else:
						raise ValueError('Unknown model name'			)
			if not torch.allclose(logits[0, :3]	, __lowercase	, atol=1E-4			):
						raise ValueError('Logits don\'t match'			)
			print('Looks ok!'			)

			if pytorch_dump_folder_path is not None:
						Path(__lowercase			).mkdir(exist_ok=__lowercase			)
						print(f'''Saving model {model_name} to {pytorch_dump_folder_path}'''			)
						model.save_pretrained(__lowercase			)
						print(f'''Saving feature extractor to {pytorch_dump_folder_path}'''			)
						feature_extractor.save_pretrained(__lowercase			)

			if push_to_hub:
						print('Pushing model and feature extractor to the hub...'			)
						model.push_to_hub(f'''MIT/{model_name}'''			)
						feature_extractor.push_to_hub(f'''MIT/{model_name}'''			)


if __name__ == "__main__":
			_lowerCamelCase	:    List[str]          =      argparse.ArgumentParser()
			# Required parameters
			parser.add_argument(
			    '''--model_name''',
			    default='''ast-finetuned-audioset-10-10-0.4593''',
			    type=str,
			    help='''Name of the Audio Spectrogram Transformer model you\'d like to convert.''',
			)
			parser.add_argument(
			    '''--pytorch_dump_folder_path''', default=None, type=str, help='''Path to the output PyTorch model directory.'''
			)
			parser.add_argument(
			    '''--push_to_hub''', action='''store_true''', help='''Whether or not to push the converted model to the 🤗 hub.'''
			)

			_lowerCamelCase	:    Any          =      parser.parse_args()
			convert_audio_spectrogram_transformer_checkpoint(args.model_name, args.pytorch_dump_folder_path, args.push_to_hub)

from __future__ import annotations

_lowerCamelCase	:    Optional[Any]          =      [-10, -5, 0, 5, 5.1, 11, 13, 21, 3, 4, -21, -10, -5, -1, 0]
_lowerCamelCase	:    Optional[int]          =      [-5, 0, 5, 5.1, 11, 13, 21, -1, 4, -1, -10, -5, -1, 0, -1]






def 	a_		(	__lowercase       :     list[float]			)			->  list[float]:
			_snake_case          =      []
			_snake_case          =      len(__lowercase			)

			for i in range(__lowercase			):
						_snake_case          =      -1
						for j in range(i + 1	, __lowercase			):
									if arr[i] < arr[j]:
												_snake_case          =      arr[j]
												break
						result.append(__lowercase			)
			return result






def 	a_		(	__lowercase       :     list[float]			)			->  list[float]:
			_snake_case          =      []
			for i, outer in enumerate(__lowercase			):
						_snake_case          =      -1
						for inner in arr[i + 1 :]:
									if outer < inner:
												_snake_case          =      inner
												break
						result.append(__lowercase			)
			return result






def 	a_		(	__lowercase       :     list[float]			)			->  list[float]:
			_snake_case          =      len(__lowercase			)
			_snake_case          =      []
			_snake_case          =      [-1] * arr_size

			for index in reversed(range(__lowercase			)			):
						if stack:
									while stack[-1] <= arr[index]:
												stack.pop()
												if not stack:
															break
						if stack:
									_snake_case          =      stack[-1]
						stack.append(arr[index]			)
			return result


if __name__ == "__main__":
			from doctest import testmod
			from timeit import timeit

			testmod()
			print(next_greatest_element_slow(arr))
			print(next_greatest_element_fast(arr))
			print(next_greatest_element(arr))

			_lowerCamelCase	:    Union[str, Any]          =      (
			    '''from __main__ import arr, next_greatest_element_slow, '''
			    '''next_greatest_element_fast, next_greatest_element'''
			)
			print(
			    '''next_greatest_element_slow():''',
			    timeit('''next_greatest_element_slow(arr)''', setup=setup),
			)
			print(
			    '''next_greatest_element_fast():''',
			    timeit('''next_greatest_element_fast(arr)''', setup=setup),
			)
			print(
			    '''     next_greatest_element():''',
			    timeit('''next_greatest_element(arr)''', setup=setup),
			)