





import argparse
import json
import os

import fairseq
import torch
from fairseq.data import Dictionary

from transformers import (
    WavaVecaConfig,
    WavaVecaCTCTokenizer,
    WavaVecaFeatureExtractor,
    WavaVecaForCTC,
    WavaVecaForPreTraining,
    WavaVecaProcessor,
    logging,
)
from transformers.models.wavaveca.modeling_wavaveca import WavaVecaForSequenceClassification


logging.set_verbosity_info()
lowercase_					     =	logging.get_logger(__name__)

lowercase_					     =	{
    'post_extract_proj': 'feature_projection.projection',
    'encoder.pos_conv.0': 'encoder.pos_conv_embed.conv',
    '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',
    'adapter_layer': 'encoder.layers.*.adapter_layer',
    'w2v_model.layer_norm': 'feature_projection.layer_norm',
    'quantizer.weight_proj': 'quantizer.weight_proj',
    'quantizer.vars': 'quantizer.codevectors',
    'project_q': 'project_q',
    'final_proj': 'project_hid',
    'w2v_encoder.proj': 'lm_head',
    'mask_emb': 'masked_spec_embed',
    'pooling_layer.linear': 'projector',
    'pooling_layer.projection': 'classifier',
}
lowercase_					     =	[
    'lm_head',
    'quantizer.weight_proj',
    'quantizer.codevectors',
    'project_q',
    'project_hid',
    'projector',
    'classifier',
]




def     __UpperCamelCase						(_SCREAMING_SNAKE_CASE	)       ->     Optional[Any]:
  lowercase__			    =						{}
  with open(__lowerCAmelCase	,		'r'	) as file:
    for line_number, line in enumerate(__lowerCAmelCase	):
      lowercase__			    =						line.strip()
      if line:
        lowercase__			    =						line.split()
        lowercase__			    =						line_number
        lowercase__			    =						words[0]
        lowercase__			    =						value
  return result




def     __UpperCamelCase						(_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	)       ->     List[str]:
  for attribute in key.split('.'	):
    lowercase__			    =						getattr(__lowerCAmelCase	,		__lowerCAmelCase	)

  lowercase__			    =						None
  for param_key in PARAM_MAPPING.keys():
    if full_name.endswith(__lowerCAmelCase	):
      lowercase__			    =						PARAM_MAPPING[full_name.split('.'	)[-1]]
      lowercase__			    =						'param'

  if weight_type is not None and weight_type != "param":
    lowercase__			    =						getattr(__lowerCAmelCase	,		__lowerCAmelCase	).shape
  elif weight_type is not None and weight_type == "param":
    lowercase__			    =						hf_pointer
    for attribute in hf_param_name.split('.'	):
      lowercase__			    =						getattr(__lowerCAmelCase	,		__lowerCAmelCase	)
    lowercase__			    =						shape_pointer.shape

    # let's reduce dimension
    lowercase__			    =						value[0]
  else:
    lowercase__			    =						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":
    lowercase__			    =						value
  elif weight_type == "weight_g":
    lowercase__			    =						value
  elif weight_type == "weight_v":
    lowercase__			    =						value
  elif weight_type == "bias":
    lowercase__			    =						value
  elif weight_type == "param":
    for attribute in hf_param_name.split('.'	):
      lowercase__			    =						getattr(__lowerCAmelCase	,		__lowerCAmelCase	)
    lowercase__			    =						value
  else:
    lowercase__			    =						value

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




def     __UpperCamelCase						(_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	)       ->     Tuple:
  lowercase__			    =						None
  for param_key in PARAM_MAPPING.keys():
    if full_name.endswith(__lowerCAmelCase	):
      lowercase__			    =						PARAM_MAPPING[full_name.split('.'	)[-1]]
      lowercase__			    =						'param'

  if weight_type is not None and weight_type != "param":
    lowercase__			    =						'.'.join([key, weight_type]	)
  elif weight_type is not None and weight_type == "param":
    lowercase__			    =						'.'.join([key, hf_param_name]	)
  else:
    lowercase__			    =						key

  lowercase__			    =						value if 'lm_head' in full_key else value[0]


lowercase_					     =	{
    'W_a': 'linear_1.weight',
    'W_b': 'linear_2.weight',
    'b_a': 'linear_1.bias',
    'b_b': 'linear_2.bias',
    'ln_W': 'norm.weight',
    'ln_b': 'norm.bias',
}




