


'''simple docstring'''


from typing import List

from packaging import version
from sklearn.metrics import fa_score

import datasets
from datasets.config import PY_VERSION


if PY_VERSION < version.parse('3.8'):
						import importlib_metadata
else:
						import importlib.metadata as importlib_metadata


# TODO(Patrick/Anton)
lowerCamelCase__     						=  '\\n'

lowerCamelCase__     						=  '\\n    XTREME-S is a benchmark to evaluate universal cross-lingual speech representations in many languages.\n    XTREME-S covers four task families: speech recognition, classification, speech-to-text translation and retrieval.\n'

lowerCamelCase__     						=  '\nCompute XTREME-S evaluation metric associated to each XTREME-S dataset.\nArgs:\n    predictions: list of predictions to score.\n        Each translation should be tokenized into a list of tokens.\n    references: list of lists of references for each translation.\n        Each reference should be tokenized into a list of tokens.\n    bleu_kwargs: optional dict of keywords to be passed when computing \'bleu\'.\n        Keywords include Dict can be one of \'smooth_method\', \'smooth_value\', \'force\', \'lowercase\',\n        \'tokenize\', \'use_effective_order\'.\n    wer_kwargs: optional dict of keywords to be passed when computing \'wer\' and \'cer\'.\n        Keywords include \'concatenate_texts\'.\nReturns: depending on the XTREME-S task, one or several of:\n    "accuracy": Accuracy - for \'fleurs-lang_id\', \'minds14\'\n    "f1": F1 score - for \'minds14\'\n    "wer": Word error rate - for \'mls\', \'fleurs-asr\', \'voxpopuli\', \'babel\'\n    "cer": Character error rate - for \'mls\', \'fleurs-asr\', \'voxpopuli\', \'babel\'\n    "bleu": BLEU score according to the `sacrebleu` metric - for \'covost2\'\nExamples:\n\n    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'mls\')  # \'mls\', \'voxpopuli\', \'fleurs-asr\' or \'babel\'\n    >>> references = ["it is sunny here", "paper and pen are essentials"]\n    >>> predictions = ["it\'s sunny", "paper pen are essential"]\n    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)\n    >>> print({k: round(v, 2) for k, v in results.items()})\n    {\'wer\': 0.56, \'cer\': 0.27}\n\n    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'covost2\')\n    >>> references = ["bonjour paris", "il est necessaire de faire du sport de temps en temp"]\n    >>> predictions = ["bonjour paris", "il est important de faire du sport souvent"]\n    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)\n    >>> print({k: round(v, 2) for k, v in results.items()})\n    {\'bleu\': 31.65}\n\n    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'fleurs-lang_id\')\n    >>> references = [0, 1, 0, 0, 1]\n    >>> predictions = [0, 1, 1, 0, 0]\n    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)\n    >>> print({k: round(v, 2) for k, v in results.items()})\n    {\'accuracy\': 0.6}\n\n    >>> xtreme_s_metric = datasets.load_metric(\'xtreme_s\', \'minds14\')\n    >>> references = [0, 1, 0, 0, 1]\n    >>> predictions = [0, 1, 1, 0, 0]\n    >>> results = xtreme_s_metric.compute(predictions=predictions, references=references)\n    >>> print({k: round(v, 2) for k, v in results.items()})\n    {\'f1\': 0.58, \'accuracy\': 0.6}\n'

lowerCamelCase__     						=  ['fleurs-asr', 'mls', 'voxpopuli', 'babel', 'covost2', 'fleurs-lang_id', 'minds14']
lowerCamelCase__     						=  ''

try:
						from jiwer import transforms as tr

						lowerCamelCase__     						=  True
except ImportError:
						lowerCamelCase__     						=  False

