
import argparse
import os
from functools import reduce

import fairseq
import torch
from datasets import load_dataset

from transformers import WavaVecaProcessor, logging
from transformers.models.dataavec.configuration_dataavec_audio import DataaVecAudioConfig

# Copied from https://github.com/pytorch/fairseq/blob/main/examples/data2vec/models/data2vec_audio.py
from transformers.models.dataavec.dataavec_audio import DataaVecAudioModel as Dummy  # noqa: F401
from transformers.models.dataavec.modeling_dataavec_audio import DataaVecAudioForCTC, DataaVecAudioModel


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

snake_case				:	Optional[int]							   =						{
    "post_extract_proj": "feature_projection.projection",
    "models.0.layer_norm": "feature_projection.layer_norm",
    "self_attn.k_proj": "encoder.layers.*.attention.k_proj",
    "self_attn.v_proj": "encoder.layers.*.attention.v_proj",
    "self_attn.q_proj": "encoder.layers.*.attention.q_proj",
    "self_attn.out_proj": "encoder.layers.*.attention.out_proj",
    "self_attn_layer_norm": "encoder.layers.*.layer_norm",
    "fc1": "encoder.layers.*.feed_forward.intermediate_dense",
    "fc2": "encoder.layers.*.feed_forward.output_dense",
    "final_layer_norm": "encoder.layers.*.final_layer_norm",
    "encoder.layer_norm": "encoder.layer_norm",
    "w2v_model.layer_norm": "feature_projection.layer_norm",
    "w2v_encoder.proj": "lm_head",
    "mask_emb": "masked_spec_embed",
}
snake_case				:	List[Any]							   =						[
    "lm_head",
]






def 						lowerCAmelCase_		(      _snake_case   :						Any   ,     _snake_case   :						str   ,     _snake_case   :						int   ,     _snake_case   :						List[Any]   ,     _snake_case   :						int     )       ->	Optional[int]:







	'''simple docstring'''


	for attribute in key.split("."     ):
		__magic_name__	:	int			     =  getattr(_snake_case   ,     _snake_case     )

	if weight_type is not None:
		__magic_name__	:	List[str]			     =  getattr(_snake_case   ,     _snake_case     ).shape
	else:
		__magic_name__	:	int			     =  hf_pointer.shape

	if hf_shape != value.shape:
		raise ValueError(
		    F'''Shape of hf {key + "." + weight_type if weight_type is not None else ""} is {hf_shape}, but should be'''
		    F''' {value.shape} for {full_name}'''     )

	if weight_type == "weight":
		__magic_name__	:	Any			     =  value
	elif weight_type == "weight_g":
		__magic_name__	:	Optional[int]			     =  value
	elif weight_type == "weight_v":
		__magic_name__	:	Dict			     =  value
	elif weight_type == "bias":
		__magic_name__	:	int			     =  value
	else:
		__magic_name__	:	List[Any]			     =  value

	logger.info(F'''{key + "." + weight_type if weight_type is not None else ""} was initialized from {full_name}.'''     )