def     __UpperCamelCase						(_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE=None	,		_SCREAMING_SNAKE_CASE=None	)       ->     Any:
  lowercase__			    =						False
  for key, mapped_key in MAPPING.items():
    lowercase__			    =						'wav2vec2.' + 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]:
      lowercase__			    =						True
      if "*" in mapped_key:
        lowercase__			    =						name.split(__lowerCAmelCase	)[0].split('.'	)[-2]
        lowercase__			    =						mapped_key.replace('*'	,		__lowerCAmelCase	)
      if "weight_g" in name:
        lowercase__			    =						'weight_g'
      elif "weight_v" in name:
        lowercase__			    =						'weight_v'
      elif "bias" in name:
        lowercase__			    =						'bias'
      elif "weight" in name:
        # TODO: don't match quantizer.weight_proj
        lowercase__			    =						'weight'
      else:
        lowercase__			    =						None
      if hf_dict is not None:
        rename_dict(__lowerCAmelCase	,		__lowerCAmelCase	,		__lowerCAmelCase	,		__lowerCAmelCase	,		__lowerCAmelCase	)
      else:
        set_recursively(__lowerCAmelCase	,		__lowerCAmelCase	,		__lowerCAmelCase	,		__lowerCAmelCase	,		__lowerCAmelCase	)
      return is_used
  return is_used




def     __UpperCamelCase						(_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	)       ->     List[str]:
  lowercase__			    =						[]
  lowercase__			    =						fairseq_model.state_dict()

  lowercase__			    =						hf_model.wavaveca.feature_extractor

  for name, value in fairseq_dict.items():
    lowercase__			    =						False
    if "conv_layers" in name:
      load_conv_layer(
          __lowerCAmelCase	,		__lowerCAmelCase	,		__lowerCAmelCase	,		__lowerCAmelCase	,		hf_model.config.feat_extract_norm == 'group'	,		)
      lowercase__			    =						True
    else:
      lowercase__			    =						load_wavaveca_layer(__lowerCAmelCase	,		__lowerCAmelCase	,		__lowerCAmelCase	)
    if not is_used:
      unused_weights.append(__lowerCAmelCase	)

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




def     __UpperCamelCase						(_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	)       ->     Any:
  lowercase__			    =						full_name.split('conv_layers.'	)[-1]
  lowercase__			    =						name.split('.'	)
  lowercase__			    =						int(items[0]	)
  lowercase__			    =						int(items[1]	)

  if type_id == 0:
    if "bias" in name:
      if value.shape != feature_extractor.conv_layers[layer_id].conv.bias.data.shape:
        raise ValueError(
            F"""{full_name} has size {value.shape}, but"""
            F""" {feature_extractor.conv_layers[layer_id].conv.bias.data.shape} was found."""	)
      lowercase__			    =						value
      logger.info(F"""Feat extract conv layer {layer_id} was initialized from {full_name}."""	)
    elif "weight" in name:
      if value.shape != feature_extractor.conv_layers[layer_id].conv.weight.data.shape:
        raise ValueError(
            F"""{full_name} has size {value.shape}, but"""
            F""" {feature_extractor.conv_layers[layer_id].conv.weight.data.shape} was found."""	)
      lowercase__			    =						value
      logger.info(F"""Feat extract conv layer {layer_id} was initialized from {full_name}."""	)
  elif (type_id == 2 and not use_group_norm) or (type_id == 2 and layer_id == 0 and use_group_norm):
    if "bias" in name:
      if value.shape != feature_extractor.conv_layers[layer_id].layer_norm.bias.data.shape:
        raise ValueError(
            F"""{full_name} has size {value.shape}, but"""
            F""" {feature_extractor.conv_layers[layer_id].layer_norm.bias.data.shape} was found."""	)
      lowercase__			    =						value
      logger.info(F"""Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}."""	)
    elif "weight" in name:
      if value.shape != feature_extractor.conv_layers[layer_id].layer_norm.weight.data.shape:
        raise ValueError(
            F"""{full_name} has size {value.shape}, but"""
            F""" {feature_extractor.conv_layers[layer_id].layer_norm.weight.data.shape} was found."""	)
      lowercase__			    =						value
      logger.info(F"""Feat extract layer norm weight of layer {layer_id} was initialized from {full_name}."""	)
  else:
    unused_weights.append(__lowerCAmelCase	)




