




"""simple docstring"""






import argparse
import datetime
import io
import itertools
import json
import math
import os
import platform
import re
import shlex
import subprocess
import sys
from pathlib import Path
from statistics import fmean

import pandas as pd
import torch
from tqdm import tqdm

import transformers


lowercase__  		=		float("""nan""")






class lowerCAmelCase__			:






			'''simple docstring'''



			def __init__(						self						,   lowercase						):
							_lowerCamelCase  :    Optional[int]					=					sys.stdout
							_lowerCamelCase  :    int					=					open(lowercase						,   'a'						)
			def __getattr__(						self						,   lowercase						):
							return getattr(self.stdout						,   lowercase						)






			def       A_					(						self						,   lowercase						):
							self.stdout.write(lowercase						)
							# strip tqdm codes
							self.file.write(re.sub(r'^.*\r'						,   ''						,   lowercase						,   0						,   re.M						)						)







def   _snake_case    (       lowercase__=80							,					lowercase__=False	):
				_lowerCamelCase  :    int					=					[]

				# deal with critical env vars
				_lowerCamelCase  :    List[str]					=					['CUDA_VISIBLE_DEVICES']
				for key in env_keys:
								_lowerCamelCase  :    int					=					os.environ.get(lowercase__							,					lowercase__	)
								if val is not None:
												cmd.append(f'''{key}={val}'''	)

    # python executable (not always needed if the script is executable)
				_lowerCamelCase  :    int					=					sys.executable if full_python_path else sys.executable.split('/'	)[-1]
				cmd.append(lowercase__	)

				# now the normal args
				cmd += list(map(shlex.quote							,					sys.argv	)	)

				# split up into up to MAX_WIDTH lines with shell multi-line escapes
				_lowerCamelCase  :    Optional[int]					=					[]
				_lowerCamelCase  :    int					=					''
				while len(lowercase__	) > 0:
								current_line += f'''{cmd.pop(0	)} '''
								if len(lowercase__	) == 0 or len(lowercase__	) + len(cmd[0]	) + 1 > max_width - 1:
												lines.append(lowercase__	)
												_lowerCamelCase  :    Optional[Any]					=					''
				return "\\\n".join(lowercase__	)







def   _snake_case    (       lowercase__							,					lowercase__	):
				# unwrap multi-line input
				_lowerCamelCase  :    Optional[int]					=					re.sub(r'[\\\n]+'							,					' '							,					args.base_cmd	)

				# remove --output_dir if any and set our own
				_lowerCamelCase  :    List[str]					=					re.sub('--output_dir\s+[^\s]+'							,					''							,					args.base_cmd	)
				args.base_cmd += f''' --output_dir {output_dir}'''

				# ensure we have --overwrite_output_dir
				_lowerCamelCase  :    List[str]					=					re.sub('--overwrite_output_dir\s+'							,					''							,					args.base_cmd	)
				args.base_cmd += " --overwrite_output_dir"

				return [sys.executable] + shlex.split(args.base_cmd	)







def   _snake_case    (       lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__	):
				# Enable to debug everything but the run itself, to do it fast and see the progress.
				# This is useful for debugging the output formatting quickly - we can remove it later once
				# everybody is happy with the output
				if 0:
								import random
								from time import sleep

								sleep(0	)
								return dict(
								    {k: random.uniform(0							,					100	) for k in metric_keys}							,					**{target_metric_key: random.choice([nan, 10.31, 100.2, 55.6666, 222.22222222]	)}							,					)

				_lowerCamelCase  :    Dict					=					subprocess.run(lowercase__							,					capture_output=lowercase__							,					text=lowercase__	)

				if verbose:
								print('STDOUT'							,					result.stdout	)
								print('STDERR'							,					result.stderr	)

				# save the streams
				_lowerCamelCase  :    int					=					variation.replace(' '							,					'-'	)
				with open(Path(lowercase__	) / f'''log.{prefix}.stdout.txt'''							,					'w'	) as f:
								f.write(result.stdout	)
				with open(Path(lowercase__	) / f'''log.{prefix}.stderr.txt'''							,					'w'	) as f:
								f.write(result.stderr	)

				if result.returncode != 0:
								if verbose:
												print('failed'	)
								return {target_metric_key: nan}

				with io.open(f'''{output_dir}/all_results.json'''							,					'r'							,					encoding='utf-8'	) as f:
								_lowerCamelCase  :    int					=					json.load(lowercase__	)

				# filter out just the keys we want
				return {k: v for k, v in metrics.items() if k in metric_keys}