def 						lowerCAmelCase_		(      _snake_case   :						Optional[Any]   ,     _snake_case   :						Any   ,     _snake_case   :						Optional[int]     )       ->	List[Any]:







	'''simple docstring'''


	__magic_name__	:	List[Any]			     =  []
	__magic_name__	:	Optional[Any]			     =  fairseq_model.state_dict()

	if not is_headless:
		__magic_name__	:	List[str]			     =  hf_model.dataavec_audio.feature_extractor
		__magic_name__	:	Optional[int]			     =  hf_model.dataavec_audio.encoder.pos_conv_embed

	else:
		__magic_name__	:	List[str]			     =  hf_model.feature_extractor
		__magic_name__	:	int			     =  hf_model.encoder.pos_conv_embed

	for name, value in fairseq_dict.items():
		__magic_name__	:	List[str]			     =  False
		if "conv_layers" in name:
			load_conv_layer(
			    _snake_case   ,     _snake_case   ,     _snake_case   ,     _snake_case   ,     )
			__magic_name__	:	Optional[int]			     =  True
		elif "pos_conv" in name:
			load_pos_conv_layer(
			    _snake_case   ,     _snake_case   ,     _snake_case   ,     _snake_case   ,     )
			__magic_name__	:	Tuple			     =  True
		else:
			for key, mapped_key in MAPPING.items():
				if not is_headless:
					__magic_name__	:	str			     =  "data2vec_audio." + mapped_key if mapped_key not in TOP_LEVEL_KEYS else mapped_key
				if key in name or key.split("w2v_model."     )[-1] == name.split("."     )[0]:
					__magic_name__	:	List[str]			     =  True
					if "*" in mapped_key:
						__magic_name__	:	List[str]			     =  name.split(_snake_case     )[0].split("."     )[-2]
						__magic_name__	:	Dict			     =  mapped_key.replace("*"   ,     _snake_case     )
					if "weight_g" in name:
						__magic_name__	:	Optional[int]			     =  "weight_g"
					elif "weight_v" in name:
						__magic_name__	:	Tuple			     =  "weight_v"
					elif "bias" in name:
						__magic_name__	:	List[Any]			     =  "bias"
					elif "weight" in name:
						# TODO: don't match quantizer.weight_proj
						__magic_name__	:	Any			     =  "weight"
					else:
						__magic_name__	:	Union[str, Any]			     =  None
					set_recursively(_snake_case   ,     _snake_case   ,     _snake_case   ,     _snake_case   ,     _snake_case     )
				continue
		if not is_used:
			unused_weights.append(_snake_case     )

	logger.warning(F'''Unused weights: {unused_weights}'''     )






def 						lowerCAmelCase_		(      _snake_case   :						Optional[int]   ,     _snake_case   :						Any     )       ->	List[str]:







	'''simple docstring'''


	__magic_name__	:	List[Any]			     =  path.split("."     )
	return reduce(_snake_case   ,     _snake_case   ,     _snake_case     )






def 						lowerCAmelCase_		(      _snake_case   :						List[Any]   ,     _snake_case   :						Tuple   ,     _snake_case   :						Any   ,     _snake_case   :						Any     )       ->	List[Any]:







	'''simple docstring'''


	__magic_name__	:	Dict			     =  access_by_string(_snake_case   ,     _snake_case     )
	__magic_name__	:	int			     =  hf_weight.data

	if fsq_value.shape != hf_value.shape:
		raise ValueError(F'''{full_name} has size {fsq_value.shape}, but {hf_value.shape} was found.'''     )
	__magic_name__	:	Tuple			     =  fsq_value
	logger.info(F'''{full_name} was correctly initialized from {hf_weight_path}.'''     )






def 						lowerCAmelCase_		(      _snake_case   :						Dict   ,     _snake_case   :						int   ,     _snake_case   :						Optional[int]   ,     _snake_case   :						Any     )       ->	Tuple:







	'''simple docstring'''


	__magic_name__	:	Optional[Any]			     =  full_name.split("conv_layers."     )[-1]
	__magic_name__	:	Union[str, Any]			     =  name.split("."     )
	__magic_name__	:	Tuple			     =  int(items[0]     )
	__magic_name__	:	List[str]			     =  int(items[1]     )

	__magic_name__	:	str			     =  name.split("."     )[-1]
	if type_id == 0:
		__magic_name__	:	Optional[int]			     =  "conv"
	elif type_id == 2:
		__magic_name__	:	Optional[Any]			     =  "layer_norm"
	else:
		unused_weights.append(_snake_case     )
		return

	set_weights(_snake_case   ,     _snake_case   ,     _snake_case   ,     F'''conv_layers.{layer_id}.{layer_type}.{weight_type}'''     )