if _jiwer_available and version.parse(importlib_metadata.version('jiwer')) < version.parse('2.3.0'):






						class 						lowerCAmelCase__      (      tr.AbstractTransform						):




									def __init__(		self	:  List[str]						,	lowerCamelCase__	:  str = " "			) ->Tuple:



											'''simple docstring'''







											_UpperCAmelCase		:							Optional[int]             =   sentence_delimiter




									def 				lowerCAmelCase__     (		self	:  Dict						,	lowerCamelCase__	:  str			) ->List[Any]:



											'''simple docstring'''







											return list(lowerCamelCase__			)






									def 				lowerCAmelCase__     (		self	:  int						,	lowerCamelCase__	:  List[str]			) ->int:



											'''simple docstring'''







											_UpperCAmelCase		:							Union[str, Any]             =   []
											for sent_idx, sentence in enumerate(lowerCamelCase__			):
													chars.extend(self.process_string(lowerCamelCase__			)			)
													if self.sentence_delimiter is not None and self.sentence_delimiter != "" and sent_idx < len(lowerCamelCase__			) - 1:
															chars.append(self.sentence_delimiter			)
											return chars




						lowerCamelCase__     						=  tr.Compose(
						    [tr.RemoveMultipleSpaces(), tr.Strip(), SentencesToListOfCharacters(SENTENCE_DELIMITER)]
						)
elif _jiwer_available:
						lowerCamelCase__     						=  tr.Compose(
						    [
						        tr.RemoveMultipleSpaces(),
						        tr.Strip(),
						        tr.ReduceToSingleSentence(SENTENCE_DELIMITER),
						        tr.ReduceToListOfListOfChars(),
						    ]
						)
else:
						lowerCamelCase__     						=  None






def 			__lowerCAmelCase			(__lowerCAmelCase   ,			__lowerCAmelCase ):
		return float((preds == labels).mean() )






def 			__lowerCAmelCase			(__lowerCAmelCase   ,			__lowerCAmelCase ):
		return {
		    "f1": float(fa_score(y_true=__lowerCAmelCase   ,			y_pred=__lowerCAmelCase   ,			average="macro" ) ),
		    "accuracy": simple_accuracy(__lowerCAmelCase   ,			__lowerCAmelCase ),
		}






def 			__lowerCAmelCase			(__lowerCAmelCase   ,			__lowerCAmelCase   ,			__lowerCAmelCase="exp"   ,			__lowerCAmelCase=None   ,			__lowerCAmelCase=False   ,			__lowerCAmelCase=False   ,			__lowerCAmelCase=None   ,			__lowerCAmelCase=False   ,			):
		# xtreme-s can only have one label
		_UpperCAmelCase		:							Dict             =   [[label] for label in labels]
		_UpperCAmelCase		:							List[str]             =   list(__lowerCAmelCase )
		try:
				import sacrebleu as scb
		except ImportError:
				raise ValueError(
				    "sacrebleu has to be installed in order to apply the bleu metric for covost2."
				    "You can install it via `pip install sacrebleu`." )

		if version.parse(scb.__version__ ) < version.parse("1.4.12" ):
				raise ImportWarning(
				    "To use `sacrebleu`, the module `sacrebleu>=1.4.12` is required, and the current version of `sacrebleu` doesn't match this condition.\n"
				    "You can install it with `pip install \"sacrebleu>=1.4.12\"`." )

		_UpperCAmelCase		:							Dict             =   len(labels[0] )
		if any(len(__lowerCAmelCase ) != references_per_prediction for refs in labels ):
				raise ValueError("Sacrebleu requires the same number of references for each prediction" )
		_UpperCAmelCase		:							Dict             =   [[refs[i] for refs in labels] for i in range(__lowerCAmelCase )]
		_UpperCAmelCase		:							Optional[Any]             =   scb.corpus_bleu(
		    __lowerCAmelCase   ,			__lowerCAmelCase   ,			smooth_method=__lowerCAmelCase   ,			smooth_value=__lowerCAmelCase   ,			force=__lowerCAmelCase   ,			lowercase=__lowerCAmelCase   ,			use_effective_order=__lowerCAmelCase   ,			**({"tokenize": tokenize} if tokenize else {})   ,			)
		return {"bleu": output.score}