def   _snake_case    (       lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					):
				_lowerCamelCase  :    Union[str, Any]					=					[]
				_lowerCamelCase  :    str					=					[]
				_lowerCamelCase  :    str					=					f'''{id}: {variation:<{longest_variation_len}}'''
				_lowerCamelCase  :    str					=					f'''{preamble}: '''
				_lowerCamelCase  :    Optional[int]					=					set(report_metric_keys + [target_metric_key]	)
				for i in tqdm(range(lowercase__	)							,					desc=lowercase__							,					leave=lowercase__	):
								_lowerCamelCase  :    List[Any]					=					process_run_single(
								    lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__	)
								_lowerCamelCase  :    int					=					single_run_metrics[target_metric_key]
								if not math.isnan(lowercase__	):
												metrics.append(lowercase__	)
												results.append(lowercase__	)
												outcome += "✓"
								else:
												outcome += "✘"
				_lowerCamelCase  :    Tuple					=					f'''\33[2K\r{outcome}'''
				if len(lowercase__	) > 0:
								_lowerCamelCase  :    Optional[int]					=					{k: fmean([x[k] for x in metrics]	) for k in metrics[0].keys()}
								_lowerCamelCase  :    str					=					round(mean_metrics[target_metric_key]							,					2	)
								_lowerCamelCase  :    Optional[Any]					=					f'''{outcome} {mean_target}'''
								if len(lowercase__	) > 1:
												results_str += f''' {tuple(round(lowercase__							,					2	) for x in results	)}'''
								print(lowercase__	)
								_lowerCamelCase  :    Dict					=					variation
								return mean_metrics
				else:
								print(lowercase__	)
								return {variation_key: variation, target_metric_key: nan}







def   _snake_case    (       ):
				_lowerCamelCase  :    List[Any]					=					torch.cuda.get_device_properties(torch.device('cuda'	)	)
				return f'''
Datetime    : {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'	)}

Software:
transformers: {transformers.__version__}
torch       : {torch.__version__}
cuda        : {torch.version.cuda}
python      : {platform.python_version()}

Hardware:
{torch.cuda.device_count()} GPUs      : {properties.name}, {properties.total_memory/2**30:0.2f}GB
'''