def 						lowerCAmelCase_		(      _snake_case   :						str   ,     _snake_case   :						List[str]   ,     _snake_case   :						Dict   ,     _snake_case   :						Optional[Any]     )       ->	Tuple:







	'''simple docstring'''


	__magic_name__	:	str			     =  full_name.split("pos_conv."     )[-1]
	__magic_name__	:	str			     =  name.split("."     )
	__magic_name__	:	List[str]			     =  int(items[0]     )
	__magic_name__	:	Tuple			     =  int(items[1]     )

	__magic_name__	:	Optional[Any]			     =  name.split("."     )[-1]
	if type_id != 0:
		unused_weights.append(_snake_case     )
		return
	else:
		__magic_name__	:	Tuple			     =  "conv"

	set_weights(_snake_case   ,     _snake_case   ,     _snake_case   ,     F'''layers.{layer_id}.{layer_type}.{weight_type}'''     )






@torch.no_grad()
def 						lowerCAmelCase_		(      _snake_case   :						Optional[int]   ,     _snake_case   :						Dict   ,     _snake_case   :						Union[str, Any]=None   ,     _snake_case   :						Any=None   ,     _snake_case   :						int=True     )       ->	List[str]:







	'''simple docstring'''


	if config_path is not None:
		__magic_name__	:	Any			     =  DataaVecAudioConfig.from_pretrained(_snake_case     )
	else:
		__magic_name__	:	int			     =  DataaVecAudioConfig()

	if not is_finetuned:
		# Modify final_proj layer name
		__magic_name__	:	Tuple			     =  DataaVecAudioModel(_snake_case     )
		__magic_name__	:	Optional[Any]			     =  os.path.dirname(_snake_case     )

		__magic_name__	:	Optional[Any]			     =  torch.load(_snake_case     )
		__magic_name__	:	int			     =  state_dict["model"].pop("final_proj.0.weight"     )
		__magic_name__	:	Optional[int]			     =  state_dict["model"].pop("final_proj.0.bias"     )
		__magic_name__	:	str			     =  os.path.join(_snake_case   ,     "converted.pt"     )
		torch.save(_snake_case   ,     _snake_case     )
	else:
		__magic_name__	:	Union[str, Any]			     =  DataaVecAudioForCTC(_snake_case     )
		__magic_name__	:	Union[str, Any]			     =  checkpoint_path

	def load_dataavec(_snake_case   :						Optional[Any]     ):
		__magic_name__     ,					__magic_name__     ,					__magic_name__	:	Optional[Any]			     =  fairseq.checkpoint_utils.load_model_ensemble_and_task([path]     )
		return model[0].eval()

	__magic_name__	:	str			     =  load_dataavec(_snake_case     )

	recursively_load_weights(_snake_case   ,     _snake_case   ,     not is_finetuned     )

	__magic_name__	:	str			     =  WavaVecaProcessor.from_pretrained("facebook/wav2vec2-large-lv60"     )

	__magic_name__	:	Tuple			     =  load_dataset("patrickvonplaten/librispeech_asr_dummy"   ,     "clean"   ,     split="validation"     )
	__magic_name__	:	Union[str, Any]			     =  [x["array"] for x in ds[:4]["audio"]]

	__magic_name__	:	str			     =  processor(_snake_case   ,     return_tensors="pt"   ,     padding=_snake_case     )

	__magic_name__	:	Tuple			     =  inputs.input_values
	__magic_name__	:	int			     =  inputs.attention_mask
	#    input_values = inputs.input_values[:, :-1]
	#    attention_mask = inputs.attention_mask[:, :-1]

	hf_wavavec.eval()
	model.eval()
	if is_finetuned:
		__magic_name__	:	int			     =  model(source=_snake_case   ,     padding_mask=(1 - attention_mask)   ,     mask=_snake_case   ,     features_only=_snake_case     )[
		    "encoder_out"
		].transpose(0   ,     1     )
		__magic_name__	:	List[Any]			     =  hf_wavavec(_snake_case   ,     attention_mask=_snake_case     )["logits"]

		__magic_name__	:	Any			     =  torch.argmax(_snake_case   ,     dim=-1     )
		__magic_name__	:	str			     =  processor.batch_decode(_snake_case     )

		print(F'''Expected Output: {ds[:4]["text"]}, Pred: {output_string}'''     )
	else:
		__magic_name__	:	Union[str, Any]			     =  model(source=_snake_case   ,     padding_mask=(1 - attention_mask)   ,     mask=_snake_case   ,     features_only=_snake_case     )[
		    "layer_results"
		][-1][0].transpose(0   ,     1     )
		__magic_name__	:	Optional[int]			     =  hf_wavavec(_snake_case   ,     attention_mask=_snake_case     )["last_hidden_state"]

	print(our_output.shape   ,     their_output.shape     )
	__magic_name__	:	Union[str, Any]			     =  torch.max(torch.abs(our_output - their_output     )     ).item()
	print(F'''max_absolute_diff = {max_absolute_diff}'''     )  # ~ 1e-7
	__magic_name__	:	Tuple			     =  torch.allclose(_snake_case   ,     _snake_case   ,     atol=1E-3     )
	print("Do both models output the same tensors?"   ,     "🔥" if success else "💩"     )
	if not success:
		raise Exception("Something went wRoNg"     )

	hf_wavavec.save_pretrained(_snake_case     )

	if is_finetuned:
		processor.save_pretrained(_snake_case     )
	else:
		processor.feature_extractor.save_pretrained(_snake_case     )


