
'''simple docstring'''







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 import save_json
def    snake_case_						(							__SCREAMING_SNAKE_CASE   :					List[Any]				):



						"""simple docstring"""





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


_lowercase					:    List[Any]       				=			logging.getLogger(__name__)






class 					lowerCAmelCase__  (    pl.Callback	):






					def       _snake_case       (  self							,				__SCREAMING_SNAKE_CASE							,				__SCREAMING_SNAKE_CASE						):


											"""simple docstring"""





											lowercase_      :	List[Any]						=			{F'''lr_group_{i}''': param["lr"] for i, param in enumerate(pl_module.trainer.optimizers[0].param_groups						)}
											pl_module.logger.log_metrics(__snake_case						)






					@rank_zero_only
					def       _snake_case       (  self							,				__SCREAMING_SNAKE_CASE							,				__SCREAMING_SNAKE_CASE							,				__SCREAMING_SNAKE_CASE							,				__SCREAMING_SNAKE_CASE=True						):


											"""simple docstring"""





											logger.info(F'''***** {type_path} results at step {trainer.global_step:05d} *****'''						)
											lowercase_      :	Any						=			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
											lowercase_      :	str						=			Path(pl_module.hparams.output_dir						)
											if type_path == "test":
																	lowercase_      :	List[str]						=			od / "test_results.txt"
																	lowercase_      :	Union[str, Any]						=			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.
																	lowercase_      :	str						=			od / F'''{type_path}_results/{trainer.global_step:05d}.txt'''
																	lowercase_      :	Union[str, Any]						=			od / F'''{type_path}_generations/{trainer.global_step:05d}.txt'''
																	results_file.parent.mkdir(exist_ok=__snake_case						)
																	generations_file.parent.mkdir(exist_ok=__snake_case						)
											with open(__snake_case							,				'''a+'''						) as writer:
																	for key in sorted(__snake_case						):
																							if key in ["log", "progress_bar", "preds"]:
																													continue
																							lowercase_      :	Optional[int]						=			metrics[key]
																							if isinstance(__snake_case							,				torch.Tensor						):
																													lowercase_      :	Optional[Any]						=			val.item()
																							lowercase_      :	Optional[int]						=			F'''{key}: {val:.6f}\n'''
																							writer.write(__snake_case						)

											if not save_generations:
																	return

											if "preds" in metrics:
																	lowercase_      :	Union[str, Any]						=			"\n".join(metrics['''preds''']						)
																	generations_file.open('''w+'''						).write(__snake_case						)






					@rank_zero_only
					def       _snake_case       (  self							,				__SCREAMING_SNAKE_CASE							,				__SCREAMING_SNAKE_CASE						):


											"""simple docstring"""





											try:
																	lowercase_      :	Union[str, Any]						=			pl_module.model.model.num_parameters()
											except AttributeError:
																	lowercase_      :	Dict						=			pl_module.model.num_parameters()

											lowercase_      :	Optional[Any]						=			count_trainable_parameters(__snake_case						)
											# 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       _snake_case       (  self							,				__SCREAMING_SNAKE_CASE							,				__SCREAMING_SNAKE_CASE						):


											"""simple docstring"""





											save_json(pl_module.metrics							,				pl_module.metrics_save_path						)
											return self._write_logs(__snake_case							,				__snake_case							,				'''test'''						)






					@rank_zero_only
					def       _snake_case       (  self							,				__SCREAMING_SNAKE_CASE							,				__SCREAMING_SNAKE_CASE						):


											"""simple docstring"""





											save_json(pl_module.metrics							,				pl_module.metrics_save_path						)
											# Uncommenting this will save val generations
											# return self._write_logs(trainer, pl_module, "valid")







