



'''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_     :   Any	 =						float("nan")






class __A    :



 '''simple docstring'''







 def __init__(self				,     A )					->  Union[str, Any]:


      """simple docstring"""



      _a											=						sys.stdout
      _a											=						open(A				,     '''a''' )



 def __getattr__(self				,     A )					->  List[str]:


      """simple docstring"""



      return getattr(self.stdout				,     A )



 def       a__						(self				,     A )					->  int:


      """simple docstring"""



      self.stdout.write(A )
      # strip tqdm codes
      self.file.write(re.sub(R'''^.*\r'''				,     ''''''				,     A				,     0				,     re.M ) )





def lowerCAmelCase						(__A=80						,			__A=False):



     """simple docstring"""



     _a											=						[]

     # deal with critical env vars
     _a											=						['''CUDA_VISIBLE_DEVICES''']
     for key in env_keys:
          _a											=						os.environ.get(__A						,			__A)
          if val is not None:
               cmd.append(F'''{key}={val}''')

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

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

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




def lowerCAmelCase						(__A						,			__A):



     """simple docstring"""



     _a											=						re.sub(r'''[\\\n]+'''						,			''' '''						,			args.base_cmd)

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

     # ensure we have --overwrite_output_dir
     _a											=						re.sub('''--overwrite_output_dir\s+'''						,			''''''						,			args.base_cmd)
     args.base_cmd += " --overwrite_output_dir"

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




def lowerCAmelCase						(__A						,			__A						,			__A						,			__A						,			__A						,			__A						,			__A):



     """simple docstring"""



     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.66_66, 222.22_222_222])}						,			)

     _a											=						subprocess.run(__A						,			capture_output=__A						,			text=__A)

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

     # save the streams
     _a											=						variation.replace(''' '''						,			'''-''')
     with open(Path(__A) / F'''log.{prefix}.stdout.txt'''						,			'''w''') as f:
          f.write(result.stdout)
     with open(Path(__A) / 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:
          _a											=						json.load(__A)

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




def lowerCAmelCase						(__A						,			__A						,			__A						,			__A						,			__A						,			__A						,			__A						,			__A						,			__A						,			__A						,			):



     """simple docstring"""



     _a											=						[]
     _a											=						[]
     _a											=						F'''{id}: {variation:<{longest_variation_len}}'''
     _a											=						F'''{preamble}: '''
     _a											=						set(report_metric_keys + [target_metric_key])
     for i in tqdm(range(__A)						,			desc=__A						,			leave=__A):
          _a											=						process_run_single(
              __A						,			__A						,			__A						,			__A						,			__A						,			__A						,			__A)
          _a											=						single_run_metrics[target_metric_key]
          if not math.isnan(__A):
               metrics.append(__A)
               results.append(__A)
               outcome += "✓"
          else:
               outcome += "✘"
     _a											=						F'''\33[2K\r{outcome}'''
     if len(__A) > 0:
          _a											=						{k: fmean([x[k] for x in metrics]) for k in metrics[0].keys()}
          _a											=						round(mean_metrics[target_metric_key]						,			2)
          _a											=						F'''{outcome} {mean_target}'''
          if len(__A) > 1:
               results_str += F''' {tuple(round(__A						,			2) for x in results)}'''
          print(__A)
          _a											=						variation
          return mean_metrics
     else:
          print(__A)
          return {variation_key: variation, target_metric_key: nan}




def lowerCAmelCase						():



     """simple docstring"""



     _a											=						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 lowerCAmelCase						(__A						,			__A						,			__A						,			__A						,			__A):



     """simple docstring"""



     _a											=						pd.DataFrame(__A)
     _a											=						'''variation'''
     _a											=						'''diff_%'''

     _a											=						nan
     if base_variation is not None and len(df[df[variation_key] == base_variation]):
          # this may still return nan
          _a											=						df.loc[df[variation_key] == base_variation][target_metric_key].item()
     if math.isnan(__A):
          # as a fallback, use the minimal value as the sentinel
          _a											=						df.loc[df[target_metric_key] != nan][target_metric_key].min()

     # create diff column if possible
     if not math.isnan(__A):
          _a											=						df.apply(
              lambda __A: 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
     _a											=						[variation_key, target_metric_key, diff_key, *report_metric_keys]
     _a											=						df.reindex(__A						,			axis='''columns''')  # reorder cols

     # capitalize
     _a											=						df.rename(str.capitalize						,			axis='''columns''')

     # make the cols as narrow as possible
     _a											=						df.rename(lambda __A: c.replace('''_'''						,			'''<br>''')						,			axis='''columns''')
     _a											=						df.rename(lambda __A: c.replace('''_'''						,			'''\n''')						,			axis='''columns''')

     _a											=						['''''', '''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=__A						,			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=__A						,			floatfmt='''.2f''')]

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