def   _snake_case    (       lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__	):
				_lowerCamelCase  :    str					=					pd.DataFrame(lowercase__	)
				_lowerCamelCase  :    int					=					'variation'
				_lowerCamelCase  :    List[Any]					=					'diff_%'

				_lowerCamelCase  :    Union[str, Any]					=					nan
				if base_variation is not None and len(df[df[variation_key] == base_variation]	):
								# this may still return nan
								_lowerCamelCase  :    Optional[int]					=					df.loc[df[variation_key] == base_variation][target_metric_key].item()
				if math.isnan(lowercase__	):
								# as a fallback, use the minimal value as the sentinel
								_lowerCamelCase  :    Dict					=					df.loc[df[target_metric_key] != nan][target_metric_key].min()

				# create diff column if possible
				if not math.isnan(lowercase__	):
								_lowerCamelCase  :    Any					=					df.apply(
								    lambda lowercase__	: round(100 * (r[target_metric_key] - sentinel_value) / sentinel_value	)
								    if not math.isnan(r[target_metric_key]	)
								    else 0							,					axis='columns'							,					)

				# re-order columns
				_lowerCamelCase  :    int					=					[variation_key, target_metric_key, diff_key, *report_metric_keys]
				_lowerCamelCase  :    List[str]					=					df.reindex(lowercase__							,					axis='columns'	)  # reorder cols

				# capitalize
				_lowerCamelCase  :    Dict					=					df.rename(str.capitalize							,					axis='columns'	)

				# make the cols as narrow as possible
				_lowerCamelCase  :    Optional[int]					=					df.rename(lambda lowercase__	: c.replace('_'							,					'<br>'	)							,					axis='columns'	)
				_lowerCamelCase  :    Any					=					df.rename(lambda lowercase__	: c.replace('_'							,					'\n'	)							,					axis='columns'	)

				_lowerCamelCase  :    Dict					=					['', 'Copy between the cut-here-lines and paste as is to github or a forum']
				report += ["----------8<-----------------8<--------"]
				report += ["*** Results:", df_github.to_markdown(index=lowercase__							,					floatfmt='.2f'	)]
				report += ["```"]
				report += ["*** Setup:", get_versions()]
				report += ["*** The benchmark command line was:", get_original_command()]
				report += ["```"]
				report += ["----------8<-----------------8<--------"]
				report += ["*** Results (console):", df_console.to_markdown(index=lowercase__							,					floatfmt='.2f'	)]

				print('\n\n'.join(lowercase__	)	)







def   _snake_case    (       ):
				_lowerCamelCase  :    List[Any]					=					argparse.ArgumentParser()
				parser.add_argument(
				    '--base-cmd'							,					default=lowercase__							,					type=lowercase__							,					required=lowercase__							,					help='Base cmd'							,					)
				parser.add_argument(
				    '--variations'							,					default=lowercase__							,					type=lowercase__							,					nargs='+'							,					required=lowercase__							,					help='Multi-dimensional variations, example: \'|--fp16|--bf16\' \'|--tf32\''							,					)
				parser.add_argument(
				    '--base-variation'							,					default=lowercase__							,					type=lowercase__							,					help='Baseline variation to compare to. if None the minimal target value will be used to compare against'							,					)
				parser.add_argument(
				    '--target-metric-key'							,					default=lowercase__							,					type=lowercase__							,					required=lowercase__							,					help='Target metric key in output_dir/all_results.json, e.g., train_samples_per_second'							,					)
				parser.add_argument(
				    '--report-metric-keys'							,					default=''							,					type=lowercase__							,					help='Report metric keys - other metric keys from output_dir/all_results.json to report, e.g., train_loss. Use a single argument e.g., \'train_loss train_samples'							,					)
				parser.add_argument(
				    '--repeat-times'							,					default=1							,					type=lowercase__							,					help='How many times to re-run each variation - an average will be reported'							,					)
				parser.add_argument(
				    '--output_dir'							,					default='output_benchmark'							,					type=lowercase__							,					help='The output directory where all the benchmark reports will go to and additionally this directory will be used to override --output_dir in the script that is being benchmarked'							,					)
				parser.add_argument(
				    '--verbose'							,					default=lowercase__							,					action='store_true'							,					help='Whether to show the outputs of each run or just the benchmark progress'							,					)
				_lowerCamelCase  :    Optional[Any]					=					parser.parse_args()

				_lowerCamelCase  :    str					=					args.output_dir
				Path(lowercase__	).mkdir(exist_ok=lowercase__	)
				_lowerCamelCase  :    List[str]					=					get_base_command(lowercase__							,					lowercase__	)

				# split each dimension into its --foo variations
				_lowerCamelCase  :    str					=					[list(map(str.strip							,					re.split(r'\|'							,					lowercase__	)	)	) for x in args.variations]
				# build a cartesian product of dimensions and convert those back into cmd-line arg strings,
				# while stripping white space for inputs that were empty
				_lowerCamelCase  :    Dict					=					list(map(str.strip							,					map(' '.join							,					itertools.product(*lowercase__	)	)	)	)
				_lowerCamelCase  :    Tuple					=					max(len(lowercase__	) for x in variations	)

				# split wanted keys
				_lowerCamelCase  :    Union[str, Any]					=					args.report_metric_keys.split()

				# capture prints into a log file for convenience
				_lowerCamelCase  :    int					=					f'''benchmark-report-{datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S'	)}.txt'''
				print(f'''\nNote: each run\'s output is also logged under {output_dir}/log.*.std*.txt'''	)
				print(f'''and this script\'s output is also piped into {report_fn}'''	)

				_lowerCamelCase  :    List[str]					=					Tee(lowercase__	)

				print(f'''\n*** Running {len(lowercase__	)} benchmarks:'''	)
				print(f'''Base command: {' '.join(lowercase__	)}'''	)

				_lowerCamelCase  :    Any					=					'variation'
				_lowerCamelCase  :    Union[str, Any]					=					[]
				for id, variation in enumerate(tqdm(lowercase__							,					desc='Total completion: '							,					leave=lowercase__	)	):
								_lowerCamelCase  :    Any					=					base_cmd + variation.split()
								results.append(
								    process_run(
								        id + 1							,					lowercase__							,					lowercase__							,					lowercase__							,					lowercase__							,					args.target_metric_key							,					lowercase__							,					args.repeat_times							,					lowercase__							,					args.verbose							,					)	)

				process_results(lowercase__							,					args.target_metric_key							,					lowercase__							,					args.base_variation							,					lowercase__	)