def    snake_case_						(							__SCREAMING_SNAKE_CASE   :					int , __SCREAMING_SNAKE_CASE   :					Optional[Any] , __SCREAMING_SNAKE_CASE   :					int=1 , __SCREAMING_SNAKE_CASE   :					int=False				):



						"""simple docstring"""





						if metric == "rouge2":
												lowercase_      :	Union[str, Any]						=			"{val_avg_rouge2:.4f}-{step_count}"
						elif metric == "bleu":
												lowercase_      :	int						=			"{val_avg_bleu:.4f}-{step_count}"
						elif metric == "loss":
												lowercase_      :	Union[str, Any]						=			"{val_avg_loss:.4f}-{step_count}"
						else:
												raise NotImplementedError(
												    F'''seq2seq callbacks only support rouge2, bleu and loss, got {metric}, You can make your own by adding to'''
												    ''' this function.'''				)

						lowercase_      :	Any						=			ModelCheckpoint(
						    dirpath=snake_case_ , filename=snake_case_ , monitor=F'''val_{metric}''' , mode='''min''' if '''loss''' in metric else '''max''' , save_top_k=snake_case_ , )
						return checkpoint_callback




def    snake_case_						(							__SCREAMING_SNAKE_CASE   :					List[str] , __SCREAMING_SNAKE_CASE   :					List[Any]				):



						"""simple docstring"""





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





import unittest

import torch

from diffusers import UNetaDModel
from diffusers.utils import floats_tensor, slow, torch_device

from .test_modeling_common import ModelTesterMixin, UNetTesterMixin





class 		__lowerCamelCase     (   lowercase							, lowercase							, unittest.TestCase		):
							lowerCamelCase__:				int      =							UNetaDModel
							lowerCamelCase__:				Any      =							'''sample'''



							@property
							def     A__ (     self							)						->     Tuple:






								"""simple docstring"""



								UpperCAmelCase:					Union[str, Any] 						=     4
								UpperCAmelCase:					Optional[Any] 						=     1_4
								UpperCAmelCase:					str 						=     1_6

								UpperCAmelCase:					Optional[int] 						=     floats_tensor((batch_size, num_features, seq_len)							).to(__snake_case							)
								UpperCAmelCase:					Any 						=     torch.tensor([1_0] * batch_size							).to(__snake_case							)

								return {"sample": noise, "timestep": time_step}



							@property
							def     A__ (     self							)						->     Tuple:






								"""simple docstring"""



								return (4, 1_4, 1_6)



							@property
							def     A__ (     self							)						->     Union[str, Any]:






								"""simple docstring"""



								return (4, 1_4, 1_6)



							def     A__ (     self							)						->     int:






								"""simple docstring"""



								pass



							def     A__ (     self							)						->     Optional[int]:






								"""simple docstring"""



								pass



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     Optional[Any]:






								"""simple docstring"""



								super().test_determinism()



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     Tuple:






								"""simple docstring"""



								super().test_outputs_equivalence()



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     Dict:






								"""simple docstring"""



								super().test_from_save_pretrained()



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     str:






								"""simple docstring"""



								super().test_from_save_pretrained_variant()



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     List[Any]:






								"""simple docstring"""



								super().test_model_from_pretrained()



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     int:






								"""simple docstring"""



								super().test_output()



							def     A__ (     self							)						->     List[str]:






								"""simple docstring"""



								UpperCAmelCase:					Tuple 						=     {
								    "block_out_channels": (3_2, 6_4, 1_2_8, 2_5_6),
								    "in_channels": 1_4,
								    "out_channels": 1_4,
								    "time_embedding_type": "positional",
								    "use_timestep_embedding": True,
								    "flip_sin_to_cos": False,
								    "freq_shift": 1.0,
								    "out_block_type": "OutConv1DBlock",
								    "mid_block_type": "MidResTemporalBlock1D",
								    "down_block_types": ("DownResnetBlock1D", "DownResnetBlock1D", "DownResnetBlock1D", "DownResnetBlock1D"),
								    "up_block_types": ("UpResnetBlock1D", "UpResnetBlock1D", "UpResnetBlock1D"),
								    "act_fn": "mish",
								}
								UpperCAmelCase:					Tuple 						=     self.dummy_input
								return init_dict, inputs_dict



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     Tuple:






								"""simple docstring"""



								UpperCAmelCase						,   UpperCAmelCase:					Any 						=     UNetaDModel.from_pretrained(
								    "bglick13/hopper-medium-v2-value-function-hor32"	,				output_loading_info=__snake_case	,				subfolder="unet"							)
								self.assertIsNotNone(__snake_case							)
								self.assertEqual(len(loading_info["missing_keys"]							)	,				0							)

								model.to(__snake_case							)
								UpperCAmelCase:					Tuple 						=     model(**self.dummy_input							)

								assert image is not None, "Make sure output is not None"



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     List[str]:






								"""simple docstring"""



								UpperCAmelCase:					Union[str, Any] 						=     UNetaDModel.from_pretrained("bglick13/hopper-medium-v2-value-function-hor32"	,				subfolder="unet"							)
								torch.manual_seed(0							)
								if torch.cuda.is_available():
									torch.cuda.manual_seed_all(0							)

								UpperCAmelCase:					int 						=     model.config.in_channels
								UpperCAmelCase:					List[str] 						=     1_6
								UpperCAmelCase:					Union[str, Any] 						=     torch.randn((1, seq_len, num_features)							).permute(
								    0	,				2	,				1							)  # match original, we can update values and remove
								UpperCAmelCase:					List[str] 						=     torch.full((num_features,)	,				0							)

								with torch.no_grad():
									UpperCAmelCase:					Union[str, Any] 						=     model(__snake_case	,				__snake_case							).sample.permute(0	,				2	,				1							)

								UpperCAmelCase:					str 						=     output[0, -3:, -3:].flatten()
								# fmt: off
								UpperCAmelCase:					Dict 						=     torch.tensor([-2.13_71_72, 1.1_42_60_16, 0.3_68_86_87, -0.76_69_22, 0.7_30_31_46, 0.11_03_88_64, -0.4_76_06_33, 0.13_27_01_72, 0.02_59_13_48]							)
								# fmt: on
								self.assertTrue(torch.allclose(__snake_case	,				__snake_case	,				rtol=1e-3							)							)



							def     A__ (     self							)						->     Any:






								"""simple docstring"""



								pass




							@slow
							def     A__ (     self							)						->     Tuple:






								"""simple docstring"""



								UpperCAmelCase:					List[str] 						=     "harmonai/maestro-150k"
								UpperCAmelCase:					Optional[Any] 						=     UNetaDModel.from_pretrained(__snake_case	,				subfolder="unet"							)
								model.to(__snake_case							)

								UpperCAmelCase:					Any 						=     6_5_5_3_6
								UpperCAmelCase:					str 						=     torch.sin(torch.arange(__snake_case							)[None, None, :].repeat(1	,				2	,				1							)							).to(__snake_case							)
								UpperCAmelCase:					Dict 						=     torch.tensor([1]							).to(__snake_case							)

								with torch.no_grad():
									UpperCAmelCase:					Optional[Any] 						=     model(__snake_case	,				__snake_case							).sample

								UpperCAmelCase:					List[Any] 						=     output.abs().sum()
								UpperCAmelCase:					Dict 						=     output.abs().max()

								assert (output_sum - 2_24.08_96).abs() < 0.5
								assert (output_max - 0.06_07).abs() < 4e-4





