






import logging
from pathlib import Path

import numpy as np
import pytorch_lightning as pl
import torch
from pytorch_lightning.callbacks import EarlyStopping, ModelCheckpoint
from pytorch_lightning.utilities import rank_zero_only
from utils_rag import save_json





def   _lowerCAmelCase				(   UpperCamelCase__:     List[str]						) ->   Any:





	"""simple docstring"""







	A								=				filter(lambda UpperCamelCase__						: p.requires_grad							,					model.parameters()						)
	A								=				sum([np.prod(p.size()						) for p in model_parameters]						)
	return params


_lowercase       :      str	=	logging.getLogger(__name__)





def   _lowerCAmelCase				(   UpperCamelCase__:     Any							,					UpperCamelCase__:     List[str]						) ->   List[str]:





	"""simple docstring"""







	if metric == "rouge2":
		A								=				'''{val_avg_rouge2:.4f}-{step_count}'''
	elif metric == "bleu":
		A								=				'''{val_avg_bleu:.4f}-{step_count}'''
	elif metric == "em":
		A								=				'''{val_avg_em:.4f}-{step_count}'''
	elif metric == "loss":
		A								=				'''{val_avg_loss:.4f}-{step_count}'''
	else:
		raise NotImplementedError(
		    f'seq2seq callbacks only support rouge2 and bleu, got {metric}, You can make your own by adding to this'
		    """ function."""						)

	A								=				ModelCheckpoint(
	    dirpath=snake_case_							,					filename=snake_case_							,					monitor=f'val_{metric}'							,					mode="""max"""							,					save_top_k=1							,					every_n_epochs=1							,					)

	return checkpoint_callback





def   _lowerCAmelCase				(   UpperCamelCase__:     int							,					UpperCamelCase__:     List[str]						) ->   List[str]:





	"""simple docstring"""







	return EarlyStopping(
	    monitor=f'val_{metric}'							,					mode="""min""" if """loss""" in metric else """max"""							,					patience=snake_case_							,					verbose=snake_case_							,					)






class       _UpperCamelCase    (					pl.Callback				):

				"""simple docstring"""







				def      _UpperCAmelCase					(						self				,   a__				,   a__   )	->				Optional[int]:
					A								=				{f'lr_group_{i}': param['''lr'''] for i, param in enumerate(pl_module.trainer.optimizers[0].param_groups   )}
					pl_module.logger.log_metrics(a__   )

				@rank_zero_only
				def      _UpperCAmelCase					(						self				,   a__				,   a__				,   a__				,   a__=True   )	->				None:
					logger.info(f'***** {type_path} results at step {trainer.global_step:05d} *****'   )
					A								=				trainer.callback_metrics
					trainer.logger.log_metrics({k: v for k, v in metrics.items() if k not in ["""log""", """progress_bar""", """preds"""]}   )
					# Log results
					A								=				Path(pl_module.hparams.output_dir   )
					if type_path == "test":
						A								=				od / '''test_results.txt'''
						A								=				od / '''test_generations.txt'''
					else:
						# this never gets hit. I prefer not to save intermediate generations, and results are in metrics.json
						# If people want this it will be easy enough to add back.
						A								=				od / f'{type_path}_results/{trainer.global_step:05d}.txt'
						A								=				od / f'{type_path}_generations/{trainer.global_step:05d}.txt'
						results_file.parent.mkdir(exist_ok=a__   )
						generations_file.parent.mkdir(exist_ok=a__   )
					with open(a__				,   """a+"""   ) as writer:
						for key in sorted(a__   ):
							if key in ["log", "progress_bar", "preds"]:
								continue
							A								=				metrics[key]
							if isinstance(a__				,   torch.Tensor   ):
								A								=				val.item()
							A								=				f'{key}: {val:.6f}\n'
							writer.write(a__   )

					if not save_generations:
						return

					if "preds" in metrics:
						A								=				'''\n'''.join(metrics["""preds"""]   )
						generations_file.open("""w+"""   ).write(a__   )

				@rank_zero_only
				def      _UpperCAmelCase					(						self				,   a__				,   a__   )	->				Union[str, Any]:
					try:
						A								=				pl_module.model.model.num_parameters()
					except AttributeError:
						A								=				pl_module.model.num_parameters()

					A								=				count_trainable_parameters(a__   )
					# mp stands for million parameters
					trainer.logger.log_metrics({"""n_params""": npars, """mp""": npars / 1e6, """grad_mp""": n_trainable_pars / 1e6}   )

				@rank_zero_only
				def      _UpperCAmelCase					(						self				,   a__				,   a__   )	->				List[str]:
					save_json(pl_module.metrics				,   pl_module.metrics_save_path   )
					return self._write_logs(a__				,   a__				,   """test"""   )

				@rank_zero_only
				def      _UpperCAmelCase					(						self				,   a__				,   a__   )	->				int:
					save_json(pl_module.metrics				,   pl_module.metrics_save_path   )
					# Uncommenting this will save val generations
					# return self._write_logs(trainer, pl_module, "valid")