if __name__ == "__main__":
			main()





"""simple docstring"""






import functools
import operator

from ...configuration_utils import PretrainedConfig
from ...utils import logging


lowercase__  		=		logging.get_logger(__name__)

lowercase__  		=		{
    """asapp/sew-d-tiny-100k""": """https://huggingface.co/asapp/sew-d-tiny-100k/resolve/main/config.json""",
    # See all SEW-D models at https://huggingface.co/models?filter=sew-d
}






class lowerCAmelCase__			(  lowercase		):






			'''simple docstring'''



			lowerCamelCase__   =    """sew-d"""
			def __init__(						self						,   lowercase=32						,   lowercase=768						,   lowercase=12						,   lowercase=12						,   lowercase=3072						,   lowercase=2						,   lowercase=512						,   lowercase=256						,   lowercase=True						,   lowercase=True						,   lowercase=("p2c", "c2p")						,   lowercase="layer_norm"						,   lowercase="gelu_python"						,   lowercase=0.1						,   lowercase=0.1						,   lowercase=0.1						,   lowercase=0.0						,   lowercase=0.1						,   lowercase=0.02						,   lowercase=1E-7						,   lowercase=1E-5						,   lowercase="group"						,   lowercase="gelu"						,   lowercase=(64, 128, 128, 128, 128, 256, 256, 256, 256, 512, 512, 512, 512)						,   lowercase=(5, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1)						,   lowercase=(10, 3, 1, 3, 1, 3, 1, 3, 1, 2, 1, 2, 1)						,   lowercase=False						,   lowercase=128						,   lowercase=16						,   lowercase=True						,   lowercase=0.05						,   lowercase=10						,   lowercase=2						,   lowercase=0.0						,   lowercase=10						,   lowercase=0						,   lowercase="mean"						,   lowercase=False						,   lowercase=False						,   lowercase=256						,   lowercase=0						,   lowercase=1						,   lowercase=2						,   **lowercase						,   ):
							super().__init__(**lowercase						,   pad_token_id=lowercase						,   bos_token_id=lowercase						,   eos_token_id=lowercase						)
							_lowerCamelCase  :    List[str]					=					hidden_size
							_lowerCamelCase  :    int					=					feat_extract_norm
							_lowerCamelCase  :    Optional[Any]					=					feat_extract_activation
							_lowerCamelCase  :    Optional[Any]					=					list(lowercase						)
							_lowerCamelCase  :    Union[str, Any]					=					list(lowercase						)
							_lowerCamelCase  :    Optional[Any]					=					list(lowercase						)
							_lowerCamelCase  :    List[str]					=					conv_bias
							_lowerCamelCase  :    str					=					num_conv_pos_embeddings
							_lowerCamelCase  :    Optional[Any]					=					num_conv_pos_embedding_groups
							_lowerCamelCase  :    Tuple					=					len(self.conv_dim						)
							_lowerCamelCase  :    Optional[int]					=					num_hidden_layers
							_lowerCamelCase  :    List[str]					=					intermediate_size
							_lowerCamelCase  :    Dict					=					squeeze_factor
							_lowerCamelCase  :    Any					=					max_position_embeddings
							_lowerCamelCase  :    List[str]					=					position_buckets
							_lowerCamelCase  :    Dict					=					share_att_key
							_lowerCamelCase  :    List[str]					=					relative_attention
							_lowerCamelCase  :    Optional[Any]					=					norm_rel_ebd
							_lowerCamelCase  :    List[Any]					=					list(lowercase						)
							_lowerCamelCase  :    List[Any]					=					hidden_act
							_lowerCamelCase  :    Optional[Any]					=					num_attention_heads
							_lowerCamelCase  :    Optional[int]					=					hidden_dropout
							_lowerCamelCase  :    Optional[int]					=					attention_dropout
							_lowerCamelCase  :    Any					=					activation_dropout
							_lowerCamelCase  :    Tuple					=					feat_proj_dropout
							_lowerCamelCase  :    Any					=					final_dropout
							_lowerCamelCase  :    str					=					layer_norm_eps
							_lowerCamelCase  :    Tuple					=					feature_layer_norm_eps
							_lowerCamelCase  :    Any					=					initializer_range
							_lowerCamelCase  :    Dict					=					vocab_size

							if (
							    (len(self.conv_stride						) != self.num_feat_extract_layers)
							    or (len(self.conv_kernel						) != self.num_feat_extract_layers)
							    or (len(self.conv_dim						) != self.num_feat_extract_layers)
							):
											raise ValueError(
											    'Configuration for convolutional layers is incorrect.'
											    'It is required that `len(config.conv_dim)` == `len(config.conv_stride)` == `len(config.conv_kernel)`,'
											    F'''but is `len(config.conv_dim) = {len(self.conv_dim						)}`, `len(config.conv_stride)'''
											    F'''= {len(self.conv_stride						)}`, `len(config.conv_kernel) = {len(self.conv_kernel						)}`.'''						)

							# fine-tuning config parameters for SpecAugment: https://arxiv.org/abs/1904.08779
							_lowerCamelCase  :    Dict					=					apply_spec_augment
							_lowerCamelCase  :    int					=					mask_time_prob
							_lowerCamelCase  :    Union[str, Any]					=					mask_time_length
							_lowerCamelCase  :    Optional[Any]					=					mask_time_min_masks
							_lowerCamelCase  :    List[Any]					=					mask_feature_prob
							_lowerCamelCase  :    Union[str, Any]					=					mask_feature_length
							_lowerCamelCase  :    List[Any]					=					mask_feature_min_masks

							# ctc loss
							_lowerCamelCase  :    List[str]					=					ctc_loss_reduction
							_lowerCamelCase  :    List[str]					=					ctc_zero_infinity

							# sequence classification
							_lowerCamelCase  :    Dict					=					use_weighted_layer_sum
							_lowerCamelCase  :    List[Any]					=					classifier_proj_size






			@property
			def       A_					(						self						):
							return functools.reduce(operator.mul						,   self.conv_stride						,   1						)