class 		__lowerCamelCase     (   lowercase							, lowercase							, unittest.TestCase		):
							lowerCamelCase__:				Dict      =							UNetaDModel
							lowerCamelCase__:				int      =							'''sample'''



							@property
							def     A__ (     self							)						->     int:






								"""simple docstring"""



								UpperCAmelCase:					List[Any] 						=     4
								UpperCAmelCase:					int 						=     1_4
								UpperCAmelCase:					Optional[int] 						=     1_6

								UpperCAmelCase:					List[str] 						=     floats_tensor((batch_size, num_features, seq_len)							).to(__snake_case							)
								UpperCAmelCase:					Any 						=     torch.tensor([1_0] * batch_size							).to(__snake_case							)

								return {"sample": noise, "timestep": time_step}



							@property
							def     A__ (     self							)						->     List[Any]:






								"""simple docstring"""



								return (4, 1_4, 1_6)



							@property
							def     A__ (     self							)						->     List[Any]:






								"""simple docstring"""



								return (4, 1_4, 1)



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     Dict:






								"""simple docstring"""



								super().test_determinism()



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     Optional[int]:






								"""simple docstring"""



								super().test_outputs_equivalence()



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     List[str]:






								"""simple docstring"""



								super().test_from_save_pretrained()



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     int:






								"""simple docstring"""



								super().test_from_save_pretrained_variant()



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     Optional[int]:






								"""simple docstring"""



								super().test_model_from_pretrained()



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     str:






								"""simple docstring"""



								UpperCAmelCase						,   UpperCAmelCase:					Optional[int] 						=     self.prepare_init_args_and_inputs_for_common()
								UpperCAmelCase:					Tuple 						=     self.model_class(**__snake_case							)
								model.to(__snake_case							)
								model.eval()

								with torch.no_grad():
									UpperCAmelCase:					Union[str, Any] 						=     model(**__snake_case							)

									if isinstance(__snake_case	,				__snake_case							):
										UpperCAmelCase:					List[str] 						=     output.sample

								self.assertIsNotNone(__snake_case							)
								UpperCAmelCase:					Optional[Any] 						=     torch.Size((inputs_dict["sample"].shape[0], 1)							)
								self.assertEqual(output.shape	,				__snake_case	,				"Input and output shapes do not match"							)



							def     A__ (     self							)						->     Tuple:






								"""simple docstring"""



								pass



							def     A__ (     self							)						->     Any:






								"""simple docstring"""



								pass



							def     A__ (     self							)						->     int:






								"""simple docstring"""



								UpperCAmelCase:					Tuple 						=     {
								    "in_channels": 1_4,
								    "out_channels": 1_4,
								    "down_block_types": ["DownResnetBlock1D", "DownResnetBlock1D", "DownResnetBlock1D", "DownResnetBlock1D"],
								    "up_block_types": [],
								    "out_block_type": "ValueFunction",
								    "mid_block_type": "ValueFunctionMidBlock1D",
								    "block_out_channels": [3_2, 6_4, 1_2_8, 2_5_6],
								    "layers_per_block": 1,
								    "downsample_each_block": True,
								    "use_timestep_embedding": True,
								    "freq_shift": 1.0,
								    "flip_sin_to_cos": False,
								    "time_embedding_type": "positional",
								    "act_fn": "mish",
								}
								UpperCAmelCase:					Union[str, Any] 						=     self.dummy_input
								return init_dict, inputs_dict



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     Tuple:






								"""simple docstring"""



								UpperCAmelCase						,   UpperCAmelCase:					Optional[Any] 						=     UNetaDModel.from_pretrained(
								    "bglick13/hopper-medium-v2-value-function-hor32"	,				output_loading_info=__snake_case	,				subfolder="value_function"							)
								self.assertIsNotNone(__snake_case							)
								self.assertEqual(len(vf_loading_info["missing_keys"]							)	,				0							)

								value_function.to(__snake_case							)
								UpperCAmelCase:					Union[str, Any] 						=     value_function(**self.dummy_input							)

								assert image is not None, "Make sure output is not None"



							@unittest.skipIf(torch_device == "mps"	,				"mish op not supported in MPS"							)
							def     A__ (     self							)						->     Any:






								"""simple docstring"""



								UpperCAmelCase						,   UpperCAmelCase:					Dict 						=     UNetaDModel.from_pretrained(
								    "bglick13/hopper-medium-v2-value-function-hor32"	,				output_loading_info=__snake_case	,				subfolder="value_function"							)
								torch.manual_seed(0							)
								if torch.cuda.is_available():
									torch.cuda.manual_seed_all(0							)

								UpperCAmelCase:					str 						=     value_function.config.in_channels
								UpperCAmelCase:					int 						=     1_4
								UpperCAmelCase:					int 						=     torch.randn((1, seq_len, num_features)							).permute(
								    0	,				2	,				1							)  # match original, we can update values and remove
								UpperCAmelCase:					Union[str, Any] 						=     torch.full((num_features,)	,				0							)

								with torch.no_grad():
									UpperCAmelCase:					Dict 						=     value_function(__snake_case	,				__snake_case							).sample

								# fmt: off
								UpperCAmelCase:					Tuple 						=     torch.tensor([1_65.25] * seq_len							)
								# fmt: on
								self.assertTrue(torch.allclose(__snake_case	,				__snake_case	,				rtol=1e-3							)							)




							def     A__ (     self							)						->     Optional[Any]:






								"""simple docstring"""



								pass