@torch.no_grad()
def     __UpperCamelCase						(_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE	,		_SCREAMING_SNAKE_CASE=None	,		_SCREAMING_SNAKE_CASE=None	,		_SCREAMING_SNAKE_CASE=True	,		_SCREAMING_SNAKE_CASE=False	)       ->     Optional[int]:
  if config_path is not None:
    lowercase__			    =						WavaVecaConfig.from_pretrained(__lowerCAmelCase	)
  else:
    lowercase__			    =						WavaVecaConfig()

  if is_seq_class:
    lowercase__			    =						read_txt_into_dict(__lowerCAmelCase	)
    lowercase__			    =						idalabel
    lowercase__			    =						WavaVecaForSequenceClassification(__lowerCAmelCase	)
    lowercase__			    =						WavaVecaFeatureExtractor(
        feature_size=1	,		sampling_rate=16000	,		padding_value=0	,		do_normalize=__lowerCAmelCase	,		return_attention_mask=__lowerCAmelCase	,		)
    feature_extractor.save_pretrained(__lowerCAmelCase	)

  elif is_finetuned:
    if dict_path:
      lowercase__			    =						Dictionary.load(__lowerCAmelCase	)

      # important change bos & pad token id since CTC symbol is <pad> and
      # not <s> as in fairseq
      lowercase__			    =						target_dict.pad_index
      lowercase__			    =						target_dict.bos_index
      lowercase__			    =						target_dict.eos_index
      lowercase__			    =						len(target_dict.symbols	)
      lowercase__			    =						os.path.join(__lowerCAmelCase	,		'vocab.json'	)
      if not os.path.isdir(__lowerCAmelCase	):
        logger.error('--pytorch_dump_folder_path ({}) should be a directory'.format(__lowerCAmelCase	)	)
        return
      os.makedirs(__lowerCAmelCase	,		exist_ok=__lowerCAmelCase	)
      lowercase__			    =						target_dict.indices

      # fairseq has the <pad> and <s> switched
      lowercase__			    =						0
      lowercase__			    =						1
      with open(__lowerCAmelCase	,		'w'	,		encoding='utf-8'	) as vocab_handle:
        json.dump(__lowerCAmelCase	,		__lowerCAmelCase	)
      lowercase__			    =						WavaVecaCTCTokenizer(
          __lowerCAmelCase	,		unk_token=target_dict.unk_word	,		pad_token=target_dict.pad_word	,		bos_token=target_dict.bos_word	,		eos_token=target_dict.eos_word	,		word_delimiter_token='|'	,		do_lower_case=__lowerCAmelCase	,		)
      lowercase__			    =						True if config.feat_extract_norm == 'layer' else False
      lowercase__			    =						WavaVecaFeatureExtractor(
          feature_size=1	,		sampling_rate=16000	,		padding_value=0	,		do_normalize=__lowerCAmelCase	,		return_attention_mask=__lowerCAmelCase	,		)
      lowercase__			    =						WavaVecaProcessor(feature_extractor=__lowerCAmelCase	,		tokenizer=__lowerCAmelCase	)
      processor.save_pretrained(__lowerCAmelCase	)

    lowercase__			    =						WavaVecaForCTC(__lowerCAmelCase	)
  else:
    lowercase__			    =						WavaVecaForPreTraining(__lowerCAmelCase	)

  if is_finetuned or is_seq_class:
    lowercase__    ,					lowercase__    ,					lowercase__			    =						fairseq.checkpoint_utils.load_model_ensemble_and_task(
        [checkpoint_path]	,		arg_overrides={'data': '/'.join(dict_path.split('/'	)[:-1]	)}	)
  else:
    lowercase__			    =						argparse.Namespace(task='audio_pretraining'	)
    lowercase__			    =						fairseq.tasks.setup_task(__lowerCAmelCase	)

    lowercase__    ,					lowercase__    ,					lowercase__			    =						fairseq.checkpoint_utils.load_model_ensemble_and_task([checkpoint_path]	,		task=__lowerCAmelCase	)

  lowercase__			    =						model[0].eval()

  recursively_load_weights(__lowerCAmelCase	,		__lowerCAmelCase	,		not is_finetuned	)

  hf_wavavec.save_pretrained(__lowerCAmelCase	)


if __name__ == "__main__":
      lowercase_					     =	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"""
      )
      parser.add_argument(
          """--is_seq_class""",
          action="""store_true""",
          help="""Whether the model to convert is a fine-tuned sequence classification model or not""",
      )
      lowercase_					     =	parser.parse_args()

      lowercase_					     =	not args.not_finetuned and not args.is_seq_class
      convert_wavaveca_checkpoint(
          args.checkpoint_path,
          args.pytorch_dump_folder_path,
          args.config_path,
          args.dict_path,
          is_finetuned,
          args.is_seq_class,
      )









def     __UpperCamelCase						(_SCREAMING_SNAKE_CASE = 50	)       ->     int:
  lowercase__			    =						[[0] * 3 for _ in range(length + 1	)]

  for row_length in range(length + 1	):
    for tile_length in range(2	,		5	):
      for tile_start in range(row_length - tile_length + 1	):
        different_colour_ways_number[row_length][tile_length - 2] += (
            different_colour_ways_number[row_length - tile_start - tile_length][
                tile_length - 2
            ]
            + 1
        )

  return sum(different_colour_ways_number[length]	)


if __name__ == "__main__":
      print(f'''{solution() = }''')