if __name__ == "__main__":
				snake_case				:	Tuple							   =						argparse.ArgumentParser()
				parser.add_argument("--pytorch_dump_folder_path", default=None, type=str, help="Path to the output PyTorch model.")
				parser.add_argument("--checkpoint_path", default=None, type=str, help="Path to fairseq checkpoint")
				parser.add_argument("--dict_path", default=None, type=str, help="Path to dict of fine-tuned model")
				parser.add_argument("--config_path", default=None, type=str, help="Path to hf config.json of model to convert")
				parser.add_argument(
				    "--not_finetuned", action="store_true", help="Whether the model to convert is a fine-tuned model or not"
				)
				snake_case				:	Any							   =						parser.parse_args()
				convert_wavaveca_checkpoint(
				    args.checkpoint_path, args.pytorch_dump_folder_path, args.config_path, args.dict_path, not args.not_finetuned
				)


def 						lowerCAmelCase_		(      _snake_case   :						int   ,     _snake_case   :						list[tuple[int, int, int]]     )       ->	list[tuple[int, int, int]]:







	'''simple docstring'''


	__magic_name__	:	Union[str, Any]			     =  sorted(_snake_case   ,     key=lambda _snake_case     : edge[2]     )

	__magic_name__	:	Union[str, Any]			     =  list(range(_snake_case     )     )

	def find_parent(_snake_case   :						Dict     ):
		if i != parent[i]:
			__magic_name__	:	Any			     =  find_parent(parent[i]     )
		return parent[i]

	__magic_name__	:	List[str]			     =  0
	__magic_name__	:	int			     =  []

	for edge in edges:
		__magic_name__	:	Any			     =  find_parent(edge[0]     )
		__magic_name__	:	int			     =  find_parent(edge[1]     )
		if parent_a != parent_b:
			minimum_spanning_tree_cost += edge[2]
			minimum_spanning_tree.append(_snake_case     )
			__magic_name__	:	Optional[int]			     =  parent_b

	return minimum_spanning_tree


if __name__ == "__main__":  # pragma: no cover
				snake_case   ,snake_case				:	int							   =						list(map(int, input().strip().split()))
				snake_case				:	int							   =						[]

				for _ in range(num_edges):
								snake_case   ,snake_case   ,snake_case				:	Dict							   =						(int(x) for x in input().strip().split())
								edges.append((nodea, nodea, cost))

				kruskal(num_nodes, edges)