def 			__lowerCAmelCase			(__lowerCAmelCase   ,			__lowerCAmelCase   ,			__lowerCAmelCase   ,			__lowerCAmelCase ):
		try:
				from jiwer import compute_measures
		except ImportError:
				raise ValueError(
				    F"""jiwer has to be installed in order to apply the wer metric for {config_name}."""
				    "You can install it via `pip install jiwer`." )

		if concatenate_texts:
				_UpperCAmelCase		:							List[Any]             =   compute_measures(__lowerCAmelCase   ,			__lowerCAmelCase )["wer"]

				_UpperCAmelCase		:							List[Any]             =   compute_measures(__lowerCAmelCase   ,			__lowerCAmelCase   ,			truth_transform=__lowerCAmelCase   ,			hypothesis_transform=__lowerCAmelCase )["wer"]
				return {"wer": wer, "cer": cer}
		else:

				def compute_score(__lowerCAmelCase   ,			__lowerCAmelCase   ,			__lowerCAmelCase="wer" ):
						_UpperCAmelCase		:							Any             =   0
						_UpperCAmelCase		:							int             =   0
						for prediction, reference in zip(__lowerCAmelCase   ,			__lowerCAmelCase ):
								if score_type == "wer":
										_UpperCAmelCase		:							str             =   compute_measures(__lowerCAmelCase   ,			__lowerCAmelCase )
								elif score_type == "cer":
										_UpperCAmelCase		:							int             =   compute_measures(
										    __lowerCAmelCase   ,			__lowerCAmelCase   ,			truth_transform=__lowerCAmelCase   ,			hypothesis_transform=__lowerCAmelCase )
								incorrect += measures["substitutions"] + measures["deletions"] + measures["insertions"]
								total += measures["substitutions"] + measures["deletions"] + measures["hits"]
						return incorrect / total

				return {"wer": compute_score(__lowerCAmelCase   ,			__lowerCAmelCase   ,			"wer" ), "cer": compute_score(__lowerCAmelCase   ,			__lowerCAmelCase   ,			"cer" )}






@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION     ,							_KWARGS_DESCRIPTION						)
class 						lowerCAmelCase__      (      datasets.Metric						):




			def 				lowerCAmelCase__     (		self	:  List[str]			) ->Optional[int]:



					'''simple docstring'''







					if self.config_name not in _CONFIG_NAMES:
							raise KeyError(F"""You should supply a configuration name selected in {_CONFIG_NAMES}"""			)

					_UpperCAmelCase		:							List[str]             =   "int64" if self.config_name in ["fleurs-lang_id", "minds14"] else "string"

					return datasets.MetricInfo(
					    description=_DESCRIPTION						,	citation=_CITATION						,	inputs_description=_KWARGS_DESCRIPTION						,	features=datasets.Features(
					        {"predictions": datasets.Value(lowerCamelCase__			), "references": datasets.Value(lowerCamelCase__			)}			)						,	codebase_urls=[]						,	reference_urls=[]						,	format="numpy"						,	)






			def 				lowerCAmelCase__     (		self	:  Tuple						,	lowerCamelCase__	:  Tuple						,	lowerCamelCase__	:  Optional[Any]						,	lowerCamelCase__	:  Dict=None						,	lowerCamelCase__	:  List[Any]=None			) ->Dict:



					'''simple docstring'''







					_UpperCAmelCase		:							Optional[int]             =   bleu_kwargs if bleu_kwargs is not None else {}
					_UpperCAmelCase		:							Optional[int]             =   wer_kwargs if wer_kwargs is not None else {}

					if self.config_name == "fleurs-lang_id":
							return {"accuracy": simple_accuracy(lowerCamelCase__						,	lowerCamelCase__			)}
					elif self.config_name == "minds14":
							return fa_and_simple_accuracy(lowerCamelCase__						,	lowerCamelCase__			)
					elif self.config_name == "covost2":
							_UpperCAmelCase		:							List[Any]             =   bleu_kwargs.pop("smooth_method"						,	"exp"			)
							_UpperCAmelCase		:							Tuple             =   bleu_kwargs.pop("smooth_value"						,	lowerCamelCase__			)
							_UpperCAmelCase		:							int             =   bleu_kwargs.pop("force"						,	lowerCamelCase__			)
							_UpperCAmelCase		:							str             =   bleu_kwargs.pop("lowercase"						,	lowerCamelCase__			)
							_UpperCAmelCase		:							Tuple             =   bleu_kwargs.pop("tokenize"						,	lowerCamelCase__			)
							_UpperCAmelCase		:							Optional[Any]             =   bleu_kwargs.pop("use_effective_order"						,	lowerCamelCase__			)
							return bleu(
							    preds=lowerCamelCase__						,	labels=lowerCamelCase__						,	smooth_method=lowerCamelCase__						,	smooth_value=lowerCamelCase__						,	force=lowerCamelCase__						,	lowercase=lowerCamelCase__						,	tokenize=lowerCamelCase__						,	use_effective_order=lowerCamelCase__						,	)
					elif self.config_name in ["fleurs-asr", "mls", "voxpopuli", "babel"]:
							_UpperCAmelCase		:							Optional[int]             =   wer_kwargs.pop("concatenate_texts"						,	lowerCamelCase__			)
							return wer_and_cer(lowerCamelCase__						,	lowerCamelCase__						,	lowerCamelCase__						,	self.config_name			)
					else:
							raise KeyError(F"""You should supply a configuration name selected in {_CONFIG_NAMES}"""			)