from typing import List, Optional, Union

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


_lowercase       :      Optional[Any]	=	logging.get_logger(__name__)

_lowercase       :      List[str]	=	{
    "huggingface/informer-tourism-monthly": (
        "https://huggingface.co/huggingface/informer-tourism-monthly/resolve/main/config.json"
    ),
    # See all Informer models at https://huggingface.co/models?filter=informer
}






class       _UpperCamelCase    (					__snake_case				):

				"""simple docstring"""







				lowerCAmelCase 		= 'informer'
				lowerCAmelCase 		= {
				    'hidden_size': 'd_model',
				    'num_attention_heads': 'encoder_attention_heads',
				    'num_hidden_layers': 'encoder_layers',
				}

				def __init__(						self				,   a__ = None				,   a__ = None				,   a__ = "student_t"				,   a__ = "nll"				,   a__ = 1				,   a__ = None				,   a__ = "mean"				,   a__ = 0				,   a__ = 0				,   a__ = 0				,   a__ = 0				,   a__ = None				,   a__ = None				,   a__ = 64				,   a__ = 32				,   a__ = 32				,   a__ = 2				,   a__ = 2				,   a__ = 2				,   a__ = 2				,   a__ = True				,   a__ = "gelu"				,   a__ = 0.05				,   a__ = 0.1				,   a__ = 0.1				,   a__ = 0.1				,   a__ = 0.1				,   a__ = 100				,   a__ = 0.02				,   a__=True				,   a__ = "prob"				,   a__ = 5				,   a__ = True				,   **a__				,   )	->				Union[str, Any]:
					# time series specific configuration
					A								=				prediction_length
					A								=				context_length or prediction_length
					A								=				distribution_output
					A								=				loss
					A								=				input_size
					A								=				num_time_features
					A								=				lags_sequence if lags_sequence is not None else [1, 2, 3, 4, 5, 6, 7]
					A								=				scaling
					A								=				num_dynamic_real_features
					A								=				num_static_real_features
					A								=				num_static_categorical_features

					# set cardinality
					if cardinality and num_static_categorical_features > 0:
						if len(a__   ) != num_static_categorical_features:
							raise ValueError(
							    """The cardinality should be a list of the same length as `num_static_categorical_features`"""   )
						A								=				cardinality
					else:
						A								=				[0]

					# set embedding_dimension
					if embedding_dimension and num_static_categorical_features > 0:
						if len(a__   ) != num_static_categorical_features:
							raise ValueError(
							    """The embedding dimension should be a list of the same length as `num_static_categorical_features`"""   )
						A								=				embedding_dimension
					else:
						A								=				[min(50				,   (cat + 1) // 2   ) for cat in self.cardinality]

					A								=				num_parallel_samples

					# Transformer architecture configuration
					A								=				input_size * len(self.lags_sequence   ) + self._number_of_features
					A								=				d_model
					A								=				encoder_attention_heads
					A								=				decoder_attention_heads
					A								=				encoder_ffn_dim
					A								=				decoder_ffn_dim
					A								=				encoder_layers
					A								=				decoder_layers

					A								=				dropout
					A								=				attention_dropout
					A								=				activation_dropout
					A								=				encoder_layerdrop
					A								=				decoder_layerdrop

					A								=				activation_function
					A								=				init_std

					A								=				use_cache

					# Informer
					A								=				attention_type
					A								=				sampling_factor
					A								=				distil

					super().__init__(is_encoder_decoder=a__				,   **a__   )

				@property
				def      _UpperCAmelCase					(						self   )	->				int:
					return (
					    sum(self.embedding_dimension   )
					    + self.num_dynamic_real_features
					    + self.num_time_features
					    + self.num_static_real_features
					    + self.input_size * 2  # the log1p(abs(loc)) and log(scale) features
					)