def lowerCAmelCase						():



     """simple docstring"""



     _a											=						argparse.ArgumentParser()
     parser.add_argument(
         '''--base-cmd'''						,			default=__A						,			type=__A						,			required=__A						,			help='''Base cmd'''						,			)
     parser.add_argument(
         '''--variations'''						,			default=__A						,			type=__A						,			nargs='''+'''						,			required=__A						,			help='''Multi-dimensional variations, example: \'|--fp16|--bf16\' \'|--tf32\''''						,			)
     parser.add_argument(
         '''--base-variation'''						,			default=__A						,			type=__A						,			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=__A						,			type=__A						,			required=__A						,			help='''Target metric key in output_dir/all_results.json, e.g., train_samples_per_second'''						,			)
     parser.add_argument(
         '''--report-metric-keys'''						,			default=''''''						,			type=__A						,			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=__A						,			help='''How many times to re-run each variation - an average will be reported'''						,			)
     parser.add_argument(
         '''--output_dir'''						,			default='''output_benchmark'''						,			type=__A						,			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=__A						,			action='''store_true'''						,			help='''Whether to show the outputs of each run or just the benchmark progress'''						,			)
     _a											=						parser.parse_args()

     _a											=						args.output_dir
     Path(__A).mkdir(exist_ok=__A)
     _a											=						get_base_command(__A						,			__A)

     # split each dimension into its --foo variations
     _a											=						[list(map(str.strip						,			re.split(r'''\|'''						,			__A))) 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
     _a											=						list(map(str.strip						,			map(''' '''.join						,			itertools.product(*__A))))
     _a											=						max(len(__A) for x in variations)

     # split wanted keys
     _a											=						args.report_metric_keys.split()

     # capture prints into a log file for convenience
     _a											=						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}''')

     _a											=						Tee(__A)

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

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

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


if __name__ == "__main__":
  main()








'''simple docstring'''





# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from ..models.auto import AutoModelForSeqaSeqLM, AutoTokenizer
from .base import PipelineTool


lowercase_	 =						{
    "Acehnese Arabic": "ace_Arab",
    "Acehnese Latin": "ace_Latn",
    "Mesopotamian Arabic": "acm_Arab",
    "Ta'izzi-Adeni Arabic": "acq_Arab",
    "Tunisian Arabic": "aeb_Arab",
    "Afrikaans": "afr_Latn",
    "South Levantine Arabic": "ajp_Arab",
    "Akan": "aka_Latn",
    "Amharic": "amh_Ethi",
    "North Levantine Arabic": "apc_Arab",
    "Modern Standard Arabic": "arb_Arab",
    "Modern Standard Arabic Romanized": "arb_Latn",
    "Najdi Arabic": "ars_Arab",
    "Moroccan Arabic": "ary_Arab",
    "Egyptian Arabic": "arz_Arab",
    "Assamese": "asm_Beng",
    "Asturian": "ast_Latn",
    "Awadhi": "awa_Deva",
    "Central Aymara": "ayr_Latn",
    "South Azerbaijani": "azb_Arab",
    "North Azerbaijani": "azj_Latn",
    "Bashkir": "bak_Cyrl",
    "Bambara": "bam_Latn",
    "Balinese": "ban_Latn",
    "Belarusian": "bel_Cyrl",
    "Bemba": "bem_Latn",
    "Bengali": "ben_Beng",
    "Bhojpuri": "bho_Deva",
    "Banjar Arabic": "bjn_Arab",
    "Banjar Latin": "bjn_Latn",
    "Standard Tibetan": "bod_Tibt",
    "Bosnian": "bos_Latn",
    "Buginese": "bug_Latn",
    "Bulgarian": "bul_Cyrl",
    "Catalan": "cat_Latn",
    "Cebuano": "ceb_Latn",
    "Czech": "ces_Latn",
    "Chokwe": "cjk_Latn",
    "Central Kurdish": "ckb_Arab",
    "Crimean Tatar": "crh_Latn",
    "Welsh": "cym_Latn",
    "Danish": "dan_Latn",
    "German": "deu_Latn",
    "Southwestern Dinka": "dik_Latn",
    "Dyula": "dyu_Latn",
    "Dzongkha": "dzo_Tibt",
    "Greek": "ell_Grek",
    "English": "eng_Latn",
    "Esperanto": "epo_Latn",
    "Estonian": "est_Latn",
    "Basque": "eus_Latn",
    "Ewe": "ewe_Latn",
    "Faroese": "fao_Latn",
    "Fijian": "fij_Latn",
    "Finnish": "fin_Latn",
    "Fon": "fon_Latn",
    "French": "fra_Latn",
    "Friulian": "fur_Latn",
    "Nigerian Fulfulde": "fuv_Latn",
    "Scottish Gaelic": "gla_Latn",
    "Irish": "gle_Latn",
    "Galician": "glg_Latn",
    "Guarani": "grn_Latn",
    "Gujarati": "guj_Gujr",
    "Haitian Creole": "hat_Latn",
    "Hausa": "hau_Latn",
    "Hebrew": "heb_Hebr",
    "Hindi": "hin_Deva",
    "Chhattisgarhi": "hne_Deva",
    "Croatian": "hrv_Latn",
    "Hungarian": "hun_Latn",
    "Armenian": "hye_Armn",
    "Igbo": "ibo_Latn",
    "Ilocano": "ilo_Latn",
    "Indonesian": "ind_Latn",
    "Icelandic": "isl_Latn",
    "Italian": "ita_Latn",
    "Javanese": "jav_Latn",
    "Japanese": "jpn_Jpan",
    "Kabyle": "kab_Latn",
    "Jingpho": "kac_Latn",
    "Kamba": "kam_Latn",
    "Kannada": "kan_Knda",
    "Kashmiri Arabic": "kas_Arab",
    "Kashmiri Devanagari": "kas_Deva",
    "Georgian": "kat_Geor",
    "Central Kanuri Arabic": "knc_Arab",
    "Central Kanuri Latin": "knc_Latn",
    "Kazakh": "kaz_Cyrl",
    "Kabiyè": "kbp_Latn",
    "Kabuverdianu": "kea_Latn",
    "Khmer": "khm_Khmr",
    "Kikuyu": "kik_Latn",
    "Kinyarwanda": "kin_Latn",
    "Kyrgyz": "kir_Cyrl",
    "Kimbundu": "kmb_Latn",
    "Northern Kurdish": "kmr_Latn",
    "Kikongo": "kon_Latn",
    "Korean": "kor_Hang",
    "Lao": "lao_Laoo",
    "Ligurian": "lij_Latn",
    "Limburgish": "lim_Latn",
    "Lingala": "lin_Latn",
    "Lithuanian": "lit_Latn",
    "Lombard": "lmo_Latn",
    "Latgalian": "ltg_Latn",
    "Luxembourgish": "ltz_Latn",
    "Luba-Kasai": "lua_Latn",
    "Ganda": "lug_Latn",
    "Luo": "luo_Latn",
    "Mizo": "lus_Latn",
    "Standard Latvian": "lvs_Latn",
    "Magahi": "mag_Deva",
    "Maithili": "mai_Deva",
    "Malayalam": "mal_Mlym",
    "Marathi": "mar_Deva",
    "Minangkabau Arabic ": "min_Arab",
    "Minangkabau Latin": "min_Latn",
    "Macedonian": "mkd_Cyrl",
    "Plateau Malagasy": "plt_Latn",
    "Maltese": "mlt_Latn",
    "Meitei Bengali": "mni_Beng",
    "Halh Mongolian": "khk_Cyrl",
    "Mossi": "mos_Latn",
    "Maori": "mri_Latn",
    "Burmese": "mya_Mymr",
    "Dutch": "nld_Latn",
    "Norwegian Nynorsk": "nno_Latn",
    "Norwegian Bokmål": "nob_Latn",
    "Nepali": "npi_Deva",
    "Northern Sotho": "nso_Latn",
    "Nuer": "nus_Latn",
    "Nyanja": "nya_Latn",
    "Occitan": "oci_Latn",
    "West Central Oromo": "gaz_Latn",
    "Odia": "ory_Orya",
    "Pangasinan": "pag_Latn",
    "Eastern Panjabi": "pan_Guru",
    "Papiamento": "pap_Latn",
    "Western Persian": "pes_Arab",
    "Polish": "pol_Latn",
    "Portuguese": "por_Latn",
    "Dari": "prs_Arab",
    "Southern Pashto": "pbt_Arab",
    "Ayacucho Quechua": "quy_Latn",
    "Romanian": "ron_Latn",
    "Rundi": "run_Latn",
    "Russian": "rus_Cyrl",
    "Sango": "sag_Latn",
    "Sanskrit": "san_Deva",
    "Santali": "sat_Olck",
    "Sicilian": "scn_Latn",
    "Shan": "shn_Mymr",
    "Sinhala": "sin_Sinh",
    "Slovak": "slk_Latn",
    "Slovenian": "slv_Latn",
    "Samoan": "smo_Latn",
    "Shona": "sna_Latn",
    "Sindhi": "snd_Arab",
    "Somali": "som_Latn",
    "Southern Sotho": "sot_Latn",
    "Spanish": "spa_Latn",
    "Tosk Albanian": "als_Latn",
    "Sardinian": "srd_Latn",
    "Serbian": "srp_Cyrl",
    "Swati": "ssw_Latn",
    "Sundanese": "sun_Latn",
    "Swedish": "swe_Latn",
    "Swahili": "swh_Latn",
    "Silesian": "szl_Latn",
    "Tamil": "tam_Taml",
    "Tatar": "tat_Cyrl",
    "Telugu": "tel_Telu",
    "Tajik": "tgk_Cyrl",
    "Tagalog": "tgl_Latn",
    "Thai": "tha_Thai",
    "Tigrinya": "tir_Ethi",
    "Tamasheq Latin": "taq_Latn",
    "Tamasheq Tifinagh": "taq_Tfng",
    "Tok Pisin": "tpi_Latn",
    "Tswana": "tsn_Latn",
    "Tsonga": "tso_Latn",
    "Turkmen": "tuk_Latn",
    "Tumbuka": "tum_Latn",
    "Turkish": "tur_Latn",
    "Twi": "twi_Latn",
    "Central Atlas Tamazight": "tzm_Tfng",
    "Uyghur": "uig_Arab",
    "Ukrainian": "ukr_Cyrl",
    "Umbundu": "umb_Latn",
    "Urdu": "urd_Arab",
    "Northern Uzbek": "uzn_Latn",
    "Venetian": "vec_Latn",
    "Vietnamese": "vie_Latn",
    "Waray": "war_Latn",
    "Wolof": "wol_Latn",
    "Xhosa": "xho_Latn",
    "Eastern Yiddish": "ydd_Hebr",
    "Yoruba": "yor_Latn",
    "Yue Chinese": "yue_Hant",
    "Chinese Simplified": "zho_Hans",
    "Chinese Traditional": "zho_Hant",
    "Standard Malay": "zsm_Latn",
    "Zulu": "zul_Latn",
}






class __A    (						A		):



 '''simple docstring'''







 __lowerCamelCase					: Dict    = 'facebook/nllb-200-distilled-600M'
 __lowerCamelCase					: Optional[Any]    = (
     'This is a tool that translates text from a language to another. It takes three inputs: `text`, which should '
     'be the text to translate, `src_lang`, which should be the language of the text to translate and `tgt_lang`, '
     'which should be the language for the desired ouput language. Both `src_lang` and `tgt_lang` are written in '
     'plain English, such as \'Romanian\', or \'Albanian\'. It returns the text translated in `tgt_lang`.'
 )
 __lowerCamelCase					: Optional[int]    = 'translator'
 __lowerCamelCase					: int    = AutoTokenizer
 __lowerCamelCase					: List[Any]    = AutoModelForSeqaSeqLM
 __lowerCamelCase					: int    = LANGUAGE_CODES

 __lowerCamelCase					: Tuple    = ['text', 'text', 'text']
 __lowerCamelCase					: Optional[Any]    = ['text']



 def       a__						(self				,     A				,     A				,     A )					->  List[str]:


      """simple docstring"""



      if src_lang not in self.lang_to_code:
           raise ValueError(f'''{src_lang} is not a supported language.''' )
      if tgt_lang not in self.lang_to_code:
           raise ValueError(f'''{tgt_lang} is not a supported language.''' )
      _a											=						self.lang_to_code[src_lang]
      _a											=						self.lang_to_code[tgt_lang]
      return self.pre_processor._build_translation_inputs(
          A				,     return_tensors='''pt'''				,     src_lang=A				,     tgt_lang=A )



 def       a__						(self				,     A )					->  Optional[Any]:


      """simple docstring"""



      return self.model.generate(**A )



 def       a__						(self				,     A )					->  List[str]:


      """simple docstring"""



      return self.post_processor.decode(outputs[0].tolist()				,     skip_special_tokens=A )