'''simple docstring'''


import torch
from torch import autograd






class 						lowerCAmelCase__      (      autograd.Function						):




			@staticmethod
			def 				lowerCAmelCase__     (		lowerCamelCase__	:  Optional[int]						,	lowerCamelCase__	:  torch.tensor						,	lowerCamelCase__	:  float						,	lowerCamelCase__	:  bool			) ->Optional[Any]:



					'''simple docstring'''







					_UpperCAmelCase		:							Optional[int]             =   inputs.numel()
					_UpperCAmelCase		:							Any             =   int(0.0_0_5 * nb_elems			) + 1
					if sigmoid:
							_UpperCAmelCase		:							List[str]             =   (torch.sigmoid(lowerCamelCase__			) > threshold).type(inputs.type()			)
					else:
							_UpperCAmelCase		:							List[Any]             =   (inputs > threshold).type(inputs.type()			)
					if mask.sum() < nb_min:
							# We limit the pruning so that at least 0.5% (half a percent) of the weights are remaining
							_UpperCAmelCase		:							str             =   inputs.flatten().kthvalue(max(nb_elems - nb_min						,	1			)			).values
							_UpperCAmelCase		:							str             =   (inputs > k_threshold).type(inputs.type()			)
					return mask






			@staticmethod
			def 				lowerCAmelCase__     (		lowerCamelCase__	:  List[Any]						,	lowerCamelCase__	:  Optional[int]			) ->Dict:



					'''simple docstring'''







					return gradOutput, None, None






class 						lowerCAmelCase__      (      autograd.Function						):




			@staticmethod
			def 				lowerCAmelCase__     (		lowerCamelCase__	:  Optional[int]						,	lowerCamelCase__	:  torch.tensor						,	lowerCamelCase__	:  float			) ->List[str]:



					'''simple docstring'''







					_UpperCAmelCase		:							Optional[int]             =   inputs.clone()
					_UpperCAmelCase       ,     _UpperCAmelCase		:							Tuple             =   inputs.flatten().sort(descending=lowerCamelCase__			)
					_UpperCAmelCase		:							Optional[int]             =   int(threshold * inputs.numel()			)

					# flat_out and mask access the same memory.
					_UpperCAmelCase		:							str             =   mask.flatten()
					_UpperCAmelCase		:							Optional[int]             =   0
					_UpperCAmelCase		:							Optional[Any]             =   1
					return mask






			@staticmethod
			def 				lowerCAmelCase__     (		lowerCamelCase__	:  Optional[int]						,	lowerCamelCase__	:  Any			) ->Union[str, Any]:



					'''simple docstring'''







					return gradOutput, None






class 						lowerCAmelCase__      (      UpperCAmelCase__						):




			@staticmethod
			def 				lowerCAmelCase__     (		lowerCamelCase__	:  torch.tensor						,	lowerCamelCase__	:  float			) ->Tuple:



					'''simple docstring'''







					_UpperCAmelCase		:							List[Any]             =   inputs.clone()
					_UpperCAmelCase       ,     _UpperCAmelCase		:							Optional[Any]             =   inputs.abs().flatten().sort(descending=lowerCamelCase__			)
					_UpperCAmelCase		:							int             =   int(threshold * inputs.numel()			)

					# flat_out and mask access the same memory.
					_UpperCAmelCase		:							int             =   mask.flatten()
					_UpperCAmelCase		:							List[Any]             =   0
					_UpperCAmelCase		:							int             =   1
					return mask



